mirror of https://github.com/procxx/kepka.git
Move shareContact and readServerHistory to ApiWrap.
Also allow non-confirming contact info sharing to Saved Messages.
This commit is contained in:
parent
f0a03223e8
commit
5bc47e5203
|
@ -31,7 +31,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "history/history_widget.h"
|
#include "boxes/add_contact_box.h"
|
||||||
|
#include "history/history_message.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
|
@ -171,7 +172,7 @@ void ApiWrap::resolveMessageDatas() {
|
||||||
gotMessageDatas(nullptr, result, requestId);
|
gotMessageDatas(nullptr, result, requestId);
|
||||||
}).fail([this](const RPCError &error, mtpRequestId requestId) {
|
}).fail([this](const RPCError &error, mtpRequestId requestId) {
|
||||||
finalizeMessageDataRequest(nullptr, requestId);
|
finalizeMessageDataRequest(nullptr, requestId);
|
||||||
}).after(kSmallDelayMs).send();
|
}).afterDelay(kSmallDelayMs).send();
|
||||||
for (auto &request : _messageDataRequests) {
|
for (auto &request : _messageDataRequests) {
|
||||||
if (request.requestId > 0) continue;
|
if (request.requestId > 0) continue;
|
||||||
request.requestId = requestId;
|
request.requestId = requestId;
|
||||||
|
@ -192,7 +193,7 @@ void ApiWrap::resolveMessageDatas() {
|
||||||
gotMessageDatas(channel, result, requestId);
|
gotMessageDatas(channel, result, requestId);
|
||||||
}).fail([=](const RPCError &error, mtpRequestId requestId) {
|
}).fail([=](const RPCError &error, mtpRequestId requestId) {
|
||||||
finalizeMessageDataRequest(channel, requestId);
|
finalizeMessageDataRequest(channel, requestId);
|
||||||
}).after(kSmallDelayMs).send();
|
}).afterDelay(kSmallDelayMs).send();
|
||||||
|
|
||||||
for (auto &request : *j) {
|
for (auto &request : *j) {
|
||||||
if (request.requestId > 0) continue;
|
if (request.requestId > 0) continue;
|
||||||
|
@ -839,7 +840,7 @@ void ApiWrap::requestSelfParticipant(ChannelData *channel) {
|
||||||
if (error.type() == qstr("USER_NOT_PARTICIPANT")) {
|
if (error.type() == qstr("USER_NOT_PARTICIPANT")) {
|
||||||
channel->inviter = -1;
|
channel->inviter = -1;
|
||||||
}
|
}
|
||||||
}).after(kSmallDelayMs).send();
|
}).afterDelay(kSmallDelayMs).send();
|
||||||
|
|
||||||
_selfParticipantRequests.insert(channel, requestId);
|
_selfParticipantRequests.insert(channel, requestId);
|
||||||
}
|
}
|
||||||
|
@ -933,7 +934,7 @@ void ApiWrap::requestStickerSets() {
|
||||||
gotStickerSet(setId, result);
|
gotStickerSet(setId, result);
|
||||||
}).fail([this, setId = i.key()](const RPCError &error) {
|
}).fail([this, setId = i.key()](const RPCError &error) {
|
||||||
_stickerSetRequests.remove(setId);
|
_stickerSetRequests.remove(setId);
|
||||||
}).after(waitMs).send();
|
}).afterDelay(waitMs).send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -987,7 +988,7 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers:
|
||||||
stickerSetDisenabled(requestId);
|
stickerSetDisenabled(requestId);
|
||||||
}).fail([this](const RPCError &error, mtpRequestId requestId) {
|
}).fail([this](const RPCError &error, mtpRequestId requestId) {
|
||||||
stickerSetDisenabled(requestId);
|
stickerSetDisenabled(requestId);
|
||||||
}).after(kSmallDelayMs).send();
|
}).afterDelay(kSmallDelayMs).send();
|
||||||
|
|
||||||
_stickerSetDisenableRequests.insert(requestId);
|
_stickerSetDisenableRequests.insert(requestId);
|
||||||
|
|
||||||
|
@ -1024,7 +1025,7 @@ void ApiWrap::saveStickerSets(const Stickers::Order &localOrder, const Stickers:
|
||||||
stickerSetDisenabled(requestId);
|
stickerSetDisenabled(requestId);
|
||||||
}).fail([this](const RPCError &error, mtpRequestId requestId) {
|
}).fail([this](const RPCError &error, mtpRequestId requestId) {
|
||||||
stickerSetDisenabled(requestId);
|
stickerSetDisenabled(requestId);
|
||||||
}).after(kSmallDelayMs).send();
|
}).afterDelay(kSmallDelayMs).send();
|
||||||
|
|
||||||
_stickerSetDisenableRequests.insert(requestId);
|
_stickerSetDisenableRequests.insert(requestId);
|
||||||
|
|
||||||
|
@ -1336,13 +1337,30 @@ void ApiWrap::clearHistory(not_null<PeerData*> peer) {
|
||||||
int ApiWrap::applyAffectedHistory(
|
int ApiWrap::applyAffectedHistory(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
const MTPmessages_AffectedHistory &result) {
|
const MTPmessages_AffectedHistory &result) {
|
||||||
auto &d = result.c_messages_affectedHistory();
|
const auto &data = result.c_messages_affectedHistory();
|
||||||
if (peer && peer->isChannel()) {
|
if (const auto channel = peer->asChannel()) {
|
||||||
peer->asChannel()->ptsUpdateAndApply(d.vpts.v, d.vpts_count.v);
|
channel->ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
||||||
} else {
|
} else {
|
||||||
App::main()->ptsUpdateAndApply(d.vpts.v, d.vpts_count.v);
|
App::main()->ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
||||||
}
|
}
|
||||||
return d.voffset.v;
|
return data.voffset.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::applyAffectedMessages(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const MTPmessages_AffectedMessages &result) {
|
||||||
|
const auto &data = result.c_messages_affectedMessages();
|
||||||
|
if (const auto channel = peer->asChannel()) {
|
||||||
|
channel->ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
||||||
|
} else {
|
||||||
|
applyAffectedMessages(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::applyAffectedMessages(
|
||||||
|
const MTPmessages_AffectedMessages &result) {
|
||||||
|
const auto &data = result.c_messages_affectedMessages();
|
||||||
|
App::main()->ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::saveDraftsToCloud() {
|
void ApiWrap::saveDraftsToCloud() {
|
||||||
|
@ -1522,13 +1540,13 @@ void ApiWrap::resolveWebPages() {
|
||||||
if (!ids.isEmpty()) {
|
if (!ids.isEmpty()) {
|
||||||
requestId = request(MTPmessages_GetMessages(MTP_vector<MTPint>(ids))).done([this](const MTPmessages_Messages &result, mtpRequestId requestId) {
|
requestId = request(MTPmessages_GetMessages(MTP_vector<MTPint>(ids))).done([this](const MTPmessages_Messages &result, mtpRequestId requestId) {
|
||||||
gotWebPages(nullptr, result, requestId);
|
gotWebPages(nullptr, result, requestId);
|
||||||
}).after(kSmallDelayMs).send();
|
}).afterDelay(kSmallDelayMs).send();
|
||||||
}
|
}
|
||||||
QVector<mtpRequestId> reqsByIndex(idsByChannel.size(), 0);
|
QVector<mtpRequestId> reqsByIndex(idsByChannel.size(), 0);
|
||||||
for (auto i = idsByChannel.cbegin(), e = idsByChannel.cend(); i != e; ++i) {
|
for (auto i = idsByChannel.cbegin(), e = idsByChannel.cend(); i != e; ++i) {
|
||||||
reqsByIndex[i.value().first] = request(MTPchannels_GetMessages(i.key()->inputChannel, MTP_vector<MTPint>(i.value().second))).done([this, channel = i.key()](const MTPmessages_Messages &result, mtpRequestId requestId) {
|
reqsByIndex[i.value().first] = request(MTPchannels_GetMessages(i.key()->inputChannel, MTP_vector<MTPint>(i.value().second))).done([this, channel = i.key()](const MTPmessages_Messages &result, mtpRequestId requestId) {
|
||||||
gotWebPages(channel, result, requestId);
|
gotWebPages(channel, result, requestId);
|
||||||
}).after(kSmallDelayMs).send();
|
}).afterDelay(kSmallDelayMs).send();
|
||||||
}
|
}
|
||||||
if (requestId || !reqsByIndex.isEmpty()) {
|
if (requestId || !reqsByIndex.isEmpty()) {
|
||||||
for (auto &pendingRequestId : _webPagesPending) {
|
for (auto &pendingRequestId : _webPagesPending) {
|
||||||
|
@ -2242,7 +2260,7 @@ void ApiWrap::sendSaveChatAdminsRequests(not_null<ChatData*> chat) {
|
||||||
if (error.type() == qstr("USER_RESTRICTED")) {
|
if (error.type() == qstr("USER_RESTRICTED")) {
|
||||||
Ui::show(Box<InformBox>(lang(lng_cant_do_this)));
|
Ui::show(Box<InformBox>(lang(lng_cant_do_this)));
|
||||||
}
|
}
|
||||||
}).canWait(5).send();
|
}).afterDelay(kSmallDelayMs).send();
|
||||||
|
|
||||||
_chatAdminsSaveRequests[chat].insert(requestId);
|
_chatAdminsSaveRequests[chat].insert(requestId);
|
||||||
};
|
};
|
||||||
|
@ -2388,6 +2406,12 @@ void ApiWrap::userPhotosDone(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::sendAction(const SendOptions &options) {
|
||||||
|
readServerHistory(options.history);
|
||||||
|
options.history->getReadyFor(ShowAtTheEndMsgId);
|
||||||
|
_sendActions.fire_copy(options);
|
||||||
|
}
|
||||||
|
|
||||||
void ApiWrap::forwardMessages(
|
void ApiWrap::forwardMessages(
|
||||||
HistoryItemsList &&items,
|
HistoryItemsList &&items,
|
||||||
const SendOptions &options,
|
const SendOptions &options,
|
||||||
|
@ -2409,7 +2433,7 @@ void ApiWrap::forwardMessages(
|
||||||
const auto genClientSideMessage = options.generateLocal && (count < 2);
|
const auto genClientSideMessage = options.generateLocal && (count < 2);
|
||||||
const auto history = options.history;
|
const auto history = options.history;
|
||||||
|
|
||||||
App::main()->readServerHistory(history);
|
readServerHistory(history);
|
||||||
|
|
||||||
const auto channelPost = history->peer->isChannel()
|
const auto channelPost = history->peer->isChannel()
|
||||||
&& !history->peer->isMegagroup();
|
&& !history->peer->isMegagroup();
|
||||||
|
@ -2450,7 +2474,7 @@ void ApiWrap::forwardMessages(
|
||||||
if (shared && !--shared->requestsLeft) {
|
if (shared && !--shared->requestsLeft) {
|
||||||
shared->callback();
|
shared->callback();
|
||||||
}
|
}
|
||||||
}).after(
|
}).afterRequest(
|
||||||
history->sendRequestId
|
history->sendRequestId
|
||||||
).send();
|
).send();
|
||||||
|
|
||||||
|
@ -2494,4 +2518,187 @@ void ApiWrap::forwardMessages(
|
||||||
sendAccumulated();
|
sendAccumulated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::shareContact(
|
||||||
|
const QString &phone,
|
||||||
|
const QString &firstName,
|
||||||
|
const QString &lastName,
|
||||||
|
const SendOptions &options) {
|
||||||
|
const auto userId = UserId(0);
|
||||||
|
sendSharedContact(phone, firstName, lastName, userId, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::shareContact(
|
||||||
|
not_null<UserData*> user,
|
||||||
|
const SendOptions &options) {
|
||||||
|
const auto userId = peerToUser(user->id);
|
||||||
|
const auto phone = user->phone().isEmpty()
|
||||||
|
? App::phoneFromSharedContact(userId)
|
||||||
|
: user->phone();
|
||||||
|
if (phone.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendSharedContact(
|
||||||
|
phone,
|
||||||
|
user->firstName,
|
||||||
|
user->lastName,
|
||||||
|
userId,
|
||||||
|
options);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::sendSharedContact(
|
||||||
|
const QString &phone,
|
||||||
|
const QString &firstName,
|
||||||
|
const QString &lastName,
|
||||||
|
UserId userId,
|
||||||
|
const SendOptions &options) {
|
||||||
|
sendAction(options);
|
||||||
|
|
||||||
|
const auto history = options.history;
|
||||||
|
const auto peer = history->peer;
|
||||||
|
|
||||||
|
const auto randomId = rand_value<uint64>();
|
||||||
|
const auto newId = FullMsgId(history->channelId(), clientMsgId());
|
||||||
|
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
|
||||||
|
const auto silentPost = channelPost && options.silent;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if (channelPost) {
|
||||||
|
flags |= MTPDmessage::Flag::f_views;
|
||||||
|
flags |= MTPDmessage::Flag::f_post;
|
||||||
|
if (peer->asChannel()->addsSignature()) {
|
||||||
|
flags |= MTPDmessage::Flag::f_post_author;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
flags |= MTPDmessage::Flag::f_from_id;
|
||||||
|
}
|
||||||
|
if (silentPost) {
|
||||||
|
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||||
|
}
|
||||||
|
const auto messageFromId = channelPost ? 0 : Auth().userId();
|
||||||
|
const auto messagePostAuthor = channelPost
|
||||||
|
? (Auth().user()->firstName + ' ' + Auth().user()->lastName)
|
||||||
|
: QString();
|
||||||
|
history->addNewMessage(
|
||||||
|
MTP_message(
|
||||||
|
MTP_flags(flags),
|
||||||
|
MTP_int(newId.msg),
|
||||||
|
MTP_int(messageFromId),
|
||||||
|
peerToMTP(peer->id),
|
||||||
|
MTPnullFwdHeader,
|
||||||
|
MTPint(),
|
||||||
|
MTP_int(options.replyTo),
|
||||||
|
MTP_int(unixtime()),
|
||||||
|
MTP_string(""),
|
||||||
|
MTP_messageMediaContact(
|
||||||
|
MTP_string(phone),
|
||||||
|
MTP_string(firstName),
|
||||||
|
MTP_string(lastName),
|
||||||
|
MTP_int(userId)),
|
||||||
|
MTPnullMarkup,
|
||||||
|
MTPnullEntities,
|
||||||
|
MTP_int(1),
|
||||||
|
MTPint(),
|
||||||
|
MTP_string(messagePostAuthor),
|
||||||
|
MTPlong()),
|
||||||
|
NewMessageUnread);
|
||||||
|
|
||||||
|
history->sendRequestId = request(MTPmessages_SendMedia(
|
||||||
|
MTP_flags(sendFlags),
|
||||||
|
peer->input,
|
||||||
|
MTP_int(options.replyTo),
|
||||||
|
MTP_inputMediaContact(
|
||||||
|
MTP_string(phone),
|
||||||
|
MTP_string(firstName),
|
||||||
|
MTP_string(lastName)),
|
||||||
|
MTP_long(randomId),
|
||||||
|
MTPnullMarkup
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
applyUpdates(result);
|
||||||
|
}).fail([](const RPCError &error) {
|
||||||
|
if (error.type() == qstr("PEER_FLOOD")) {
|
||||||
|
Ui::show(Box<InformBox>(
|
||||||
|
PeerFloodErrorText(PeerFloodType::Send)));
|
||||||
|
} else if (error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
|
||||||
|
const auto link = textcmdLink(
|
||||||
|
Messenger::Instance().createInternalLinkFull(qsl("spambot")),
|
||||||
|
lang(lng_cant_more_info));
|
||||||
|
Ui::show(Box<InformBox>(lng_error_public_groups_denied(
|
||||||
|
lt_more_info,
|
||||||
|
link)));
|
||||||
|
}
|
||||||
|
}).afterRequest(
|
||||||
|
history->sendRequestId
|
||||||
|
).send();
|
||||||
|
|
||||||
|
App::historyRegRandom(randomId, newId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::readServerHistory(not_null<History*> history) {
|
||||||
|
if (history->unreadCount()) {
|
||||||
|
readServerHistoryForce(history);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::readServerHistoryForce(not_null<History*> history) {
|
||||||
|
const auto peer = history->peer;
|
||||||
|
const auto upTo = history->inboxRead(0);
|
||||||
|
if (const auto channel = peer->asChannel()) {
|
||||||
|
if (!channel->amIn()) {
|
||||||
|
return; // no read request for channels that I didn't join
|
||||||
|
} else if (const auto migrateFrom = channel->migrateFrom()) {
|
||||||
|
if (const auto migrated = App::historyLoaded(migrateFrom)) {
|
||||||
|
readServerHistory(migrated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_readRequests.contains(peer)) {
|
||||||
|
const auto i = _readRequestsPending.find(peer);
|
||||||
|
if (i == _readRequestsPending.cend()) {
|
||||||
|
_readRequestsPending.emplace(peer, upTo);
|
||||||
|
} else if (i->second < upTo) {
|
||||||
|
i->second = upTo;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sendReadRequest(peer, upTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::sendReadRequest(not_null<PeerData*> peer, MsgId upTo) {
|
||||||
|
const auto requestId = [&] {
|
||||||
|
const auto finished = [=] {
|
||||||
|
_readRequests.remove(peer);
|
||||||
|
if (const auto next = _readRequestsPending.take(peer)) {
|
||||||
|
sendReadRequest(peer, *next);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (const auto channel = peer->asChannel()) {
|
||||||
|
return request(MTPchannels_ReadHistory(
|
||||||
|
channel->inputChannel,
|
||||||
|
MTP_int(upTo)
|
||||||
|
)).done([=](const MTPBool &result) {
|
||||||
|
finished();
|
||||||
|
}).fail([=](const RPCError &error) {
|
||||||
|
finished();
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
return request(MTPmessages_ReadHistory(
|
||||||
|
peer->input,
|
||||||
|
MTP_int(upTo)
|
||||||
|
)).done([=](const MTPmessages_AffectedMessages &result) {
|
||||||
|
applyAffectedMessages(peer, result);
|
||||||
|
finished();
|
||||||
|
}).fail([=](const RPCError &error) {
|
||||||
|
finished();
|
||||||
|
}).send();
|
||||||
|
}();
|
||||||
|
_readRequests.emplace(peer, requestId, upTo);
|
||||||
|
}
|
||||||
|
|
||||||
ApiWrap::~ApiWrap() = default;
|
ApiWrap::~ApiWrap() = default;
|
||||||
|
|
|
@ -167,13 +167,25 @@ public:
|
||||||
MsgId replyTo = 0;
|
MsgId replyTo = 0;
|
||||||
bool silent = false;
|
bool silent = false;
|
||||||
WebPageId webPageId = 0;
|
WebPageId webPageId = 0;
|
||||||
bool clearDraft = true;
|
bool clearDraft = false;
|
||||||
bool generateLocal = true;
|
bool generateLocal = true;
|
||||||
};
|
};
|
||||||
|
rpl::producer<SendOptions> sendActions() const {
|
||||||
|
return _sendActions.events();
|
||||||
|
}
|
||||||
|
void sendAction(const SendOptions &options);
|
||||||
void forwardMessages(
|
void forwardMessages(
|
||||||
HistoryItemsList &&items,
|
HistoryItemsList &&items,
|
||||||
const SendOptions &options,
|
const SendOptions &options,
|
||||||
base::lambda_once<void()> &&successCallback = nullptr);
|
base::lambda_once<void()> &&successCallback = nullptr);
|
||||||
|
void shareContact(
|
||||||
|
const QString &phone,
|
||||||
|
const QString &firstName,
|
||||||
|
const QString &lastName,
|
||||||
|
const SendOptions &options);
|
||||||
|
void shareContact(not_null<UserData*> user, const SendOptions &options);
|
||||||
|
void readServerHistory(not_null<History*> history);
|
||||||
|
void readServerHistoryForce(not_null<History*> history);
|
||||||
|
|
||||||
~ApiWrap();
|
~ApiWrap();
|
||||||
|
|
||||||
|
@ -245,10 +257,6 @@ private:
|
||||||
const QDate &date,
|
const QDate &date,
|
||||||
Callback &&callback);
|
Callback &&callback);
|
||||||
|
|
||||||
int applyAffectedHistory(
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
const MTPmessages_AffectedHistory &result);
|
|
||||||
|
|
||||||
void sharedMediaDone(
|
void sharedMediaDone(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
SharedMediaType type,
|
SharedMediaType type,
|
||||||
|
@ -261,6 +269,22 @@ private:
|
||||||
PhotoId photoId,
|
PhotoId photoId,
|
||||||
const MTPphotos_Photos &result);
|
const MTPphotos_Photos &result);
|
||||||
|
|
||||||
|
void sendSharedContact(
|
||||||
|
const QString &phone,
|
||||||
|
const QString &firstName,
|
||||||
|
const QString &lastName,
|
||||||
|
UserId userId,
|
||||||
|
const SendOptions &options);
|
||||||
|
|
||||||
|
void sendReadRequest(not_null<PeerData*> peer, MsgId upTo);
|
||||||
|
int applyAffectedHistory(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const MTPmessages_AffectedHistory &result);
|
||||||
|
void applyAffectedMessages(const MTPmessages_AffectedMessages &result);
|
||||||
|
void applyAffectedMessages(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const MTPmessages_AffectedMessages &result);
|
||||||
|
|
||||||
not_null<AuthSession*> _session;
|
not_null<AuthSession*> _session;
|
||||||
mtpRequestId _changelogSubscription = 0;
|
mtpRequestId _changelogSubscription = 0;
|
||||||
|
|
||||||
|
@ -339,6 +363,20 @@ private:
|
||||||
|
|
||||||
base::flat_map<not_null<UserData*>, mtpRequestId> _userPhotosRequests;
|
base::flat_map<not_null<UserData*>, mtpRequestId> _userPhotosRequests;
|
||||||
|
|
||||||
|
rpl::event_stream<SendOptions> _sendActions;
|
||||||
|
|
||||||
|
struct ReadRequest {
|
||||||
|
ReadRequest(mtpRequestId requestId, MsgId upTo)
|
||||||
|
: requestId(requestId)
|
||||||
|
, upTo(upTo) {
|
||||||
|
}
|
||||||
|
|
||||||
|
mtpRequestId requestId = 0;
|
||||||
|
MsgId upTo = 0;
|
||||||
|
};
|
||||||
|
base::flat_map<not_null<PeerData*>, ReadRequest> _readRequests;
|
||||||
|
base::flat_map<not_null<PeerData*>, MsgId> _readRequestsPending;
|
||||||
|
|
||||||
base::Observable<PeerData*> _fullPeerUpdated;
|
base::Observable<PeerData*> _fullPeerUpdated;
|
||||||
|
|
||||||
rpl::event_stream<uint64> _stickerSetInstalled;
|
rpl::event_stream<uint64> _stickerSetInstalled;
|
||||||
|
|
|
@ -103,24 +103,16 @@ public:
|
||||||
using value_type = pair_type;
|
using value_type = pair_type;
|
||||||
using difference_type = typename iterator_impl::difference_type;
|
using difference_type = typename iterator_impl::difference_type;
|
||||||
using pointer = pointer_impl;
|
using pointer = pointer_impl;
|
||||||
using const_pointer = const pair_type*;
|
|
||||||
using reference = reference_impl;
|
using reference = reference_impl;
|
||||||
using const_reference = const pair_type&;
|
|
||||||
|
|
||||||
flat_multi_map_iterator_base_impl(iterator_impl impl = iterator_impl())
|
flat_multi_map_iterator_base_impl(iterator_impl impl = iterator_impl())
|
||||||
: _impl(impl) {
|
: _impl(impl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
reference operator*() {
|
reference operator*() const {
|
||||||
return *_impl;
|
return *_impl;
|
||||||
}
|
}
|
||||||
const_reference operator*() const {
|
pointer operator->() const {
|
||||||
return *_impl;
|
|
||||||
}
|
|
||||||
pointer operator->() {
|
|
||||||
return std::addressof(**this);
|
|
||||||
}
|
|
||||||
const_pointer operator->() const {
|
|
||||||
return std::addressof(**this);
|
return std::addressof(**this);
|
||||||
}
|
}
|
||||||
Me &operator++() {
|
Me &operator++() {
|
||||||
|
@ -166,10 +158,7 @@ public:
|
||||||
other_reference_impl> &right) const {
|
other_reference_impl> &right) const {
|
||||||
return _impl - right._impl;
|
return _impl - right._impl;
|
||||||
}
|
}
|
||||||
reference operator[](difference_type offset) {
|
reference operator[](difference_type offset) const {
|
||||||
return _impl[offset];
|
|
||||||
}
|
|
||||||
const_reference operator[](difference_type offset) const {
|
|
||||||
return _impl[offset];
|
return _impl[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -756,7 +756,7 @@ void DialogsWidget::dragEnterEvent(QDragEnterEvent *e) {
|
||||||
e->setDropAction(Qt::CopyAction);
|
e->setDropAction(Qt::CopyAction);
|
||||||
e->accept();
|
e->accept();
|
||||||
updateDragInScroll(_scroll->geometry().contains(e->pos()));
|
updateDragInScroll(_scroll->geometry().contains(e->pos()));
|
||||||
} else if (App::main() && App::main()->getDragState(e->mimeData()) != DragStateNone) {
|
} else if (App::main() && App::main()->getDragState(e->mimeData()) != DragState::None) {
|
||||||
e->setDropAction(Qt::CopyAction);
|
e->setDropAction(Qt::CopyAction);
|
||||||
e->accept();
|
e->accept();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "observer_peer.h"
|
#include "observer_peer.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
#include "apiwrap.h"
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
|
@ -121,10 +122,13 @@ void activateBotCommand(const HistoryItem *msg, int row, int col) {
|
||||||
|
|
||||||
case ButtonType::RequestPhone: {
|
case ButtonType::RequestPhone: {
|
||||||
hideSingleUseKeyboard(msg);
|
hideSingleUseKeyboard(msg);
|
||||||
Ui::show(Box<ConfirmBox>(lang(lng_bot_share_phone), lang(lng_bot_share_phone_confirm), [peerId = msg->history()->peer->id] {
|
const auto msgId = msg->id;
|
||||||
if (auto m = App::main()) {
|
const auto history = msg->history();
|
||||||
m->onShareContact(peerId, App::self());
|
Ui::show(Box<ConfirmBox>(lang(lng_bot_share_phone), lang(lng_bot_share_phone_confirm), [=] {
|
||||||
}
|
Ui::showPeerHistory(history, ShowAtTheEndMsgId);
|
||||||
|
auto options = ApiWrap::SendOptions(history);
|
||||||
|
options.replyTo = msgId;
|
||||||
|
Auth().api().shareContact(App::self(), options);
|
||||||
}));
|
}));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
|
||||||
|
|
||||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
It is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
In addition, as a special exception, the copyright holders give permission
|
|
||||||
to link the code of portions of this program with the OpenSSL library.
|
|
||||||
|
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|
||||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
enum DragState {
|
|
||||||
DragStateNone = 0x00,
|
|
||||||
DragStateFiles = 0x01,
|
|
||||||
DragStatePhotoFiles = 0x02,
|
|
||||||
DragStateImage = 0x03,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ReadServerHistoryChecks {
|
|
||||||
OnlyIfUnread,
|
|
||||||
ForceRequest,
|
|
||||||
};
|
|
|
@ -395,7 +395,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
HistoryLayout::paintEmpty(p, width(), height());
|
HistoryLayout::paintEmpty(p, width(), height());
|
||||||
}
|
}
|
||||||
if (!noHistoryDisplayed) {
|
if (!noHistoryDisplayed) {
|
||||||
auto readMentions = HistoryItemsMap();
|
auto readMentions = base::flat_set<not_null<HistoryItem*>>();
|
||||||
|
|
||||||
adjustCurrent(clip.top());
|
adjustCurrent(clip.top());
|
||||||
|
|
||||||
|
|
|
@ -185,13 +185,6 @@ HistoryHider::HistoryHider(
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryHider::HistoryHider(MainWidget *parent, UserData *sharedContact) : RpWidget(parent)
|
|
||||||
, _sharedContact(sharedContact)
|
|
||||||
, _send(this, langFactory(lng_forward_send), st::defaultBoxButton)
|
|
||||||
, _cancel(this, langFactory(lng_cancel), st::defaultBoxButton) {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
HistoryHider::HistoryHider(MainWidget *parent) : RpWidget(parent)
|
HistoryHider::HistoryHider(MainWidget *parent) : RpWidget(parent)
|
||||||
, _sendPath(true)
|
, _sendPath(true)
|
||||||
, _send(this, langFactory(lng_forward_send), st::defaultBoxButton)
|
, _send(this, langFactory(lng_forward_send), st::defaultBoxButton)
|
||||||
|
@ -231,7 +224,7 @@ void HistoryHider::refreshLang() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryHider::withConfirm() const {
|
bool HistoryHider::withConfirm() const {
|
||||||
return _sharedContact || _sendPath;
|
return _sendPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryHider::paintEvent(QPaintEvent *e) {
|
void HistoryHider::paintEvent(QPaintEvent *e) {
|
||||||
|
@ -317,9 +310,7 @@ void HistoryHider::animationCallback() {
|
||||||
|
|
||||||
void HistoryHider::forward() {
|
void HistoryHider::forward() {
|
||||||
if (!_hiding && _offered) {
|
if (!_hiding && _offered) {
|
||||||
if (_sharedContact) {
|
if (_sendPath) {
|
||||||
parent()->onShareContact(_offered->id, _sharedContact);
|
|
||||||
} else if (_sendPath) {
|
|
||||||
parent()->onSendPaths(_offered->id);
|
parent()->onSendPaths(_offered->id);
|
||||||
} else if (!_shareUrl.isEmpty()) {
|
} else if (!_shareUrl.isEmpty()) {
|
||||||
parent()->shareUrl(_offered, _shareUrl, _shareText);
|
parent()->shareUrl(_offered, _shareUrl, _shareText);
|
||||||
|
@ -375,17 +366,7 @@ bool HistoryHider::offerPeer(PeerId peer) {
|
||||||
_offered = App::peer(peer);
|
_offered = App::peer(peer);
|
||||||
auto phrase = QString();
|
auto phrase = QString();
|
||||||
auto recipient = _offered->isUser() ? _offered->name : '\xAB' + _offered->name + '\xBB';
|
auto recipient = _offered->isUser() ? _offered->name : '\xAB' + _offered->name + '\xBB';
|
||||||
if (_sharedContact) {
|
if (_sendPath) {
|
||||||
if (!_offered->canWrite()) {
|
|
||||||
Ui::show(Box<InformBox>(lang(lng_forward_share_cant)));
|
|
||||||
_offered = nullptr;
|
|
||||||
_toText.setText(st::boxLabelStyle, QString());
|
|
||||||
_toTextWidth = 0;
|
|
||||||
resizeEvent(nullptr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
phrase = lng_forward_share_contact(lt_recipient, recipient);
|
|
||||||
} else if (_sendPath) {
|
|
||||||
auto toId = _offered->id;
|
auto toId = _offered->id;
|
||||||
_offered = nullptr;
|
_offered = nullptr;
|
||||||
if (parent()->onSendPaths(toId)) {
|
if (parent()->onSendPaths(toId)) {
|
||||||
|
@ -766,6 +747,17 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont
|
||||||
setMembersShowAreaActive(active);
|
setMembersShowAreaActive(active);
|
||||||
}, _topBar->lifetime());
|
}, _topBar->lifetime());
|
||||||
|
|
||||||
|
Auth().api().sendActions(
|
||||||
|
) | rpl::start_with_next([this](const ApiWrap::SendOptions &options) {
|
||||||
|
fastShowAtEnd(options.history);
|
||||||
|
const auto lastKeyboardUsed = lastForceReplyReplied(FullMsgId(
|
||||||
|
options.history->channelId(),
|
||||||
|
options.replyTo));
|
||||||
|
if (cancelReply(lastKeyboardUsed) && !options.clearDraft) {
|
||||||
|
onCloudDraftSave();
|
||||||
|
}
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
orderWidgets();
|
orderWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1345,7 +1337,6 @@ void HistoryWidget::onRecordDone(QByteArray result, VoiceWaveform waveform, qint
|
||||||
auto to = FileLoadTo(_peer->id, _silent->checked(), replyToId());
|
auto to = FileLoadTo(_peer->id, _silent->checked(), replyToId());
|
||||||
auto caption = QString();
|
auto caption = QString();
|
||||||
_fileLoader.addTask(MakeShared<FileLoadTask>(result, duration, waveform, to, caption));
|
_fileLoader.addTask(MakeShared<FileLoadTask>(result, duration, waveform, to, caption));
|
||||||
cancelReplyAfterMediaSend(lastForceReplyReplied());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
|
void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
|
||||||
|
@ -1555,23 +1546,21 @@ void HistoryWidget::calcNextReplyReturn() {
|
||||||
if (!_replyReturn) updateControlsVisibility();
|
if (!_replyReturn) updateControlsVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::fastShowAtEnd(History *h) {
|
void HistoryWidget::fastShowAtEnd(not_null<History*> history) {
|
||||||
if (h == _history) {
|
if (_history != history) {
|
||||||
h->getReadyFor(ShowAtTheEndMsgId);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
clearAllLoadRequests();
|
clearAllLoadRequests();
|
||||||
|
|
||||||
setMsgId(ShowAtUnreadMsgId);
|
setMsgId(ShowAtUnreadMsgId);
|
||||||
_historyInited = false;
|
_historyInited = false;
|
||||||
|
|
||||||
if (h->isReadyFor(_showAtMsgId)) {
|
if (_history->isReadyFor(_showAtMsgId)) {
|
||||||
historyLoaded();
|
historyLoaded();
|
||||||
} else {
|
} else {
|
||||||
firstLoadMessages();
|
firstLoadMessages();
|
||||||
doneShow();
|
doneShow();
|
||||||
}
|
|
||||||
} else if (h) {
|
|
||||||
h->getReadyFor(ShowAtTheEndMsgId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2219,7 +2208,7 @@ void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
|
||||||
if (item->mentionsMe() && item->isMediaUnread()) {
|
if (item->mentionsMe() && item->isMediaUnread()) {
|
||||||
App::main()->mediaMarkRead(item);
|
App::main()->mediaMarkRead(item);
|
||||||
}
|
}
|
||||||
historyWasRead(ReadServerHistoryChecks::ForceRequest);
|
Auth().api().readServerHistoryForce(history);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2237,13 +2226,6 @@ void HistoryWidget::historyToDown(History *history) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::historyWasRead(ReadServerHistoryChecks checks) {
|
|
||||||
App::main()->readServerHistory(_history, checks);
|
|
||||||
if (_migrated) {
|
|
||||||
App::main()->readServerHistory(_migrated, ReadServerHistoryChecks::OnlyIfUnread);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::unreadCountChanged(History *history) {
|
void HistoryWidget::unreadCountChanged(History *history) {
|
||||||
if (history == _history || history == _migrated) {
|
if (history == _history || history == _migrated) {
|
||||||
updateHistoryDownVisibility();
|
updateHistoryDownVisibility();
|
||||||
|
@ -2722,7 +2704,7 @@ void HistoryWidget::visibleAreaUpdated() {
|
||||||
auto showFromVisible = (showFrom && !showFrom->detached() && scrollBottom > _list->itemTop(showFrom));
|
auto showFromVisible = (showFrom && !showFrom->detached() && scrollBottom > _list->itemTop(showFrom));
|
||||||
auto atBottom = (scrollTop >= _scroll->scrollTopMax());
|
auto atBottom = (scrollTop >= _scroll->scrollTopMax());
|
||||||
if ((showFromVisible || atBottom) && App::wnd()->doWeReadServerHistory()) {
|
if ((showFromVisible || atBottom) && App::wnd()->doWeReadServerHistory()) {
|
||||||
historyWasRead(ReadServerHistoryChecks::OnlyIfUnread);
|
Auth().api().readServerHistory(_history);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
controller()->floatPlayerAreaUpdated().notify(true);
|
controller()->floatPlayerAreaUpdated().notify(true);
|
||||||
|
@ -2911,7 +2893,7 @@ void HistoryWidget::hideSelectorControlsAnimated() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
|
void HistoryWidget::onSend(bool ctrlShiftEnter) {
|
||||||
if (!_history) return;
|
if (!_history) return;
|
||||||
|
|
||||||
if (_editMsgId) {
|
if (_editMsgId) {
|
||||||
|
@ -2919,14 +2901,11 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(_channel, replyTo));
|
|
||||||
|
|
||||||
WebPageId webPageId = _previewCancelled ? CancelledWebPageId : ((_previewData && _previewData->pendingTill >= 0) ? _previewData->id : 0);
|
WebPageId webPageId = _previewCancelled ? CancelledWebPageId : ((_previewData && _previewData->pendingTill >= 0) ? _previewData->id : 0);
|
||||||
|
|
||||||
MainWidget::MessageToSend message;
|
auto message = MainWidget::MessageToSend(_history);
|
||||||
message.history = _history;
|
|
||||||
message.textWithTags = _field->getTextWithTags();
|
message.textWithTags = _field->getTextWithTags();
|
||||||
message.replyTo = replyTo;
|
message.replyTo = replyToId();
|
||||||
message.silent = _silent->checked();
|
message.silent = _silent->checked();
|
||||||
message.webPageId = webPageId;
|
message.webPageId = webPageId;
|
||||||
App::main()->sendMessage(message);
|
App::main()->sendMessage(message);
|
||||||
|
@ -2938,11 +2917,12 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
|
||||||
|
|
||||||
hideSelectorControlsAnimated();
|
hideSelectorControlsAnimated();
|
||||||
|
|
||||||
if (replyTo < 0) cancelReply(lastKeyboardUsed);
|
|
||||||
if (_previewData && _previewData->pendingTill) previewCancel();
|
if (_previewData && _previewData->pendingTill) previewCancel();
|
||||||
_field->setFocus();
|
_field->setFocus();
|
||||||
|
|
||||||
if (!_keyboard->hasMarkup() && _keyboard->forceReply() && !_kbReplyTo) onKbToggle();
|
if (!_keyboard->hasMarkup() && _keyboard->forceReply() && !_kbReplyTo) {
|
||||||
|
onKbToggle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onUnblock() {
|
void HistoryWidget::onUnblock() {
|
||||||
|
@ -3039,84 +3019,6 @@ void HistoryWidget::onBroadcastSilentChange() {
|
||||||
updateFieldPlaceholder();
|
updateFieldPlaceholder();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) {
|
|
||||||
auto phone = contact->phone();
|
|
||||||
if (phone.isEmpty()) phone = App::phoneFromSharedContact(peerToUser(contact->id));
|
|
||||||
if (!contact || phone.isEmpty()) return;
|
|
||||||
|
|
||||||
Ui::showPeerHistory(peer, ShowAtTheEndMsgId);
|
|
||||||
if (!_history) return;
|
|
||||||
|
|
||||||
shareContact(peer, phone, contact->firstName, contact->lastName, replyToId(), peerToUser(contact->id));
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, int32 userId) {
|
|
||||||
auto history = App::history(peer);
|
|
||||||
|
|
||||||
uint64 randomId = rand_value<uint64>();
|
|
||||||
FullMsgId newId(peerToChannel(peer), clientMsgId());
|
|
||||||
|
|
||||||
App::main()->readServerHistory(history);
|
|
||||||
fastShowAtEnd(history);
|
|
||||||
|
|
||||||
auto p = App::peer(peer);
|
|
||||||
auto flags = NewMessageFlags(p) | MTPDmessage::Flag::f_media; // unread, out
|
|
||||||
|
|
||||||
bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(peerToChannel(peer), replyTo));
|
|
||||||
|
|
||||||
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
|
||||||
if (replyTo) {
|
|
||||||
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool channelPost = p->isChannel() && !p->isMegagroup();
|
|
||||||
bool silentPost = channelPost && _silent->checked();
|
|
||||||
if (channelPost) {
|
|
||||||
flags |= MTPDmessage::Flag::f_views;
|
|
||||||
flags |= MTPDmessage::Flag::f_post;
|
|
||||||
}
|
|
||||||
if (!channelPost) {
|
|
||||||
flags |= MTPDmessage::Flag::f_from_id;
|
|
||||||
} else if (p->asChannel()->addsSignature()) {
|
|
||||||
flags |= MTPDmessage::Flag::f_post_author;
|
|
||||||
}
|
|
||||||
if (silentPost) {
|
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
|
||||||
}
|
|
||||||
auto messageFromId = channelPost ? 0 : Auth().userId();
|
|
||||||
auto messagePostAuthor = channelPost ? (Auth().user()->firstName + ' ' + Auth().user()->lastName) : QString();
|
|
||||||
history->addNewMessage(
|
|
||||||
MTP_message(
|
|
||||||
MTP_flags(flags),
|
|
||||||
MTP_int(newId.msg),
|
|
||||||
MTP_int(messageFromId),
|
|
||||||
peerToMTP(peer),
|
|
||||||
MTPnullFwdHeader,
|
|
||||||
MTPint(),
|
|
||||||
MTP_int(replyToId()),
|
|
||||||
MTP_int(unixtime()),
|
|
||||||
MTP_string(""),
|
|
||||||
MTP_messageMediaContact(
|
|
||||||
MTP_string(phone),
|
|
||||||
MTP_string(fname),
|
|
||||||
MTP_string(lname),
|
|
||||||
MTP_int(userId)),
|
|
||||||
MTPnullMarkup,
|
|
||||||
MTPnullEntities,
|
|
||||||
MTP_int(1),
|
|
||||||
MTPint(),
|
|
||||||
MTP_string(messagePostAuthor),
|
|
||||||
MTPlong()),
|
|
||||||
NewMessageUnread);
|
|
||||||
history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), p->input, MTP_int(replyTo), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, history->sendRequestId);
|
|
||||||
|
|
||||||
App::historyRegRandom(randomId, newId);
|
|
||||||
|
|
||||||
App::main()->finishForwarding(history, _silent->checked());
|
|
||||||
cancelReplyAfterMediaSend(lastKeyboardUsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
History *HistoryWidget::history() const {
|
History *HistoryWidget::history() const {
|
||||||
return _history;
|
return _history;
|
||||||
}
|
}
|
||||||
|
@ -3278,22 +3180,22 @@ void HistoryWidget::dragEnterEvent(QDragEnterEvent *e) {
|
||||||
_attachDrag = getDragState(e->mimeData());
|
_attachDrag = getDragState(e->mimeData());
|
||||||
updateDragAreas();
|
updateDragAreas();
|
||||||
|
|
||||||
if (_attachDrag) {
|
if (_attachDrag != DragState::None) {
|
||||||
e->setDropAction(Qt::IgnoreAction);
|
e->setDropAction(Qt::IgnoreAction);
|
||||||
e->accept();
|
e->accept();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::dragLeaveEvent(QDragLeaveEvent *e) {
|
void HistoryWidget::dragLeaveEvent(QDragLeaveEvent *e) {
|
||||||
if (_attachDrag != DragStateNone || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
|
if (_attachDrag != DragState::None || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
|
||||||
_attachDrag = DragStateNone;
|
_attachDrag = DragState::None;
|
||||||
updateDragAreas();
|
updateDragAreas();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::leaveEventHook(QEvent *e) {
|
void HistoryWidget::leaveEventHook(QEvent *e) {
|
||||||
if (_attachDrag != DragStateNone || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
|
if (_attachDrag != DragState::None || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
|
||||||
_attachDrag = DragStateNone;
|
_attachDrag = DragState::None;
|
||||||
updateDragAreas();
|
updateDragAreas();
|
||||||
}
|
}
|
||||||
if (hasMouseTracking()) mouseMoveEvent(0);
|
if (hasMouseTracking()) mouseMoveEvent(0);
|
||||||
|
@ -3362,8 +3264,8 @@ void HistoryWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
_replyForwardPressed = false;
|
_replyForwardPressed = false;
|
||||||
update(0, _field->y() - st::historySendPadding - st::historyReplyHeight, width(), st::historyReplyHeight);
|
update(0, _field->y() - st::historySendPadding - st::historyReplyHeight, width(), st::historyReplyHeight);
|
||||||
}
|
}
|
||||||
if (_attachDrag != DragStateNone || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
|
if (_attachDrag != DragState::None || !_attachDragPhoto->isHidden() || !_attachDragDocument->isHidden()) {
|
||||||
_attachDrag = DragStateNone;
|
_attachDrag = DragState::None;
|
||||||
updateDragAreas();
|
updateDragAreas();
|
||||||
}
|
}
|
||||||
if (_recording) {
|
if (_recording) {
|
||||||
|
@ -3405,10 +3307,13 @@ void HistoryWidget::sendBotCommand(PeerData *peer, UserData *bot, const QString
|
||||||
toSend += '@' + username;
|
toSend += '@' + username;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWidget::MessageToSend message;
|
auto message = MainWidget::MessageToSend(_history);
|
||||||
message.history = _history;
|
|
||||||
message.textWithTags = { toSend, TextWithTags::Tags() };
|
message.textWithTags = { toSend, TextWithTags::Tags() };
|
||||||
message.replyTo = replyTo ? ((!_peer->isUser()/* && (botStatus == 0 || botStatus == 2)*/) ? replyTo : -1) : 0;
|
message.replyTo = replyTo
|
||||||
|
? ((!_peer->isUser()/* && (botStatus == 0 || botStatus == 2)*/)
|
||||||
|
? replyTo
|
||||||
|
: replyToId())
|
||||||
|
: 0;
|
||||||
message.silent = false;
|
message.silent = false;
|
||||||
App::main()->sendMessage(message);
|
App::main()->sendMessage(message);
|
||||||
if (replyTo) {
|
if (replyTo) {
|
||||||
|
@ -3585,30 +3490,30 @@ DragState HistoryWidget::getDragState(const QMimeData *d) {
|
||||||
if (!d
|
if (!d
|
||||||
|| d->hasFormat(qsl("application/x-td-forward-selected"))
|
|| d->hasFormat(qsl("application/x-td-forward-selected"))
|
||||||
|| d->hasFormat(qsl("application/x-td-forward-pressed"))
|
|| d->hasFormat(qsl("application/x-td-forward-pressed"))
|
||||||
|| d->hasFormat(qsl("application/x-td-forward-pressed-link"))) return DragStateNone;
|
|| d->hasFormat(qsl("application/x-td-forward-pressed-link"))) return DragState::None;
|
||||||
|
|
||||||
if (d->hasImage()) return DragStateImage;
|
if (d->hasImage()) return DragState::Image;
|
||||||
|
|
||||||
QString uriListFormat(qsl("text/uri-list"));
|
QString uriListFormat(qsl("text/uri-list"));
|
||||||
if (!d->hasFormat(uriListFormat)) return DragStateNone;
|
if (!d->hasFormat(uriListFormat)) return DragState::None;
|
||||||
|
|
||||||
QStringList imgExtensions(cImgExtensions()), files;
|
QStringList imgExtensions(cImgExtensions()), files;
|
||||||
|
|
||||||
const QList<QUrl> &urls(d->urls());
|
const QList<QUrl> &urls(d->urls());
|
||||||
if (urls.isEmpty()) return DragStateNone;
|
if (urls.isEmpty()) return DragState::None;
|
||||||
|
|
||||||
bool allAreSmallImages = true;
|
bool allAreSmallImages = true;
|
||||||
for (QList<QUrl>::const_iterator i = urls.cbegin(), en = urls.cend(); i != en; ++i) {
|
for (QList<QUrl>::const_iterator i = urls.cbegin(), en = urls.cend(); i != en; ++i) {
|
||||||
if (!i->isLocalFile()) return DragStateNone;
|
if (!i->isLocalFile()) return DragState::None;
|
||||||
|
|
||||||
auto file = Platform::File::UrlToLocal(*i);
|
auto file = Platform::File::UrlToLocal(*i);
|
||||||
|
|
||||||
QFileInfo info(file);
|
QFileInfo info(file);
|
||||||
if (info.isDir()) return DragStateNone;
|
if (info.isDir()) return DragState::None;
|
||||||
|
|
||||||
quint64 s = info.size();
|
quint64 s = info.size();
|
||||||
if (s > App::kFileSizeLimit) {
|
if (s > App::kFileSizeLimit) {
|
||||||
return DragStateNone;
|
return DragState::None;
|
||||||
}
|
}
|
||||||
if (allAreSmallImages) {
|
if (allAreSmallImages) {
|
||||||
if (s > App::kImageSizeLimit) {
|
if (s > App::kImageSizeLimit) {
|
||||||
|
@ -3627,30 +3532,30 @@ DragState HistoryWidget::getDragState(const QMimeData *d) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return allAreSmallImages ? DragStatePhotoFiles : DragStateFiles;
|
return allAreSmallImages ? DragState::PhotoFiles : DragState::Files;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateDragAreas() {
|
void HistoryWidget::updateDragAreas() {
|
||||||
_field->setAcceptDrops(!_attachDrag);
|
_field->setAcceptDrops(_attachDrag == DragState::None);
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
|
||||||
switch (_attachDrag) {
|
switch (_attachDrag) {
|
||||||
case DragStateNone:
|
case DragState::None:
|
||||||
_attachDragDocument->otherLeave();
|
_attachDragDocument->otherLeave();
|
||||||
_attachDragPhoto->otherLeave();
|
_attachDragPhoto->otherLeave();
|
||||||
break;
|
break;
|
||||||
case DragStateFiles:
|
case DragState::Files:
|
||||||
_attachDragDocument->setText(lang(lng_drag_files_here), lang(lng_drag_to_send_files));
|
_attachDragDocument->setText(lang(lng_drag_files_here), lang(lng_drag_to_send_files));
|
||||||
_attachDragDocument->otherEnter();
|
_attachDragDocument->otherEnter();
|
||||||
_attachDragPhoto->hideFast();
|
_attachDragPhoto->hideFast();
|
||||||
break;
|
break;
|
||||||
case DragStatePhotoFiles:
|
case DragState::PhotoFiles:
|
||||||
_attachDragDocument->setText(lang(lng_drag_images_here), lang(lng_drag_to_send_no_compression));
|
_attachDragDocument->setText(lang(lng_drag_images_here), lang(lng_drag_to_send_no_compression));
|
||||||
_attachDragPhoto->setText(lang(lng_drag_photos_here), lang(lng_drag_to_send_quick));
|
_attachDragPhoto->setText(lang(lng_drag_photos_here), lang(lng_drag_to_send_quick));
|
||||||
_attachDragDocument->otherEnter();
|
_attachDragDocument->otherEnter();
|
||||||
_attachDragPhoto->otherEnter();
|
_attachDragPhoto->otherEnter();
|
||||||
break;
|
break;
|
||||||
case DragStateImage:
|
case DragState::Image:
|
||||||
_attachDragPhoto->setText(lang(lng_drag_images_here), lang(lng_drag_to_send_quick));
|
_attachDragPhoto->setText(lang(lng_drag_images_here), lang(lng_drag_to_send_quick));
|
||||||
_attachDragDocument->hideFast();
|
_attachDragDocument->hideFast();
|
||||||
_attachDragPhoto->otherEnter();
|
_attachDragPhoto->otherEnter();
|
||||||
|
@ -3774,7 +3679,7 @@ bool HistoryWidget::kbWasHidden() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::dropEvent(QDropEvent *e) {
|
void HistoryWidget::dropEvent(QDropEvent *e) {
|
||||||
_attachDrag = DragStateNone;
|
_attachDrag = DragState::None;
|
||||||
updateDragAreas();
|
updateDragAreas();
|
||||||
e->acceptProposedAction();
|
e->acceptProposedAction();
|
||||||
}
|
}
|
||||||
|
@ -4123,11 +4028,18 @@ bool HistoryWidget::showSendFilesBox(object_ptr<SendFilesBox> box, const QString
|
||||||
box->setConfirmedCallback(base::lambda_guarded(this, [this, withComment, sendCallback = std::move(callback)](const QStringList &files, const QImage &image, std::unique_ptr<FileLoadTask::MediaInformation> information, bool compressed, const QString &caption, bool ctrlShiftEnter) {
|
box->setConfirmedCallback(base::lambda_guarded(this, [this, withComment, sendCallback = std::move(callback)](const QStringList &files, const QImage &image, std::unique_ptr<FileLoadTask::MediaInformation> information, bool compressed, const QString &caption, bool ctrlShiftEnter) {
|
||||||
if (!canWriteMessage()) return;
|
if (!canWriteMessage()) return;
|
||||||
|
|
||||||
auto replyTo = replyToId();
|
const auto replyTo = replyToId();
|
||||||
if (withComment) {
|
if (withComment) {
|
||||||
onSend(ctrlShiftEnter, replyTo);
|
// This call will clear replyToId().
|
||||||
|
onSend(ctrlShiftEnter);
|
||||||
}
|
}
|
||||||
sendCallback(files, image, std::move(information), compressed, caption, replyTo);
|
sendCallback(
|
||||||
|
files,
|
||||||
|
image,
|
||||||
|
std::move(information),
|
||||||
|
compressed,
|
||||||
|
caption,
|
||||||
|
replyTo);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (withComment) {
|
if (withComment) {
|
||||||
|
@ -4244,7 +4156,9 @@ bool HistoryWidget::confirmShareContact(
|
||||||
bool compressed,
|
bool compressed,
|
||||||
const QString &caption,
|
const QString &caption,
|
||||||
MsgId replyTo) {
|
MsgId replyTo) {
|
||||||
shareContact(_peer->id, phone, fname, lname, replyTo);
|
auto options = ApiWrap::SendOptions(_history);
|
||||||
|
options.replyTo = replyTo;
|
||||||
|
Auth().api().shareContact(phone, fname, lname, options);
|
||||||
};
|
};
|
||||||
auto insertTextOnCancel = QString();
|
auto insertTextOnCancel = QString();
|
||||||
return showSendFilesBox(
|
return showSendFilesBox(
|
||||||
|
@ -4311,13 +4225,18 @@ void HistoryWidget::uploadFiles(const QStringList &files, SendMediaType type) {
|
||||||
uploadFilesAfterConfirmation(files, QByteArray(), QImage(), nullptr, type, caption);
|
uploadFilesAfterConfirmation(files, QByteArray(), QImage(), nullptr, type, caption);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::uploadFilesAfterConfirmation(const QStringList &files, const QByteArray &content, const QImage &image, std::unique_ptr<FileLoadTask::MediaInformation> information, SendMediaType type, QString caption) {
|
void HistoryWidget::uploadFilesAfterConfirmation(
|
||||||
|
const QStringList &files,
|
||||||
|
const QByteArray &content,
|
||||||
|
const QImage &image,
|
||||||
|
std::unique_ptr<FileLoadTask::MediaInformation> information,
|
||||||
|
SendMediaType type,
|
||||||
|
QString caption) {
|
||||||
Assert(canWriteMessage());
|
Assert(canWriteMessage());
|
||||||
|
|
||||||
auto to = FileLoadTo(_peer->id, _silent->checked(), replyToId());
|
auto to = FileLoadTo(_peer->id, _silent->checked(), replyToId());
|
||||||
if (files.size() > 1 && !caption.isEmpty()) {
|
if (files.size() > 1 && !caption.isEmpty()) {
|
||||||
MainWidget::MessageToSend message;
|
auto message = MainWidget::MessageToSend(_history);
|
||||||
message.history = _history;
|
|
||||||
message.textWithTags = { caption, TextWithTags::Tags() };
|
message.textWithTags = { caption, TextWithTags::Tags() };
|
||||||
message.replyTo = to.replyTo;
|
message.replyTo = to.replyTo;
|
||||||
message.silent = to.silent;
|
message.silent = to.silent;
|
||||||
|
@ -4335,8 +4254,6 @@ void HistoryWidget::uploadFilesAfterConfirmation(const QStringList &files, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_fileLoader.addTasks(tasks);
|
_fileLoader.addTasks(tasks);
|
||||||
|
|
||||||
cancelReplyAfterMediaSend(lastForceReplyReplied());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::uploadFile(const QByteArray &fileContent, SendMediaType type) {
|
void HistoryWidget::uploadFile(const QByteArray &fileContent, SendMediaType type) {
|
||||||
|
@ -4345,8 +4262,6 @@ void HistoryWidget::uploadFile(const QByteArray &fileContent, SendMediaType type
|
||||||
auto to = FileLoadTo(_peer->id, _silent->checked(), replyToId());
|
auto to = FileLoadTo(_peer->id, _silent->checked(), replyToId());
|
||||||
auto caption = QString();
|
auto caption = QString();
|
||||||
_fileLoader.addTask(MakeShared<FileLoadTask>(fileContent, QImage(), type, to, caption));
|
_fileLoader.addTask(MakeShared<FileLoadTask>(fileContent, QImage(), type, to, caption));
|
||||||
|
|
||||||
cancelReplyAfterMediaSend(lastForceReplyReplied());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
|
void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
|
||||||
|
@ -4364,13 +4279,19 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
|
||||||
|
|
||||||
Auth().uploader().upload(newId, file);
|
Auth().uploader().upload(newId, file);
|
||||||
|
|
||||||
History *h = App::history(file->to.peer);
|
const auto history = App::history(file->to.peer);
|
||||||
|
const auto peer = history->peer;
|
||||||
|
|
||||||
fastShowAtEnd(h);
|
auto options = ApiWrap::SendOptions(history);
|
||||||
|
options.clearDraft = false;
|
||||||
|
options.replyTo = file->to.replyTo;
|
||||||
|
options.generateLocal = true;
|
||||||
|
options.silent = file->to.silent;
|
||||||
|
Auth().api().sendAction(options);
|
||||||
|
|
||||||
auto flags = NewMessageFlags(h->peer) | MTPDmessage::Flag::f_media; // unread, out
|
auto flags = NewMessageFlags(peer) | MTPDmessage::Flag::f_media;
|
||||||
if (file->to.replyTo) flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
if (file->to.replyTo) flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
||||||
bool channelPost = h->peer->isChannel() && !h->peer->isMegagroup();
|
bool channelPost = peer->isChannel() && !peer->isMegagroup();
|
||||||
bool silentPost = channelPost && file->to.silent;
|
bool silentPost = channelPost && file->to.silent;
|
||||||
if (channelPost) {
|
if (channelPost) {
|
||||||
flags |= MTPDmessage::Flag::f_views;
|
flags |= MTPDmessage::Flag::f_views;
|
||||||
|
@ -4378,7 +4299,7 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
|
||||||
}
|
}
|
||||||
if (!channelPost) {
|
if (!channelPost) {
|
||||||
flags |= MTPDmessage::Flag::f_from_id;
|
flags |= MTPDmessage::Flag::f_from_id;
|
||||||
} else if (h->peer->asChannel()->addsSignature()) {
|
} else if (peer->asChannel()->addsSignature()) {
|
||||||
flags |= MTPDmessage::Flag::f_post_author;
|
flags |= MTPDmessage::Flag::f_post_author;
|
||||||
}
|
}
|
||||||
if (silentPost) {
|
if (silentPost) {
|
||||||
|
@ -4396,7 +4317,7 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
|
||||||
file->photo,
|
file->photo,
|
||||||
MTP_string(file->caption),
|
MTP_string(file->caption),
|
||||||
MTPint());
|
MTPint());
|
||||||
h->addNewMessage(
|
history->addNewMessage(
|
||||||
MTP_message(
|
MTP_message(
|
||||||
MTP_flags(flags),
|
MTP_flags(flags),
|
||||||
MTP_int(newId.msg),
|
MTP_int(newId.msg),
|
||||||
|
@ -4425,7 +4346,7 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
|
||||||
file->document,
|
file->document,
|
||||||
MTP_string(file->caption),
|
MTP_string(file->caption),
|
||||||
MTPint());
|
MTPint());
|
||||||
h->addNewMessage(
|
history->addNewMessage(
|
||||||
MTP_message(
|
MTP_message(
|
||||||
MTP_flags(flags),
|
MTP_flags(flags),
|
||||||
MTP_int(newId.msg),
|
MTP_int(newId.msg),
|
||||||
|
@ -4445,7 +4366,7 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
|
||||||
MTPlong()),
|
MTPlong()),
|
||||||
NewMessageUnread);
|
NewMessageUnread);
|
||||||
} else if (file->type == SendMediaType::Audio) {
|
} else if (file->type == SendMediaType::Audio) {
|
||||||
if (!h->peer->isChannel()) {
|
if (!peer->isChannel()) {
|
||||||
flags |= MTPDmessage::Flag::f_media_unread;
|
flags |= MTPDmessage::Flag::f_media_unread;
|
||||||
}
|
}
|
||||||
auto documentFlags = MTPDmessageMediaDocument::Flag::f_document | 0;
|
auto documentFlags = MTPDmessageMediaDocument::Flag::f_document | 0;
|
||||||
|
@ -4457,7 +4378,7 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
|
||||||
file->document,
|
file->document,
|
||||||
MTP_string(file->caption),
|
MTP_string(file->caption),
|
||||||
MTPint());
|
MTPint());
|
||||||
h->addNewMessage(
|
history->addNewMessage(
|
||||||
MTP_message(
|
MTP_message(
|
||||||
MTP_flags(flags),
|
MTP_flags(flags),
|
||||||
MTP_int(newId.msg),
|
MTP_int(newId.msg),
|
||||||
|
@ -4483,8 +4404,6 @@ void HistoryWidget::sendFileConfirmed(const FileLoadResultPtr &file) {
|
||||||
}
|
}
|
||||||
App::main()->dialogsToUp();
|
App::main()->dialogsToUp();
|
||||||
peerMessagesUpdated(file->to.peer);
|
peerMessagesUpdated(file->to.peer);
|
||||||
|
|
||||||
cancelReplyAfterMediaSend(lastKeyboardUsed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, bool silent, const MTPInputFile &file) {
|
void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, bool silent, const MTPInputFile &file) {
|
||||||
|
@ -4833,17 +4752,17 @@ void HistoryWidget::updateControlsGeometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (_attachDrag) {
|
switch (_attachDrag) {
|
||||||
case DragStateFiles:
|
case DragState::Files:
|
||||||
_attachDragDocument->resize(width() - st::dragMargin.left() - st::dragMargin.right(), height() - st::dragMargin.top() - st::dragMargin.bottom());
|
_attachDragDocument->resize(width() - st::dragMargin.left() - st::dragMargin.right(), height() - st::dragMargin.top() - st::dragMargin.bottom());
|
||||||
_attachDragDocument->move(st::dragMargin.left(), st::dragMargin.top());
|
_attachDragDocument->move(st::dragMargin.left(), st::dragMargin.top());
|
||||||
break;
|
break;
|
||||||
case DragStatePhotoFiles:
|
case DragState::PhotoFiles:
|
||||||
_attachDragDocument->resize(width() - st::dragMargin.left() - st::dragMargin.right(), (height() - st::dragMargin.top() - st::dragMargin.bottom()) / 2);
|
_attachDragDocument->resize(width() - st::dragMargin.left() - st::dragMargin.right(), (height() - st::dragMargin.top() - st::dragMargin.bottom()) / 2);
|
||||||
_attachDragDocument->move(st::dragMargin.left(), st::dragMargin.top());
|
_attachDragDocument->move(st::dragMargin.left(), st::dragMargin.top());
|
||||||
_attachDragPhoto->resize(_attachDragDocument->width(), _attachDragDocument->height());
|
_attachDragPhoto->resize(_attachDragDocument->width(), _attachDragDocument->height());
|
||||||
_attachDragPhoto->move(st::dragMargin.left(), height() - _attachDragPhoto->height() - st::dragMargin.bottom());
|
_attachDragPhoto->move(st::dragMargin.left(), height() - _attachDragPhoto->height() - st::dragMargin.bottom());
|
||||||
break;
|
break;
|
||||||
case DragStateImage:
|
case DragState::Image:
|
||||||
_attachDragPhoto->resize(width() - st::dragMargin.left() - st::dragMargin.right(), height() - st::dragMargin.top() - st::dragMargin.bottom());
|
_attachDragPhoto->resize(width() - st::dragMargin.left() - st::dragMargin.right(), height() - st::dragMargin.top() - st::dragMargin.bottom());
|
||||||
_attachDragPhoto->move(st::dragMargin.left(), st::dragMargin.top());
|
_attachDragPhoto->move(st::dragMargin.left(), st::dragMargin.top());
|
||||||
break;
|
break;
|
||||||
|
@ -5365,23 +5284,24 @@ void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
App::main()->readServerHistory(_history);
|
auto options = ApiWrap::SendOptions(_history);
|
||||||
fastShowAtEnd(_history);
|
options.clearDraft = true;
|
||||||
|
options.replyTo = replyToId();
|
||||||
|
options.generateLocal = true;
|
||||||
|
options.silent = _silent->checked();
|
||||||
|
Auth().api().sendAction(options);
|
||||||
|
|
||||||
uint64 randomId = rand_value<uint64>();
|
uint64 randomId = rand_value<uint64>();
|
||||||
FullMsgId newId(_channel, clientMsgId());
|
FullMsgId newId(_channel, clientMsgId());
|
||||||
|
|
||||||
bool lastKeyboardUsed = lastForceReplyReplied();
|
auto flags = NewMessageFlags(_peer) | MTPDmessage::Flag::f_media;
|
||||||
|
|
||||||
bool out = !_peer->isSelf(), unread = !_peer->isSelf();
|
|
||||||
auto flags = NewMessageFlags(_peer) | MTPDmessage::Flag::f_media; // unread, out
|
|
||||||
auto sendFlags = MTPmessages_SendInlineBotResult::Flag::f_clear_draft | 0;
|
auto sendFlags = MTPmessages_SendInlineBotResult::Flag::f_clear_draft | 0;
|
||||||
if (replyToId()) {
|
if (options.replyTo) {
|
||||||
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
||||||
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_reply_to_msg_id;
|
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_reply_to_msg_id;
|
||||||
}
|
}
|
||||||
bool channelPost = _peer->isChannel() && !_peer->isMegagroup();
|
bool channelPost = _peer->isChannel() && !_peer->isMegagroup();
|
||||||
bool silentPost = channelPost && _silent->checked();
|
bool silentPost = channelPost && options.silent;
|
||||||
if (channelPost) {
|
if (channelPost) {
|
||||||
flags |= MTPDmessage::Flag::f_views;
|
flags |= MTPDmessage::Flag::f_views;
|
||||||
flags |= MTPDmessage::Flag::f_post;
|
flags |= MTPDmessage::Flag::f_post;
|
||||||
|
@ -5408,7 +5328,6 @@ void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot
|
||||||
|
|
||||||
_history->sendRequestId = MTP::send(MTPmessages_SendInlineBotResult(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_long(randomId), MTP_long(result->getQueryId()), MTP_string(result->getId())), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
|
_history->sendRequestId = MTP::send(MTPmessages_SendInlineBotResult(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_long(randomId), MTP_long(result->getQueryId()), MTP_string(result->getId())), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
|
||||||
App::main()->finishForwarding(_history, _silent->checked());
|
App::main()->finishForwarding(_history, _silent->checked());
|
||||||
cancelReply(lastKeyboardUsed);
|
|
||||||
|
|
||||||
App::historyRegRandom(randomId, newId);
|
App::historyRegRandom(randomId, newId);
|
||||||
|
|
||||||
|
@ -5548,23 +5467,24 @@ bool HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
App::main()->readServerHistory(_history);
|
auto options = ApiWrap::SendOptions(_history);
|
||||||
fastShowAtEnd(_history);
|
options.clearDraft = false;
|
||||||
|
options.replyTo = replyToId();
|
||||||
|
options.generateLocal = true;
|
||||||
|
options.silent = _silent->checked();
|
||||||
|
Auth().api().sendAction(options);
|
||||||
|
|
||||||
uint64 randomId = rand_value<uint64>();
|
uint64 randomId = rand_value<uint64>();
|
||||||
FullMsgId newId(_channel, clientMsgId());
|
FullMsgId newId(_channel, clientMsgId());
|
||||||
|
|
||||||
bool lastKeyboardUsed = lastForceReplyReplied();
|
auto flags = NewMessageFlags(_peer) | MTPDmessage::Flag::f_media;
|
||||||
|
|
||||||
bool out = !_peer->isSelf(), unread = !_peer->isSelf();
|
|
||||||
auto flags = NewMessageFlags(_peer) | MTPDmessage::Flag::f_media; // unread, out
|
|
||||||
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
||||||
if (replyToId()) {
|
if (replyToId()) {
|
||||||
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
|
||||||
}
|
}
|
||||||
bool channelPost = _peer->isChannel() && !_peer->isMegagroup();
|
bool channelPost = _peer->isChannel() && !_peer->isMegagroup();
|
||||||
bool silentPost = channelPost && _silent->checked();
|
bool silentPost = channelPost && options.silent;
|
||||||
if (channelPost) {
|
if (channelPost) {
|
||||||
flags |= MTPDmessage::Flag::f_views;
|
flags |= MTPDmessage::Flag::f_views;
|
||||||
flags |= MTPDmessage::Flag::f_post;
|
flags |= MTPDmessage::Flag::f_post;
|
||||||
|
@ -5583,7 +5503,6 @@ bool HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
|
||||||
|
|
||||||
_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaDocument(MTP_flags(0), mtpInput, MTP_string(caption), MTPint()), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
|
_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaDocument(MTP_flags(0), mtpInput, MTP_string(caption), MTPint()), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
|
||||||
App::main()->finishForwarding(_history, _silent->checked());
|
App::main()->finishForwarding(_history, _silent->checked());
|
||||||
cancelReplyAfterMediaSend(lastKeyboardUsed);
|
|
||||||
|
|
||||||
if (doc->sticker()) App::main()->incrementSticker(doc);
|
if (doc->sticker()) App::main()->incrementSticker(doc);
|
||||||
|
|
||||||
|
@ -5608,16 +5527,17 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
App::main()->readServerHistory(_history);
|
auto options = ApiWrap::SendOptions(_history);
|
||||||
fastShowAtEnd(_history);
|
options.clearDraft = false;
|
||||||
|
options.replyTo = replyToId();
|
||||||
|
options.generateLocal = true;
|
||||||
|
options.silent = _silent->checked();
|
||||||
|
Auth().api().sendAction(options);
|
||||||
|
|
||||||
uint64 randomId = rand_value<uint64>();
|
uint64 randomId = rand_value<uint64>();
|
||||||
FullMsgId newId(_channel, clientMsgId());
|
FullMsgId newId(_channel, clientMsgId());
|
||||||
|
|
||||||
bool lastKeyboardUsed = lastForceReplyReplied();
|
auto flags = NewMessageFlags(_peer) | MTPDmessage::Flag::f_media;
|
||||||
|
|
||||||
bool out = !_peer->isSelf(), unread = !_peer->isSelf();
|
|
||||||
auto flags = NewMessageFlags(_peer) | MTPDmessage::Flag::f_media; // unread, out
|
|
||||||
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
||||||
if (replyToId()) {
|
if (replyToId()) {
|
||||||
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
||||||
|
@ -5643,7 +5563,6 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption)
|
||||||
|
|
||||||
_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaPhoto(MTP_flags(0), MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)), MTP_string(caption), MTPint()), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
|
_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaPhoto(MTP_flags(0), MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)), MTP_string(caption), MTPint()), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
|
||||||
App::main()->finishForwarding(_history, _silent->checked());
|
App::main()->finishForwarding(_history, _silent->checked());
|
||||||
cancelReplyAfterMediaSend(lastKeyboardUsed);
|
|
||||||
|
|
||||||
App::historyRegRandom(randomId, newId);
|
App::historyRegRandom(randomId, newId);
|
||||||
|
|
||||||
|
@ -5843,10 +5762,18 @@ void HistoryWidget::onCopyPostLink() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const {
|
bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const {
|
||||||
if (replyTo.msg > 0 && replyTo.channel != _channel) return false;
|
if (replyTo.channel != _channel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return _keyboard->forceReply()
|
return _keyboard->forceReply()
|
||||||
&& _keyboard->forMsgId() == FullMsgId(_channel, _history->lastKeyboardId)
|
&& _keyboard->forMsgId() == FullMsgId(_channel, _history->lastKeyboardId)
|
||||||
&& _keyboard->forMsgId().msg == (replyTo.msg < 0 ? replyToId() : replyTo.msg);
|
&& _keyboard->forMsgId().msg == replyTo.msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryWidget::lastForceReplyReplied() const {
|
||||||
|
return _keyboard->forceReply()
|
||||||
|
&& _keyboard->forMsgId() == FullMsgId(_channel, _history->lastKeyboardId)
|
||||||
|
&& _keyboard->forMsgId().msg == replyToId();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryWidget::cancelReply(bool lastKeyboardUsed) {
|
bool HistoryWidget::cancelReply(bool lastKeyboardUsed) {
|
||||||
|
@ -5880,7 +5807,10 @@ bool HistoryWidget::cancelReply(bool lastKeyboardUsed) {
|
||||||
_saveDraftStart = getms();
|
_saveDraftStart = getms();
|
||||||
onDraftSave();
|
onDraftSave();
|
||||||
}
|
}
|
||||||
if (!_editMsgId && _keyboard->singleUse() && _keyboard->forceReply() && lastKeyboardUsed) {
|
if (!_editMsgId
|
||||||
|
&& _keyboard->singleUse()
|
||||||
|
&& _keyboard->forceReply()
|
||||||
|
&& lastKeyboardUsed) {
|
||||||
if (_kbReplyTo) {
|
if (_kbReplyTo) {
|
||||||
onKbToggle(false);
|
onKbToggle(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "storage/localimageloader.h"
|
#include "storage/localimageloader.h"
|
||||||
#include "ui/widgets/tooltip.h"
|
#include "ui/widgets/tooltip.h"
|
||||||
#include "history/history_common.h"
|
#include "mainwidget.h"
|
||||||
#include "chat_helpers/field_autocomplete.h"
|
#include "chat_helpers/field_autocomplete.h"
|
||||||
#include "window/section_widget.h"
|
#include "window/section_widget.h"
|
||||||
#include "core/single_timer.h"
|
#include "core/single_timer.h"
|
||||||
|
@ -103,7 +103,6 @@ class HistoryHider : public Ui::RpWidget, private base::Subscriber {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HistoryHider(MainWidget *parent, MessageIdsList &&items); // forward messages
|
HistoryHider(MainWidget *parent, MessageIdsList &&items); // forward messages
|
||||||
HistoryHider(MainWidget *parent, UserData *sharedContact); // share contact
|
|
||||||
HistoryHider(MainWidget *parent); // send path from command line argument
|
HistoryHider(MainWidget *parent); // send path from command line argument
|
||||||
HistoryHider(MainWidget *parent, const QString &url, const QString &text); // share url
|
HistoryHider(MainWidget *parent, const QString &url, const QString &text); // share url
|
||||||
HistoryHider(MainWidget *parent, const QString &botAndQuery); // inline switch button handler
|
HistoryHider(MainWidget *parent, const QString &botAndQuery); // inline switch button handler
|
||||||
|
@ -142,7 +141,6 @@ private:
|
||||||
void init();
|
void init();
|
||||||
MainWidget *parent();
|
MainWidget *parent();
|
||||||
|
|
||||||
UserData *_sharedContact = nullptr;
|
|
||||||
MessageIdsList _forwardItems;
|
MessageIdsList _forwardItems;
|
||||||
bool _sendPath = false;
|
bool _sendPath = false;
|
||||||
|
|
||||||
|
@ -200,7 +198,6 @@ public:
|
||||||
|
|
||||||
void newUnreadMsg(History *history, HistoryItem *item);
|
void newUnreadMsg(History *history, HistoryItem *item);
|
||||||
void historyToDown(History *history);
|
void historyToDown(History *history);
|
||||||
void historyWasRead(ReadServerHistoryChecks checks);
|
|
||||||
void unreadCountChanged(History *history);
|
void unreadCountChanged(History *history);
|
||||||
|
|
||||||
QRect historyRect() const;
|
QRect historyRect() const;
|
||||||
|
@ -234,10 +231,6 @@ public:
|
||||||
void updateControlsVisibility();
|
void updateControlsVisibility();
|
||||||
void updateControlsGeometry();
|
void updateControlsGeometry();
|
||||||
|
|
||||||
void onShareContact(const PeerId &peer, UserData *contact);
|
|
||||||
|
|
||||||
void shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, int32 userId = 0);
|
|
||||||
|
|
||||||
History *history() const;
|
History *history() const;
|
||||||
PeerData *peer() const;
|
PeerData *peer() const;
|
||||||
void setMsgId(MsgId showAtMsgId);
|
void setMsgId(MsgId showAtMsgId);
|
||||||
|
@ -268,7 +261,8 @@ public:
|
||||||
|
|
||||||
MsgId replyToId() const;
|
MsgId replyToId() const;
|
||||||
void messageDataReceived(ChannelData *channel, MsgId msgId);
|
void messageDataReceived(ChannelData *channel, MsgId msgId);
|
||||||
bool lastForceReplyReplied(const FullMsgId &replyTo = FullMsgId(NoChannel, -1)) const;
|
bool lastForceReplyReplied(const FullMsgId &replyTo) const;
|
||||||
|
bool lastForceReplyReplied() const;
|
||||||
bool cancelReply(bool lastKeyboardUsed = false);
|
bool cancelReply(bool lastKeyboardUsed = false);
|
||||||
void cancelEdit();
|
void cancelEdit();
|
||||||
void updateForwarding();
|
void updateForwarding();
|
||||||
|
@ -301,7 +295,7 @@ public:
|
||||||
|
|
||||||
DragState getDragState(const QMimeData *d);
|
DragState getDragState(const QMimeData *d);
|
||||||
|
|
||||||
void fastShowAtEnd(History *h);
|
void fastShowAtEnd(not_null<History*> history);
|
||||||
void applyDraft(bool parseLinks = true, Ui::FlatTextarea::UndoHistoryAction undoHistoryAction = Ui::FlatTextarea::ClearUndoHistory);
|
void applyDraft(bool parseLinks = true, Ui::FlatTextarea::UndoHistoryAction undoHistoryAction = Ui::FlatTextarea::ClearUndoHistory);
|
||||||
void showHistory(const PeerId &peer, MsgId showAtMsgId, bool reload = false);
|
void showHistory(const PeerId &peer, MsgId showAtMsgId, bool reload = false);
|
||||||
void clearDelayedShowAt();
|
void clearDelayedShowAt();
|
||||||
|
@ -405,7 +399,6 @@ public slots:
|
||||||
void onReportSpamClear();
|
void onReportSpamClear();
|
||||||
|
|
||||||
void onScroll();
|
void onScroll();
|
||||||
void onSend(bool ctrlShiftEnter = false, MsgId replyTo = -1);
|
|
||||||
|
|
||||||
void onUnblock();
|
void onUnblock();
|
||||||
void onBotStart();
|
void onBotStart();
|
||||||
|
@ -452,6 +445,8 @@ public slots:
|
||||||
void preloadHistoryIfNeeded();
|
void preloadHistoryIfNeeded();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void onSend(bool ctrlShiftEnter = false);
|
||||||
|
|
||||||
void onHashtagOrBotCommandInsert(QString str, FieldAutocomplete::ChooseMethod method);
|
void onHashtagOrBotCommandInsert(QString str, FieldAutocomplete::ChooseMethod method);
|
||||||
void onMentionInsert(UserData *user);
|
void onMentionInsert(UserData *user);
|
||||||
void onInlineBotCancel();
|
void onInlineBotCancel();
|
||||||
|
@ -825,7 +820,7 @@ private:
|
||||||
object_ptr<InlineBots::Layout::Widget> _inlineResults = { nullptr };
|
object_ptr<InlineBots::Layout::Widget> _inlineResults = { nullptr };
|
||||||
object_ptr<TabbedPanel> _tabbedPanel;
|
object_ptr<TabbedPanel> _tabbedPanel;
|
||||||
QPointer<TabbedSelector> _tabbedSelector;
|
QPointer<TabbedSelector> _tabbedSelector;
|
||||||
DragState _attachDrag = DragStateNone;
|
DragState _attachDrag = DragState::None;
|
||||||
object_ptr<DragArea> _attachDragDocument, _attachDragPhoto;
|
object_ptr<DragArea> _attachDragDocument, _attachDragPhoto;
|
||||||
|
|
||||||
object_ptr<Ui::Emoji::SuggestionsController> _emojiSuggestions = { nullptr };
|
object_ptr<Ui::Emoji::SuggestionsController> _emojiSuggestions = { nullptr };
|
||||||
|
|
|
@ -790,10 +790,6 @@ void MainWidget::onUpdateMuted() {
|
||||||
App::updateMuted();
|
App::updateMuted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::onShareContact(const PeerId &peerId, UserData *contact) {
|
|
||||||
_history->onShareContact(peerId, contact);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWidget::onSendPaths(const PeerId &peerId) {
|
bool MainWidget::onSendPaths(const PeerId &peerId) {
|
||||||
Expects(peerId != 0);
|
Expects(peerId != 0);
|
||||||
auto peer = App::peer(peerId);
|
auto peer = App::peer(peerId);
|
||||||
|
@ -1016,10 +1012,6 @@ void MainWidget::deletePhotoLayer(PhotoData *photo) {
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::shareContactLayer(UserData *contact) {
|
|
||||||
hiderLayer(object_ptr<HistoryHider>(this, contact));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::shareUrlLayer(const QString &url, const QString &text) {
|
void MainWidget::shareUrlLayer(const QString &url, const QString &text) {
|
||||||
// Don't allow to insert an inline bot query by share url link.
|
// Don't allow to insert an inline bot query by share url link.
|
||||||
if (url.trimmed().startsWith('@')) {
|
if (url.trimmed().startsWith('@')) {
|
||||||
|
@ -1100,15 +1092,26 @@ void MainWidget::deleteHistoryPart(DeleteHistoryRequest request, const MTPmessag
|
||||||
MTP::send(MTPmessages_DeleteHistory(MTP_flags(flags), peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, request));
|
MTP::send(MTPmessages_DeleteHistory(MTP_flags(flags), peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, request));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::deleteMessages(PeerData *peer, const QVector<MTPint> &ids, bool forEveryone) {
|
void MainWidget::deleteMessages(
|
||||||
if (peer->isChannel()) {
|
not_null<PeerData*> peer,
|
||||||
MTP::send(MTPchannels_DeleteMessages(peer->asChannel()->inputChannel, MTP_vector<MTPint>(ids)), rpcDone(&MainWidget::messagesAffected, peer));
|
const QVector<MTPint> &ids,
|
||||||
|
bool forEveryone) {
|
||||||
|
if (const auto channel = peer->asChannel()) {
|
||||||
|
MTP::send(
|
||||||
|
MTPchannels_DeleteMessages(
|
||||||
|
channel->inputChannel,
|
||||||
|
MTP_vector<MTPint>(ids)),
|
||||||
|
rpcDone(&MainWidget::messagesAffected, peer));
|
||||||
} else {
|
} else {
|
||||||
auto flags = MTPmessages_DeleteMessages::Flags(0);
|
auto flags = MTPmessages_DeleteMessages::Flags(0);
|
||||||
if (forEveryone) {
|
if (forEveryone) {
|
||||||
flags |= MTPmessages_DeleteMessages::Flag::f_revoke;
|
flags |= MTPmessages_DeleteMessages::Flag::f_revoke;
|
||||||
}
|
}
|
||||||
MTP::send(MTPmessages_DeleteMessages(MTP_flags(flags), MTP_vector<MTPint>(ids)), rpcDone(&MainWidget::messagesAffected, peer));
|
MTP::send(
|
||||||
|
MTPmessages_DeleteMessages(
|
||||||
|
MTP_flags(flags),
|
||||||
|
MTP_vector<MTPint>(ids)),
|
||||||
|
rpcDone(&MainWidget::messagesAffected, peer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1458,13 +1461,18 @@ Dialogs::IndexedList *MainWidget::contactsNoDialogsList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::sendMessage(const MessageToSend &message) {
|
void MainWidget::sendMessage(const MessageToSend &message) {
|
||||||
auto history = message.history;
|
const auto history = message.history;
|
||||||
auto &textWithTags = message.textWithTags;
|
auto &textWithTags = message.textWithTags;
|
||||||
|
|
||||||
readServerHistory(history);
|
auto options = ApiWrap::SendOptions(message.history);
|
||||||
_history->fastShowAtEnd(history);
|
options.clearDraft = message.clearDraft;
|
||||||
|
options.replyTo = message.replyTo;
|
||||||
|
options.generateLocal = true;
|
||||||
|
options.silent = message.silent;
|
||||||
|
options.webPageId = message.webPageId;
|
||||||
|
Auth().api().sendAction(options);
|
||||||
|
|
||||||
if (!history || !history->peer->canWrite()) {
|
if (!history->peer->canWrite()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
saveRecentHashtags(textWithTags.text);
|
saveRecentHashtags(textWithTags.text);
|
||||||
|
@ -1476,7 +1484,6 @@ void MainWidget::sendMessage(const MessageToSend &message) {
|
||||||
|
|
||||||
HistoryItem *lastMessage = nullptr;
|
HistoryItem *lastMessage = nullptr;
|
||||||
|
|
||||||
auto replyTo = (message.replyTo < 0) ? _history->replyToId() : message.replyTo;
|
|
||||||
while (TextUtilities::CutPart(sending, left, MaxMessageSize)) {
|
while (TextUtilities::CutPart(sending, left, MaxMessageSize)) {
|
||||||
auto newId = FullMsgId(peerToChannel(history->peer->id), clientMsgId());
|
auto newId = FullMsgId(peerToChannel(history->peer->id), clientMsgId());
|
||||||
auto randomId = rand_value<uint64>();
|
auto randomId = rand_value<uint64>();
|
||||||
|
@ -1489,7 +1496,7 @@ void MainWidget::sendMessage(const MessageToSend &message) {
|
||||||
MTPstring msgText(MTP_string(sending.text));
|
MTPstring msgText(MTP_string(sending.text));
|
||||||
auto flags = NewMessageFlags(history->peer) | MTPDmessage::Flag::f_entities; // unread, out
|
auto flags = NewMessageFlags(history->peer) | MTPDmessage::Flag::f_entities; // unread, out
|
||||||
auto sendFlags = MTPmessages_SendMessage::Flags(0);
|
auto sendFlags = MTPmessages_SendMessage::Flags(0);
|
||||||
if (replyTo) {
|
if (message.replyTo) {
|
||||||
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to_msg_id;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to_msg_id;
|
||||||
}
|
}
|
||||||
|
@ -1534,7 +1541,7 @@ void MainWidget::sendMessage(const MessageToSend &message) {
|
||||||
peerToMTP(history->peer->id),
|
peerToMTP(history->peer->id),
|
||||||
MTPnullFwdHeader,
|
MTPnullFwdHeader,
|
||||||
MTPint(),
|
MTPint(),
|
||||||
MTP_int(replyTo),
|
MTP_int(message.replyTo),
|
||||||
MTP_int(unixtime()),
|
MTP_int(unixtime()),
|
||||||
msgText,
|
msgText,
|
||||||
media,
|
media,
|
||||||
|
@ -1545,7 +1552,20 @@ void MainWidget::sendMessage(const MessageToSend &message) {
|
||||||
MTP_string(messagePostAuthor),
|
MTP_string(messagePostAuthor),
|
||||||
MTPlong()),
|
MTPlong()),
|
||||||
NewMessageUnread);
|
NewMessageUnread);
|
||||||
history->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_flags(sendFlags), history->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, sentEntities), rpcDone(&MainWidget::sentUpdatesReceived, randomId), rpcFail(&MainWidget::sendMessageFail), 0, 0, history->sendRequestId);
|
history->sendRequestId = MTP::send(
|
||||||
|
MTPmessages_SendMessage(
|
||||||
|
MTP_flags(sendFlags),
|
||||||
|
history->peer->input,
|
||||||
|
MTP_int(message.replyTo),
|
||||||
|
msgText,
|
||||||
|
MTP_long(randomId),
|
||||||
|
MTPnullMarkup,
|
||||||
|
sentEntities),
|
||||||
|
rpcDone(&MainWidget::sentUpdatesReceived, randomId),
|
||||||
|
rpcFail(&MainWidget::sendMessageFail),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
history->sendRequestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
history->lastSentMsg = lastMessage;
|
history->lastSentMsg = lastMessage;
|
||||||
|
@ -1581,30 +1601,6 @@ void MainWidget::saveRecentHashtags(const QString &text) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::readServerHistory(History *history, ReadServerHistoryChecks checks) {
|
|
||||||
if (!history) return;
|
|
||||||
if (checks == ReadServerHistoryChecks::OnlyIfUnread && !history->unreadCount()) return;
|
|
||||||
|
|
||||||
auto peer = history->peer;
|
|
||||||
MsgId upTo = history->inboxRead(0);
|
|
||||||
if (auto channel = peer->asChannel()) {
|
|
||||||
if (!channel->amIn()) {
|
|
||||||
return; // no read request for channels that I didn't koin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_readRequests.contains(peer)) {
|
|
||||||
auto i = _readRequestsPending.find(peer);
|
|
||||||
if (i == _readRequestsPending.cend()) {
|
|
||||||
_readRequestsPending.insert(peer, upTo);
|
|
||||||
} else if (i.value() < upTo) {
|
|
||||||
i.value() = upTo;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sendReadRequest(peer, upTo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::unreadCountChanged(History *history) {
|
void MainWidget::unreadCountChanged(History *history) {
|
||||||
_history->unreadCountChanged(history);
|
_history->unreadCountChanged(history);
|
||||||
}
|
}
|
||||||
|
@ -1761,45 +1757,14 @@ void MainWidget::overviewLoaded(
|
||||||
Notify::mediaOverviewUpdated(history->peer, type);
|
Notify::mediaOverviewUpdated(history->peer, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::sendReadRequest(PeerData *peer, MsgId upTo) {
|
void MainWidget::messagesAffected(
|
||||||
if (peer->isChannel()) {
|
not_null<PeerData*> peer,
|
||||||
_readRequests.insert(peer, qMakePair(MTP::send(MTPchannels_ReadHistory(peer->asChannel()->inputChannel, MTP_int(upTo)), rpcDone(&MainWidget::channelReadDone, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo));
|
const MTPmessages_AffectedMessages &result) {
|
||||||
|
const auto &data = result.c_messages_affectedMessages();
|
||||||
|
if (const auto channel = peer->asChannel()) {
|
||||||
|
channel->ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
||||||
} else {
|
} else {
|
||||||
_readRequests.insert(peer, qMakePair(MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(upTo)), rpcDone(&MainWidget::historyReadDone, peer), rpcFail(&MainWidget::readRequestFail, peer)), upTo));
|
ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::channelReadDone(PeerData *peer, const MTPBool &result) {
|
|
||||||
readRequestDone(peer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::historyReadDone(PeerData *peer, const MTPmessages_AffectedMessages &result) {
|
|
||||||
messagesAffected(peer, result);
|
|
||||||
readRequestDone(peer);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWidget::readRequestFail(PeerData *peer, const RPCError &error) {
|
|
||||||
if (MTP::isDefaultHandledError(error)) return false;
|
|
||||||
|
|
||||||
readRequestDone(peer);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::readRequestDone(PeerData *peer) {
|
|
||||||
_readRequests.remove(peer);
|
|
||||||
ReadRequestsPending::iterator i = _readRequestsPending.find(peer);
|
|
||||||
if (i != _readRequestsPending.cend()) {
|
|
||||||
sendReadRequest(peer, i.value());
|
|
||||||
_readRequestsPending.erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::messagesAffected(PeerData *peer, const MTPmessages_AffectedMessages &result) {
|
|
||||||
auto &d = result.c_messages_affectedMessages();
|
|
||||||
if (peer && peer->isChannel()) {
|
|
||||||
peer->asChannel()->ptsUpdateAndApply(d.vpts.v, d.vpts_count.v);
|
|
||||||
} else {
|
|
||||||
ptsUpdateAndApply(d.vpts.v, d.vpts_count.v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto h = App::historyLoaded(peer ? peer->id : 0)) {
|
if (auto h = App::historyLoaded(peer ? peer->id : 0)) {
|
||||||
|
@ -1809,6 +1774,12 @@ void MainWidget::messagesAffected(PeerData *peer, const MTPmessages_AffectedMess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::messagesContentsRead(
|
||||||
|
const MTPmessages_AffectedMessages &result) {
|
||||||
|
const auto &data = result.c_messages_affectedMessages();
|
||||||
|
ptsUpdateAndApply(data.vpts.v, data.vpts_count.v);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWidget::handleAudioUpdate(const AudioMsgId &audioId) {
|
void MainWidget::handleAudioUpdate(const AudioMsgId &audioId) {
|
||||||
using State = Media::Player::State;
|
using State = Media::Player::State;
|
||||||
auto state = Media::Player::mixer()->currentState(audioId.type());
|
auto state = Media::Player::mixer()->currentState(audioId.type());
|
||||||
|
@ -2063,31 +2034,37 @@ void MainWidget::mediaMarkRead(not_null<DocumentData*> data) {
|
||||||
auto &items = App::documentItems();
|
auto &items = App::documentItems();
|
||||||
auto i = items.constFind(data);
|
auto i = items.constFind(data);
|
||||||
if (i != items.cend()) {
|
if (i != items.cend()) {
|
||||||
mediaMarkRead(i.value());
|
mediaMarkRead({ i.value().begin(), i.value().end() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::mediaMarkRead(const HistoryItemsMap &items) {
|
void MainWidget::mediaMarkRead(
|
||||||
|
const base::flat_set<not_null<HistoryItem*>> &items) {
|
||||||
QVector<MTPint> markedIds;
|
QVector<MTPint> markedIds;
|
||||||
QMap<ChannelData*, QVector<MTPint>> channelMarkedIds;
|
base::flat_map<not_null<ChannelData*>, QVector<MTPint>> channelMarkedIds;
|
||||||
markedIds.reserve(items.size());
|
markedIds.reserve(items.size());
|
||||||
for_const (auto item, items) {
|
for (const auto item : items) {
|
||||||
if ((!item->out() || item->mentionsMe()) && item->isMediaUnread()) {
|
if (!item->isMediaUnread() || (item->out() && !item->mentionsMe())) {
|
||||||
item->markMediaRead();
|
continue;
|
||||||
if (item->id > 0) {
|
}
|
||||||
if (auto channel = item->history()->peer->asChannel()) {
|
item->markMediaRead();
|
||||||
channelMarkedIds[channel].push_back(MTP_int(item->id));
|
if (item->id > 0) {
|
||||||
} else {
|
if (const auto channel = item->history()->peer->asChannel()) {
|
||||||
markedIds.push_back(MTP_int(item->id));
|
channelMarkedIds[channel].push_back(MTP_int(item->id));
|
||||||
}
|
} else {
|
||||||
|
markedIds.push_back(MTP_int(item->id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!markedIds.isEmpty()) {
|
if (!markedIds.isEmpty()) {
|
||||||
MTP::send(MTPmessages_ReadMessageContents(MTP_vector<MTPint>(markedIds)), rpcDone(&MainWidget::messagesAffected, (PeerData*)0));
|
MTP::send(
|
||||||
|
MTPmessages_ReadMessageContents(MTP_vector<MTPint>(markedIds)),
|
||||||
|
rpcDone(&MainWidget::messagesContentsRead));
|
||||||
}
|
}
|
||||||
for (auto i = channelMarkedIds.cbegin(), e = channelMarkedIds.cend(); i != e; ++i) {
|
for (const auto &channelIds : channelMarkedIds) {
|
||||||
MTP::send(MTPchannels_ReadMessageContents(i.key()->inputChannel, MTP_vector<MTPint>(i.value())));
|
MTP::send(MTPchannels_ReadMessageContents(
|
||||||
|
channelIds.first->inputChannel,
|
||||||
|
MTP_vector<MTPint>(channelIds.second)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2095,10 +2072,16 @@ void MainWidget::mediaMarkRead(not_null<HistoryItem*> item) {
|
||||||
if ((!item->out() || item->mentionsMe()) && item->isMediaUnread()) {
|
if ((!item->out() || item->mentionsMe()) && item->isMediaUnread()) {
|
||||||
item->markMediaRead();
|
item->markMediaRead();
|
||||||
if (item->id > 0) {
|
if (item->id > 0) {
|
||||||
if (auto channel = item->history()->peer->asChannel()) {
|
const auto ids = MTP_vector<MTPint>(1, MTP_int(item->id));
|
||||||
MTP::send(MTPchannels_ReadMessageContents(channel->inputChannel, MTP_vector<MTPint>(1, MTP_int(item->id))));
|
if (const auto channel = item->history()->peer->asChannel()) {
|
||||||
|
MTP::send(
|
||||||
|
MTPchannels_ReadMessageContents(
|
||||||
|
channel->inputChannel,
|
||||||
|
ids));
|
||||||
} else {
|
} else {
|
||||||
MTP::send(MTPmessages_ReadMessageContents(MTP_vector<MTPint>(1, MTP_int(item->id))), rpcDone(&MainWidget::messagesAffected, (PeerData*)0));
|
MTP::send(
|
||||||
|
MTPmessages_ReadMessageContents(ids),
|
||||||
|
rpcDone(&MainWidget::messagesContentsRead));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3115,7 +3098,9 @@ void MainWidget::newUnreadMsg(History *history, HistoryItem *item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::markActiveHistoryAsRead() {
|
void MainWidget::markActiveHistoryAsRead() {
|
||||||
_history->historyWasRead(ReadServerHistoryChecks::OnlyIfUnread);
|
if (const auto activeHistory = _history->history()) {
|
||||||
|
Auth().api().readServerHistory(activeHistory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::showAnimated(const QPixmap &bgAnimCache, bool back) {
|
void MainWidget::showAnimated(const QPixmap &bgAnimCache, bool back) {
|
||||||
|
|
|
@ -21,7 +21,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "storage/localimageloader.h"
|
#include "storage/localimageloader.h"
|
||||||
#include "history/history_common.h"
|
|
||||||
#include "core/single_timer.h"
|
#include "core/single_timer.h"
|
||||||
#include "base/weak_ptr.h"
|
#include "base/weak_ptr.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
@ -81,6 +80,13 @@ class ItemBase;
|
||||||
} // namespace Layout
|
} // namespace Layout
|
||||||
} // namespace InlineBots
|
} // namespace InlineBots
|
||||||
|
|
||||||
|
enum class DragState {
|
||||||
|
None = 0x00,
|
||||||
|
Files = 0x01,
|
||||||
|
PhotoFiles = 0x02,
|
||||||
|
Image = 0x03,
|
||||||
|
};
|
||||||
|
|
||||||
class MainWidget : public Ui::RpWidget, public RPCSender, private base::Subscriber {
|
class MainWidget : public Ui::RpWidget, public RPCSender, private base::Subscriber {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -182,7 +188,6 @@ public:
|
||||||
void showSendPathsLayer();
|
void showSendPathsLayer();
|
||||||
void deleteLayer(int selectedCount = 0); // 0 - context item
|
void deleteLayer(int selectedCount = 0); // 0 - context item
|
||||||
void cancelUploadLayer();
|
void cancelUploadLayer();
|
||||||
void shareContactLayer(UserData *contact);
|
|
||||||
void shareUrlLayer(const QString &url, const QString &text);
|
void shareUrlLayer(const QString &url, const QString &text);
|
||||||
void inlineSwitchLayer(const QString &botAndQuery);
|
void inlineSwitchLayer(const QString &botAndQuery);
|
||||||
void hiderLayer(object_ptr<HistoryHider> h);
|
void hiderLayer(object_ptr<HistoryHider> h);
|
||||||
|
@ -194,7 +199,6 @@ public:
|
||||||
const QString &url,
|
const QString &url,
|
||||||
const QString &text);
|
const QString &text);
|
||||||
bool onInlineSwitchChosen(const PeerId &peer, const QString &botAndQuery);
|
bool onInlineSwitchChosen(const PeerId &peer, const QString &botAndQuery);
|
||||||
void onShareContact(const PeerId &peer, UserData *contact);
|
|
||||||
bool onSendPaths(const PeerId &peer);
|
bool onSendPaths(const PeerId &peer);
|
||||||
void onFilesOrForwardDrop(const PeerId &peer, const QMimeData *data);
|
void onFilesOrForwardDrop(const PeerId &peer, const QMimeData *data);
|
||||||
bool selectingPeer(bool withConfirm = false) const;
|
bool selectingPeer(bool withConfirm = false) const;
|
||||||
|
@ -208,7 +212,10 @@ public:
|
||||||
|
|
||||||
bool leaveChatFailed(PeerData *peer, const RPCError &e);
|
bool leaveChatFailed(PeerData *peer, const RPCError &e);
|
||||||
void deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updates);
|
void deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updates);
|
||||||
void deleteMessages(PeerData *peer, const QVector<MTPint> &ids, bool forEveryone);
|
void deleteMessages(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const QVector<MTPint> &ids,
|
||||||
|
bool forEveryone);
|
||||||
void deletedContact(UserData *user, const MTPcontacts_Link &result);
|
void deletedContact(UserData *user, const MTPcontacts_Link &result);
|
||||||
void deleteConversation(PeerData *peer, bool deleteHistory = true);
|
void deleteConversation(PeerData *peer, bool deleteHistory = true);
|
||||||
void deleteAndExit(ChatData *chat);
|
void deleteAndExit(ChatData *chat);
|
||||||
|
@ -243,7 +250,10 @@ public:
|
||||||
Dialogs::IndexedList *contactsNoDialogsList();
|
Dialogs::IndexedList *contactsNoDialogsList();
|
||||||
|
|
||||||
struct MessageToSend {
|
struct MessageToSend {
|
||||||
History *history = nullptr;
|
MessageToSend(not_null<History*> history) : history(history) {
|
||||||
|
}
|
||||||
|
|
||||||
|
not_null<History*> history;
|
||||||
TextWithTags textWithTags;
|
TextWithTags textWithTags;
|
||||||
MsgId replyTo = 0;
|
MsgId replyTo = 0;
|
||||||
bool silent = false;
|
bool silent = false;
|
||||||
|
@ -253,7 +263,6 @@ public:
|
||||||
void sendMessage(const MessageToSend &message);
|
void sendMessage(const MessageToSend &message);
|
||||||
void saveRecentHashtags(const QString &text);
|
void saveRecentHashtags(const QString &text);
|
||||||
|
|
||||||
void readServerHistory(History *history, ReadServerHistoryChecks checks = ReadServerHistoryChecks::OnlyIfUnread);
|
|
||||||
void unreadCountChanged(History *history);
|
void unreadCountChanged(History *history);
|
||||||
|
|
||||||
TimeMs highlightStartTime(not_null<const HistoryItem*> item) const;
|
TimeMs highlightStartTime(not_null<const HistoryItem*> item) const;
|
||||||
|
@ -295,7 +304,7 @@ public:
|
||||||
void finishForwarding(History *history, bool silent); // send them
|
void finishForwarding(History *history, bool silent); // send them
|
||||||
|
|
||||||
void mediaMarkRead(not_null<DocumentData*> data);
|
void mediaMarkRead(not_null<DocumentData*> data);
|
||||||
void mediaMarkRead(const HistoryItemsMap &items);
|
void mediaMarkRead(const base::flat_set<not_null<HistoryItem*>> &items);
|
||||||
void mediaMarkRead(not_null<HistoryItem*> item);
|
void mediaMarkRead(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
void webPageUpdated(WebPageData *page);
|
void webPageUpdated(WebPageData *page);
|
||||||
|
@ -458,13 +467,10 @@ private:
|
||||||
void destroyCallTopBar();
|
void destroyCallTopBar();
|
||||||
void callTopBarHeightUpdated(int callTopBarHeight);
|
void callTopBarHeightUpdated(int callTopBarHeight);
|
||||||
|
|
||||||
void sendReadRequest(PeerData *peer, MsgId upTo);
|
void messagesAffected(
|
||||||
void channelReadDone(PeerData *peer, const MTPBool &result);
|
not_null<PeerData*> peer,
|
||||||
void historyReadDone(PeerData *peer, const MTPmessages_AffectedMessages &result);
|
const MTPmessages_AffectedMessages &result);
|
||||||
bool readRequestFail(PeerData *peer, const RPCError &error);
|
void messagesContentsRead(const MTPmessages_AffectedMessages &result);
|
||||||
void readRequestDone(PeerData *peer);
|
|
||||||
|
|
||||||
void messagesAffected(PeerData *peer, const MTPmessages_AffectedMessages &result);
|
|
||||||
void overviewLoaded(
|
void overviewLoaded(
|
||||||
std::pair<not_null<History*>, MsgId> historyAndStartMsgId,
|
std::pair<not_null<History*>, MsgId> historyAndStartMsgId,
|
||||||
const MTPmessages_Messages &result,
|
const MTPmessages_Messages &result,
|
||||||
|
@ -640,11 +646,6 @@ private:
|
||||||
base::flat_set<not_null<PeerData*>> updateNotifySettingPeers;
|
base::flat_set<not_null<PeerData*>> updateNotifySettingPeers;
|
||||||
SingleTimer updateNotifySettingTimer;
|
SingleTimer updateNotifySettingTimer;
|
||||||
|
|
||||||
typedef QMap<PeerData*, QPair<mtpRequestId, MsgId> > ReadRequests;
|
|
||||||
ReadRequests _readRequests;
|
|
||||||
typedef QMap<PeerData*, MsgId> ReadRequestsPending;
|
|
||||||
ReadRequestsPending _readRequestsPending;
|
|
||||||
|
|
||||||
typedef QMap<PeerData*, mtpRequestId> OverviewsPreload;
|
typedef QMap<PeerData*, mtpRequestId> OverviewsPreload;
|
||||||
OverviewsPreload _overviewPreload[OverviewCount], _overviewLoad[OverviewCount];
|
OverviewsPreload _overviewPreload[OverviewCount], _overviewLoad[OverviewCount];
|
||||||
|
|
||||||
|
|
|
@ -218,7 +218,7 @@ public:
|
||||||
setToDC(dcId);
|
setToDC(dcId);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
[[nodiscard]] SpecificRequestBuilder &canWait(TimeMs ms) noexcept {
|
[[nodiscard]] SpecificRequestBuilder &afterDelay(TimeMs ms) noexcept {
|
||||||
setCanWait(ms);
|
setCanWait(ms);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ public:
|
||||||
setFailSkipPolicy(FailSkipPolicy::HandleAll);
|
setFailSkipPolicy(FailSkipPolicy::HandleAll);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
[[nodiscard]] SpecificRequestBuilder &after(mtpRequestId requestId) noexcept {
|
[[nodiscard]] SpecificRequestBuilder &afterRequest(mtpRequestId requestId) noexcept {
|
||||||
setAfter(requestId);
|
setAfter(requestId);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,13 +417,15 @@ void Manager::notificationActivated(PeerId peerId, MsgId msgId) {
|
||||||
onAfterNotificationActivated(peerId, msgId);
|
onAfterNotificationActivated(peerId, msgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::notificationReplied(PeerId peerId, MsgId msgId, const QString &reply) {
|
void Manager::notificationReplied(
|
||||||
|
PeerId peerId,
|
||||||
|
MsgId msgId,
|
||||||
|
const QString &reply) {
|
||||||
if (!peerId) return;
|
if (!peerId) return;
|
||||||
|
|
||||||
auto history = App::history(peerId);
|
auto history = App::history(peerId);
|
||||||
|
|
||||||
MainWidget::MessageToSend message;
|
auto message = MainWidget::MessageToSend(history);
|
||||||
message.history = history;
|
|
||||||
message.textWithTags = { reply, TextWithTags::Tags() };
|
message.textWithTags = { reply, TextWithTags::Tags() };
|
||||||
message.replyTo = (msgId > 0 && !history->peer->isUser()) ? msgId : 0;
|
message.replyTo = (msgId > 0 && !history->peer->isUser()) ? msgId : 0;
|
||||||
message.silent = false;
|
message.silent = false;
|
||||||
|
|
|
@ -419,17 +419,20 @@ void PeerMenuAddContact(not_null<UserData*> user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerMenuShareContactBox(not_null<UserData*> user) {
|
void PeerMenuShareContactBox(not_null<UserData*> user) {
|
||||||
auto callback = [user](not_null<PeerData*> peer) {
|
const auto weak = std::make_shared<QPointer<PeerListBox>>();
|
||||||
|
auto callback = [=](not_null<PeerData*> peer) {
|
||||||
if (!peer->canWrite()) {
|
if (!peer->canWrite()) {
|
||||||
Ui::show(Box<InformBox>(
|
Ui::show(Box<InformBox>(
|
||||||
lang(lng_forward_share_cant)),
|
lang(lng_forward_share_cant)),
|
||||||
LayerOption::KeepOther);
|
LayerOption::KeepOther);
|
||||||
return;
|
return;
|
||||||
} else if (peer->isSelf()) {
|
} else if (peer->isSelf()) {
|
||||||
App::main()->onShareContact(
|
auto options = ApiWrap::SendOptions(App::history(peer));
|
||||||
peer->id,
|
Auth().api().shareContact(user, options);
|
||||||
user);
|
|
||||||
Ui::Toast::Show(lang(lng_share_done));
|
Ui::Toast::Show(lang(lng_share_done));
|
||||||
|
if (auto strong = *weak) {
|
||||||
|
strong->closeBox();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto recipient = peer->isUser()
|
auto recipient = peer->isUser()
|
||||||
|
@ -439,13 +442,13 @@ void PeerMenuShareContactBox(not_null<UserData*> user) {
|
||||||
lng_forward_share_contact(lt_recipient, recipient),
|
lng_forward_share_contact(lt_recipient, recipient),
|
||||||
lang(lng_forward_send),
|
lang(lng_forward_send),
|
||||||
[peer, user] {
|
[peer, user] {
|
||||||
App::main()->onShareContact(
|
const auto history = App::history(peer);
|
||||||
peer->id,
|
Ui::showPeerHistory(history, ShowAtTheEndMsgId);
|
||||||
user);
|
auto options = ApiWrap::SendOptions(history);
|
||||||
Ui::hideLayer();
|
Auth().api().shareContact(user, options);
|
||||||
}), LayerOption::KeepOther);
|
}), LayerOption::KeepOther);
|
||||||
};
|
};
|
||||||
Ui::show(Box<PeerListBox>(
|
*weak = Ui::show(Box<PeerListBox>(
|
||||||
std::make_unique<ChooseRecipientBoxController>(std::move(callback)),
|
std::make_unique<ChooseRecipientBoxController>(std::move(callback)),
|
||||||
[](not_null<PeerListBox*> box) {
|
[](not_null<PeerListBox*> box) {
|
||||||
box->addButton(langFactory(lng_cancel), [box] {
|
box->addButton(langFactory(lng_cancel), [box] {
|
||||||
|
@ -457,7 +460,7 @@ void PeerMenuShareContactBox(not_null<UserData*> user) {
|
||||||
void ShowForwardMessagesBox(
|
void ShowForwardMessagesBox(
|
||||||
MessageIdsList &&items,
|
MessageIdsList &&items,
|
||||||
base::lambda_once<void()> &&successCallback) {
|
base::lambda_once<void()> &&successCallback) {
|
||||||
auto weak = std::make_shared<QPointer<PeerListBox>>();
|
const auto weak = std::make_shared<QPointer<PeerListBox>>();
|
||||||
auto callback = [
|
auto callback = [
|
||||||
ids = std::move(items),
|
ids = std::move(items),
|
||||||
callback = std::move(successCallback),
|
callback = std::move(successCallback),
|
||||||
|
|
|
@ -203,7 +203,6 @@
|
||||||
<(src_loc)/history/history_admin_log_item.h
|
<(src_loc)/history/history_admin_log_item.h
|
||||||
<(src_loc)/history/history_admin_log_section.cpp
|
<(src_loc)/history/history_admin_log_section.cpp
|
||||||
<(src_loc)/history/history_admin_log_section.h
|
<(src_loc)/history/history_admin_log_section.h
|
||||||
<(src_loc)/history/history_common.h
|
|
||||||
<(src_loc)/history/history_drag_area.cpp
|
<(src_loc)/history/history_drag_area.cpp
|
||||||
<(src_loc)/history/history_drag_area.h
|
<(src_loc)/history/history_drag_area.h
|
||||||
<(src_loc)/history/history_item.cpp
|
<(src_loc)/history/history_item.cpp
|
||||||
|
|
Loading…
Reference in New Issue