mirror of https://github.com/procxx/kepka.git
Track sending and failed messages.
This commit is contained in:
parent
0005e0a3ce
commit
c50ade565a
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "api/api_sending.h"
|
||||
|
||||
#include "base/unixtime.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_channel.h" // ChannelData::addsSignature.
|
||||
#include "data/data_user.h" // App::peerName(UserData*).
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_message.h" // NewMessageFlags.
|
||||
#include "ui/text/text_entity.h" // TextWithEntities.
|
||||
#include "auth_session.h"
|
||||
#include "mainwidget.h"
|
||||
#include "apiwrap.h"
|
||||
|
||||
namespace Api {
|
||||
namespace {
|
||||
|
||||
template <typename MediaData>
|
||||
void SendExistingMedia(
|
||||
not_null<History*> history,
|
||||
not_null<MediaData*> media,
|
||||
const MTPInputMedia &inputMedia,
|
||||
Data::FileOrigin origin,
|
||||
TextWithEntities caption,
|
||||
MsgId replyToId) {
|
||||
const auto peer = history->peer;
|
||||
const auto session = &history->session();
|
||||
const auto api = &session->api();
|
||||
|
||||
auto options = ApiWrap::SendOptions(history);
|
||||
options.clearDraft = false;
|
||||
options.replyTo = replyToId;
|
||||
options.generateLocal = true;
|
||||
|
||||
api->sendAction(options);
|
||||
|
||||
const auto newId = FullMsgId(peerToChannel(peer->id), clientMsgId());
|
||||
const auto randomId = rand_value<uint64>();
|
||||
|
||||
auto flags = NewMessageFlags(peer) | MTPDmessage::Flag::f_media;
|
||||
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
||||
if (options.replyTo) {
|
||||
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
|
||||
}
|
||||
bool channelPost = peer->isChannel() && !peer->isMegagroup();
|
||||
bool silentPost = channelPost && session->data().notifySilentPosts(peer);
|
||||
if (channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
}
|
||||
if (!channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
} else if (peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||
}
|
||||
auto messageFromId = channelPost ? 0 : session->userId();
|
||||
auto messagePostAuthor = channelPost
|
||||
? App::peerName(session->user())
|
||||
: QString();
|
||||
|
||||
TextUtilities::Trim(caption);
|
||||
auto sentEntities = TextUtilities::EntitiesToMTP(
|
||||
caption.entities,
|
||||
TextUtilities::ConvertOption::SkipLocal);
|
||||
if (!sentEntities.v.isEmpty()) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
||||
}
|
||||
const auto replyTo = options.replyTo;
|
||||
const auto captionText = caption.text;
|
||||
|
||||
session->data().registerMessageRandomId(randomId, newId);
|
||||
|
||||
history->addNewLocalMessage(
|
||||
newId.msg,
|
||||
flags,
|
||||
0,
|
||||
replyTo,
|
||||
base::unixtime::now(),
|
||||
messageFromId,
|
||||
messagePostAuthor,
|
||||
media,
|
||||
caption,
|
||||
MTPReplyMarkup());
|
||||
|
||||
auto failHandler = std::make_shared<Fn<void(const RPCError&, QByteArray)>>();
|
||||
auto performRequest = [=] {
|
||||
const auto usedFileReference = media->fileReference();
|
||||
history->sendRequestId = api->request(MTPmessages_SendMedia(
|
||||
MTP_flags(sendFlags),
|
||||
peer->input,
|
||||
MTP_int(replyTo),
|
||||
inputMedia,
|
||||
MTP_string(captionText),
|
||||
MTP_long(randomId),
|
||||
MTPReplyMarkup(),
|
||||
sentEntities
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
api->applyUpdates(result, randomId);
|
||||
}).fail([=](const RPCError &error) {
|
||||
(*failHandler)(error, usedFileReference);
|
||||
}).afterRequest(history->sendRequestId
|
||||
).send();
|
||||
};
|
||||
*failHandler = [=](const RPCError &error, QByteArray usedFileReference) {
|
||||
if (error.code() == 400
|
||||
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
|
||||
api->refreshFileReference(origin, [=](const auto &result) {
|
||||
if (media->fileReference() != usedFileReference) {
|
||||
performRequest();
|
||||
} else {
|
||||
api->sendMessageFail(error, peer, newId);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
api->sendMessageFail(error, peer, newId);
|
||||
}
|
||||
};
|
||||
performRequest();
|
||||
|
||||
if (const auto main = App::main()) {
|
||||
main->finishForwarding(history);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SendExistingDocument(
|
||||
not_null<History*> history,
|
||||
not_null<DocumentData*> document) {
|
||||
SendExistingDocument(history, document, {});
|
||||
}
|
||||
|
||||
void SendExistingDocument(
|
||||
not_null<History*> history,
|
||||
not_null<DocumentData*> document,
|
||||
TextWithEntities caption,
|
||||
MsgId replyToId) {
|
||||
SendExistingMedia(
|
||||
history,
|
||||
document,
|
||||
MTP_inputMediaDocument(
|
||||
MTP_flags(0),
|
||||
document->mtpInput(),
|
||||
MTPint()),
|
||||
document->stickerOrGifOrigin(),
|
||||
caption,
|
||||
replyToId);
|
||||
|
||||
if (document->sticker()) {
|
||||
if (const auto main = App::main()) {
|
||||
main->incrementSticker(document);
|
||||
document->session().data().notifyRecentStickersUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendExistingPhoto(
|
||||
not_null<History*> history,
|
||||
not_null<PhotoData*> photo) {
|
||||
SendExistingPhoto(history, photo, {});
|
||||
}
|
||||
|
||||
void SendExistingPhoto(
|
||||
not_null<History*> history,
|
||||
not_null<PhotoData*> photo,
|
||||
TextWithEntities caption,
|
||||
MsgId replyToId) {
|
||||
SendExistingMedia(
|
||||
history,
|
||||
photo,
|
||||
MTP_inputMediaPhoto(
|
||||
MTP_flags(0),
|
||||
photo->mtpInput(),
|
||||
MTPint()),
|
||||
Data::FileOrigin(),
|
||||
caption,
|
||||
replyToId);
|
||||
}
|
||||
|
||||
} // namespace Api
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class History;
|
||||
class DocumentData;
|
||||
struct TextWithEntities;
|
||||
|
||||
namespace Api {
|
||||
|
||||
void SendExistingDocument(
|
||||
not_null<History*> history,
|
||||
not_null<DocumentData*> document);
|
||||
|
||||
void SendExistingDocument(
|
||||
not_null<History*> history,
|
||||
not_null<DocumentData*> document,
|
||||
TextWithEntities caption,
|
||||
MsgId replyToId = 0);
|
||||
|
||||
void SendExistingPhoto(
|
||||
not_null<History*> history,
|
||||
not_null<PhotoData*> photo);
|
||||
|
||||
void SendExistingPhoto(
|
||||
not_null<History*> history,
|
||||
not_null<PhotoData*> photo,
|
||||
TextWithEntities caption,
|
||||
MsgId replyToId = 0);
|
||||
|
||||
} // namespace Api
|
|
@ -549,8 +549,9 @@ void ApiWrap::toggleHistoryArchived(
|
|||
//}
|
||||
|
||||
void ApiWrap::sendMessageFail(
|
||||
const RPCError &error,
|
||||
not_null<PeerData*> peer,
|
||||
const RPCError &error) {
|
||||
FullMsgId itemId) {
|
||||
if (error.type() == qstr("PEER_FLOOD")) {
|
||||
Ui::show(Box<InformBox>(
|
||||
PeerFloodErrorText(PeerFloodType::Send)));
|
||||
|
@ -571,6 +572,9 @@ void ApiWrap::sendMessageFail(
|
|||
base::unixtime::now() - (left - seconds));
|
||||
}
|
||||
}
|
||||
if (const auto item = _session->data().message(itemId)) {
|
||||
item->sendFailed();
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback) {
|
||||
|
@ -4452,6 +4456,7 @@ void ApiWrap::forwardMessages(
|
|||
auto currentGroupId = items.front()->groupId();
|
||||
auto ids = QVector<MTPint>();
|
||||
auto randomIds = QVector<MTPlong>();
|
||||
auto localIds = std::unique_ptr<std::vector<FullMsgId>>();
|
||||
|
||||
const auto sendAccumulated = [&] {
|
||||
if (shared) {
|
||||
|
@ -4473,12 +4478,21 @@ void ApiWrap::forwardMessages(
|
|||
if (shared && !--shared->requestsLeft) {
|
||||
shared->callback();
|
||||
}
|
||||
}).fail([=, ids = std::move(localIds)](const RPCError &error) {
|
||||
if (ids) {
|
||||
for (const auto &itemId : *ids) {
|
||||
sendMessageFail(error, peer, itemId);
|
||||
}
|
||||
} else {
|
||||
sendMessageFail(error, peer);
|
||||
}
|
||||
}).afterRequest(
|
||||
history->sendRequestId
|
||||
).send();
|
||||
|
||||
ids.resize(0);
|
||||
randomIds.resize(0);
|
||||
localIds = nullptr;
|
||||
};
|
||||
|
||||
ids.reserve(count);
|
||||
|
@ -4486,7 +4500,7 @@ void ApiWrap::forwardMessages(
|
|||
for (const auto item : items) {
|
||||
auto randomId = rand_value<uint64>();
|
||||
if (genClientSideMessage) {
|
||||
if (auto message = item->toHistoryMessage()) {
|
||||
if (const auto message = item->toHistoryMessage()) {
|
||||
const auto newId = FullMsgId(
|
||||
peerToChannel(peer->id),
|
||||
clientMsgId());
|
||||
|
@ -4497,7 +4511,7 @@ void ApiWrap::forwardMessages(
|
|||
const auto messagePostAuthor = channelPost
|
||||
? App::peerName(self)
|
||||
: QString();
|
||||
history->addNewForwarded(
|
||||
history->addNewLocalMessage(
|
||||
newId.msg,
|
||||
flags,
|
||||
base::unixtime::now(),
|
||||
|
@ -4505,6 +4519,10 @@ void ApiWrap::forwardMessages(
|
|||
messagePostAuthor,
|
||||
message);
|
||||
_session->data().registerMessageRandomId(randomId, newId);
|
||||
if (!localIds) {
|
||||
localIds = std::make_unique<std::vector<FullMsgId>>();
|
||||
}
|
||||
localIds->push_back(newId);
|
||||
}
|
||||
}
|
||||
const auto newFrom = item->history()->peer;
|
||||
|
@ -4864,7 +4882,7 @@ void ApiWrap::editUploadedFile(
|
|||
Box<InformBox>(tr::lng_edit_media_invalid_file(tr::now)),
|
||||
LayerOption::KeepOther);
|
||||
} else {
|
||||
sendMessageFail(peer, error);
|
||||
sendMessageFail(error, peer);
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
@ -4997,7 +5015,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
|||
if (error.type() == qstr("MESSAGE_EMPTY")) {
|
||||
lastMessage->destroy();
|
||||
} else {
|
||||
sendMessageFail(peer, error);
|
||||
sendMessageFail(error, peer, newId);
|
||||
}
|
||||
history->clearSentDraftText(QString());
|
||||
}).afterRequest(history->sendRequestId
|
||||
|
@ -5110,7 +5128,7 @@ void ApiWrap::sendInlineResult(
|
|||
applyUpdates(result, randomId);
|
||||
history->clearSentDraftText(QString());
|
||||
}).fail([=](const RPCError &error) {
|
||||
sendMessageFail(peer, error);
|
||||
sendMessageFail(error, peer, newId);
|
||||
history->clearSentDraftText(QString());
|
||||
}).afterRequest(history->sendRequestId
|
||||
).send();
|
||||
|
@ -5120,116 +5138,6 @@ void ApiWrap::sendInlineResult(
|
|||
}
|
||||
}
|
||||
|
||||
void ApiWrap::sendExistingDocument(
|
||||
not_null<DocumentData*> document,
|
||||
Data::FileOrigin origin,
|
||||
TextWithEntities caption,
|
||||
const SendOptions &options) {
|
||||
sendAction(options);
|
||||
|
||||
const auto history = options.history;
|
||||
const auto peer = history->peer;
|
||||
const auto newId = FullMsgId(peerToChannel(peer->id), clientMsgId());
|
||||
const auto randomId = rand_value<uint64>();
|
||||
|
||||
auto flags = NewMessageFlags(peer) | MTPDmessage::Flag::f_media;
|
||||
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
||||
if (options.replyTo) {
|
||||
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
|
||||
}
|
||||
bool channelPost = peer->isChannel() && !peer->isMegagroup();
|
||||
bool silentPost = channelPost
|
||||
&& _session->data().notifySilentPosts(peer);
|
||||
if (channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
}
|
||||
if (!channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
} else if (peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||
}
|
||||
auto messageFromId = channelPost ? 0 : _session->userId();
|
||||
auto messagePostAuthor = channelPost
|
||||
? App::peerName(_session->user())
|
||||
: QString();
|
||||
|
||||
TextUtilities::Trim(caption);
|
||||
auto sentEntities = TextUtilities::EntitiesToMTP(
|
||||
caption.entities,
|
||||
TextUtilities::ConvertOption::SkipLocal);
|
||||
if (!sentEntities.v.isEmpty()) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
||||
}
|
||||
const auto replyTo = options.replyTo;
|
||||
const auto captionText = caption.text;
|
||||
|
||||
_session->data().registerMessageRandomId(randomId, newId);
|
||||
|
||||
history->addNewDocument(
|
||||
newId.msg,
|
||||
flags,
|
||||
0,
|
||||
replyTo,
|
||||
base::unixtime::now(),
|
||||
messageFromId,
|
||||
messagePostAuthor,
|
||||
document,
|
||||
caption,
|
||||
MTPReplyMarkup());
|
||||
|
||||
auto failHandler = std::make_shared<Fn<void(const RPCError&, QByteArray)>>();
|
||||
auto performRequest = [=] {
|
||||
const auto usedFileReference = document->fileReference();
|
||||
history->sendRequestId = request(MTPmessages_SendMedia(
|
||||
MTP_flags(sendFlags),
|
||||
peer->input,
|
||||
MTP_int(replyTo),
|
||||
MTP_inputMediaDocument(
|
||||
MTP_flags(0),
|
||||
document->mtpInput(),
|
||||
MTPint()),
|
||||
MTP_string(captionText),
|
||||
MTP_long(randomId),
|
||||
MTPReplyMarkup(),
|
||||
sentEntities
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result, randomId);
|
||||
}).fail([=](const RPCError &error) {
|
||||
(*failHandler)(error, usedFileReference);
|
||||
}).afterRequest(history->sendRequestId
|
||||
).send();
|
||||
};
|
||||
*failHandler = [=](const RPCError &error, QByteArray usedFileReference) {
|
||||
if (error.code() == 400
|
||||
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
|
||||
auto refreshed = [=](const UpdatedFileReferences &data) {
|
||||
if (document->fileReference() != usedFileReference) {
|
||||
performRequest();
|
||||
} else {
|
||||
sendMessageFail(peer, error);
|
||||
}
|
||||
};
|
||||
refreshFileReference(origin, std::move(refreshed));
|
||||
} else {
|
||||
sendMessageFail(peer, error);
|
||||
}
|
||||
};
|
||||
performRequest();
|
||||
|
||||
if (const auto main = App::main()) {
|
||||
main->finishForwarding(history);
|
||||
if (document->sticker()) {
|
||||
main->incrementSticker(document);
|
||||
_session->data().notifyRecentStickersUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::uploadAlbumMedia(
|
||||
not_null<HistoryItem*> item,
|
||||
const MessageGroupId &groupId,
|
||||
|
@ -5341,6 +5249,7 @@ void ApiWrap::sendMediaWithRandomId(
|
|||
: MTPmessages_SendMedia::Flag(0));
|
||||
|
||||
const auto peer = history->peer;
|
||||
const auto itemId = item->fullId();
|
||||
history->sendRequestId = request(MTPmessages_SendMedia(
|
||||
MTP_flags(flags),
|
||||
peer->input,
|
||||
|
@ -5350,9 +5259,12 @@ void ApiWrap::sendMediaWithRandomId(
|
|||
MTP_long(randomId),
|
||||
MTPReplyMarkup(),
|
||||
sentEntities
|
||||
)).done([=](const MTPUpdates &result) { applyUpdates(result);
|
||||
}).fail([=](const RPCError &error) { sendMessageFail(peer, error);
|
||||
}).afterRequest(history->sendRequestId
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
sendMessageFail(error, peer, itemId);
|
||||
}).afterRequest(
|
||||
history->sendRequestId
|
||||
).send();
|
||||
}
|
||||
|
||||
|
@ -5438,9 +5350,15 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
|||
_sendingAlbums.remove(groupId);
|
||||
applyUpdates(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
_sendingAlbums.remove(groupId);
|
||||
sendMessageFail(peer, error);
|
||||
}).afterRequest(history->sendRequestId
|
||||
if (const auto album = _sendingAlbums.take(groupId)) {
|
||||
for (const auto &item : (*album)->items) {
|
||||
sendMessageFail(error, peer, item.msgId);
|
||||
}
|
||||
} else {
|
||||
sendMessageFail(error, peer);
|
||||
}
|
||||
}).afterRequest(
|
||||
history->sendRequestId
|
||||
).send();
|
||||
}
|
||||
|
||||
|
|
|
@ -459,11 +459,10 @@ public:
|
|||
not_null<UserData*> bot,
|
||||
not_null<InlineBots::Result*> data,
|
||||
const SendOptions &options);
|
||||
void sendExistingDocument(
|
||||
not_null<DocumentData*> document,
|
||||
Data::FileOrigin origin,
|
||||
TextWithEntities caption,
|
||||
const SendOptions &options);
|
||||
void sendMessageFail(
|
||||
const RPCError &error,
|
||||
not_null<PeerData*> peer,
|
||||
FullMsgId itemId = FullMsgId());
|
||||
|
||||
void requestSupportContact(FnMut<void(const MTPUser&)> callback);
|
||||
|
||||
|
@ -662,9 +661,6 @@ private:
|
|||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> from);
|
||||
|
||||
void sendMessageFail(
|
||||
not_null<PeerData*> peer,
|
||||
const RPCError &error);
|
||||
void uploadAlbumMedia(
|
||||
not_null<HistoryItem*> item,
|
||||
const MessageGroupId &groupId,
|
||||
|
|
|
@ -29,24 +29,27 @@ namespace {
|
|||
void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
||||
const auto history = chat->owner().historyLoaded(chat);
|
||||
const auto randomId = rand_value<uint64>();
|
||||
const auto requestId = MTP::send(
|
||||
MTPmessages_SendMedia(
|
||||
MTP_flags(0),
|
||||
chat->input,
|
||||
MTP_int(0),
|
||||
MTP_inputMediaGame(
|
||||
MTP_inputGameShortName(
|
||||
bot->inputUser,
|
||||
MTP_string(bot->botInfo->shareGameShortName))),
|
||||
MTP_string(),
|
||||
MTP_long(randomId),
|
||||
MTPReplyMarkup(),
|
||||
MTPVector<MTPMessageEntity>()),
|
||||
App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
|
||||
App::main()->rpcFail(&MainWidget::sendMessageFail),
|
||||
0,
|
||||
0,
|
||||
history ? history->sendRequestId : 0);
|
||||
const auto api = &chat->session().api();
|
||||
const auto requestId = api->request(MTPmessages_SendMedia(
|
||||
MTP_flags(0),
|
||||
chat->input,
|
||||
MTP_int(0),
|
||||
MTP_inputMediaGame(
|
||||
MTP_inputGameShortName(
|
||||
bot->inputUser,
|
||||
MTP_string(bot->botInfo->shareGameShortName))),
|
||||
MTP_string(),
|
||||
MTP_long(randomId),
|
||||
MTPReplyMarkup(),
|
||||
MTPVector<MTPMessageEntity>()
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
api->applyUpdates(result, randomId);
|
||||
}).fail([=](const RPCError &error) {
|
||||
api->sendMessageFail(error, chat);
|
||||
}).afterRequest(
|
||||
history ? history->sendRequestId : 0
|
||||
).send();
|
||||
|
||||
if (history) {
|
||||
history->sendRequestId = requestId;
|
||||
}
|
||||
|
|
|
@ -614,18 +614,6 @@ std::vector<not_null<HistoryItem*>> History::createItems(
|
|||
return result;
|
||||
}
|
||||
|
||||
not_null<HistoryItem*> History::addNewService(
|
||||
MsgId msgId,
|
||||
TimeId date,
|
||||
const QString &text,
|
||||
MTPDmessage::Flags flags,
|
||||
bool unread) {
|
||||
auto message = HistoryService::PreparedText { text };
|
||||
return addNewItem(
|
||||
new HistoryService(this, msgId, date, message, flags),
|
||||
unread);
|
||||
}
|
||||
|
||||
HistoryItem *History::addNewMessage(
|
||||
const MTPMessage &msg,
|
||||
NewMessageType type) {
|
||||
|
@ -696,13 +684,13 @@ HistoryItem *History::addToHistory(const MTPMessage &msg) {
|
|||
return createItem(msg, detachExistingItem);
|
||||
}
|
||||
|
||||
not_null<HistoryItem*> History::addNewForwarded(
|
||||
not_null<HistoryItem*> History::addNewLocalMessage(
|
||||
MsgId id,
|
||||
MTPDmessage::Flags flags,
|
||||
TimeId date,
|
||||
UserId from,
|
||||
const QString &postAuthor,
|
||||
not_null<HistoryMessage*> original) {
|
||||
not_null<HistoryMessage*> forwardOriginal) {
|
||||
return addNewItem(
|
||||
owner().makeMessage(
|
||||
this,
|
||||
|
@ -711,11 +699,11 @@ not_null<HistoryItem*> History::addNewForwarded(
|
|||
date,
|
||||
from,
|
||||
postAuthor,
|
||||
original),
|
||||
forwardOriginal),
|
||||
true);
|
||||
}
|
||||
|
||||
not_null<HistoryItem*> History::addNewDocument(
|
||||
not_null<HistoryItem*> History::addNewLocalMessage(
|
||||
MsgId id,
|
||||
MTPDmessage::Flags flags,
|
||||
UserId viaBotId,
|
||||
|
@ -742,7 +730,7 @@ not_null<HistoryItem*> History::addNewDocument(
|
|||
true);
|
||||
}
|
||||
|
||||
not_null<HistoryItem*> History::addNewPhoto(
|
||||
not_null<HistoryItem*> History::addNewLocalMessage(
|
||||
MsgId id,
|
||||
MTPDmessage::Flags flags,
|
||||
UserId viaBotId,
|
||||
|
@ -769,7 +757,7 @@ not_null<HistoryItem*> History::addNewPhoto(
|
|||
true);
|
||||
}
|
||||
|
||||
not_null<HistoryItem*> History::addNewGame(
|
||||
not_null<HistoryItem*> History::addNewLocalMessage(
|
||||
MsgId id,
|
||||
MTPDmessage::Flags flags,
|
||||
UserId viaBotId,
|
||||
|
@ -1260,10 +1248,33 @@ void History::newItemAdded(not_null<HistoryItem*> item) {
|
|||
|
||||
void History::registerLocalMessage(not_null<HistoryItem*> item) {
|
||||
_localMessages.emplace(item);
|
||||
if (peer->isChannel()) {
|
||||
Notify::peerUpdatedDelayed(
|
||||
peer,
|
||||
Notify::PeerUpdate::Flag::ChannelLocalMessages);
|
||||
}
|
||||
}
|
||||
|
||||
void History::unregisterLocalMessage(not_null<HistoryItem*> item) {
|
||||
_localMessages.remove(item);
|
||||
if (peer->isChannel()) {
|
||||
Notify::peerUpdatedDelayed(
|
||||
peer,
|
||||
Notify::PeerUpdate::Flag::ChannelLocalMessages);
|
||||
}
|
||||
}
|
||||
|
||||
HistoryItem *History::latestSendingMessage() const {
|
||||
auto sending = ranges::view::all(
|
||||
_localMessages
|
||||
) | ranges::view::filter([](not_null<HistoryItem*> item) {
|
||||
return item->isSending();
|
||||
});
|
||||
const auto i = ranges::max_element(sending, ranges::less(), [](
|
||||
not_null<HistoryItem*> item) {
|
||||
return uint64(item->date()) << 32 | uint32(item->id);
|
||||
});
|
||||
return (i == sending.end()) ? nullptr : i->get();
|
||||
}
|
||||
|
||||
HistoryBlock *History::prepareBlockForAddingItem() {
|
||||
|
|
|
@ -95,20 +95,14 @@ public:
|
|||
|
||||
HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type);
|
||||
HistoryItem *addToHistory(const MTPMessage &msg);
|
||||
not_null<HistoryItem*> addNewService(
|
||||
MsgId msgId,
|
||||
TimeId date,
|
||||
const QString &text,
|
||||
MTPDmessage::Flags flags = 0,
|
||||
bool newMsg = true);
|
||||
not_null<HistoryItem*> addNewForwarded(
|
||||
not_null<HistoryItem*> addNewLocalMessage(
|
||||
MsgId id,
|
||||
MTPDmessage::Flags flags,
|
||||
TimeId date,
|
||||
UserId from,
|
||||
const QString &postAuthor,
|
||||
not_null<HistoryMessage*> original);
|
||||
not_null<HistoryItem*> addNewDocument(
|
||||
not_null<HistoryMessage*> forwardOriginal);
|
||||
not_null<HistoryItem*> addNewLocalMessage(
|
||||
MsgId id,
|
||||
MTPDmessage::Flags flags,
|
||||
UserId viaBotId,
|
||||
|
@ -119,7 +113,7 @@ public:
|
|||
not_null<DocumentData*> document,
|
||||
const TextWithEntities &caption,
|
||||
const MTPReplyMarkup &markup);
|
||||
not_null<HistoryItem*> addNewPhoto(
|
||||
not_null<HistoryItem*> addNewLocalMessage(
|
||||
MsgId id,
|
||||
MTPDmessage::Flags flags,
|
||||
UserId viaBotId,
|
||||
|
@ -130,7 +124,7 @@ public:
|
|||
not_null<PhotoData*> photo,
|
||||
const TextWithEntities &caption,
|
||||
const MTPReplyMarkup &markup);
|
||||
not_null<HistoryItem*> addNewGame(
|
||||
not_null<HistoryItem*> addNewLocalMessage(
|
||||
MsgId id,
|
||||
MTPDmessage::Flags flags,
|
||||
UserId viaBotId,
|
||||
|
@ -155,6 +149,7 @@ public:
|
|||
|
||||
void registerLocalMessage(not_null<HistoryItem*> item);
|
||||
void unregisterLocalMessage(not_null<HistoryItem*> item);
|
||||
[[nodiscard]] HistoryItem *latestSendingMessage() const;
|
||||
|
||||
MsgId readInbox();
|
||||
void applyInboxReadUpdate(
|
||||
|
|
|
@ -39,6 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_user.h"
|
||||
#include "observer_peer.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_history.h"
|
||||
|
||||
|
@ -664,6 +665,19 @@ MsgId HistoryItem::idOriginal() const {
|
|||
return id;
|
||||
}
|
||||
|
||||
void HistoryItem::sendFailed() {
|
||||
Expects(_flags & MTPDmessage_ClientFlag::f_sending);
|
||||
Expects(!(_flags & MTPDmessage_ClientFlag::f_failed));
|
||||
|
||||
_flags = (_flags | MTPDmessage_ClientFlag::f_failed)
|
||||
& ~MTPDmessage_ClientFlag::f_sending;
|
||||
if (history()->peer->isChannel()) {
|
||||
Notify::peerUpdatedDelayed(
|
||||
history()->peer,
|
||||
Notify::PeerUpdate::Flag::ChannelLocalMessages);
|
||||
}
|
||||
}
|
||||
|
||||
bool HistoryItem::needCheck() const {
|
||||
return out() || (id < 0 && history()->peer->isSelf());
|
||||
}
|
||||
|
|
|
@ -122,7 +122,6 @@ public:
|
|||
[[nodiscard]] bool hasUnreadMediaFlag() const;
|
||||
void markMediaRead();
|
||||
|
||||
|
||||
// For edit media in history_message.
|
||||
virtual void returnSavedMedia() {};
|
||||
void savePreviousMedia() {
|
||||
|
@ -174,6 +173,13 @@ public:
|
|||
bool isSilent() const {
|
||||
return _flags & MTPDmessage::Flag::f_silent;
|
||||
}
|
||||
bool isSending() const {
|
||||
return _flags & MTPDmessage_ClientFlag::f_sending;
|
||||
}
|
||||
bool hasFailed() const {
|
||||
return _flags & MTPDmessage_ClientFlag::f_failed;
|
||||
}
|
||||
void sendFailed();
|
||||
virtual int viewsCount() const {
|
||||
return hasViews() ? 1 : -1;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "history/history_widget.h"
|
||||
|
||||
#include "api/api_sending.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/send_files_box.h"
|
||||
#include "boxes/share_box.h"
|
||||
|
@ -236,7 +237,7 @@ object_ptr<Ui::FlatButton> SetupDiscussButton(
|
|||
return result;
|
||||
}
|
||||
|
||||
void ShowSlowmodeToast(const QString &text) {
|
||||
void ShowErrorToast(const QString &text) {
|
||||
auto config = Ui::Toast::Config();
|
||||
config.multiline = true;
|
||||
config.minWidth = st::msgMinWidth;
|
||||
|
@ -244,13 +245,6 @@ void ShowSlowmodeToast(const QString &text) {
|
|||
Ui::Toast::Show(config);
|
||||
}
|
||||
|
||||
void ShowSlowmodeToast(int seconds) {
|
||||
ShowSlowmodeToast(tr::lng_slowmode_enabled(
|
||||
tr::now,
|
||||
lt_left,
|
||||
formatDurationWords(seconds)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
HistoryWidget::HistoryWidget(
|
||||
|
@ -511,7 +505,9 @@ HistoryWidget::HistoryWidget(
|
|||
| UpdateFlag::NotificationsEnabled
|
||||
| UpdateFlag::ChannelAmIn
|
||||
| UpdateFlag::ChannelPromotedChanged
|
||||
| UpdateFlag::ChannelLinkedChat;
|
||||
| UpdateFlag::ChannelLinkedChat
|
||||
| UpdateFlag::ChannelSlowmode
|
||||
| UpdateFlag::ChannelLocalMessages;
|
||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(changes, [=](const Notify::PeerUpdate &update) {
|
||||
if (update.peer == _peer) {
|
||||
if (update.flags & UpdateFlag::RightsChanged) {
|
||||
|
@ -552,6 +548,10 @@ HistoryWidget::HistoryWidget(
|
|||
updateControlsGeometry();
|
||||
this->update();
|
||||
}
|
||||
if (update.flags & (UpdateFlag::ChannelSlowmode
|
||||
| UpdateFlag::ChannelLocalMessages)) {
|
||||
updateSendButtonType();
|
||||
}
|
||||
if (update.flags & (UpdateFlag::UserIsBlocked
|
||||
| UpdateFlag::AdminsChanged
|
||||
| UpdateFlag::MembersChanged
|
||||
|
@ -2820,8 +2820,7 @@ void HistoryWidget::send(Qt::KeyboardModifiers modifiers) {
|
|||
} else if (_editMsgId) {
|
||||
saveEditMsg();
|
||||
return;
|
||||
} else if (const auto left = _peer->slowmodeSecondsLeft()) {
|
||||
ShowSlowmodeToast(left);
|
||||
} else if (showSlowmodeError()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2842,7 +2841,7 @@ void HistoryWidget::send(Qt::KeyboardModifiers modifiers) {
|
|||
|| (!_toForward.empty()
|
||||
&& !message.textWithTags.text.isEmpty())
|
||||
|| (message.textWithTags.text.size() > MaxMessageSize)) {
|
||||
ShowSlowmodeToast(tr::lng_slowmode_no_many(tr::now));
|
||||
ShowErrorToast(tr::lng_slowmode_no_many(tr::now));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -3047,8 +3046,7 @@ void HistoryWidget::chooseAttach() {
|
|||
ChatRestriction::f_send_media)) {
|
||||
Ui::Toast::Show(*error);
|
||||
return;
|
||||
} else if (const auto left = _peer->slowmodeSecondsLeft()) {
|
||||
ShowSlowmodeToast(left);
|
||||
} else if (showSlowmodeError()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3167,6 +3165,8 @@ void HistoryWidget::recordStartCallback() {
|
|||
if (error) {
|
||||
Ui::show(Box<InformBox>(*error));
|
||||
return;
|
||||
} else if (showSlowmodeError()) {
|
||||
return;
|
||||
} else if (!Media::Capture::instance()->available()) {
|
||||
return;
|
||||
}
|
||||
|
@ -3581,6 +3581,10 @@ void HistoryWidget::updateSendButtonType() {
|
|||
: 0;
|
||||
}();
|
||||
_send->setSlowmodeDelay(delay);
|
||||
_send->setDisabled(_peer
|
||||
&& _peer->slowmodeApplied()
|
||||
&& (_history->latestSendingMessage() != nullptr)
|
||||
&& (type == Type::Send || type == Type::Record));
|
||||
|
||||
if (delay != 0) {
|
||||
App::CallDelayed(
|
||||
|
@ -4020,7 +4024,7 @@ bool HistoryWidget::showSendingFilesError(
|
|||
return false;
|
||||
}
|
||||
|
||||
ShowSlowmodeToast(text);
|
||||
ShowErrorToast(text);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4218,7 +4222,7 @@ void HistoryWidget::uploadFilesAfterConfirmation(
|
|||
|| (!list.files.empty()
|
||||
&& !caption.text.isEmpty()
|
||||
&& !list.canAddCaption(isAlbum, compressImages)))) {
|
||||
ShowSlowmodeToast(tr::lng_slowmode_no_many(tr::now));
|
||||
ShowErrorToast(tr::lng_slowmode_no_many(tr::now));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5331,6 +5335,31 @@ void HistoryWidget::replyToNextMessage() {
|
|||
}
|
||||
}
|
||||
|
||||
bool HistoryWidget::showSlowmodeError() {
|
||||
const auto text = [&] {
|
||||
if (const auto left = _peer->slowmodeSecondsLeft()) {
|
||||
return tr::lng_slowmode_enabled(
|
||||
tr::now,
|
||||
lt_left,
|
||||
formatDurationWords(left));
|
||||
} else if (_peer->slowmodeApplied()) {
|
||||
if (const auto item = _history->latestSendingMessage()) {
|
||||
if (const auto view = item->mainView()) {
|
||||
animatedScrollToItem(item->id);
|
||||
enqueueMessageHighlight(view);
|
||||
}
|
||||
return tr::lng_slowmode_no_many(tr::now);
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}();
|
||||
if (text.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
ShowErrorToast(text);
|
||||
return true;
|
||||
}
|
||||
|
||||
void HistoryWidget::onFieldTabbed() {
|
||||
if (_supportAutocomplete) {
|
||||
_supportAutocomplete->activate(_field.data());
|
||||
|
@ -5344,8 +5373,7 @@ void HistoryWidget::sendInlineResult(
|
|||
not_null<UserData*> bot) {
|
||||
if (!_peer || !_peer->canWrite()) {
|
||||
return;
|
||||
} else if (const auto left = _peer->slowmodeSecondsLeft()) {
|
||||
ShowSlowmodeToast(left);
|
||||
} else if (showSlowmodeError()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5500,18 +5528,11 @@ bool HistoryWidget::sendExistingDocument(
|
|||
return false;
|
||||
} else if (!_peer || !_peer->canWrite()) {
|
||||
return false;
|
||||
} else if (const auto left = _peer->slowmodeSecondsLeft()) {
|
||||
ShowSlowmodeToast(left);
|
||||
} else if (showSlowmodeError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto origin = document->stickerOrGifOrigin();
|
||||
|
||||
auto options = ApiWrap::SendOptions(_history);
|
||||
options.clearDraft = false;
|
||||
options.replyTo = replyToId();
|
||||
options.generateLocal = true;
|
||||
session().api().sendExistingDocument(document, origin, caption, options);
|
||||
Api::SendExistingDocument(_history, document, caption, replyToId());
|
||||
|
||||
if (_fieldAutocomplete->stickersShown()) {
|
||||
clearFieldText();
|
||||
|
@ -5538,91 +5559,15 @@ bool HistoryWidget::sendExistingPhoto(
|
|||
return false;
|
||||
} else if (!_peer || !_peer->canWrite()) {
|
||||
return false;
|
||||
} else if (const auto left = _peer->slowmodeSecondsLeft()) {
|
||||
ShowSlowmodeToast(left);
|
||||
} else if (showSlowmodeError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto options = ApiWrap::SendOptions(_history);
|
||||
options.clearDraft = false;
|
||||
options.replyTo = replyToId();
|
||||
options.generateLocal = true;
|
||||
session().api().sendAction(options);
|
||||
|
||||
const auto randomId = rand_value<uint64>();
|
||||
const auto newId = FullMsgId(_channel, clientMsgId());
|
||||
|
||||
auto flags = NewMessageFlags(_peer) | MTPDmessage::Flag::f_media;
|
||||
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
||||
if (options.replyTo) {
|
||||
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
|
||||
}
|
||||
bool channelPost = _peer->isChannel() && !_peer->isMegagroup();
|
||||
bool silentPost = channelPost && session().data().notifySilentPosts(_peer);
|
||||
if (channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_views;
|
||||
flags |= MTPDmessage::Flag::f_post;
|
||||
}
|
||||
if (!channelPost) {
|
||||
flags |= MTPDmessage::Flag::f_from_id;
|
||||
} else if (_peer->asChannel()->addsSignature()) {
|
||||
flags |= MTPDmessage::Flag::f_post_author;
|
||||
}
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||
}
|
||||
auto messageFromId = channelPost ? 0 : session().userId();
|
||||
auto messagePostAuthor = channelPost
|
||||
? App::peerName(session().user())
|
||||
: QString();
|
||||
|
||||
TextUtilities::Trim(caption);
|
||||
auto sentEntities = TextUtilities::EntitiesToMTP(
|
||||
caption.entities,
|
||||
TextUtilities::ConvertOption::SkipLocal);
|
||||
if (!sentEntities.v.isEmpty()) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
||||
}
|
||||
|
||||
_history->addNewPhoto(
|
||||
newId.msg,
|
||||
flags,
|
||||
0,
|
||||
options.replyTo,
|
||||
base::unixtime::now(),
|
||||
messageFromId,
|
||||
messagePostAuthor,
|
||||
photo,
|
||||
caption,
|
||||
MTPReplyMarkup());
|
||||
|
||||
_history->sendRequestId = MTP::send(
|
||||
MTPmessages_SendMedia(
|
||||
MTP_flags(sendFlags),
|
||||
_peer->input,
|
||||
MTP_int(options.replyTo),
|
||||
MTP_inputMediaPhoto(
|
||||
MTP_flags(0),
|
||||
photo->mtpInput(),
|
||||
MTPint()),
|
||||
MTP_string(caption.text),
|
||||
MTP_long(randomId),
|
||||
MTPReplyMarkup(),
|
||||
sentEntities),
|
||||
App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
|
||||
App::main()->rpcFail(&MainWidget::sendMessageFail),
|
||||
0,
|
||||
0,
|
||||
_history->sendRequestId);
|
||||
App::main()->finishForwarding(_history);
|
||||
|
||||
_history->owner().registerMessageRandomId(randomId, newId);
|
||||
Api::SendExistingPhoto(_history, photo, caption, replyToId());
|
||||
|
||||
hideSelectorControlsAnimated();
|
||||
|
||||
_field->setFocus();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -467,6 +467,7 @@ private:
|
|||
void cancelReplyAfterMediaSend(bool lastKeyboardUsed);
|
||||
void replyToPreviousMessage();
|
||||
void replyToNextMessage();
|
||||
[[nodiscard]] bool showSlowmodeError();
|
||||
|
||||
void hideSelectorControlsAnimated();
|
||||
int countMembersDropdownHeightMax() const;
|
||||
|
|
|
@ -128,7 +128,7 @@ void SendPhoto::addToHistory(
|
|||
MsgId replyToId,
|
||||
const QString &postAuthor,
|
||||
const MTPReplyMarkup &markup) const {
|
||||
history->addNewPhoto(
|
||||
history->addNewLocalMessage(
|
||||
msgId,
|
||||
flags,
|
||||
viaBotId,
|
||||
|
@ -161,7 +161,7 @@ void SendFile::addToHistory(
|
|||
MsgId replyToId,
|
||||
const QString &postAuthor,
|
||||
const MTPReplyMarkup &markup) const {
|
||||
history->addNewDocument(
|
||||
history->addNewLocalMessage(
|
||||
msgId,
|
||||
flags,
|
||||
viaBotId,
|
||||
|
@ -208,7 +208,7 @@ void SendGame::addToHistory(
|
|||
MsgId replyToId,
|
||||
const QString &postAuthor,
|
||||
const MTPReplyMarkup &markup) const {
|
||||
history->addNewGame(
|
||||
history->addNewLocalMessage(
|
||||
msgId,
|
||||
flags,
|
||||
viaBotId,
|
||||
|
|
|
@ -918,23 +918,6 @@ void MainWidget::removeDialog(Dialogs::Key key) {
|
|||
_dialogs->removeDialog(key);
|
||||
}
|
||||
|
||||
bool MainWidget::sendMessageFail(const RPCError &error) {
|
||||
if (MTP::isDefaultHandledError(error)) return false;
|
||||
|
||||
if (error.type() == qstr("PEER_FLOOD")) {
|
||||
Ui::show(Box<InformBox>(PeerFloodErrorText(PeerFloodType::Send)));
|
||||
return true;
|
||||
} else if (error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
|
||||
const auto link = textcmdLink(
|
||||
Core::App().createInternalLinkFull(qsl("spambot")),
|
||||
tr::lng_cant_more_info(tr::now));
|
||||
const auto text = tr::lng_error_public_groups_denied(tr::now, lt_more_info, link);
|
||||
Ui::show(Box<InformBox>(text));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MainWidget::cacheBackground() {
|
||||
if (Window::Theme::Background()->colorForFill()) {
|
||||
return;
|
||||
|
|
|
@ -195,8 +195,6 @@ public:
|
|||
|
||||
void deletePhotoLayer(PhotoData *photo);
|
||||
|
||||
bool sendMessageFail(const RPCError &error);
|
||||
|
||||
// While HistoryInner is not HistoryView::ListWidget.
|
||||
crl::time highlightStartTime(not_null<const HistoryItem*> item) const;
|
||||
|
||||
|
|
|
@ -60,8 +60,11 @@ enum class MTPDmessage_ClientFlag : uint32 {
|
|||
// message is an outgoing message that is being sent
|
||||
f_sending = (1U << 23),
|
||||
|
||||
// message was an outgoing message and failed to be sent
|
||||
f_failed = (1U << 22),
|
||||
|
||||
// update this when adding new client side flags
|
||||
MIN_FIELD = (1U << 23),
|
||||
MIN_FIELD = (1U << 22),
|
||||
};
|
||||
DEFINE_MTP_CLIENT_FLAGS(MTPDmessage)
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ struct PeerUpdate {
|
|||
ChannelLinkedChat = (1 << 20),
|
||||
ChannelLocation = (1 << 21),
|
||||
ChannelSlowmode = (1 << 22),
|
||||
ChannelLocalMessages = (1 << 23),
|
||||
};
|
||||
using Flags = base::flags<Flag>;
|
||||
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "apiwrap.h"
|
||||
#include "auth_session.h"
|
||||
#include "api/api_sending.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "chat_helpers/emoji_list_widget.h"
|
||||
#include "core/application.h"
|
||||
|
@ -809,11 +810,7 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
|||
if (const auto error = RestrictionToSendStickers()) {
|
||||
Ui::show(Box<InformBox>(*error));
|
||||
}
|
||||
Auth().api().sendExistingDocument(
|
||||
document,
|
||||
document->stickerSetOrigin(),
|
||||
{},
|
||||
ApiWrap::SendOptions(chat.history()));
|
||||
Api::SendExistingDocument(chat.history(), document);
|
||||
return true;
|
||||
} else if (const auto emoji = _stickers[index].emoji) {
|
||||
if (const auto inputField = qobject_cast<QTextEdit*>(
|
||||
|
|
|
@ -375,11 +375,15 @@ void SendButton::paintEvent(QPaintEvent *e) {
|
|||
|
||||
void SendButton::paintRecord(Painter &p, bool over) {
|
||||
auto recordActive = recordActiveRatio();
|
||||
auto rippleColor = anim::color(st::historyAttachEmoji.ripple.color, st::historyRecordVoiceRippleBgActive, recordActive);
|
||||
paintRipple(p, (width() - st::historyAttachEmoji.rippleAreaSize) / 2, st::historyAttachEmoji.rippleAreaPosition.y(), &rippleColor);
|
||||
if (!isDisabled()) {
|
||||
auto rippleColor = anim::color(st::historyAttachEmoji.ripple.color, st::historyRecordVoiceRippleBgActive, recordActive);
|
||||
paintRipple(p, (width() - st::historyAttachEmoji.rippleAreaSize) / 2, st::historyAttachEmoji.rippleAreaPosition.y(), &rippleColor);
|
||||
}
|
||||
|
||||
auto fastIcon = [&] {
|
||||
if (recordActive == 1.) {
|
||||
if (isDisabled()) {
|
||||
return &st::historyRecordVoice;
|
||||
} else if (recordActive == 1.) {
|
||||
return &st::historyRecordVoiceActive;
|
||||
} else if (over) {
|
||||
return &st::historyRecordVoiceOver;
|
||||
|
@ -387,7 +391,7 @@ void SendButton::paintRecord(Painter &p, bool over) {
|
|||
return &st::historyRecordVoice;
|
||||
};
|
||||
fastIcon()->paintInCenter(p, rect());
|
||||
if (recordActive > 0. && recordActive < 1.) {
|
||||
if (!isDisabled() && recordActive > 0. && recordActive < 1.) {
|
||||
p.setOpacity(recordActive);
|
||||
st::historyRecordVoiceActive.paintInCenter(p, rect());
|
||||
p.setOpacity(1.);
|
||||
|
@ -414,7 +418,12 @@ void SendButton::paintSend(Painter &p, bool over) {
|
|||
const auto &sendIcon = over
|
||||
? st::historySendIconOver
|
||||
: st::historySendIcon;
|
||||
sendIcon.paint(p, st::historySendIconPosition, width());
|
||||
if (isDisabled()) {
|
||||
const auto color = st::historyRecordVoiceFg->c;
|
||||
sendIcon.paint(p, st::historySendIconPosition, width(), color);
|
||||
} else {
|
||||
sendIcon.paint(p, st::historySendIconPosition, width());
|
||||
}
|
||||
}
|
||||
|
||||
void SendButton::paintSlowmode(Painter &p) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<(src_loc)/api/api_sending.cpp
|
||||
<(src_loc)/api/api_sending.h
|
||||
<(src_loc)/boxes/peers/add_participants_box.cpp
|
||||
<(src_loc)/boxes/peers/add_participants_box.h
|
||||
<(src_loc)/boxes/peers/edit_contact_box.cpp
|
||||
|
|
Loading…
Reference in New Issue