mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Move updates handling MainWidget -> Api::Updates.
This commit is contained in:
parent
ee43027bea
commit
0b028b959b
30 changed files with 2526 additions and 2218 deletions
|
@ -167,6 +167,8 @@ PRIVATE
|
|||
api/api_single_message_search.h
|
||||
api/api_text_entities.cpp
|
||||
api/api_text_entities.h
|
||||
api/api_updates.cpp
|
||||
api/api_updates.h
|
||||
boxes/filters/edit_filter_box.cpp
|
||||
boxes/filters/edit_filter_box.h
|
||||
boxes/filters/edit_filter_chats_list.cpp
|
||||
|
|
2030
Telegram/SourceFiles/api/api_updates.cpp
Normal file
2030
Telegram/SourceFiles/api/api_updates.cpp
Normal file
File diff suppressed because it is too large
Load diff
172
Telegram/SourceFiles/api/api_updates.h
Normal file
172
Telegram/SourceFiles/api/api_updates.h
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "mtproto/mtproto_rpc_sender.h"
|
||||
#include "data/data_pts_waiter.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
class ApiWrap;
|
||||
class History;
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Api {
|
||||
|
||||
class Updates final {
|
||||
public:
|
||||
explicit Updates(not_null<Main::Session*> session);
|
||||
|
||||
[[nodiscard]] Main::Session &session() const;
|
||||
[[nodiscard]] ApiWrap &api() const;
|
||||
|
||||
void applyUpdates(
|
||||
const MTPUpdates &updates,
|
||||
uint64 sentMessageRandomId = 0);
|
||||
void applyUpdatesNoPtsCheck(const MTPUpdates &updates);
|
||||
void applyUpdateNoPtsCheck(const MTPUpdate &update);
|
||||
|
||||
void updateOnline();
|
||||
[[nodiscard]] bool isIdle() const;
|
||||
void checkIdleFinish();
|
||||
bool lastWasOnline() const;
|
||||
crl::time lastSetOnline() const;
|
||||
bool isQuitPrevent();
|
||||
|
||||
bool updateAndApply(int32 pts, int32 ptsCount, const MTPUpdates &updates);
|
||||
bool updateAndApply(int32 pts, int32 ptsCount, const MTPUpdate &update);
|
||||
bool updateAndApply(int32 pts, int32 ptsCount);
|
||||
|
||||
void checkLastUpdate(bool afterSleep);
|
||||
|
||||
// ms <= 0 - stop timer
|
||||
void ptsWaiterStartTimerFor(ChannelData *channel, crl::time ms);
|
||||
|
||||
void getDifference();
|
||||
void requestChannelRangeDifference(not_null<History*> history);
|
||||
|
||||
void addActiveChat(rpl::producer<PeerData*> chat);
|
||||
|
||||
private:
|
||||
enum class ChannelDifferenceRequest {
|
||||
Unknown,
|
||||
PtsGapOrShortPoll,
|
||||
AfterFail,
|
||||
};
|
||||
|
||||
struct ActiveChatTracker {
|
||||
PeerData *peer = nullptr;
|
||||
rpl::lifetime lifetime;
|
||||
};
|
||||
|
||||
void channelRangeDifferenceSend(
|
||||
not_null<ChannelData*> channel,
|
||||
MsgRange range,
|
||||
int32 pts);
|
||||
void channelRangeDifferenceDone(
|
||||
not_null<ChannelData*> channel,
|
||||
MsgRange range,
|
||||
const MTPupdates_ChannelDifference &result);
|
||||
|
||||
void updateOnline(bool gotOtherOffline);
|
||||
void sendPing();
|
||||
void getDifferenceByPts();
|
||||
void getDifferenceAfterFail();
|
||||
|
||||
[[nodiscard]] bool requestingDifference() const {
|
||||
return _ptsWaiter.requesting();
|
||||
}
|
||||
void getChannelDifference(
|
||||
not_null<ChannelData*> channel,
|
||||
ChannelDifferenceRequest from = ChannelDifferenceRequest::Unknown);
|
||||
void differenceDone(const MTPupdates_Difference &result);
|
||||
void differenceFail(const RPCError &error);
|
||||
void feedDifference(
|
||||
const MTPVector<MTPUser> &users,
|
||||
const MTPVector<MTPChat> &chats,
|
||||
const MTPVector<MTPMessage> &msgs,
|
||||
const MTPVector<MTPUpdate> &other);
|
||||
void stateDone(const MTPupdates_State &state);
|
||||
void setState(int32 pts, int32 date, int32 qts, int32 seq);
|
||||
void channelDifferenceDone(
|
||||
not_null<ChannelData*> channel,
|
||||
const MTPupdates_ChannelDifference &diff);
|
||||
void channelDifferenceFail(
|
||||
not_null<ChannelData*> channel,
|
||||
const RPCError &error);
|
||||
void failDifferenceStartTimerFor(ChannelData *channel);
|
||||
void feedChannelDifference(const MTPDupdates_channelDifference &data);
|
||||
|
||||
void mtpUpdateReceived(const MTPUpdates &updates);
|
||||
void mtpNewSessionCreated();
|
||||
void feedUpdateVector(
|
||||
const MTPVector<MTPUpdate> &updates,
|
||||
bool skipMessageIds = false);
|
||||
// Doesn't call sendHistoryChangeNotifications itself.
|
||||
void feedMessageIds(const MTPVector<MTPUpdate> &updates);
|
||||
// Doesn't call sendHistoryChangeNotifications itself.
|
||||
void feedUpdate(const MTPUpdate &update);
|
||||
|
||||
bool whenGetDiffChanged(
|
||||
ChannelData *channel,
|
||||
int32 ms,
|
||||
base::flat_map<not_null<ChannelData*>, crl::time> &whenMap,
|
||||
crl::time &curTime);
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
|
||||
int32 _updatesDate = 0;
|
||||
int32 _updatesQts = -1;
|
||||
int32 _updatesSeq = 0;
|
||||
base::Timer _noUpdatesTimer;
|
||||
base::Timer _onlineTimer;
|
||||
|
||||
PtsWaiter _ptsWaiter;
|
||||
|
||||
base::flat_map<not_null<ChannelData*>, crl::time> _whenGetDiffByPts;
|
||||
base::flat_map<not_null<ChannelData*>, crl::time> _whenGetDiffAfterFail;
|
||||
crl::time _getDifferenceTimeByPts = 0;
|
||||
crl::time _getDifferenceTimeAfterFail = 0;
|
||||
|
||||
base::Timer _byPtsTimer;
|
||||
|
||||
base::flat_map<int32, MTPUpdates> _bySeqUpdates;
|
||||
base::Timer _bySeqTimer;
|
||||
|
||||
base::Timer _byMinChannelTimer;
|
||||
|
||||
// growing timeout for getDifference calls, if it fails
|
||||
crl::time _failDifferenceTimeout = 1;
|
||||
// growing timeout for getChannelDifference calls, if it fails
|
||||
base::flat_map<
|
||||
not_null<ChannelData*>,
|
||||
crl::time> _channelFailDifferenceTimeout;
|
||||
base::Timer _failDifferenceTimer;
|
||||
|
||||
base::flat_map<
|
||||
not_null<ChannelData*>,
|
||||
mtpRequestId> _rangeDifferenceRequests;
|
||||
|
||||
crl::time _lastUpdateTime = 0;
|
||||
bool _handlingChannelDifference = false;
|
||||
|
||||
base::flat_map<int, ActiveChatTracker> _activeChats;
|
||||
|
||||
mtpRequestId _onlineRequest = 0;
|
||||
base::Timer _idleFinishTimer;
|
||||
crl::time _lastSetOnline = 0;
|
||||
bool _lastWasOnline = false;
|
||||
bool _isIdle = false;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Api
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "api/api_text_entities.h"
|
||||
#include "api/api_self_destruct.h"
|
||||
#include "api/api_sensitive_content.h"
|
||||
#include "api/api_updates.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "data/data_photo.h"
|
||||
|
@ -272,6 +273,10 @@ Storage::Account &ApiWrap::local() const {
|
|||
return _session->local();
|
||||
}
|
||||
|
||||
Api::Updates &ApiWrap::updates() const {
|
||||
return _session->updates();
|
||||
}
|
||||
|
||||
void ApiWrap::setupSupportMode() {
|
||||
if (!_session->supportMode()) {
|
||||
return;
|
||||
|
@ -491,12 +496,6 @@ void ApiWrap::importChatInvite(const QString &hash) {
|
|||
}).send();
|
||||
}
|
||||
|
||||
void ApiWrap::applyUpdates(
|
||||
const MTPUpdates &updates,
|
||||
uint64 sentMessageRandomId) {
|
||||
App::main()->feedUpdates(updates, sentMessageRandomId);
|
||||
}
|
||||
|
||||
void ApiWrap::savePinnedOrder(Data::Folder *folder) {
|
||||
const auto &order = _session->data().pinnedChatsOrder(
|
||||
folder,
|
||||
|
@ -2321,8 +2320,8 @@ void ApiWrap::deleteConversation(not_null<PeerData*> peer, bool revoke) {
|
|||
request(MTPmessages_DeleteChatUser(
|
||||
chat->inputChat,
|
||||
_session->user()->inputUser
|
||||
)).done([=](const MTPUpdates &updates) {
|
||||
applyUpdates(updates);
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
deleteHistory(peer, false, revoke);
|
||||
}).fail([=](const RPCError &error) {
|
||||
deleteHistory(peer, false, revoke);
|
||||
|
@ -2392,6 +2391,12 @@ void ApiWrap::deleteHistory(
|
|||
}
|
||||
}
|
||||
|
||||
void ApiWrap::applyUpdates(
|
||||
const MTPUpdates &updates,
|
||||
uint64 sentMessageRandomId) {
|
||||
this->updates().applyUpdates(updates, sentMessageRandomId);
|
||||
}
|
||||
|
||||
int ApiWrap::applyAffectedHistory(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPmessages_AffectedHistory &result) {
|
||||
|
@ -2399,7 +2404,7 @@ int ApiWrap::applyAffectedHistory(
|
|||
if (const auto channel = peer->asChannel()) {
|
||||
channel->ptsUpdateAndApply(data.vpts().v, data.vpts_count().v);
|
||||
} else {
|
||||
App::main()->ptsUpdateAndApply(data.vpts().v, data.vpts_count().v);
|
||||
updates().updateAndApply(data.vpts().v, data.vpts_count().v);
|
||||
}
|
||||
return data.voffset().v;
|
||||
}
|
||||
|
@ -2418,7 +2423,26 @@ void ApiWrap::applyAffectedMessages(
|
|||
void ApiWrap::applyAffectedMessages(
|
||||
const MTPmessages_AffectedMessages &result) {
|
||||
const auto &data = result.c_messages_affectedMessages();
|
||||
App::main()->ptsUpdateAndApply(data.vpts().v, data.vpts_count().v);
|
||||
updates().updateAndApply(data.vpts().v, data.vpts_count().v);
|
||||
}
|
||||
|
||||
void ApiWrap::saveCurrentDraftToCloud() {
|
||||
Core::App().saveCurrentDraftsToHistories();
|
||||
|
||||
for (const auto controller : session().windows()) {
|
||||
if (const auto peer = controller->activeChatCurrent().peer()) {
|
||||
if (const auto history = session().data().historyLoaded(peer)) {
|
||||
session().local().writeDrafts(history);
|
||||
|
||||
const auto localDraft = history->localDraft();
|
||||
const auto cloudDraft = history->cloudDraft();
|
||||
if (!Data::draftsAreEqual(localDraft, cloudDraft)
|
||||
&& !session().supportMode()) {
|
||||
saveDraftToCloudDelayed(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::saveDraftsToCloud() {
|
||||
|
@ -2713,98 +2737,6 @@ void ApiWrap::requestParticipantsCountDelayed(
|
|||
[=] { channel->updateFullForced(); });
|
||||
}
|
||||
|
||||
void ApiWrap::requestChannelRangeDifference(not_null<History*> history) {
|
||||
Expects(history->isChannel());
|
||||
|
||||
const auto channel = history->peer->asChannel();
|
||||
if (const auto requestId = _rangeDifferenceRequests.take(channel)) {
|
||||
request(*requestId).cancel();
|
||||
}
|
||||
const auto range = history->rangeForDifferenceRequest();
|
||||
if (!(range.from < range.till) || !channel->pts()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MTP_LOG(0, ("getChannelDifference { good - "
|
||||
"after channelDifferenceTooLong was received, "
|
||||
"validating history part }%1").arg(cTestMode() ? " TESTMODE" : ""));
|
||||
channelRangeDifferenceSend(channel, range, channel->pts());
|
||||
}
|
||||
|
||||
void ApiWrap::channelRangeDifferenceSend(
|
||||
not_null<ChannelData*> channel,
|
||||
MsgRange range,
|
||||
int32 pts) {
|
||||
Expects(range.from < range.till);
|
||||
|
||||
const auto limit = range.till - range.from;
|
||||
const auto filter = MTP_channelMessagesFilter(
|
||||
MTP_flags(0),
|
||||
MTP_vector<MTPMessageRange>(1, MTP_messageRange(
|
||||
MTP_int(range.from),
|
||||
MTP_int(range.till - 1))));
|
||||
const auto requestId = request(MTPupdates_GetChannelDifference(
|
||||
MTP_flags(MTPupdates_GetChannelDifference::Flag::f_force),
|
||||
channel->inputChannel,
|
||||
filter,
|
||||
MTP_int(pts),
|
||||
MTP_int(limit)
|
||||
)).done([=](const MTPupdates_ChannelDifference &result) {
|
||||
_rangeDifferenceRequests.remove(channel);
|
||||
channelRangeDifferenceDone(channel, range, result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
_rangeDifferenceRequests.remove(channel);
|
||||
}).send();
|
||||
_rangeDifferenceRequests.emplace(channel, requestId);
|
||||
}
|
||||
|
||||
void ApiWrap::channelRangeDifferenceDone(
|
||||
not_null<ChannelData*> channel,
|
||||
MsgRange range,
|
||||
const MTPupdates_ChannelDifference &result) {
|
||||
auto nextRequestPts = int32(0);
|
||||
auto isFinal = true;
|
||||
|
||||
switch (result.type()) {
|
||||
case mtpc_updates_channelDifferenceEmpty: {
|
||||
const auto &d = result.c_updates_channelDifferenceEmpty();
|
||||
nextRequestPts = d.vpts().v;
|
||||
isFinal = d.is_final();
|
||||
} break;
|
||||
|
||||
case mtpc_updates_channelDifferenceTooLong: {
|
||||
const auto &d = result.c_updates_channelDifferenceTooLong();
|
||||
|
||||
_session->data().processUsers(d.vusers());
|
||||
_session->data().processChats(d.vchats());
|
||||
|
||||
nextRequestPts = d.vdialog().match([&](const MTPDdialog &data) {
|
||||
return data.vpts().value_or_empty();
|
||||
}, [&](const MTPDdialogFolder &data) {
|
||||
return 0;
|
||||
});
|
||||
isFinal = d.is_final();
|
||||
} break;
|
||||
|
||||
case mtpc_updates_channelDifference: {
|
||||
const auto &d = result.c_updates_channelDifference();
|
||||
|
||||
App::main()->feedChannelDifference(d);
|
||||
|
||||
nextRequestPts = d.vpts().v;
|
||||
isFinal = d.is_final();
|
||||
} break;
|
||||
}
|
||||
|
||||
if (!isFinal && nextRequestPts) {
|
||||
MTP_LOG(0, ("getChannelDifference { "
|
||||
"good - after not final channelDifference was received, "
|
||||
"validating history part }%1"
|
||||
).arg(cTestMode() ? " TESTMODE" : ""));
|
||||
channelRangeDifferenceSend(channel, range, nextRequestPts);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Request>
|
||||
void ApiWrap::requestFileReference(
|
||||
Data::FileOrigin origin,
|
||||
|
@ -3418,224 +3350,6 @@ void ApiWrap::parseRecentChannelParticipants(
|
|||
}, std::move(callbackNotModified));
|
||||
}
|
||||
|
||||
void ApiWrap::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
|
||||
switch (updates.type()) {
|
||||
case mtpc_updateShortMessage: {
|
||||
const auto &d = updates.c_updateShortMessage();
|
||||
const auto flags = mtpCastFlags(d.vflags().v)
|
||||
| MTPDmessage::Flag::f_from_id;
|
||||
const auto peerUserId = d.is_out()
|
||||
? d.vuser_id()
|
||||
: MTP_int(_session->userId());
|
||||
const auto fwd = d.vfwd_from();
|
||||
_session->data().addNewMessage(
|
||||
MTP_message(
|
||||
MTP_flags(flags),
|
||||
d.vid(),
|
||||
d.is_out() ? MTP_int(_session->userId()) : d.vuser_id(),
|
||||
MTP_peerUser(peerUserId),
|
||||
fwd ? (*fwd) : MTPMessageFwdHeader(),
|
||||
MTP_int(d.vvia_bot_id().value_or_empty()),
|
||||
MTP_int(d.vreply_to_msg_id().value_or_empty()),
|
||||
d.vdate(),
|
||||
d.vmessage(),
|
||||
MTP_messageMediaEmpty(),
|
||||
MTPReplyMarkup(),
|
||||
MTP_vector<MTPMessageEntity>(d.ventities().value_or_empty()),
|
||||
MTPint(),
|
||||
MTPint(),
|
||||
MTPstring(),
|
||||
MTPlong(),
|
||||
//MTPMessageReactions(),
|
||||
MTPVector<MTPRestrictionReason>()),
|
||||
MTPDmessage_ClientFlags(),
|
||||
NewMessageType::Unread);
|
||||
} break;
|
||||
|
||||
case mtpc_updateShortChatMessage: {
|
||||
const auto &d = updates.c_updateShortChatMessage();
|
||||
const auto flags = mtpCastFlags(d.vflags().v) | MTPDmessage::Flag::f_from_id;
|
||||
const auto fwd = d.vfwd_from();
|
||||
_session->data().addNewMessage(
|
||||
MTP_message(
|
||||
MTP_flags(flags),
|
||||
d.vid(),
|
||||
d.vfrom_id(),
|
||||
MTP_peerChat(d.vchat_id()),
|
||||
fwd ? (*fwd) : MTPMessageFwdHeader(),
|
||||
MTP_int(d.vvia_bot_id().value_or_empty()),
|
||||
MTP_int(d.vreply_to_msg_id().value_or_empty()),
|
||||
d.vdate(),
|
||||
d.vmessage(),
|
||||
MTP_messageMediaEmpty(),
|
||||
MTPReplyMarkup(),
|
||||
MTP_vector<MTPMessageEntity>(d.ventities().value_or_empty()),
|
||||
MTPint(),
|
||||
MTPint(),
|
||||
MTPstring(),
|
||||
MTPlong(),
|
||||
//MTPMessageReactions(),
|
||||
MTPVector<MTPRestrictionReason>()),
|
||||
MTPDmessage_ClientFlags(),
|
||||
NewMessageType::Unread);
|
||||
} break;
|
||||
|
||||
case mtpc_updateShortSentMessage: {
|
||||
auto &d = updates.c_updateShortSentMessage();
|
||||
Q_UNUSED(d); // Sent message data was applied anyway.
|
||||
} break;
|
||||
|
||||
default: Unexpected("Type in applyUpdatesNoPtsCheck()");
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::applyUpdateNoPtsCheck(const MTPUpdate &update) {
|
||||
switch (update.type()) {
|
||||
case mtpc_updateNewMessage: {
|
||||
auto &d = update.c_updateNewMessage();
|
||||
auto needToAdd = true;
|
||||
if (d.vmessage().type() == mtpc_message) { // index forwarded messages to links _overview
|
||||
const auto &data = d.vmessage().c_message();
|
||||
if (_session->data().checkEntitiesAndViewsUpdate(data)) { // already in blocks
|
||||
LOG(("Skipping message, because it is already in blocks!"));
|
||||
needToAdd = false;
|
||||
}
|
||||
if (needToAdd && !data.is_from_scheduled()) {
|
||||
// If we still need to add a new message,
|
||||
// we should first check if this message is in
|
||||
// the list of scheduled messages.
|
||||
// This is necessary to correctly update the file reference.
|
||||
// Note that when a message is scheduled until online
|
||||
// while the recipient is already online, the server sends
|
||||
// an ordinary new message with skipped "from_scheduled" flag.
|
||||
_session->data().scheduledMessages().checkEntitiesAndUpdate(
|
||||
data);
|
||||
}
|
||||
}
|
||||
if (needToAdd) {
|
||||
_session->data().addNewMessage(
|
||||
d.vmessage(),
|
||||
MTPDmessage_ClientFlags(),
|
||||
NewMessageType::Unread);
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateReadMessagesContents: {
|
||||
const auto &d = update.c_updateReadMessagesContents();
|
||||
auto possiblyReadMentions = base::flat_set<MsgId>();
|
||||
for (const auto &msgId : d.vmessages().v) {
|
||||
if (const auto item = _session->data().message(NoChannel, msgId.v)) {
|
||||
if (item->isUnreadMedia() || item->isUnreadMention()) {
|
||||
item->markMediaRead();
|
||||
_session->data().requestItemRepaint(item);
|
||||
|
||||
if (item->out()
|
||||
&& item->history()->peer->isUser()
|
||||
&& !App::main()->requestingDifference()) {
|
||||
item->history()->peer->asUser()->madeAction(base::unixtime::now());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Perhaps it was an unread mention!
|
||||
possiblyReadMentions.insert(msgId.v);
|
||||
}
|
||||
}
|
||||
checkForUnreadMentions(possiblyReadMentions);
|
||||
} break;
|
||||
|
||||
case mtpc_updateReadHistoryInbox: {
|
||||
const auto &d = update.c_updateReadHistoryInbox();
|
||||
const auto peer = peerFromMTP(d.vpeer());
|
||||
if (const auto history = _session->data().historyLoaded(peer)) {
|
||||
const auto folderId = d.vfolder_id().value_or_empty();
|
||||
history->applyInboxReadUpdate(
|
||||
folderId,
|
||||
d.vmax_id().v,
|
||||
d.vstill_unread_count().v);
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateReadHistoryOutbox: {
|
||||
const auto &d = update.c_updateReadHistoryOutbox();
|
||||
const auto peer = peerFromMTP(d.vpeer());
|
||||
if (const auto history = _session->data().historyLoaded(peer)) {
|
||||
history->outboxRead(d.vmax_id().v);
|
||||
if (!App::main()->requestingDifference()) {
|
||||
if (const auto user = history->peer->asUser()) {
|
||||
user->madeAction(base::unixtime::now());
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateWebPage: {
|
||||
auto &d = update.c_updateWebPage();
|
||||
Q_UNUSED(d); // Web page was updated anyway.
|
||||
} break;
|
||||
|
||||
case mtpc_updateFolderPeers: {
|
||||
const auto &data = update.c_updateFolderPeers();
|
||||
auto &owner = _session->data();
|
||||
for (const auto &peer : data.vfolder_peers().v) {
|
||||
peer.match([&](const MTPDfolderPeer &data) {
|
||||
const auto peerId = peerFromMTP(data.vpeer());
|
||||
if (const auto history = owner.historyLoaded(peerId)) {
|
||||
if (const auto folderId = data.vfolder_id().v) {
|
||||
history->setFolder(owner.folder(folderId));
|
||||
} else {
|
||||
history->clearFolder();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateDeleteMessages: {
|
||||
auto &d = update.c_updateDeleteMessages();
|
||||
_session->data().processMessagesDeleted(NoChannel, d.vmessages().v);
|
||||
} break;
|
||||
|
||||
case mtpc_updateNewChannelMessage: {
|
||||
auto &d = update.c_updateNewChannelMessage();
|
||||
auto needToAdd = true;
|
||||
if (d.vmessage().type() == mtpc_message) { // index forwarded messages to links _overview
|
||||
if (_session->data().checkEntitiesAndViewsUpdate(d.vmessage().c_message())) { // already in blocks
|
||||
LOG(("Skipping message, because it is already in blocks!"));
|
||||
needToAdd = false;
|
||||
}
|
||||
}
|
||||
if (needToAdd) {
|
||||
_session->data().addNewMessage(
|
||||
d.vmessage(),
|
||||
MTPDmessage_ClientFlags(),
|
||||
NewMessageType::Unread);
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateEditChannelMessage: {
|
||||
auto &d = update.c_updateEditChannelMessage();
|
||||
_session->data().updateEditedMessage(d.vmessage());
|
||||
} break;
|
||||
|
||||
case mtpc_updateEditMessage: {
|
||||
auto &d = update.c_updateEditMessage();
|
||||
_session->data().updateEditedMessage(d.vmessage());
|
||||
} break;
|
||||
|
||||
case mtpc_updateChannelWebPage: {
|
||||
auto &d = update.c_updateChannelWebPage();
|
||||
Q_UNUSED(d); // Web page was updated anyway.
|
||||
} break;
|
||||
|
||||
case mtpc_updateDeleteChannelMessages: {
|
||||
auto &d = update.c_updateDeleteChannelMessages();
|
||||
_session->data().processMessagesDeleted(d.vchannel_id().v, d.vmessages().v);
|
||||
} break;
|
||||
|
||||
default: Unexpected("Type in applyUpdateNoPtsCheck()");
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::jumpToDate(Dialogs::Key chat, const QDate &date) {
|
||||
if (const auto peer = chat.peer()) {
|
||||
jumpToHistoryDate(peer, date);
|
||||
|
@ -4346,9 +4060,8 @@ void ApiWrap::forwardMessages(
|
|||
MTP_vector<MTPlong>(randomIds),
|
||||
peer->input,
|
||||
MTP_int(action.options.scheduled)
|
||||
)).done([=](
|
||||
const MTPUpdates &updates) {
|
||||
applyUpdates(updates);
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
if (shared && !--shared->requestsLeft) {
|
||||
shared->callback();
|
||||
}
|
||||
|
|
|
@ -66,6 +66,8 @@ inline QString ToString(uint64 value) {
|
|||
|
||||
} // namespace details
|
||||
|
||||
class Updates;
|
||||
|
||||
template <
|
||||
typename ...Types,
|
||||
typename = std::enable_if_t<(sizeof...(Types) > 0)>>
|
||||
|
@ -139,6 +141,7 @@ public:
|
|||
|
||||
[[nodiscard]] Main::Session &session() const;
|
||||
[[nodiscard]] Storage::Account &local() const;
|
||||
[[nodiscard]] Api::Updates &updates() const;
|
||||
|
||||
void applyUpdates(
|
||||
const MTPUpdates &updates,
|
||||
|
@ -154,6 +157,8 @@ public:
|
|||
MTPInputNotifyPeer peer,
|
||||
const MTPPeerNotifySettings &settings);
|
||||
|
||||
void saveCurrentDraftToCloud();
|
||||
|
||||
void savePinnedOrder(Data::Folder *folder);
|
||||
void toggleHistoryArchived(
|
||||
not_null<History*> history,
|
||||
|
@ -194,7 +199,6 @@ public:
|
|||
void requestBots(not_null<ChannelData*> channel);
|
||||
void requestAdmins(not_null<ChannelData*> channel);
|
||||
void requestParticipantsCountDelayed(not_null<ChannelData*> channel);
|
||||
void requestChannelRangeDifference(not_null<History*> history);
|
||||
|
||||
using UpdatedFileReferences = Data::UpdatedFileReferences;
|
||||
using FileReferencesHandler = FnMut<void(const UpdatedFileReferences&)>;
|
||||
|
@ -310,9 +314,6 @@ public:
|
|||
|
||||
bool isQuitPrevent();
|
||||
|
||||
void applyUpdatesNoPtsCheck(const MTPUpdates &updates);
|
||||
void applyUpdateNoPtsCheck(const MTPUpdate &update);
|
||||
|
||||
void jumpToDate(Dialogs::Key chat, const QDate &date);
|
||||
|
||||
void preloadEnoughUnreadMentions(not_null<History*> history);
|
||||
|
@ -554,15 +555,6 @@ private:
|
|||
mtpRequestId req);
|
||||
void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result);
|
||||
|
||||
void channelRangeDifferenceSend(
|
||||
not_null<ChannelData*> channel,
|
||||
MsgRange range,
|
||||
int32 pts);
|
||||
void channelRangeDifferenceDone(
|
||||
not_null<ChannelData*> channel,
|
||||
MsgRange range,
|
||||
const MTPupdates_ChannelDifference &result);
|
||||
|
||||
void stickerSetDisenabled(mtpRequestId requestId);
|
||||
void stickersSaveOrder();
|
||||
|
||||
|
@ -709,10 +701,6 @@ private:
|
|||
|
||||
base::flat_set<not_null<ChannelData*>> _selfParticipantRequests;
|
||||
|
||||
base::flat_map<
|
||||
not_null<ChannelData*>,
|
||||
mtpRequestId> _rangeDifferenceRequests;
|
||||
|
||||
QMap<WebPageData*, mtpRequestId> _webPagesPending;
|
||||
base::Timer _webPagesTimer;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/history.h"
|
||||
#include "main/main_session.h"
|
||||
#include "apiwrap.h"
|
||||
#include "api/api_updates.h"
|
||||
#include "calls/calls_instance.h"
|
||||
#include "lang/lang_file_parser.h"
|
||||
#include "lang/lang_translator.h"
|
||||
|
@ -464,13 +465,14 @@ void Application::forceLogOut(const TextWithEntities &explanation) {
|
|||
}
|
||||
|
||||
void Application::checkLocalTime() {
|
||||
if (crl::adjust_time()) {
|
||||
const auto adjusted = crl::adjust_time();
|
||||
if (adjusted) {
|
||||
base::Timer::Adjust();
|
||||
base::ConcurrentTimerEnvironment::Adjust();
|
||||
base::unixtime::http_invalidate();
|
||||
if (App::main()) App::main()->checkLastUpdate(true);
|
||||
} else {
|
||||
if (App::main()) App::main()->checkLastUpdate(false);
|
||||
}
|
||||
if (activeAccount().sessionExists()) {
|
||||
activeAccount().session().updates().checkLastUpdate(adjusted);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -697,6 +699,9 @@ bool Application::passcodeLocked() const {
|
|||
|
||||
void Application::updateNonIdle() {
|
||||
_lastNonIdleTime = crl::now();
|
||||
if (activeAccount().sessionExists()) {
|
||||
activeAccount().session().updates().checkIdleFinish();
|
||||
}
|
||||
}
|
||||
|
||||
crl::time Application::lastNonIdleTime() const {
|
||||
|
@ -794,6 +799,25 @@ rpl::producer<bool> Application::lockValue() const {
|
|||
_1 || _2);
|
||||
}
|
||||
|
||||
bool Application::hasActiveWindow(not_null<Main::Session*> session) const {
|
||||
if (App::quitting() || !_window) {
|
||||
return false;
|
||||
} else if (const auto controller = _window->sessionController()) {
|
||||
if (&controller->session() == session) {
|
||||
return _window->widget()->isActive();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Application::saveCurrentDraftsToHistories() {
|
||||
if (!_window) {
|
||||
return;
|
||||
} else if (const auto controller = _window->sessionController()) {
|
||||
controller->content()->saveFieldToHistoryLocalDraft();
|
||||
}
|
||||
}
|
||||
|
||||
Window::Controller *Application::activeWindow() const {
|
||||
return _window.get();
|
||||
}
|
||||
|
@ -897,10 +921,8 @@ void Application::QuitAttempt() {
|
|||
if (IsAppLaunched()
|
||||
&& App().activeAccount().sessionExists()
|
||||
&& !Sandbox::Instance().isSavingSession()) {
|
||||
if (const auto mainwidget = App::main()) {
|
||||
if (mainwidget->isQuitPrevent()) {
|
||||
prevents = true;
|
||||
}
|
||||
if (App().activeAccount().session().updates().isQuitPrevent()) {
|
||||
prevents = true;
|
||||
}
|
||||
if (App().activeAccount().session().api().isQuitPrevent()) {
|
||||
prevents = true;
|
||||
|
|
|
@ -37,6 +37,7 @@ void quit();
|
|||
|
||||
namespace Main {
|
||||
class Account;
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Ui {
|
||||
|
@ -96,6 +97,8 @@ public:
|
|||
}
|
||||
|
||||
// Windows interface.
|
||||
bool hasActiveWindow(not_null<Main::Session*> session) const;
|
||||
void saveCurrentDraftsToHistories();
|
||||
[[nodiscard]] Window::Controller *activeWindow() const;
|
||||
bool closeActiveWindow();
|
||||
bool minimizeActiveWindow();
|
||||
|
|
|
@ -46,7 +46,7 @@ void MegagroupInfo::setLocation(const ChannelLocation &location) {
|
|||
ChannelData::ChannelData(not_null<Data::Session*> owner, PeerId id)
|
||||
: PeerData(owner, id)
|
||||
, inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0)))
|
||||
, _ptsWaiter(&owner->session()) {
|
||||
, _ptsWaiter(&owner->session().updates()) {
|
||||
Data::PeerFlagValue(
|
||||
this,
|
||||
MTPDchannel::Flag::f_megagroup
|
||||
|
|
|
@ -7,12 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "data/data_pts_waiter.h"
|
||||
|
||||
#include "mainwidget.h"
|
||||
#include "main/main_session.h"
|
||||
#include "apiwrap.h"
|
||||
#include "app.h"
|
||||
#include "api/api_updates.h"
|
||||
|
||||
PtsWaiter::PtsWaiter(not_null<Main::Session*> session) : _session(session) {
|
||||
PtsWaiter::PtsWaiter(not_null<Api::Updates*> owner) : _owner(owner) {
|
||||
}
|
||||
|
||||
uint64 PtsWaiter::ptsKey(PtsSkippedQueue queue, int32 pts) {
|
||||
|
@ -22,11 +19,9 @@ uint64 PtsWaiter::ptsKey(PtsSkippedQueue queue, int32 pts) {
|
|||
).first->first;
|
||||
}
|
||||
|
||||
void PtsWaiter::setWaitingForSkipped(ChannelData *channel, int32 ms) {
|
||||
void PtsWaiter::setWaitingForSkipped(ChannelData *channel, crl::time ms) {
|
||||
if (ms >= 0) {
|
||||
if (App::main()) {
|
||||
App::main()->ptsWaiterStartTimerFor(channel, ms);
|
||||
}
|
||||
_owner->ptsWaiterStartTimerFor(channel, ms);
|
||||
_waitingForSkipped = true;
|
||||
} else {
|
||||
_waitingForSkipped = false;
|
||||
|
@ -34,11 +29,9 @@ void PtsWaiter::setWaitingForSkipped(ChannelData *channel, int32 ms) {
|
|||
}
|
||||
}
|
||||
|
||||
void PtsWaiter::setWaitingForShortPoll(ChannelData *channel, int32 ms) {
|
||||
void PtsWaiter::setWaitingForShortPoll(ChannelData *channel, crl::time ms) {
|
||||
if (ms >= 0) {
|
||||
if (App::main()) {
|
||||
App::main()->ptsWaiterStartTimerFor(channel, ms);
|
||||
}
|
||||
_owner->ptsWaiterStartTimerFor(channel, ms);
|
||||
_waitingForShortPoll = true;
|
||||
} else {
|
||||
_waitingForShortPoll = false;
|
||||
|
@ -47,8 +40,8 @@ void PtsWaiter::setWaitingForShortPoll(ChannelData *channel, int32 ms) {
|
|||
}
|
||||
|
||||
void PtsWaiter::checkForWaiting(ChannelData *channel) {
|
||||
if (!_waitingForSkipped && !_waitingForShortPoll && App::main()) {
|
||||
App::main()->ptsWaiterStartTimerFor(channel, -1);
|
||||
if (!_waitingForSkipped && !_waitingForShortPoll) {
|
||||
_owner->ptsWaiterStartTimerFor(channel, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,10 +60,10 @@ void PtsWaiter::applySkippedUpdates(ChannelData *channel) {
|
|||
for (auto i = _queue.cbegin(), e = _queue.cend(); i != e; ++i) {
|
||||
switch (i->second) {
|
||||
case SkippedUpdate: {
|
||||
_session->api().applyUpdateNoPtsCheck(_updateQueue[i->first]);
|
||||
_owner->applyUpdateNoPtsCheck(_updateQueue[i->first]);
|
||||
} break;
|
||||
case SkippedUpdates: {
|
||||
_session->api().applyUpdatesNoPtsCheck(_updatesQueue[i->first]);
|
||||
_owner->applyUpdatesNoPtsCheck(_updatesQueue[i->first]);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +129,7 @@ bool PtsWaiter::updateAndApply(
|
|||
}
|
||||
if (!_waitingForSkipped || _queue.empty()) {
|
||||
// Optimization - no need to put in queue and back.
|
||||
_session->api().applyUpdatesNoPtsCheck(updates);
|
||||
_owner->applyUpdatesNoPtsCheck(updates);
|
||||
} else {
|
||||
_updatesQueue.emplace(ptsKey(SkippedUpdates, pts), updates);
|
||||
applySkippedUpdates(channel);
|
||||
|
@ -154,7 +147,7 @@ bool PtsWaiter::updateAndApply(
|
|||
}
|
||||
if (!_waitingForSkipped || _queue.empty()) {
|
||||
// Optimization - no need to put in queue and back.
|
||||
_session->api().applyUpdateNoPtsCheck(update);
|
||||
_owner->applyUpdateNoPtsCheck(update);
|
||||
} else {
|
||||
_updateQueue.emplace(ptsKey(SkippedUpdate, pts), update);
|
||||
applySkippedUpdates(channel);
|
||||
|
|
|
@ -7,9 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
namespace Api {
|
||||
class Updates;
|
||||
} // namespace Api
|
||||
|
||||
enum PtsSkippedQueue {
|
||||
SkippedUpdate,
|
||||
|
@ -18,7 +18,7 @@ enum PtsSkippedQueue {
|
|||
|
||||
class PtsWaiter {
|
||||
public:
|
||||
explicit PtsWaiter(not_null<Main::Session*> session);
|
||||
explicit PtsWaiter(not_null<Api::Updates*> owner);
|
||||
|
||||
// 1s wait for skipped seq or pts in updates.
|
||||
static constexpr auto kWaitForSkippedTimeout = 1000;
|
||||
|
@ -45,8 +45,8 @@ public:
|
|||
bool waitingForShortPoll() const {
|
||||
return _waitingForShortPoll;
|
||||
}
|
||||
void setWaitingForSkipped(ChannelData *channel, int32 ms); // < 0 - not waiting
|
||||
void setWaitingForShortPoll(ChannelData *channel, int32 ms); // < 0 - not waiting
|
||||
void setWaitingForSkipped(ChannelData *channel, crl::time ms); // < 0 - not waiting
|
||||
void setWaitingForShortPoll(ChannelData *channel, crl::time ms); // < 0 - not waiting
|
||||
int32 current() const{
|
||||
return _good;
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ private:
|
|||
uint64 ptsKey(PtsSkippedQueue queue, int32 pts);
|
||||
void checkForWaiting(ChannelData *channel);
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
const not_null<Api::Updates*> _owner;
|
||||
base::flat_map<uint64, PtsSkippedQueue> _queue;
|
||||
base::flat_map<uint64, MTPUpdate> _updateQueue;
|
||||
base::flat_map<uint64, MTPUpdates> _updatesQueue;
|
||||
|
|
|
@ -3272,6 +3272,7 @@ void Session::notifyPollUpdateDelayed(not_null<PollData*> poll) {
|
|||
|
||||
void Session::sendWebPageGamePollNotifications() {
|
||||
for (const auto page : base::take(_webpagesUpdated)) {
|
||||
_webpageUpdates.fire_copy(page);
|
||||
const auto i = _webpageViews.find(page);
|
||||
if (i != _webpageViews.end()) {
|
||||
for (const auto view : i->second) {
|
||||
|
@ -3295,6 +3296,26 @@ void Session::sendWebPageGamePollNotifications() {
|
|||
}
|
||||
}
|
||||
|
||||
rpl::producer<not_null<WebPageData*>> Session::webPageUpdates() const {
|
||||
return _webpageUpdates.events();
|
||||
}
|
||||
|
||||
void Session::channelDifferenceTooLong(not_null<ChannelData*> channel) {
|
||||
_channelDifferenceTooLong.fire_copy(channel);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<ChannelData*>> Session::channelDifferenceTooLong() const {
|
||||
return _channelDifferenceTooLong.events();
|
||||
}
|
||||
|
||||
void Session::historyOutboxRead(not_null<History*> history) {
|
||||
_historyOutboxReads.fire_copy(history);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<History*>> Session::historyOutboxReads() const {
|
||||
return _historyOutboxReads.events();
|
||||
}
|
||||
|
||||
void Session::registerItemView(not_null<ViewElement*> view) {
|
||||
_views[view->data()].push_back(view);
|
||||
}
|
||||
|
|
|
@ -549,8 +549,15 @@ public:
|
|||
void notifyWebPageUpdateDelayed(not_null<WebPageData*> page);
|
||||
void notifyGameUpdateDelayed(not_null<GameData*> game);
|
||||
void notifyPollUpdateDelayed(not_null<PollData*> poll);
|
||||
bool hasPendingWebPageGamePollNotification() const;
|
||||
[[nodiscard]] bool hasPendingWebPageGamePollNotification() const;
|
||||
void sendWebPageGamePollNotifications();
|
||||
[[nodiscard]] rpl::producer<not_null<WebPageData*>> webPageUpdates() const;
|
||||
|
||||
void channelDifferenceTooLong(not_null<ChannelData*> channel);
|
||||
[[nodiscard]] rpl::producer<not_null<ChannelData*>> channelDifferenceTooLong() const;
|
||||
|
||||
void historyOutboxRead(not_null<History*> history);
|
||||
[[nodiscard]] rpl::producer<not_null<History*>> historyOutboxReads() const;
|
||||
|
||||
void registerItemView(not_null<ViewElement*> view);
|
||||
void unregisterItemView(not_null<ViewElement*> view);
|
||||
|
@ -868,6 +875,10 @@ private:
|
|||
base::flat_set<not_null<GameData*>> _gamesUpdated;
|
||||
base::flat_set<not_null<PollData*>> _pollsUpdated;
|
||||
|
||||
rpl::event_stream<not_null<WebPageData*>> _webpageUpdates;
|
||||
rpl::event_stream<not_null<ChannelData*>> _channelDifferenceTooLong;
|
||||
rpl::event_stream<not_null<History*>> _historyOutboxReads;
|
||||
|
||||
base::flat_multi_map<TimeId, not_null<PollData*>> _pollsClosings;
|
||||
base::Timer _pollsClosingTimer;
|
||||
|
||||
|
|
|
@ -320,6 +320,24 @@ Widget::Widget(
|
|||
}, lifetime());
|
||||
}
|
||||
|
||||
void Widget::setGeometryWithTopMoved(
|
||||
const QRect &newGeometry,
|
||||
int topDelta) {
|
||||
_topDelta = topDelta;
|
||||
bool willBeResized = (size() != newGeometry.size());
|
||||
if (geometry() != newGeometry) {
|
||||
auto weak = Ui::MakeWeak(this);
|
||||
setGeometry(newGeometry);
|
||||
if (!weak) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!willBeResized) {
|
||||
resizeEvent(nullptr);
|
||||
}
|
||||
_topDelta = 0;
|
||||
}
|
||||
|
||||
void Widget::setupScrollUpButton() {
|
||||
_scrollToTop->setClickedCallback([=] {
|
||||
if (_scrollToAnimation.animating()) {
|
||||
|
@ -707,8 +725,10 @@ void Widget::escape() {
|
|||
|
||||
void Widget::refreshLoadMoreButton(bool mayBlock, bool isBlocked) {
|
||||
if (!mayBlock) {
|
||||
_loadMoreChats.destroy();
|
||||
updateControlsGeometry();
|
||||
if (_loadMoreChats) {
|
||||
_loadMoreChats.destroy();
|
||||
updateControlsGeometry();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!_loadMoreChats) {
|
||||
|
@ -1560,8 +1580,7 @@ void Widget::updateControlsGeometry() {
|
|||
right -= _chooseFromUser->width(); _chooseFromUser->moveToLeft(right, _filter->y());
|
||||
|
||||
auto scrollTop = filterAreaTop + filterAreaHeight;
|
||||
auto addToScroll = controller()->content()->contentScrollAddToY();
|
||||
auto newScrollTop = _scroll->scrollTop() + addToScroll;
|
||||
auto newScrollTop = _scroll->scrollTop() + _topDelta;
|
||||
auto scrollHeight = height() - scrollTop;
|
||||
const auto putBottomButton = [&](object_ptr<BottomButton> &button) {
|
||||
if (button && !button->isHidden()) {
|
||||
|
@ -1582,7 +1601,7 @@ void Widget::updateControlsGeometry() {
|
|||
if (scrollHeight != wasScrollHeight) {
|
||||
controller()->floatPlayerAreaUpdated().notify(true);
|
||||
}
|
||||
if (addToScroll) {
|
||||
if (_topDelta) {
|
||||
_scroll->scrollToY(newScrollTop);
|
||||
} else {
|
||||
onListScroll();
|
||||
|
|
|
@ -55,6 +55,11 @@ class Widget : public Window::AbstractSectionWidget, public RPCSender {
|
|||
public:
|
||||
Widget(QWidget *parent, not_null<Window::SessionController*> controller);
|
||||
|
||||
// When resizing the widget with top edge moved up or down and we
|
||||
// want to add this top movement to the scroll position, so inner
|
||||
// content will not move.
|
||||
void setGeometryWithTopMoved(const QRect &newGeometry, int topDelta);
|
||||
|
||||
void updateDragInScroll(bool inScroll);
|
||||
|
||||
void searchInChat(Key chat);
|
||||
|
@ -233,6 +238,8 @@ private:
|
|||
object_ptr<QTimer> _draggingScrollTimer = { nullptr };
|
||||
int _draggingScrollDelta = 0;
|
||||
|
||||
int _topDelta = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Dialogs
|
||||
|
|
|
@ -37,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "storage/localstorage.h"
|
||||
#include "storage/storage_facade.h"
|
||||
#include "storage/storage_shared_media.h"
|
||||
#include "storage/storage_account.h"
|
||||
//#include "storage/storage_feed_messages.h" // #feed
|
||||
#include "support/support_helper.h"
|
||||
#include "ui/image/image.h"
|
||||
|
@ -336,7 +337,7 @@ void History::clearEditDraft() {
|
|||
|
||||
void History::draftSavedToCloud() {
|
||||
updateChatListEntry();
|
||||
if (App::main()) App::main()->writeDrafts(this);
|
||||
session().local().writeDrafts(this);
|
||||
}
|
||||
|
||||
HistoryItemsList History::validateForwardDraft() {
|
||||
|
@ -1760,6 +1761,7 @@ void History::outboxRead(MsgId upTo) {
|
|||
}
|
||||
}
|
||||
updateChatListEntry();
|
||||
session().data().historyOutboxRead(this);
|
||||
}
|
||||
|
||||
void History::outboxRead(not_null<const HistoryItem*> wasRead) {
|
||||
|
|
|
@ -198,6 +198,12 @@ HistoryInner::HistoryInner(
|
|||
}) | rpl::start_with_next([this](not_null<const Element*> view) {
|
||||
mouseActionUpdate();
|
||||
}, lifetime());
|
||||
session().data().historyOutboxReads(
|
||||
) | rpl::filter([=](not_null<History*> history) {
|
||||
return (_history == history);
|
||||
}) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
Main::Session &HistoryInner::session() const {
|
||||
|
|
|
@ -512,6 +512,21 @@ HistoryWidget::HistoryWidget(
|
|||
}
|
||||
}, lifetime());
|
||||
|
||||
session().data().webPageUpdates(
|
||||
) | rpl::filter([=](not_null<WebPageData*> page) {
|
||||
return (_previewData == page.get());
|
||||
}) | rpl::start_with_next([=] {
|
||||
updatePreview();
|
||||
}, lifetime());
|
||||
|
||||
session().data().channelDifferenceTooLong(
|
||||
) | rpl::filter([=](not_null<ChannelData*> channel) {
|
||||
return _peer == channel.get();
|
||||
}) | rpl::start_with_next([=] {
|
||||
updateHistoryDownVisibility();
|
||||
preloadHistoryIfNeeded();
|
||||
}, lifetime());
|
||||
|
||||
session().data().userIsBotChanges(
|
||||
) | rpl::filter([=](not_null<UserData*> user) {
|
||||
return (_peer == user.get());
|
||||
|
@ -681,6 +696,24 @@ HistoryWidget::HistoryWidget(
|
|||
setupShortcuts();
|
||||
}
|
||||
|
||||
void HistoryWidget::setGeometryWithTopMoved(
|
||||
const QRect &newGeometry,
|
||||
int topDelta) {
|
||||
_topDelta = topDelta;
|
||||
bool willBeResized = (size() != newGeometry.size());
|
||||
if (geometry() != newGeometry) {
|
||||
auto weak = Ui::MakeWeak(this);
|
||||
setGeometry(newGeometry);
|
||||
if (!weak) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!willBeResized) {
|
||||
resizeEvent(nullptr);
|
||||
}
|
||||
_topDelta = 0;
|
||||
}
|
||||
|
||||
void HistoryWidget::refreshTabbedPanel() {
|
||||
if (_peer && controller()->hasTabbedSelectorOwnership()) {
|
||||
createTabbedPanel();
|
||||
|
@ -1230,7 +1263,7 @@ void HistoryWidget::saveFieldToHistoryLocalDraft() {
|
|||
}
|
||||
|
||||
void HistoryWidget::onCloudDraftSave() {
|
||||
controller()->content()->saveDraftToCloud();
|
||||
controller()->session().api().saveCurrentDraftToCloud();
|
||||
}
|
||||
|
||||
void HistoryWidget::writeDrafts(Data::Draft **localDraft, Data::Draft **editDraft) {
|
||||
|
@ -1735,7 +1768,7 @@ void HistoryWidget::showHistory(
|
|||
// Removing focus from list clears selected and updates top bar.
|
||||
setFocus();
|
||||
}
|
||||
controller()->content()->saveDraftToCloud();
|
||||
controller()->session().api().saveCurrentDraftToCloud();
|
||||
if (_migrated) {
|
||||
_migrated->clearLocalDraft(); // use migrated draft only once
|
||||
_migrated->clearEditDraft();
|
||||
|
@ -2550,7 +2583,7 @@ bool HistoryWidget::doWeReadMentions() const {
|
|||
&& !_firstLoadRequest
|
||||
&& !_delayedShowAtRequest
|
||||
&& !_a_show.animating()
|
||||
&& App::wnd()->doWeMarkAsRead();
|
||||
&& controller()->widget()->doWeMarkAsRead();
|
||||
}
|
||||
|
||||
void HistoryWidget::checkHistoryActivation() {
|
||||
|
@ -3022,7 +3055,7 @@ void HistoryWidget::saveEditMsgDone(History *history, const MTPUpdates &updates,
|
|||
if (auto editDraft = history->editDraft()) {
|
||||
if (editDraft->saveRequestId == req) {
|
||||
history->clearEditDraft();
|
||||
controller()->content()->writeDrafts(history);
|
||||
session().local().writeDrafts(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5028,7 +5061,7 @@ void HistoryWidget::updateControlsGeometry() {
|
|||
}
|
||||
}
|
||||
|
||||
updateHistoryGeometry(false, false, { ScrollChangeAdd, controller()->content()->contentScrollAddToY() });
|
||||
updateHistoryGeometry(false, false, { ScrollChangeAdd, _topDelta });
|
||||
|
||||
updateFieldSize();
|
||||
|
||||
|
|
|
@ -112,6 +112,11 @@ public:
|
|||
|
||||
void historyLoaded();
|
||||
|
||||
// When resizing the widget with top edge moved up or down and we
|
||||
// want to add this top movement to the scroll position, so inner
|
||||
// content will not move.
|
||||
void setGeometryWithTopMoved(const QRect &newGeometry, int topDelta);
|
||||
|
||||
void windowShown();
|
||||
[[nodiscard]] bool doWeReadServerHistory() const;
|
||||
[[nodiscard]] bool doWeReadMentions() const;
|
||||
|
@ -820,4 +825,6 @@ private:
|
|||
object_ptr<Ui::PlainShadow> _topShadow;
|
||||
bool _inGrab = false;
|
||||
|
||||
int _topDelta = 0;
|
||||
|
||||
};
|
||||
|
|
|
@ -20,6 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/image/image.h"
|
||||
#include "mainwidget.h"
|
||||
#include "observer_peer.h"
|
||||
#include "api/api_updates.h"
|
||||
#include "apiwrap.h"
|
||||
#include "main/main_app_config.h"
|
||||
#include "main/main_session.h"
|
||||
#include "facades.h"
|
||||
|
@ -353,9 +355,11 @@ void Account::startMtp() {
|
|||
Global::RefConnectionTypeChanged().notify();
|
||||
}
|
||||
});
|
||||
_mtp->setSessionResetHandler([](MTP::ShiftedDcId shiftedDcId) {
|
||||
if (App::main() && shiftedDcId == MTP::maindc()) {
|
||||
App::main()->getDifference();
|
||||
_mtp->setSessionResetHandler([=](MTP::ShiftedDcId shiftedDcId) {
|
||||
if (sessionExists()) {
|
||||
if (shiftedDcId == session().api().instance()->mainDcId()) {
|
||||
session().updates().getDifference();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "main/main_session.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "api/api_updates.h"
|
||||
#include "core/application.h"
|
||||
#include "core/changelogs.h"
|
||||
#include "main/main_account.h"
|
||||
|
@ -22,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
//#include "platform/platform_specific.h"
|
||||
#include "calls/calls_instance.h"
|
||||
|
@ -48,6 +50,7 @@ Session::Session(
|
|||
, _settings(std::move(settings))
|
||||
, _saveSettingsTimer([=] { local().writeSettings(); })
|
||||
, _api(std::make_unique<ApiWrap>(this))
|
||||
, _updates(std::make_unique<Api::Updates>(this))
|
||||
, _calls(std::make_unique<Calls::Instance>(this))
|
||||
, _downloader(std::make_unique<Storage::DownloadManagerMtproto>(_api.get()))
|
||||
, _uploader(std::make_unique<Storage::Uploader>(_api.get()))
|
||||
|
@ -176,4 +179,20 @@ void Session::saveSettingsNowIfNeeded() {
|
|||
}
|
||||
}
|
||||
|
||||
void Session::addWindow(not_null<Window::SessionController*> controller) {
|
||||
_windows.emplace(controller);
|
||||
controller->lifetime().add([=] {
|
||||
_windows.remove(controller);
|
||||
});
|
||||
updates().addActiveChat(controller->activeChatChanges(
|
||||
) | rpl::map([=](const Dialogs::Key &chat) {
|
||||
return chat.peer();
|
||||
}) | rpl::distinct_until_changed());
|
||||
}
|
||||
|
||||
auto Session::windows() const
|
||||
-> const base::flat_set<not_null<Window::SessionController*>> & {
|
||||
return _windows;
|
||||
}
|
||||
|
||||
} // namespace Main
|
||||
|
|
|
@ -15,6 +15,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
class ApiWrap;
|
||||
|
||||
namespace Api {
|
||||
class Updates;
|
||||
} // namespace Api
|
||||
|
||||
namespace MTP {
|
||||
class Instance;
|
||||
} // namespace MTP
|
||||
|
@ -39,6 +43,7 @@ namespace Window {
|
|||
namespace Notifications {
|
||||
class System;
|
||||
} // namespace Notifications
|
||||
class SessionController;
|
||||
} // namespace Window
|
||||
|
||||
namespace Calls {
|
||||
|
@ -81,13 +86,16 @@ public:
|
|||
}
|
||||
bool validateSelf(const MTPUser &user);
|
||||
|
||||
[[nodiscard]] Storage::DownloadManagerMtproto &downloader() {
|
||||
[[nodiscard]] Api::Updates &updates() const {
|
||||
return *_updates;
|
||||
}
|
||||
[[nodiscard]] Storage::DownloadManagerMtproto &downloader() const {
|
||||
return *_downloader;
|
||||
}
|
||||
[[nodiscard]] Storage::Uploader &uploader() {
|
||||
[[nodiscard]] Storage::Uploader &uploader() const {
|
||||
return *_uploader;
|
||||
}
|
||||
[[nodiscard]] Storage::Facade &storage() {
|
||||
[[nodiscard]] Storage::Facade &storage() const {
|
||||
return *_storage;
|
||||
}
|
||||
[[nodiscard]] Stickers::EmojiPack &emojiStickersPack() const {
|
||||
|
@ -112,6 +120,10 @@ public:
|
|||
void saveSettingsDelayed(crl::time delay = kDefaultSaveDelay);
|
||||
void saveSettingsNowIfNeeded();
|
||||
|
||||
void addWindow(not_null<Window::SessionController*> controller);
|
||||
[[nodiscard]] auto windows() const
|
||||
-> const base::flat_set<not_null<Window::SessionController*>> &;
|
||||
|
||||
[[nodiscard]] not_null<MTP::Instance*> mtp();
|
||||
[[nodiscard]] ApiWrap &api() {
|
||||
return *_api;
|
||||
|
@ -143,6 +155,7 @@ private:
|
|||
base::Timer _saveSettingsTimer;
|
||||
|
||||
const std::unique_ptr<ApiWrap> _api;
|
||||
const std::unique_ptr<Api::Updates> _updates;
|
||||
const std::unique_ptr<Calls::Instance> _calls;
|
||||
const std::unique_ptr<Storage::DownloadManagerMtproto> _downloader;
|
||||
const std::unique_ptr<Storage::Uploader> _uploader;
|
||||
|
@ -162,6 +175,8 @@ private:
|
|||
|
||||
const std::unique_ptr<Support::Helper> _supportHelper;
|
||||
|
||||
base::flat_set<not_null<Window::SessionController*>> _windows;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -111,6 +111,7 @@ public:
|
|||
MainWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller);
|
||||
~MainWidget();
|
||||
|
||||
[[nodiscard]] Main::Session &session() const;
|
||||
[[nodiscard]] not_null<Window::SessionController*> controller() const;
|
||||
|
@ -118,8 +119,6 @@ public:
|
|||
[[nodiscard]] bool isMainSectionShown() const;
|
||||
[[nodiscard]] bool isThirdSectionShown() const;
|
||||
|
||||
[[nodiscard]] int contentScrollAddToY() const;
|
||||
|
||||
void returnTabbedSelector();
|
||||
|
||||
void showAnimated(const QPixmap &bgAnimCache, bool back = false);
|
||||
|
@ -146,10 +145,6 @@ public:
|
|||
|
||||
void windowShown();
|
||||
|
||||
void sentUpdatesReceived(uint64 randomId, const MTPUpdates &updates);
|
||||
void sentUpdatesReceived(const MTPUpdates &updates) {
|
||||
return sentUpdatesReceived(0, updates);
|
||||
}
|
||||
void historyToDown(History *hist);
|
||||
void dialogsToUp();
|
||||
void checkHistoryActivation();
|
||||
|
@ -174,16 +169,11 @@ public:
|
|||
const std::optional<FullMsgId> &oldId);
|
||||
bool onSendSticker(DocumentData *sticker);
|
||||
|
||||
void updateOnlineDisplayIn(int32 msecs);
|
||||
|
||||
bool isActive() const;
|
||||
[[nodiscard]] bool doWeMarkAsRead() const;
|
||||
bool lastWasOnline() const;
|
||||
crl::time lastSetOnline() const;
|
||||
|
||||
void saveDraftToCloud();
|
||||
void applyCloudDraft(History *history);
|
||||
void writeDrafts(History *history);
|
||||
void saveFieldToHistoryLocalDraft();
|
||||
|
||||
int32 dlgsWidth() const;
|
||||
|
||||
|
@ -222,10 +212,6 @@ public:
|
|||
void searchMessages(const QString &query, Dialogs::Key inChat);
|
||||
void itemEdited(not_null<HistoryItem*> item);
|
||||
|
||||
void checkLastUpdate(bool afterSleep);
|
||||
|
||||
bool isIdle() const;
|
||||
|
||||
QPixmap cachedBackground(const QRect &forRect, int &x, int &y);
|
||||
void updateScrollColors();
|
||||
|
||||
|
@ -248,31 +234,13 @@ public:
|
|||
void choosePeer(PeerId peerId, MsgId showAtMsgId);
|
||||
void clearBotStartToken(PeerData *peer);
|
||||
|
||||
void ptsWaiterStartTimerFor(ChannelData *channel, int32 ms); // ms <= 0 - stop timer
|
||||
void feedUpdates(const MTPUpdates &updates, uint64 randomId = 0);
|
||||
|
||||
void ctrlEnterSubmitUpdated();
|
||||
void setInnerFocus();
|
||||
|
||||
void scheduleViewIncrement(HistoryItem *item);
|
||||
|
||||
void feedChannelDifference(const MTPDupdates_channelDifference &data);
|
||||
|
||||
// Made public for ApiWrap, while it is still here.
|
||||
// Better would be for this to be moved to ApiWrap.
|
||||
bool requestingDifference() const {
|
||||
return _ptsWaiter.requesting();
|
||||
}
|
||||
void getDifference();
|
||||
void updateOnline(bool gotOtherOffline = false);
|
||||
void checkIdleFinish();
|
||||
|
||||
bool contentOverlapped(const QRect &globalRect);
|
||||
|
||||
bool ptsUpdateAndApply(int32 pts, int32 ptsCount, const MTPUpdates &updates);
|
||||
bool ptsUpdateAndApply(int32 pts, int32 ptsCount, const MTPUpdate &update);
|
||||
bool ptsUpdateAndApply(int32 pts, int32 ptsCount);
|
||||
|
||||
void searchInChat(Dialogs::Key chat);
|
||||
|
||||
void app_sendBotCallback(
|
||||
|
@ -293,10 +261,6 @@ public:
|
|||
|
||||
void closeBothPlayers();
|
||||
|
||||
bool isQuitPrevent();
|
||||
|
||||
~MainWidget();
|
||||
|
||||
signals:
|
||||
void dialogsUpdated();
|
||||
|
||||
|
@ -313,27 +277,7 @@ protected:
|
|||
bool eventFilter(QObject *o, QEvent *e) override;
|
||||
|
||||
private:
|
||||
using ChannelGetDifferenceTime = QMap<ChannelData*, crl::time>;
|
||||
enum class ChannelDifferenceRequest {
|
||||
Unknown,
|
||||
PtsGapOrShortPoll,
|
||||
AfterFail,
|
||||
};
|
||||
|
||||
struct DeleteHistoryRequest {
|
||||
PeerData *peer;
|
||||
bool justClearHistory;
|
||||
};
|
||||
|
||||
struct DeleteAllFromUserParams {
|
||||
ChannelData *channel;
|
||||
UserData *from;
|
||||
};
|
||||
|
||||
void viewsIncrement();
|
||||
void sendPing();
|
||||
void getDifferenceByPts();
|
||||
void getDifferenceAfterFail();
|
||||
|
||||
void animationCallback();
|
||||
void handleAdaptiveLayoutUpdate();
|
||||
|
@ -349,7 +293,6 @@ private:
|
|||
[[nodiscard]] bool saveThirdSectionToStackBack() const;
|
||||
[[nodiscard]] auto thirdSectionForCurrentMainSection(Dialogs::Key key)
|
||||
-> std::unique_ptr<Window::SectionMemento>;
|
||||
void userIsContactUpdated(not_null<UserData*> user);
|
||||
|
||||
void setupConnectingWidget();
|
||||
void createPlayer();
|
||||
|
@ -381,28 +324,6 @@ private:
|
|||
|
||||
void saveSectionInStack();
|
||||
|
||||
void getChannelDifference(
|
||||
not_null<ChannelData*> channel,
|
||||
ChannelDifferenceRequest from = ChannelDifferenceRequest::Unknown);
|
||||
void gotDifference(const MTPupdates_Difference &diff);
|
||||
bool failDifference(const RPCError &e);
|
||||
void feedDifference(const MTPVector<MTPUser> &users, const MTPVector<MTPChat> &chats, const MTPVector<MTPMessage> &msgs, const MTPVector<MTPUpdate> &other);
|
||||
void gotState(const MTPupdates_State &state);
|
||||
void updSetState(int32 pts, int32 date, int32 qts, int32 seq);
|
||||
void gotChannelDifference(ChannelData *channel, const MTPupdates_ChannelDifference &diff);
|
||||
bool failChannelDifference(ChannelData *channel, const RPCError &err);
|
||||
void failDifferenceStartTimerFor(ChannelData *channel);
|
||||
|
||||
void mtpUpdateReceived(const MTPUpdates &updates);
|
||||
void mtpNewSessionCreated();
|
||||
void feedUpdateVector(
|
||||
const MTPVector<MTPUpdate> &updates,
|
||||
bool skipMessageIds = false);
|
||||
// Doesn't call sendHistoryChangeNotifications itself.
|
||||
void feedMessageIds(const MTPVector<MTPUpdate> &updates);
|
||||
// Doesn't call sendHistoryChangeNotifications itself.
|
||||
void feedUpdate(const MTPUpdate &update);
|
||||
|
||||
void usernameResolveDone(QPair<MsgId, QString> msgIdAndStartToken, const MTPcontacts_ResolvedPeer &result);
|
||||
bool usernameResolveFail(QString name, const RPCError &error);
|
||||
|
||||
|
@ -427,14 +348,9 @@ private:
|
|||
bool floatPlayerIsVisible(not_null<HistoryItem*> item) override;
|
||||
void floatPlayerClosed(FullMsgId itemId);
|
||||
|
||||
bool getDifferenceTimeChanged(ChannelData *channel, int32 ms, ChannelGetDifferenceTime &channelCurTime, crl::time &curTime);
|
||||
|
||||
void viewsIncrementDone(QVector<MTPint> ids, const MTPVector<MTPint> &result, mtpRequestId req);
|
||||
bool viewsIncrementFail(const RPCError &error, mtpRequestId req);
|
||||
|
||||
void updateStatusDone(const MTPBool &result);
|
||||
bool updateStatusFail(const RPCError &error);
|
||||
|
||||
void refreshResizeAreas();
|
||||
template <typename MoveCallback, typename FinishCallback>
|
||||
void createResizeArea(
|
||||
|
@ -498,38 +414,6 @@ private:
|
|||
int _exportTopBarHeight = 0;
|
||||
int _contentScrollAddToY = 0;
|
||||
|
||||
int32 updDate = 0;
|
||||
int32 updQts = -1;
|
||||
int32 updSeq = 0;
|
||||
base::Timer _noUpdatesTimer;
|
||||
|
||||
PtsWaiter _ptsWaiter;
|
||||
|
||||
ChannelGetDifferenceTime _channelGetDifferenceTimeByPts, _channelGetDifferenceTimeAfterFail;
|
||||
crl::time _getDifferenceTimeByPts = 0;
|
||||
crl::time _getDifferenceTimeAfterFail = 0;
|
||||
|
||||
base::Timer _byPtsTimer;
|
||||
|
||||
QMap<int32, MTPUpdates> _bySeqUpdates;
|
||||
base::Timer _bySeqTimer;
|
||||
|
||||
base::Timer _byMinChannelTimer;
|
||||
|
||||
mtpRequestId _onlineRequest = 0;
|
||||
base::Timer _onlineTimer;
|
||||
base::Timer _idleFinishTimer;
|
||||
bool _lastWasOnline = false;
|
||||
crl::time _lastSetOnline = 0;
|
||||
bool _isIdle = false;
|
||||
|
||||
int32 _failDifferenceTimeout = 1; // growing timeout for getDifference calls, if it fails
|
||||
QMap<ChannelData*, int32> _channelFailDifferenceTimeout; // growing timeout for getChannelDifference calls, if it fails
|
||||
base::Timer _failDifferenceTimer;
|
||||
|
||||
crl::time _lastUpdateTime = 0;
|
||||
bool _handlingChannelDifference = false;
|
||||
|
||||
QPixmap _cachedBackground;
|
||||
QRect _cachedFor, _willCacheFor;
|
||||
int _cachedX = 0;
|
||||
|
|
|
@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "storage/storage_account.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "apiwrap.h"
|
||||
#include "api/api_updates.h"
|
||||
#include "settings/settings_intro.h"
|
||||
#include "platform/platform_notifications_manager.h"
|
||||
#include "base/platform/base_platform_info.h"
|
||||
|
@ -556,9 +557,12 @@ bool MainWindow::eventFilter(QObject *object, QEvent *e) {
|
|||
|
||||
case QEvent::MouseMove: {
|
||||
const auto position = static_cast<QMouseEvent*>(e)->globalPos();
|
||||
if (_main && _main->isIdle() && _lastMousePosition != position) {
|
||||
Core::App().updateNonIdle();
|
||||
_main->checkIdleFinish();
|
||||
if (_lastMousePosition != position) {
|
||||
if (const auto controller = sessionController()) {
|
||||
if (controller->session().updates().isIdle()) {
|
||||
Core::App().updateNonIdle();
|
||||
}
|
||||
}
|
||||
}
|
||||
_lastMousePosition = position;
|
||||
} break;
|
||||
|
@ -1007,7 +1011,9 @@ void MainWindow::sendPaths() {
|
|||
}
|
||||
|
||||
void MainWindow::updateIsActiveHook() {
|
||||
if (_main) _main->updateOnline();
|
||||
if (const auto controller = sessionController()) {
|
||||
controller->session().updates().updateOnline();
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
|
|
|
@ -271,7 +271,9 @@ public:
|
|||
|
||||
public:
|
||||
void cancel() {
|
||||
_sender->senderRequestCancel(_requestId);
|
||||
if (_requestId) {
|
||||
_sender->senderRequestCancel(_requestId);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_session_controller.h"
|
||||
#include "media/audio/media_audio_track.h"
|
||||
#include "settings/settings_common.h"
|
||||
#include "api/api_updates.h"
|
||||
#include "facades.h"
|
||||
|
||||
namespace Settings {
|
||||
|
@ -87,8 +88,8 @@ auto GenerateCodes() {
|
|||
}));
|
||||
});
|
||||
codes.emplace(qsl("getdifference"), [](SessionController *window) {
|
||||
if (auto main = App::main()) {
|
||||
main->getDifference();
|
||||
if (window) {
|
||||
window->session().updates().getDifference();
|
||||
}
|
||||
});
|
||||
codes.emplace(qsl("loadcolors"), [](SessionController *window) {
|
||||
|
|
|
@ -968,6 +968,35 @@ void Account::readMtpData() {
|
|||
applyReadContext(std::move(context));
|
||||
}
|
||||
|
||||
void Account::writeDrafts(not_null<History*> history) {
|
||||
Storage::MessageDraft storedLocalDraft, storedEditDraft;
|
||||
MessageCursor localCursor, editCursor;
|
||||
if (const auto localDraft = history->localDraft()) {
|
||||
if (_owner->session().supportMode()
|
||||
|| !Data::draftsAreEqual(localDraft, history->cloudDraft())) {
|
||||
storedLocalDraft = Storage::MessageDraft{
|
||||
localDraft->msgId,
|
||||
localDraft->textWithTags,
|
||||
localDraft->previewCancelled
|
||||
};
|
||||
localCursor = localDraft->cursor;
|
||||
}
|
||||
}
|
||||
if (const auto editDraft = history->editDraft()) {
|
||||
storedEditDraft = Storage::MessageDraft{
|
||||
editDraft->msgId,
|
||||
editDraft->textWithTags,
|
||||
editDraft->previewCancelled
|
||||
};
|
||||
editCursor = editDraft->cursor;
|
||||
}
|
||||
writeDrafts(
|
||||
history->peer->id,
|
||||
storedLocalDraft,
|
||||
storedEditDraft);
|
||||
writeDraftCursors(history->peer->id, localCursor, editCursor);
|
||||
}
|
||||
|
||||
void Account::writeDrafts(
|
||||
const PeerId &peer,
|
||||
const MessageDraft &localDraft,
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
void writeBackground(const Data::WallPaper &paper, const QImage &image);
|
||||
bool readBackground();
|
||||
|
||||
void writeDrafts(not_null<History*> history);
|
||||
void writeDrafts(
|
||||
const PeerId &peer,
|
||||
const MessageDraft &localDraft,
|
||||
|
|
|
@ -21,7 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_session_controller.h"
|
||||
#include "core/application.h"
|
||||
#include "mainwindow.h"
|
||||
#include "mainwidget.h"
|
||||
#include "api/api_updates.h"
|
||||
#include "apiwrap.h"
|
||||
#include "main/main_session.h"
|
||||
#include "facades.h"
|
||||
|
@ -120,9 +120,10 @@ void System::schedule(not_null<HistoryItem*> item) {
|
|||
auto delay = item->Has<HistoryMessageForwarded>() ? 500 : 100;
|
||||
const auto t = base::unixtime::now();
|
||||
const auto ms = crl::now();
|
||||
const bool isOnline = App::main()->lastWasOnline();
|
||||
const auto &updates = history->session().updates();
|
||||
const bool isOnline = updates.lastWasOnline();
|
||||
const auto otherNotOld = ((cOtherOnline() * 1000LL) + Global::OnlineCloudTimeout() > t * 1000LL);
|
||||
const bool otherLaterThanMe = (cOtherOnline() * 1000LL + (ms - App::main()->lastSetOnline()) > t * 1000LL);
|
||||
const bool otherLaterThanMe = (cOtherOnline() * 1000LL + (ms - updates.lastSetOnline()) > t * 1000LL);
|
||||
if (!isOnline && otherNotOld && otherLaterThanMe) {
|
||||
delay = Global::NotifyCloudDelay();
|
||||
} else if (cOtherOnline() >= t) {
|
||||
|
|
|
@ -144,6 +144,8 @@ SessionController::SessionController(
|
|||
refreshFiltersMenu();
|
||||
});
|
||||
}, session->lifetime());
|
||||
|
||||
session->addWindow(this);
|
||||
}
|
||||
|
||||
not_null<::MainWindow*> SessionController::widget() const {
|
||||
|
|
Loading…
Add table
Reference in a new issue