diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index d071feae1..cd5431495 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -357,6 +357,8 @@ PRIVATE data/data_chat.h data/data_chat_filters.cpp data/data_chat_filters.h + data/data_changes.cpp + data/data_changes.h data/data_channel.cpp data/data_channel.h data/data_channel_admins.cpp @@ -1046,8 +1048,6 @@ PRIVATE mainwidget.h mainwindow.cpp mainwindow.h - observer_peer.cpp - observer_peer.h qt_static_plugins.cpp settings.cpp settings.h diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index c50fa875e..6f971c43d 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -168,9 +168,7 @@ void SendExistingMedia( }; performRequest(); - if (const auto main = App::main()) { - main->finishForwarding(message.action); - } + api->finishForwarding(message.action); } } // namespace @@ -191,10 +189,7 @@ void SendExistingDocument( document->stickerOrGifOrigin()); if (document->sticker()) { - if (const auto main = App::main()) { - main->incrementSticker(document); - } - document->owner().stickers().notifyRecentUpdated(); + document->owner().stickers().incrementSticker(document); } } @@ -323,6 +318,7 @@ bool SendDice(Api::MessageToSend &message) { ).send(); return history->sendRequestId; }); + api->finishForwarding(message.action); return true; } diff --git a/Telegram/SourceFiles/api/api_updates.cpp b/Telegram/SourceFiles/api/api_updates.cpp index 82a835de7..70a2a370c 100644 --- a/Telegram/SourceFiles/api/api_updates.cpp +++ b/Telegram/SourceFiles/api/api_updates.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "data/data_user.h" #include "data/data_chat.h" +#include "data/data_changes.h" #include "data/data_channel.h" #include "data/data_chat_filters.h" #include "data/data_cloud_themes.h" @@ -37,7 +38,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_controller.h" #include "boxes/confirm_box.h" #include "apiwrap.h" -#include "observer_peer.h" #include "app.h" // App::formatPhone #include "facades.h" @@ -828,9 +828,9 @@ void Updates::updateOnline(bool gotOtherOffline) { const auto self = session().user(); self->onlineTill = base::unixtime::now() + (isOnline ? (Global::OnlineUpdatePeriod() / 1000) : -1); - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( self, - Notify::PeerUpdate::Flag::UserOnlineChanged); + Data::PeerUpdate::Flag::OnlineStatus); if (!isOnline) { // Went offline, so we need to save message draft to the cloud. api().saveCurrentDraftToCloud(); } @@ -1582,9 +1582,9 @@ void Updates::feedUpdate(const MTPUpdate &update) { case mtpc_userStatusOffline: user->onlineTill = d.vstatus().c_userStatusOffline().vwas_online().v; break; case mtpc_userStatusOnline: user->onlineTill = d.vstatus().c_userStatusOnline().vexpires().v; break; } - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( user, - Notify::PeerUpdate::Flag::UserOnlineChanged); + Data::PeerUpdate::Flag::OnlineStatus); } if (d.vuser_id().v == session().userId()) { if (d.vstatus().type() == mtpc_userStatusOffline @@ -1680,9 +1680,9 @@ void Updates::feedUpdate(const MTPUpdate &update) { : App::formatPhone(user->phone())), user->username); - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( user, - Notify::PeerUpdate::Flag::UserPhoneChanged); + Data::PeerUpdate::Flag::PhoneNumber); } } } break; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 3c7eb19f7..84ba30584 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_updates.h" #include "data/stickers/data_stickers.h" #include "data/data_drafts.h" +#include "data/data_changes.h" #include "data/data_photo.h" #include "data/data_web_page.h" #include "data/data_poll.h" @@ -38,7 +39,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/openssl_help.h" #include "base/unixtime.h" #include "base/call_delayed.h" -#include "observer_peer.h" #include "lang/lang_keys.h" #include "mainwindow.h" #include "mainwidget.h" @@ -358,14 +358,11 @@ void ApiWrap::topPromotionDone(const MTPhelp_PromoData &proxy) { _session->data().processChats(data.vchats()); _session->data().processUsers(data.vusers()); const auto peerId = peerFromMTP(data.vpeer()); - const auto peer = _session->data().peer(peerId); + const auto history = _session->data().history(peerId); _session->data().setTopPromoted( - peer, + history, data.vpsa_type().value_or_empty(), data.vpsa_message().value_or_empty()); - if (const auto history = _session->data().historyLoaded(peer)) { - history->owner().histories().requestDialogEntry(history); - } }); } @@ -422,7 +419,7 @@ void ApiWrap::requestTermsUpdate() { const auto &terms = data.vterms_of_service(); const auto &fields = terms.c_help_termsOfService(); Core::App().lockByTerms( - Window::TermsLock::FromMTP(&session(), fields)); + Window::TermsLock::FromMTP(_session, fields)); requestNext(data); } break; default: Unexpected("Type in requestTermsUpdate()."); @@ -606,7 +603,7 @@ void ApiWrap::sendMessageFail( } if (const auto item = _session->data().message(itemId)) { Assert(randomId != 0); - session().data().unregisterMessageRandomId(randomId); + _session->data().unregisterMessageRandomId(randomId); item->sendFailed(); } } @@ -1065,7 +1062,7 @@ void ApiWrap::requestWallPaper( )).done([=](const MTPWallPaper &result) { _wallPaperRequestId = 0; _wallPaperSlug = QString(); - if (const auto paper = Data::WallPaper::Create(&session(), result)) { + if (const auto paper = Data::WallPaper::Create(_session, result)) { if (const auto done = base::take(_wallPaperDone)) { done(*paper); } @@ -1261,9 +1258,9 @@ void ApiWrap::migrateChat( } _migrateCallbacks.emplace(chat).first->second.push_back(callback()); if (const auto channel = chat->migrateTo()) { - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( chat, - Notify::PeerUpdate::Flag::MigrationChanged); + Data::PeerUpdate::Flag::Migration); crl::on_main([=] { migrateDone(chat, channel); }); @@ -1291,7 +1288,7 @@ void ApiWrap::migrateChat( chat->inputChat )).done([=](const MTPUpdates &result) { applyUpdates(result); - Notify::peerUpdatedSendDelayed(); + session().changes().sendNotifications(); if (const auto channel = chat->migrateTo()) { if (auto handlers = _migrateCallbacks.take(chat)) { @@ -1311,7 +1308,7 @@ void ApiWrap::migrateChat( void ApiWrap::migrateDone( not_null peer, not_null channel) { - Notify::peerUpdatedSendDelayed(); + session().changes().sendNotifications(); if (auto handlers = _migrateCallbacks.take(peer)) { for (auto &handler : *handlers) { if (handler.done) { @@ -1602,9 +1599,9 @@ void ApiWrap::applyLastParticipantsList( //} else { // channel->setMembersCount(availableCount); //} - Notify::PeerUpdate update(channel); - update.flags |= Notify::PeerUpdate::Flag::MembersChanged | Notify::PeerUpdate::Flag::AdminsChanged; - Notify::peerUpdatedDelayed(update); + session().changes().peerUpdated( + channel, + (Data::PeerUpdate::Flag::Members | Data::PeerUpdate::Flag::Admins)); channel->mgInfo->botStatus = botStatus; fullPeerUpdated().notify(channel); @@ -2008,9 +2005,9 @@ void ApiWrap::stickerSetDisenabled(mtpRequestId requestId) { void ApiWrap::joinChannel(not_null channel) { if (channel->amIn()) { - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( channel, - Notify::PeerUpdate::Flag::ChannelAmIn); + Data::PeerUpdate::Flag::ChannelAmIn); } else if (!_channelAmInRequests.contains(channel)) { auto requestId = request(MTPchannels_JoinChannel( channel->inputChannel @@ -2038,9 +2035,9 @@ void ApiWrap::joinChannel(not_null channel) { void ApiWrap::leaveChannel(not_null channel) { if (!channel->amIn()) { - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( channel, - Notify::PeerUpdate::Flag::ChannelAmIn); + Data::PeerUpdate::Flag::ChannelAmIn); } else if (!_channelAmInRequests.contains(channel)) { auto requestId = request(MTPchannels_LeaveChannel( channel->inputChannel @@ -2057,7 +2054,9 @@ void ApiWrap::leaveChannel(not_null channel) { void ApiWrap::blockUser(not_null user) { if (user->isBlocked()) { - Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserIsBlocked); + session().changes().peerUpdated( + user, + Data::PeerUpdate::Flag::IsBlocked); } else if (_blockRequests.find(user) == end(_blockRequests)) { const auto requestId = request(MTPcontacts_Block(user->inputUser)).done([this, user](const MTPBool &result) { _blockRequests.erase(user); @@ -2079,9 +2078,9 @@ void ApiWrap::blockUser(not_null user) { void ApiWrap::unblockUser(not_null user, Fn onDone) { if (!user->isBlocked()) { - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( user, - Notify::PeerUpdate::Flag::UserIsBlocked); + Data::PeerUpdate::Flag::IsBlocked); return; } else if (_blockRequests.find(user) != end(_blockRequests)) { return; @@ -2269,7 +2268,9 @@ void ApiWrap::updatePrivacyLastSeens(const QVector &rules) { } else { user->onlineTill = 0; } - Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserOnlineChanged); + session().changes().peerUpdated( + user, + Data::PeerUpdate::Flag::OnlineStatus); }); if (_contactsStatusesRequestId) { @@ -2278,7 +2279,7 @@ void ApiWrap::updatePrivacyLastSeens(const QVector &rules) { _contactsStatusesRequestId = request(MTPcontacts_GetStatuses( )).done([=](const MTPVector &result) { _contactsStatusesRequestId = 0; - for_const (auto &item, result.v) { + for (const auto &item : result.v) { Assert(item.type() == mtpc_contactStatus); auto &data = item.c_contactStatus(); if (auto user = _session->data().userLoaded(data.vuser_id().v)) { @@ -2286,7 +2287,9 @@ void ApiWrap::updatePrivacyLastSeens(const QVector &rules) { auto newOnlineTill = OnlineTillFromStatus(data.vstatus(), oldOnlineTill); if (oldOnlineTill != newOnlineTill) { user->onlineTill = newOnlineTill; - Notify::peerUpdatedDelayed(user, Notify::PeerUpdate::Flag::UserOnlineChanged); + session().changes().peerUpdated( + user, + Data::PeerUpdate::Flag::OnlineStatus); } } } @@ -2429,15 +2432,15 @@ void ApiWrap::applyAffectedMessages( void ApiWrap::saveCurrentDraftToCloud() { Core::App().saveCurrentDraftsToHistories(); - for (const auto controller : session().windows()) { + 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); + 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()) { + && !_session->supportMode()) { saveDraftToCloudDelayed(history); } } @@ -2473,7 +2476,7 @@ void ApiWrap::saveDraftsToCloud() { flags |= MTPmessages_SaveDraft::Flag::f_entities; } auto entities = Api::EntitiesToMTP( - &session(), + _session, TextUtilities::ConvertTextTagsToEntities(textWithTags.tags), Api::ConvertOption::SkipLocal); @@ -2709,7 +2712,7 @@ void ApiWrap::requestAttachedStickerSets(not_null photo) { Ui::show(Box(tr::lng_stickers_not_found(tr::now))); return; } else if (result.v.size() > 1) { - Ui::show(Box(&session(), result)); + Ui::show(Box(_session, result)); return; } // Single attached sticker pack. @@ -2827,7 +2830,7 @@ void ApiWrap::refreshFileReference( origin.data.match([&](Data::FileOriginMessage data) { if (const auto item = _session->data().message(data)) { if (item->isScheduled()) { - const auto &scheduled = session().data().scheduledMessages(); + const auto &scheduled = _session->data().scheduledMessages(); const auto realId = scheduled.lookupId(item); request(MTPmessages_GetScheduledMessages( item->history()->peer->input, @@ -2865,16 +2868,16 @@ void ApiWrap::refreshFileReference( request(MTPmessages_GetRecentStickers( MTP_flags(0), MTP_int(0)), - [=] { crl::on_main(&session(), [=] { local().writeRecentStickers(); }); }); + [=] { crl::on_main(_session, [=] { local().writeRecentStickers(); }); }); } else if (data.setId == Data::Stickers::FavedSetId) { request(MTPmessages_GetFavedStickers(MTP_int(0)), - [=] { crl::on_main(&session(), [=] { local().writeFavedStickers(); }); }); + [=] { crl::on_main(_session, [=] { local().writeFavedStickers(); }); }); } else { request(MTPmessages_GetStickerSet( MTP_inputStickerSetID( MTP_long(data.setId), MTP_long(data.accessHash))), - [=] { crl::on_main(&session(), [=] { + [=] { crl::on_main(_session, [=] { local().writeInstalledStickers(); local().writeRecentStickers(); local().writeFavedStickers(); @@ -2883,7 +2886,7 @@ void ApiWrap::refreshFileReference( }, [&](Data::FileOriginSavedGifs data) { request( MTPmessages_GetSavedGifs(MTP_int(0)), - [=] { crl::on_main(&session(), [=] { local().writeSavedGifs(); }); }); + [=] { crl::on_main(_session, [=] { local().writeSavedGifs(); }); }); }, [&](Data::FileOriginWallpaper data) { request(MTPaccount_GetWallPaper( MTP_inputWallPaper( @@ -2902,7 +2905,7 @@ void ApiWrap::refreshFileReference( } void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req) { - WebPageData::ApplyChanges(&session(), channel, result); + WebPageData::ApplyChanges(_session, channel, result); for (auto i = _webPagesPending.begin(); i != _webPagesPending.cend();) { if (i.value() == req) { if (i.key()->pendingTill > 0) { @@ -3103,7 +3106,7 @@ void ApiWrap::requestStickers(TimeId now) { } }; _stickersUpdateRequest = request(MTPmessages_GetAllStickers( - MTP_int(Api::CountStickersHash(&session(), true)) + MTP_int(Api::CountStickersHash(_session, true)) )).done(onDone).fail([=](const RPCError &error) { LOG(("App Fail: Failed to get stickers!")); onDone(MTP_messages_allStickersNotModified()); @@ -3115,7 +3118,7 @@ void ApiWrap::requestRecentStickers(TimeId now) { return; } requestRecentStickersWithHash( - Api::CountRecentStickersHash(&session())); + Api::CountRecentStickersHash(_session)); } void ApiWrap::requestRecentStickersWithHash(int32 hash) { @@ -3157,7 +3160,7 @@ void ApiWrap::requestFavedStickers(TimeId now) { return; } _favedStickersUpdateRequest = request(MTPmessages_GetFavedStickers( - MTP_int(Api::CountFavedStickersHash(&session())) + MTP_int(Api::CountFavedStickersHash(_session)) )).done([=](const MTPmessages_FavedStickers &result) { _session->data().stickers().setLastFavedUpdate(crl::now()); _favedStickersUpdateRequest = 0; @@ -3189,7 +3192,7 @@ void ApiWrap::requestFeaturedStickers(TimeId now) { return; } _featuredStickersUpdateRequest = request(MTPmessages_GetFeaturedStickers( - MTP_int(Api::CountFeaturedStickersHash(&session())) + MTP_int(Api::CountFeaturedStickersHash(_session)) )).done([=](const MTPmessages_FeaturedStickers &result) { _session->data().stickers().setLastFeaturedUpdate(crl::now()); _featuredStickersUpdateRequest = 0; @@ -3219,7 +3222,7 @@ void ApiWrap::requestSavedGifs(TimeId now) { return; } _savedGifsUpdateRequest = request(MTPmessages_GetSavedGifs( - MTP_int(Api::CountSavedGifsHash(&session())) + MTP_int(Api::CountSavedGifsHash(_session)) )).done([=](const MTPmessages_SavedGifs &result) { _session->data().stickers().setLastSavedGifsUpdate(crl::now()); _savedGifsUpdateRequest = 0; @@ -3622,7 +3625,7 @@ void ApiWrap::requestSharedMedia( return; } - const auto history = session().data().history(peer); + const auto history = _session->data().history(peer); auto &histories = history->owner().histories(); const auto requestType = Data::Histories::RequestType::History; histories.sendRequest(history, requestType, [=](Fn finish) { @@ -3988,18 +3991,35 @@ void ApiWrap::userPhotosDone( //} void ApiWrap::sendAction(const SendAction &action) { - session().data().histories().readInbox(action.history); + _session->data().histories().readInbox(action.history); action.history->getReadyFor(ShowAtTheEndMsgId); _sendActions.fire_copy(action); } +void ApiWrap::finishForwarding(const SendAction &action) { + const auto history = action.history; + auto toForward = history->validateForwardDraft(); + if (!toForward.empty()) { + const auto error = GetErrorTextForSending(history->peer, toForward); + if (!error.isEmpty()) { + return; + } + + forwardMessages(std::move(toForward), action); + _session->data().cancelForwarding(history); + } + + _session->data().sendHistoryChangeNotifications(); + _session->data().newMessageSent(history); +} + void ApiWrap::forwardMessages( HistoryItemsList &&items, const SendAction &action, FnMut &&successCallback) { Expects(!items.empty()); - auto &histories = session().data().histories(); + auto &histories = _session->data().histories(); struct SharedCallback { int requestsLeft = 0; @@ -4094,7 +4114,7 @@ void ApiWrap::forwardMessages( if (const auto message = item->toHistoryMessage()) { const auto newId = FullMsgId( peerToChannel(peer->id), - session().data().nextLocalMessageId()); + _session->data().nextLocalMessageId()); const auto self = _session->user(); const auto messageFromId = channelPost ? UserId(0) @@ -4170,7 +4190,7 @@ void ApiWrap::sendSharedContact( const auto newId = FullMsgId( history->channelId(), - session().data().nextLocalMessageId()); + _session->data().nextLocalMessageId()); const auto channelPost = peer->isChannel() && !peer->isMegagroup(); auto flags = NewMessageFlags(peer) | MTPDmessage::Flag::f_media; @@ -4227,11 +4247,8 @@ void ApiWrap::sendSharedContact( options.silent = _session->data().notifySilentPosts(peer); sendMedia(item, media, options); - if (const auto main = App::main()) { - _session->data().sendHistoryChangeNotifications(); - main->historyToDown(history); - main->dialogsToUp(); - } + _session->data().sendHistoryChangeNotifications(); + _session->data().newMessageSent(history); } void ApiWrap::sendVoiceMessage( @@ -4411,7 +4428,7 @@ void ApiWrap::editUploadedFile( } auto sentEntities = Api::EntitiesToMTP( - &session(), + _session, item->originalText().entities, Api::ConvertOption::SkipLocal); @@ -4530,7 +4547,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) { while (TextUtilities::CutPart(sending, left, MaxMessageSize)) { auto newId = FullMsgId( peerToChannel(peer->id), - session().data().nextLocalMessageId()); + _session->data().nextLocalMessageId()); auto randomId = rand_value(); TextUtilities::Trim(sending); @@ -4565,10 +4582,10 @@ void ApiWrap::sendMessage(MessageToSend &&message) { sendFlags |= MTPmessages_SendMessage::Flag::f_silent; } auto localEntities = Api::EntitiesToMTP( - &session(), + _session, sending.entities); auto sentEntities = Api::EntitiesToMTP( - &session(), + _session, sending.entities, Api::ConvertOption::SkipLocal); if (!sentEntities.v.isEmpty()) { @@ -4640,9 +4657,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) { }); } - if (const auto main = App::main()) { - main->finishForwarding(action); - } + finishForwarding(action); } void ApiWrap::sendBotStart(not_null bot, PeerData *chat) { @@ -4687,7 +4702,7 @@ void ApiWrap::sendInlineResult( const auto peer = history->peer; const auto newId = FullMsgId( peerToChannel(peer->id), - session().data().nextLocalMessageId()); + _session->data().nextLocalMessageId()); const auto randomId = rand_value(); auto flags = NewMessageFlags(peer) | MTPDmessage::Flag::f_media; @@ -4758,9 +4773,7 @@ void ApiWrap::sendInlineResult( ).send(); return history->sendRequestId; }); - if (const auto main = App::main()) { - main->finishForwarding(action); - } + finishForwarding(action); } void ApiWrap::uploadAlbumMedia( @@ -4859,7 +4872,7 @@ void ApiWrap::sendMediaWithRandomId( auto caption = item->originalText(); TextUtilities::Trim(caption); auto sentEntities = Api::EntitiesToMTP( - &session(), + _session, caption.entities, Api::ConvertOption::SkipLocal); @@ -5025,7 +5038,7 @@ void ApiWrap::uploadPeerPhoto(not_null peer, QImage &&image) { const auto fakeId = FullMsgId( peerToChannel(peer->id), - session().data().nextLocalMessageId()); + _session->data().nextLocalMessageId()); const auto already = ranges::find( _peerPhotoUploads, peer, @@ -5536,7 +5549,7 @@ void ApiWrap::rescheduleMessage( Api::SendOptions options) { const auto text = item->originalText().text; const auto sentEntities = Api::EntitiesToMTP( - &session(), + _session, item->originalText().entities, Api::ConvertOption::SkipLocal); const auto media = item->media(); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 1169fc198..f502f7f8d 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -374,6 +374,7 @@ public: return _sendActions.events(); } void sendAction(const SendAction &action); + void finishForwarding(const SendAction &action); void forwardMessages( HistoryItemsList &&items, const SendAction &action, diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index cdc9e428f..018fefc2e 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -39,7 +39,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwidget.h" #include "apiwrap.h" #include "numbers.h" -#include "observer_peer.h" #include "main/main_session.h" #include "styles/style_boxes.h" #include "styles/style_overview.h" diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index c352047d5..8db083635 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -34,11 +34,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat.h" #include "data/data_user.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "data/data_cloud_file.h" #include "mainwidget.h" #include "mainwindow.h" #include "apiwrap.h" -#include "observer_peer.h" #include "main/main_session.h" #include "facades.h" #include "styles/style_layers.h" @@ -817,11 +817,13 @@ void SetupChannelBox::prepare() { connect(&_checkTimer, &QTimer::timeout, [=] { check(); }); _privacyGroup->setChangedCallback([this](Privacy value) { privacyChanged(value); }); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::InviteLinkChanged, [this](const Notify::PeerUpdate &update) { - if (update.peer == _channel) { - rtlupdate(_invitationLink); - } - })); + + _channel->session().changes().peerUpdates( + _channel, + Data::PeerUpdate::Flag::InviteLink + ) | rpl::start_with_next([=] { + rtlupdate(_invitationLink); + }, lifetime()); boxClosing() | rpl::start_with_next([=] { if (!_existing) { diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 61270a514..67f6872c3 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -33,9 +33,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_file_origin.h" #include "data/data_histories.h" #include "data/data_photo_media.h" +#include "data/data_changes.h" #include "base/unixtime.h" #include "main/main_session.h" -#include "observer_peer.h" #include "facades.h" #include "app.h" #include "styles/style_layers.h" @@ -367,11 +367,12 @@ void MaxInviteBox::prepare() { _textHeight = qMin(_text.countHeight(_textWidth), 16 * st::boxLabelStyle.lineHeight); setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxTextFont->height + st::boxTextFont->height * 2 + st::newGroupLinkPadding.bottom()); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::InviteLinkChanged, [this](const Notify::PeerUpdate &update) { - if (update.peer == _channel) { - rtlupdate(_invitationLink); - } - })); + _channel->session().changes().peerUpdates( + _channel, + Data::PeerUpdate::Flag::InviteLink + ) | rpl::start_with_next([=] { + rtlupdate(_invitationLink); + }, lifetime()); } void MaxInviteBox::mouseMoveEvent(QMouseEvent *e) { diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index f99f27e62..a866b8a23 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -19,11 +19,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/slide_wrap.h" #include "ui/text_options.h" #include "lang/lang_keys.h" -#include "observer_peer.h" #include "storage/file_download.h" #include "data/data_peer_values.h" #include "data/data_chat.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "base/unixtime.h" #include "window/themes/window_theme.h" #include "styles/style_layers.h" @@ -666,15 +666,18 @@ PeerListContent::PeerListContent( update(); }); - using UpdateFlag = Notify::PeerUpdate::Flag; - auto changes = UpdateFlag::NameChanged | UpdateFlag::PhotoChanged; - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(changes, [this](const Notify::PeerUpdate &update) { - if (update.flags & UpdateFlag::PhotoChanged) { - this->update(); - } else if (update.flags & UpdateFlag::NameChanged) { - handleNameChanged(update); + using UpdateFlag = Data::PeerUpdate::Flag; + _controller->session().changes().peerUpdates( + UpdateFlag::Name | UpdateFlag::Photo + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { + if (update.flags & UpdateFlag::Name) { + handleNameChanged(update.peer); } - })); + if (update.flags & UpdateFlag::Photo) { + this->update(); + } + }, lifetime()); + subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { if (update.paletteChanged()) { invalidatePixmapsCache(); @@ -1717,8 +1720,8 @@ PeerListContent::RowIndex PeerListContent::findRowIndex( return result; } -void PeerListContent::handleNameChanged(const Notify::PeerUpdate &update) { - auto byPeer = _rowsByPeer.find(update.peer); +void PeerListContent::handleNameChanged(not_null peer) { + auto byPeer = _rowsByPeer.find(peer); if (byPeer != _rowsByPeer.cend()) { for (auto row : byPeer->second) { if (addingToSearchIndex()) { diff --git a/Telegram/SourceFiles/boxes/peer_list_box.h b/Telegram/SourceFiles/boxes/peer_list_box.h index 8cb07163b..467299118 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.h +++ b/Telegram/SourceFiles/boxes/peer_list_box.h @@ -34,10 +34,6 @@ struct ScrollToRequest; class PopupMenu; } // namespace Ui -namespace Notify { -struct PeerUpdate; -} // namespace Notify - using PaintRoundImageCallback = Fn> &from, int index); - void handleNameChanged(const Notify::PeerUpdate &update); + void handleNameChanged(not_null peer); void invalidatePixmapsCache(); diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index d8e07c329..007da687a 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/peer_list_controllers.h" #include "boxes/confirm_box.h" -#include "observer_peer.h" #include "ui/widgets/checkbox.h" #include "ui/ui_utility.h" #include "main/main_session.h" diff --git a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp index 9cc8dcea5..fd2bd3ecc 100644 --- a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "data/data_session.h" #include "data/data_folder.h" +#include "data/data_changes.h" #include "history/history.h" #include "dialogs/dialogs_indexed_list.h" #include "base/unixtime.h" @@ -23,7 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwindow.h" #include "window/window_session_controller.h" #include "apiwrap.h" -#include "observer_peer.h" #include "facades.h" #include "app.h" @@ -348,17 +348,16 @@ void AddSpecialBoxController::prepareChatRows(not_null chat) { chat->updateFullForced(); } - using UpdateFlag = Notify::PeerUpdate::Flag; - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler( - UpdateFlag::MembersChanged | UpdateFlag::AdminsChanged, - [=](const Notify::PeerUpdate &update) { - if (update.peer == chat) { - _additional.fillFromPeer(); - if (update.flags & UpdateFlag::MembersChanged) { - rebuildChatRows(chat); - } - } - })); + using UpdateFlag = Data::PeerUpdate::Flag; + chat->session().changes().peerUpdates( + chat, + UpdateFlag::Members | UpdateFlag::Admins + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { + _additional.fillFromPeer(); + if (update.flags & UpdateFlag::Members) { + rebuildChatRows(chat); + } + }, lifetime()); } void AddSpecialBoxController::rebuildChatRows(not_null chat) { diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp index 80a27e8c2..43185f80d 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp @@ -16,13 +16,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "lang/lang_keys.h" #include "mainwidget.h" -#include "observer_peer.h" #include "dialogs/dialogs_indexed_list.h" #include "data/data_peer_values.h" #include "data/data_session.h" #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_user.h" +#include "data/data_changes.h" #include "base/unixtime.h" #include "ui/widgets/popup_menu.h" #include "ui/ui_utility.h" @@ -286,20 +286,19 @@ void SubscribeToMigration( if (const auto channel = peer->migrateTo()) { migrate(channel); } else if (!chat->isDeactivated()) { - const auto alive = lifetime.make_state(); - const auto handler = [=](const Notify::PeerUpdate &update) { - if (update.peer == peer) { - if (const auto channel = peer->migrateTo()) { - const auto onstack = base::duplicate(migrate); - *alive = base::Subscription(); - onstack(channel); - } - } - }; - *alive = Notify::PeerUpdated().add_subscription( - Notify::PeerUpdatedHandler( - Notify::PeerUpdate::Flag::MigrationChanged, - handler)); + chat->session().changes().peerUpdates( + peer, + Data::PeerUpdate::Flag::Migration + ) | rpl::map([](const Data::PeerUpdate &update) { + return update.peer->migrateTo(); + }) | rpl::filter([](ChannelData *channel) { + return (channel != nullptr); + }) | rpl::take( + 1 + ) | rpl::start_with_next([=](not_null channel) { + const auto onstack = base::duplicate(migrate); + onstack(channel); + }, lifetime); } } } @@ -686,17 +685,15 @@ ParticipantsOnlineSorter::ParticipantsOnlineSorter( : _peer(peer) , _delegate(delegate) , _sortByOnlineTimer([=] { sort(); }) { - const auto handleUpdate = [=](const Notify::PeerUpdate &update) { + peer->session().changes().peerUpdates( + Data::PeerUpdate::Flag::OnlineStatus + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { const auto peerId = update.peer->id; if (const auto row = _delegate->peerListFindRow(peerId)) { row->refreshStatus(); sortDelayed(); } - }; - - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler( - Notify::PeerUpdate::Flag::UserOnlineChanged, - handleUpdate)); + }, _lifetime); sort(); } @@ -985,10 +982,10 @@ auto ParticipantsBoxController::saveState() const const auto weak = result.get(); if (const auto chat = _peer->asChat()) { - Notify::PeerUpdateViewer( + chat->session().changes().peerUpdates( chat, - Notify::PeerUpdate::Flag::MembersChanged - ) | rpl::start_with_next([=](const Notify::PeerUpdate &) { + Data::PeerUpdate::Flag::Members + ) | rpl::start_with_next([=] { weak->controllerState = nullptr; }, my->lifetime); } else if (const auto channel = _peer->asMegagroup()) { @@ -1104,23 +1101,20 @@ void ParticipantsBoxController::prepareChatRows(not_null chat) { chat->updateFullForced(); } - using UpdateFlag = Notify::PeerUpdate::Flag; - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler( - UpdateFlag::MembersChanged - | UpdateFlag::AdminsChanged, - [=](const Notify::PeerUpdate &update) { - if (update.peer != chat) { - return; - } - _additional.fillFromPeer(); - if ((update.flags & UpdateFlag::MembersChanged) - || (_role == Role::Admins)) { - rebuildChatRows(chat); - } - if (update.flags & UpdateFlag::AdminsChanged) { - rebuildRowTypes(); - } - })); + using UpdateFlag = Data::PeerUpdate::Flag; + chat->session().changes().peerUpdates( + chat, + UpdateFlag::Members | UpdateFlag::Admins + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { + _additional.fillFromPeer(); + if ((update.flags & UpdateFlag::Members) + || (_role == Role::Admins)) { + rebuildChatRows(chat); + } + if (update.flags & UpdateFlag::Admins) { + rebuildRowTypes(); + } + }, lifetime()); } void ParticipantsBoxController::rebuildChatRows(not_null chat) { diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.h b/Telegram/SourceFiles/boxes/peers/edit_participants_box.h index 5c439f198..65d8994fa 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.h +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.h @@ -50,7 +50,7 @@ enum class ParticipantsRole { Kicked, }; -class ParticipantsOnlineSorter : private base::Subscriber { +class ParticipantsOnlineSorter { public: ParticipantsOnlineSorter( not_null peer, @@ -63,10 +63,11 @@ private: void sortDelayed(); void refreshOnlineCount(); - not_null _peer; - not_null _delegate; + const not_null _peer; + const not_null _delegate; base::Timer _sortByOnlineTimer; rpl::variable _onlineCount = 0; + rpl::lifetime _lifetime; }; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 03ec4c4a3..a0a390fe3 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -29,7 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwidget.h" #include "mainwindow.h" #include "mtproto/sender.h" -#include "observer_peer.h" #include "ui/rp_widget.h" #include "ui/special_buttons.h" #include "ui/toast/toast.h" diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp index 5f2a891d8..4476fce8d 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp @@ -19,11 +19,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat.h" #include "data/data_peer.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "info/profile/info_profile_values.h" #include "lang/lang_keys.h" #include "mainwindow.h" #include "mtproto/sender.h" -#include "observer_peer.h" #include "ui/rp_widget.h" #include "ui/special_buttons.h" #include "ui/toast/toast.h" @@ -574,9 +574,9 @@ void Controller::observeInviteLink() { if (!_controls.editInviteLinkWrap) { return; } - Notify::PeerUpdateValue( + _peer->session().changes().peerFlagsValue( _peer, - Notify::PeerUpdate::Flag::InviteLinkChanged + Data::PeerUpdate::Flag::InviteLink ) | rpl::start_with_next([=] { refreshCreateInviteLink(); refreshEditInviteLink(); diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index a2a223be9..3f333a498 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/share_box.h" #include "dialogs/dialogs_indexed_list.h" -#include "observer_peer.h" #include "lang/lang_keys.h" #include "mainwindow.h" #include "mainwidget.h" @@ -35,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "data/data_session.h" #include "data/data_folder.h" +#include "data/data_changes.h" #include "main/main_session.h" #include "core/application.h" #include "styles/style_layers.h" @@ -91,7 +91,6 @@ private: Ui::Animations::Simple nameActive; }; - void notifyPeerUpdated(const Notify::PeerUpdate &update); void invalidateCache(); int displayedChatsCount() const; @@ -558,11 +557,19 @@ ShareBox::Inner::Inner( _filter = qsl("a"); updateFilter(); - using UpdateFlag = Notify::PeerUpdate::Flag; - auto observeEvents = UpdateFlag::NameChanged | UpdateFlag::PhotoChanged; - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) { - notifyPeerUpdated(update); - })); + _navigation->session().changes().peerUpdates( + Data::PeerUpdate::Flag::Photo + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { + updateChat(update.peer); + }, lifetime()); + + _navigation->session().changes().realtimeNameUpdates( + ) | rpl::start_with_next([=](const Data::NameUpdate &update) { + _chatsIndexed->peerNameChanged( + update.peer, + update.oldFirstLetters); + }, lifetime()); + subscribe(_navigation->session().downloaderTaskFinished(), [=] { update(); }); @@ -616,16 +623,6 @@ void ShareBox::Inner::activateSkipPage(int pageHeight, int direction) { activateSkipRow(direction * (pageHeight / _rowHeight)); } -void ShareBox::Inner::notifyPeerUpdated(const Notify::PeerUpdate &update) { - if (update.flags & Notify::PeerUpdate::Flag::NameChanged) { - _chatsIndexed->peerNameChanged( - update.peer, - update.oldNameFirstLetters); - } - - updateChat(update.peer); -} - void ShareBox::Inner::updateChat(not_null peer) { if (const auto i = _dataMap.find(peer); i != end(_dataMap)) { updateChatName(i->second.get(), peer); diff --git a/Telegram/SourceFiles/boxes/share_box.h b/Telegram/SourceFiles/boxes/share_box.h index 14a0e0dbc..605b68f63 100644 --- a/Telegram/SourceFiles/boxes/share_box.h +++ b/Telegram/SourceFiles/boxes/share_box.h @@ -33,10 +33,6 @@ class Row; class IndexedList; } // namespace Dialogs -namespace Notify { -struct PeerUpdate; -} // namespace Notify - namespace Ui { class MultiSelect; class InputField; diff --git a/Telegram/SourceFiles/calls/calls_box_controller.cpp b/Telegram/SourceFiles/calls/calls_box_controller.cpp index 88754cb92..3f7dd8c38 100644 --- a/Telegram/SourceFiles/calls/calls_box_controller.cpp +++ b/Telegram/SourceFiles/calls/calls_box_controller.cpp @@ -10,7 +10,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_calls.h" #include "styles/style_boxes.h" #include "lang/lang_keys.h" -#include "observer_peer.h" #include "ui/effects/ripple_animation.h" #include "calls/calls_instance.h" #include "history/history.h" diff --git a/Telegram/SourceFiles/calls/calls_panel.cpp b/Telegram/SourceFiles/calls/calls_panel.cpp index 43c7b3486..abf7c9ec7 100644 --- a/Telegram/SourceFiles/calls/calls_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_panel.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_file_origin.h" #include "data/data_photo_media.h" #include "data/data_cloud_file.h" +#include "data/data_changes.h" #include "calls/calls_emoji_fingerprint.h" #include "ui/widgets/buttons.h" #include "ui/widgets/labels.h" @@ -28,7 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "main/main_session.h" #include "apiwrap.h" -#include "observer_peer.h" #include "platform/platform_specific.h" #include "window/main_window.h" #include "layout.h" @@ -361,13 +361,7 @@ void Panel::initControls() { subscribe(_call->muteChanged(), [this](bool mute) { _mute->setIconOverride(mute ? &st::callUnmuteIcon : nullptr); }); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::NameChanged, [this](const Notify::PeerUpdate &update) { - if (!_call || update.peer != _call->user()) { - return; - } - _name->setText(_call->user()->name); - updateControlsGeometry(); - })); + _updateDurationTimer.setCallback([this] { if (_call) { updateStatusText(_call->state()); @@ -423,7 +417,7 @@ void Panel::reinitControls() { st::callPanelSignalBars, [=] { rtlupdate(signalBarsRect()); }); - _name->setText(_call->user()->name); + _name->setText(_user->name); updateStatusText(_call->state()); } @@ -435,12 +429,22 @@ void Panel::initLayout() { initGeometry(); - Notify::PeerUpdateValue( - _user, - Notify::PeerUpdate::Flag::PhotoChanged - ) | rpl::start_with_next( - [this] { processUserPhoto(); }, - lifetime()); + using UpdateFlag = Data::PeerUpdate::Flag; + _user->session().changes().peerUpdates( + UpdateFlag::Name | UpdateFlag::Photo + ) | rpl::filter([=](const Data::PeerUpdate &update) { + // _user may change for the same Panel. + return (_call != nullptr) && (update.peer == _user); + }) | rpl::start_with_next([=](const Data::PeerUpdate &update) { + if (update.flags & UpdateFlag::Name) { + _name->setText(_call->user()->name); + updateControlsGeometry(); + } + if (update.flags & UpdateFlag::Photo) { + processUserPhoto(); + } + }, lifetime()); + processUserPhoto(); subscribe(_user->session().downloaderTaskFinished(), [=] { refreshUserPhoto(); diff --git a/Telegram/SourceFiles/calls/calls_top_bar.cpp b/Telegram/SourceFiles/calls/calls_top_bar.cpp index f4e0d76aa..1eb33b46e 100644 --- a/Telegram/SourceFiles/calls/calls_top_bar.cpp +++ b/Telegram/SourceFiles/calls/calls_top_bar.cpp @@ -15,8 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "calls/calls_instance.h" #include "calls/calls_panel.h" #include "data/data_user.h" +#include "data/data_changes.h" #include "main/main_session.h" -#include "observer_peer.h" #include "boxes/abstract_box.h" #include "base/timer.h" #include "layout.h" @@ -101,13 +101,16 @@ void TopBar::initControls() { setMuted(mute); update(); }); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::NameChanged, [this](const Notify::PeerUpdate &update) { - if (auto call = _call.get()) { - if (update.peer == call->user()) { - updateInfoLabels(); - } - } - })); + + _call->user()->session().changes().peerUpdates( + Data::PeerUpdate::Flag::Name + ) | rpl::filter([=](const Data::PeerUpdate &update) { + // _user may change for the same Panel. + return (_call != nullptr) && (update.peer == _call->user()); + }) | rpl::start_with_next([=] { + updateInfoLabels(); + }, lifetime()); + setInfoLabels(); _info->setClickedCallback([=] { if (const auto call = _call.get()) { diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index 4de94aaa1..ea87276a8 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_file_origin.h" #include "data/data_cloud_file.h" +#include "data/data_changes.h" #include "chat_helpers/stickers_lottie.h" #include "ui/widgets/buttons.h" #include "ui/effects/animations.h" @@ -32,7 +33,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/confirm_box.h" #include "window/window_session_controller.h" // GifPauseReason. #include "main/main_session.h" -#include "observer_peer.h" #include "apiwrap.h" #include "app.h" #include "styles/style_chat_helpers.h" @@ -896,11 +896,19 @@ StickersListWidget::StickersListWidget( readVisibleFeatured(getVisibleTop(), getVisibleBottom()); } }); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::ChannelStickersChanged, [this](const Notify::PeerUpdate &update) { - if (update.peer == _megagroupSet) { - refreshStickers(); - } - })); + + session().changes().peerUpdates( + Data::PeerUpdate::Flag::StickersSet + ) | rpl::filter([=](const Data::PeerUpdate &update) { + return (update.peer.get() == _megagroupSet); + }) | rpl::start_with_next([=] { + refreshStickers(); + }, lifetime()); + + session().data().stickers().recentUpdated( + ) | rpl::start_with_next([=] { + refreshRecent(); + }, lifetime()); } Main::Session &StickersListWidget::session() const { diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp index 3185964a4..075bca788 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp +++ b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp @@ -20,10 +20,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/localstorage.h" #include "data/data_channel.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "data/stickers/data_stickers.h" #include "lang/lang_keys.h" #include "mainwindow.h" -#include "observer_peer.h" #include "apiwrap.h" #include "styles/style_chat_helpers.h" @@ -347,16 +347,13 @@ TabbedSelector::TabbedSelector( if (full()) { _tabsSlider->raise(); - const auto handleUpdate = [=](const Notify::PeerUpdate &update) { - if (update.peer == _currentPeer) { - checkRestrictedPeer(); - } - }; - subscribe( - Notify::PeerUpdated(), - Notify::PeerUpdatedHandler( - Notify::PeerUpdate::Flag::RightsChanged, - handleUpdate)); + session().changes().peerUpdates( + Data::PeerUpdate::Flag::Rights + ) | rpl::filter([=](const Data::PeerUpdate &update) { + return (update.peer.get() == _currentPeer); + }) | rpl::start_with_next([=] { + checkRestrictedPeer(); + }, lifetime()); session().api().stickerSetInstalled( ) | rpl::start_with_next([this](uint64 setId) { diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 8d1864451..e02935f4e 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -35,7 +35,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_translator.h" #include "lang/lang_cloud_manager.h" #include "lang/lang_hardcoded.h" -#include "observer_peer.h" #include "storage/storage_databases.h" #include "mainwidget.h" #include "core/file_utilities.h" @@ -502,10 +501,6 @@ void Application::call_handleUnreadCounterUpdate() { Global::RefUnreadCounterUpdate().notify(true); } -void Application::call_handleDelayedPeerUpdates() { - Notify::peerUpdatedSendDelayed(); -} - void Application::call_handleObservables() { base::HandleObservables(); } diff --git a/Telegram/SourceFiles/core/application.h b/Telegram/SourceFiles/core/application.h index edf6d8739..498f5f278 100644 --- a/Telegram/SourceFiles/core/application.h +++ b/Telegram/SourceFiles/core/application.h @@ -229,7 +229,6 @@ public: void writeInstallBetaVersionsSetting(); void call_handleUnreadCounterUpdate(); - void call_handleDelayedPeerUpdates(); void call_handleObservables(); protected: diff --git a/Telegram/SourceFiles/data/data_changes.cpp b/Telegram/SourceFiles/data/data_changes.cpp new file mode 100644 index 000000000..461d97e3e --- /dev/null +++ b/Telegram/SourceFiles/data/data_changes.cpp @@ -0,0 +1,169 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "data/data_changes.h" + +#include "main/main_session.h" + +namespace Data { + +template +void Changes::Manager::updated( + not_null data, + Flags flags) { + sendRealtimeNotifications(data, flags); +} + +template +void Changes::Manager::sendRealtimeNotifications( + not_null data, + Flags flags) { + auto clearRealtime = false; + for (auto i = 0; i != kCount; ++i) { + const auto flag = static_cast(1U << i); + if (flags & flag) { + _realtimeStreams[i].fire({ data, flags }); + } + } +} + +template +rpl::producer Changes::Manager::updates( + Flags flags) const { + return _stream.events( + ) | rpl::filter([=](const UpdateType &update) { + return (update.flags & flags); + }); +} + +template +rpl::producer Changes::Manager::updates( + not_null data, + Flags flags) const { + return _stream.events( + ) | rpl::filter([=](const UpdateType &update) { + const auto [updateData, updateFlags] = update; + return (updateData == data) && (updateFlags & flags); + }); +} + +template +auto Changes::Manager::realtimeUpdates(Flag flag) const +-> rpl::producer { + return _realtimeStreams[CountBit(flag)].events(); +} + +template +rpl::producer Changes::Manager::flagsValue( + not_null data, + Flags flags) const { + return rpl::single( + UpdateType{ data, flags } + ) | rpl::then(updates(data, flags)); +} + +template +void Changes::Manager::sendNotifications() { + for (const auto [data, flags] : base::take(_updates)) { + _stream.fire({ data, flags }); + } +} + +Changes::Changes(not_null session) : _session(session) { +} + +Main::Session &Changes::session() const { + return *_session; +} + +void Changes::nameUpdated( + not_null peer, + base::flat_set oldFirstLetters) { + _nameStream.fire({ peer, std::move(oldFirstLetters) }); +} + +rpl::producer Changes::realtimeNameUpdates() const { + return _nameStream.events(); +} + +rpl::producer Changes::realtimeNameUpdates( + not_null peer) const { + return _nameStream.events() | rpl::filter([=](const NameUpdate &update) { + return (update.peer == peer); + }); +} + +void Changes::peerUpdated(not_null peer, PeerUpdate::Flags flags) { + _peerChanges.updated(peer, flags); + scheduleNotifications(); +} + +rpl::producer Changes::peerUpdates( + PeerUpdate::Flags flags) const { + return _peerChanges.updates(flags); +} + +rpl::producer Changes::peerUpdates( + not_null peer, + PeerUpdate::Flags flags) const { + return _peerChanges.updates(peer, flags); +} + +rpl::producer Changes::peerFlagsValue( + not_null peer, + PeerUpdate::Flags flags) const { + return _peerChanges.flagsValue(peer, flags); +} + +rpl::producer Changes::realtimePeerUpdates( + PeerUpdate::Flag flag) const { + return _peerChanges.realtimeUpdates(flag); +} + +void Changes::historyUpdated( + not_null history, + HistoryUpdate::Flags flags) { + _historyChanges.updated(history, flags); + scheduleNotifications(); +} + +rpl::producer Changes::historyUpdates( + HistoryUpdate::Flags flags) const { + return _historyChanges.updates(flags); +} + +rpl::producer Changes::historyUpdates( + not_null history, + HistoryUpdate::Flags flags) const { + return _historyChanges.updates(history, flags); +} + +rpl::producer Changes::historyFlagsValue( + not_null history, + HistoryUpdate::Flags flags) const { + return _historyChanges.flagsValue(history, flags); +} + +void Changes::scheduleNotifications() { + if (!_notify) { + _notify = true; + crl::on_main(&session(), [=] { + sendNotifications(); + }); + } +} + +void Changes::sendNotifications() { + if (!_notify) { + return; + } + _notify = false; + _peerChanges.sendNotifications(); + _historyChanges.sendNotifications(); +} + +} // namespace Data diff --git a/Telegram/SourceFiles/data/data_changes.h b/Telegram/SourceFiles/data/data_changes.h new file mode 100644 index 000000000..6c84c4949 --- /dev/null +++ b/Telegram/SourceFiles/data/data_changes.h @@ -0,0 +1,197 @@ +/* +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 "base/flags.h" + +class History; +class PeerData; + +namespace Data { + +struct NameUpdate { + NameUpdate( + not_null peer, + base::flat_set oldFirstLetters) + : peer(peer) + , oldFirstLetters(std::move(oldFirstLetters)) { + } + + not_null peer; + base::flat_set oldFirstLetters; +}; + +struct PeerUpdate { + enum class Flag : uint32 { + None = 0, + + // Common flags + Name = (1 << 0), + Username = (1 << 1), + Photo = (1 << 2), + About = (1 << 3), + Notifications = (1 << 4), + Migration = (1 << 5), + UnavailableReason = (1 << 6), + PinnedMessage = (1 << 7), + + // For users + CanShareContact = (1 << 8), + IsContact = (1 << 9), + PhoneNumber = (1 << 10), + IsBlocked = (1 << 11), + OnlineStatus = (1 << 12), + BotCommands = (1 << 13), + BotCanBeInvited = (1 << 14), + CommonChats = (1 << 15), + HasCalls = (1 << 16), + SupportInfo = (1 << 17), + IsBot = (1 << 18), + + // For chats and channels + InviteLink = (1 << 19), + Members = (1 << 20), + Admins = (1 << 21), + BannedUsers = (1 << 22), + Rights = (1 << 23), + + // For channels + ChannelAmIn = (1 << 24), + StickersSet = (1 << 25), + ChannelLinkedChat = (1 << 26), + ChannelLocation = (1 << 27), + Slowmode = (1 << 28), + + // For iteration + LastUsedBit = (1 << 28), + }; + using Flags = base::flags; + friend inline constexpr auto is_flag_type(Flag) { return true; } + + not_null peer; + Flags flags = 0; + +}; + +struct HistoryUpdate { + enum class Flag : uint32 { + None = 0, + + IsPinned = (1 << 0), + UnreadView = (1 << 1), + TopPromoted = (1 << 2), + Folder = (1 << 3), + UnreadMentions = (1 << 4), + LocalMessages = (1 << 5), + ChatOccupied = (1 << 6), + + LastUsedBit = (1 << 6), + }; + using Flags = base::flags; + friend inline constexpr auto is_flag_type(Flag) { return true; } + + not_null history; + Flags flags = 0; + +}; + +class Changes final { +public: + explicit Changes(not_null session); + + [[nodiscard]] Main::Session &session() const; + + void nameUpdated( + not_null peer, + base::flat_set oldFirstLetters); + [[nodiscard]] rpl::producer realtimeNameUpdates() const; + [[nodiscard]] rpl::producer realtimeNameUpdates( + not_null peer) const; + + void peerUpdated(not_null peer, PeerUpdate::Flags flags); + [[nodiscard]] rpl::producer peerUpdates( + PeerUpdate::Flags flags) const; + [[nodiscard]] rpl::producer peerUpdates( + not_null peer, + PeerUpdate::Flags flags) const; + [[nodiscard]] rpl::producer peerFlagsValue( + not_null peer, + PeerUpdate::Flags flags) const; + [[nodiscard]] rpl::producer realtimePeerUpdates( + PeerUpdate::Flag flag) const; + + void historyUpdated( + not_null history, + HistoryUpdate::Flags flags); + [[nodiscard]] rpl::producer historyUpdates( + HistoryUpdate::Flags flags) const; + [[nodiscard]] rpl::producer historyUpdates( + not_null history, + HistoryUpdate::Flags flags) const; + [[nodiscard]] rpl::producer historyFlagsValue( + not_null history, + HistoryUpdate::Flags flags) const; + + void sendNotifications(); + +private: + template + static constexpr int CountBit(Flag Last = Flag::LastUsedBit) { + auto i = 0; + while ((1ULL << i) != static_cast(Last)) { + ++i; + Assert(i != 64); + } + return (i + 1); + } + + template + class Manager final { + public: + using Flag = typename UpdateType::Flag; + using Flags = typename UpdateType::Flags; + + void updated(not_null data, Flags flags); + [[nodiscard]] rpl::producer updates(Flags flags) const; + [[nodiscard]] rpl::producer updates( + not_null data, + Flags flags) const; + [[nodiscard]] rpl::producer flagsValue( + not_null data, + Flags flags) const; + [[nodiscard]] rpl::producer realtimeUpdates( + Flag flag) const; + + void sendNotifications(); + + private: + static constexpr auto kCount = CountBit(); + + void sendRealtimeNotifications(not_null data, Flags flags); + + std::array, kCount> _realtimeStreams; + base::flat_map, Flags> _updates; + rpl::event_stream _stream; + + }; + + static constexpr auto kHistoryCount = CountBit(); + + void scheduleNotifications(); + + const not_null _session; + + rpl::event_stream _nameStream; + Manager _peerChanges; + Manager _historyChanges; + + bool _notify = false; + +}; + +} // namespace Data diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 1d3746f7a..0feaa3887 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_peer_values.h" +#include "data/data_changes.h" #include "data/data_channel_admins.h" #include "data/data_user.h" #include "data/data_chat.h" @@ -17,13 +18,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_histories.h" #include "base/unixtime.h" #include "history/history.h" -#include "observer_peer.h" #include "main/main_session.h" #include "apiwrap.h" namespace { -using UpdateFlag = Notify::PeerUpdate::Flag; +using UpdateFlag = Data::PeerUpdate::Flag; } // namespace @@ -66,8 +66,8 @@ ChannelData::ChannelData(not_null owner, PeerId id) ) | rpl::distinct_until_changed( ) | rpl::start_with_next([=] { if (const auto chat = getMigrateFromChat()) { - Notify::peerUpdatedDelayed(chat, UpdateFlag::MigrationChanged); - Notify::peerUpdatedDelayed(this, UpdateFlag::MigrationChanged); + session().changes().peerUpdated(chat, UpdateFlag::Migration); + session().changes().peerUpdated(this, UpdateFlag::Migration); } }, _lifetime); } @@ -97,7 +97,7 @@ void ChannelData::setAccessHash(uint64 accessHash) { void ChannelData::setInviteLink(const QString &newInviteLink) { if (newInviteLink != _inviteLink) { _inviteLink = newInviteLink; - Notify::peerUpdatedDelayed(this, UpdateFlag::InviteLinkChanged); + session().changes().peerUpdated(this, UpdateFlag::InviteLink); } } @@ -131,9 +131,9 @@ void ChannelData::setLocation(const MTPChannelLocation &data) { const auto now = mgInfo->getLocation(); const auto nowValue = now ? *now : ChannelLocation(); if (was != now || (was && wasValue != nowValue)) { - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( this, - Notify::PeerUpdate::Flag::ChannelLocation); + UpdateFlag::ChannelLocation); } } @@ -144,7 +144,7 @@ const ChannelLocation *ChannelData::getLocation() const { void ChannelData::setLinkedChat(ChannelData *linked) { if (_linkedChat != linked) { _linkedChat = linked; - Notify::peerUpdatedDelayed(this, UpdateFlag::ChannelLinkedChat); + session().changes().peerUpdated(this, UpdateFlag::ChannelLinkedChat); } } @@ -159,28 +159,28 @@ void ChannelData::setMembersCount(int newMembersCount) { mgInfo->lastParticipantsCount = membersCount(); } _membersCount = newMembersCount; - Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::MembersChanged); + session().changes().peerUpdated(this, UpdateFlag::Members); } } void ChannelData::setAdminsCount(int newAdminsCount) { if (_adminsCount != newAdminsCount) { _adminsCount = newAdminsCount; - Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::AdminsChanged); + session().changes().peerUpdated(this, UpdateFlag::Admins); } } void ChannelData::setRestrictedCount(int newRestrictedCount) { if (_restrictedCount != newRestrictedCount) { _restrictedCount = newRestrictedCount; - Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::BannedUsersChanged); + session().changes().peerUpdated(this, UpdateFlag::BannedUsers); } } void ChannelData::setKickedCount(int newKickedCount) { if (_kickedCount != newKickedCount) { _kickedCount = newKickedCount; - Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::BannedUsersChanged); + session().changes().peerUpdated(this, UpdateFlag::BannedUsers); } } @@ -260,13 +260,11 @@ void ChannelData::applyEditAdmin( setAdminsCount(adminsCount() + 1); updateFullForced(); } - Notify::peerUpdatedDelayed( - this, - Notify::PeerUpdate::Flag::AdminsChanged); + session().changes().peerUpdated(this, UpdateFlag::Admins); } void ChannelData::applyEditBanned(not_null user, const MTPChatBannedRights &oldRights, const MTPChatBannedRights &newRights) { - auto flags = Notify::PeerUpdate::Flag::BannedUsersChanged | Notify::PeerUpdate::Flag::None; + auto flags = UpdateFlag::BannedUsers | UpdateFlag::None; auto isKicked = (newRights.c_chatBannedRights().vflags().v & MTPDchatBannedRights::Flag::f_view_messages); auto isRestricted = !isKicked && (newRights.c_chatBannedRights().vflags().v != 0); if (mgInfo) { @@ -276,7 +274,7 @@ void ChannelData::applyEditBanned(not_null user, const MTPChatBannedR if (adminsCount() > 1) { setAdminsCount(adminsCount() - 1); } else { - flags |= Notify::PeerUpdate::Flag::AdminsChanged; + flags |= UpdateFlag::Admins; } } auto it = mgInfo->lastRestricted.find(user); @@ -312,7 +310,7 @@ void ChannelData::applyEditBanned(not_null user, const MTPChatBannedR mgInfo->botStatus = -1; } } - flags |= Notify::PeerUpdate::Flag::MembersChanged; + flags |= UpdateFlag::Members; owner().removeMegagroupParticipant(this, user); } } @@ -321,12 +319,12 @@ void ChannelData::applyEditBanned(not_null user, const MTPChatBannedR if (isKicked) { if (membersCount() > 1) { setMembersCount(membersCount() - 1); - flags |= Notify::PeerUpdate::Flag::MembersChanged; + flags |= UpdateFlag::Members; } setKickedCount(kickedCount() + 1); } } - Notify::peerUpdatedDelayed(this, flags); + session().changes().peerUpdated(this, flags); } void ChannelData::markForbidden() { @@ -366,12 +364,11 @@ auto ChannelData::unavailableReasons() const return _unavailableReasons; } -void ChannelData::setUnavailableReasons(std::vector &&reasons) { +void ChannelData::setUnavailableReasons( + std::vector &&reasons) { if (_unavailableReasons != reasons) { _unavailableReasons = std::move(reasons); - Notify::peerUpdatedDelayed( - this, - Notify::PeerUpdate::Flag::UnavailableReasonChanged); + session().changes().peerUpdated(this, UpdateFlag::UnavailableReason); } } @@ -538,7 +535,9 @@ void ChannelData::setAdminRights(const MTPChatAdminRights &rights) { mgInfo->lastAdmins.remove(self); } } - Notify::peerUpdatedDelayed(this, UpdateFlag::RightsChanged | UpdateFlag::AdminsChanged | UpdateFlag::BannedUsersChanged); + session().changes().peerUpdated( + this, + UpdateFlag::Rights | UpdateFlag::Admins | UpdateFlag::BannedUsers); } void ChannelData::setRestrictions(const MTPChatBannedRights &rights) { @@ -561,7 +560,9 @@ void ChannelData::setRestrictions(const MTPChatBannedRights &rights) { mgInfo->lastRestricted.remove(self); } } - Notify::peerUpdatedDelayed(this, UpdateFlag::RightsChanged | UpdateFlag::AdminsChanged | UpdateFlag::BannedUsersChanged); + session().changes().peerUpdated( + this, + UpdateFlag::Rights | UpdateFlag::Admins | UpdateFlag::BannedUsers); } void ChannelData::setDefaultRestrictions(const MTPChatBannedRights &rights) { @@ -569,7 +570,7 @@ void ChannelData::setDefaultRestrictions(const MTPChatBannedRights &rights) { return; } _defaultRestrictions.set(rights.c_chatBannedRights().vflags().v); - Notify::peerUpdatedDelayed(this, UpdateFlag::RightsChanged); + session().changes().peerUpdated(this, UpdateFlag::Rights); } auto ChannelData::applyUpdateVersion(int version) -> UpdateStatus { @@ -597,7 +598,7 @@ void ChannelData::setMigrateFromChat(ChatData *chat) { if (chat != info->getMigrateFromChat()) { info->setMigrateFromChat(chat); if (amIn()) { - Notify::peerUpdatedDelayed(this, UpdateFlag::MigrationChanged); + session().changes().peerUpdated(this, UpdateFlag::Migration); } } } @@ -611,7 +612,7 @@ void ChannelData::setSlowmodeSeconds(int seconds) { return; } _slowmodeSeconds = seconds; - Notify::peerUpdatedDelayed(this, UpdateFlag::ChannelSlowmode); + session().changes().peerUpdated(this, UpdateFlag::Slowmode); } TimeId ChannelData::slowmodeLastMessage() const { @@ -628,7 +629,7 @@ void ChannelData::growSlowmodeLastMessage(TimeId when) { } else { _slowmodeLastMessage = when; } - Notify::peerUpdatedDelayed(this, UpdateFlag::ChannelSlowmode); + session().changes().peerUpdated(this, UpdateFlag::Slowmode); } namespace Data { @@ -655,6 +656,8 @@ void ApplyChannelUpdate( void ApplyChannelUpdate( not_null channel, const MTPDchannelFull &update) { + const auto session = &channel->session(); + channel->setAvailableMinId(update.vavailable_min_id().value_or_empty()); auto canViewAdmins = channel->canViewAdmins(); auto canViewMembers = channel->canViewMembers(); @@ -672,7 +675,7 @@ void ApplyChannelUpdate( item.match([&](const MTPDbotInfo &info) { if (const auto user = owner.userLoaded(info.vuser_id().v)) { user->setBotInfo(item); - channel->session().api().fullPeerUpdated().notify(user); + session->api().fullPeerUpdated().notify(user); } }); } @@ -746,21 +749,17 @@ void ApplyChannelUpdate( : MTP_inputStickerSetEmpty(); } if (stickersChanged) { - Notify::peerUpdatedDelayed( - channel, - Notify::PeerUpdate::Flag::ChannelStickersChanged); + session->changes().peerUpdated(channel, UpdateFlag::StickersSet); } } channel->fullUpdated(); if (canViewAdmins != channel->canViewAdmins() || canViewMembers != channel->canViewMembers()) { - Notify::peerUpdatedDelayed( - channel, - Notify::PeerUpdate::Flag::RightsChanged); + session->changes().peerUpdated(channel, UpdateFlag::Rights); } - channel->session().api().applyNotifySettings( + session->api().applyNotifySettings( MTP_inputNotifyPeer(channel->input), update.vnotify_settings()); diff --git a/Telegram/SourceFiles/data/data_chat.cpp b/Telegram/SourceFiles/data/data_chat.cpp index d3dfbc9e9..502cb2595 100644 --- a/Telegram/SourceFiles/data/data_chat.cpp +++ b/Telegram/SourceFiles/data/data_chat.cpp @@ -10,14 +10,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "data/data_channel.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "history/history.h" #include "main/main_session.h" #include "apiwrap.h" -#include "observer_peer.h" namespace { -using UpdateFlag = Notify::PeerUpdate::Flag; +using UpdateFlag = Data::PeerUpdate::Flag; } // namespace @@ -96,16 +96,12 @@ void ChatData::setName(const QString &newName) { } void ChatData::applyEditAdmin(not_null user, bool isAdmin) { - auto flags = Notify::PeerUpdate::Flag::AdminsChanged - | Notify::PeerUpdate::Flag::None; if (isAdmin) { admins.emplace(user); } else { admins.remove(user); } - Notify::peerUpdatedDelayed( - this, - Notify::PeerUpdate::Flag::AdminsChanged); + session().changes().peerUpdated(this, UpdateFlag::Admins); } void ChatData::invalidateParticipants() { @@ -115,15 +111,15 @@ void ChatData::invalidateParticipants() { //setDefaultRestrictions(MTP_chatBannedRights(MTP_flags(0), MTP_int(0))); invitedByMe.clear(); botStatus = 0; - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( this, - UpdateFlag::MembersChanged | UpdateFlag::AdminsChanged); + UpdateFlag::Members | UpdateFlag::Admins); } void ChatData::setInviteLink(const QString &newInviteLink) { if (newInviteLink != _inviteLink) { _inviteLink = newInviteLink; - Notify::peerUpdatedDelayed(this, UpdateFlag::InviteLinkChanged); + session().changes().peerUpdated(this, UpdateFlag::InviteLink); } } @@ -132,11 +128,9 @@ void ChatData::setAdminRights(const MTPChatAdminRights &rights) { return; } _adminRights.set(rights.c_chatAdminRights().vflags().v); - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( this, - (UpdateFlag::RightsChanged - | UpdateFlag::AdminsChanged - | UpdateFlag::BannedUsersChanged)); + UpdateFlag::Rights | UpdateFlag::Admins | UpdateFlag::BannedUsers); } void ChatData::setDefaultRestrictions(const MTPChatBannedRights &rights) { @@ -144,7 +138,7 @@ void ChatData::setDefaultRestrictions(const MTPChatBannedRights &rights) { return; } _defaultRestrictions.set(rights.c_chatBannedRights().vflags().v); - Notify::peerUpdatedDelayed(this, UpdateFlag::RightsChanged); + session().changes().peerUpdated(this, UpdateFlag::Rights); } void ChatData::refreshBotStatus() { @@ -176,7 +170,7 @@ void ChatData::setMigrateToChannel(ChannelData *channel) { if (_migratedTo != channel) { _migratedTo = channel; if (channel->amIn()) { - Notify::peerUpdatedDelayed(this, UpdateFlag::MigrationChanged); + session().changes().peerUpdated(this, UpdateFlag::Migration); } } } @@ -199,6 +193,7 @@ void ApplyChatUpdate( return; } const auto user = chat->owner().userLoaded(update.vuser_id().v); + const auto session = &chat->session(); if (!user || (!chat->participants.empty() && chat->participants.contains(user))) { @@ -213,7 +208,7 @@ void ApplyChatUpdate( chat->botStatus = 0; } else { chat->participants.emplace(user); - if (update.vinviter_id().v == chat->session().userId()) { + if (update.vinviter_id().v == session->userId()) { chat->invitedByMe.insert(user); } else { chat->invitedByMe.remove(user); @@ -222,13 +217,11 @@ void ApplyChatUpdate( if (user->isBot()) { chat->botStatus = 2; if (!user->botInfo->inited) { - chat->session().api().requestFullPeer(user); + session->api().requestFullPeer(user); } } } - Notify::peerUpdatedDelayed( - chat, - Notify::PeerUpdate::Flag::MembersChanged); + session->changes().peerUpdated(chat, UpdateFlag::Members); } void ApplyChatUpdate( @@ -270,9 +263,7 @@ void ApplyChatUpdate( chat->refreshBotStatus(); } } - Notify::peerUpdatedDelayed( - chat, - Notify::PeerUpdate::Flag::MembersChanged); + chat->session().changes().peerUpdated(chat, UpdateFlag::Members); } void ApplyChatUpdate( @@ -282,7 +273,7 @@ void ApplyChatUpdate( != ChatData::UpdateStatus::Good) { return; } - + const auto session = &chat->session(); const auto user = chat->owner().userLoaded(update.vuser_id().v); if (!user) { chat->invalidateParticipants(); @@ -295,16 +286,14 @@ void ApplyChatUpdate( } if (mtpIsTrue(update.vis_admin())) { if (chat->noParticipantInfo()) { - chat->session().api().requestFullPeer(chat); + session->api().requestFullPeer(chat); } else { chat->admins.emplace(user); } } else { chat->admins.erase(user); } - Notify::peerUpdatedDelayed( - chat, - Notify::PeerUpdate::Flag::AdminsChanged); + session->changes().peerUpdated(chat, UpdateFlag::Admins); } void ApplyChatUpdate( @@ -360,6 +349,7 @@ void ApplyChatUpdate(not_null chat, const MTPDchatFull &update) { void ApplyChatUpdate( not_null chat, const MTPChatParticipants &participants) { + const auto session = &chat->session(); participants.match([&](const MTPDchatParticipantsForbidden &data) { if (const auto self = data.vself_participant()) { // self-> @@ -381,7 +371,7 @@ void ApplyChatUpdate( chat->invitedByMe.clear(); chat->admins.clear(); chat->setAdminRights(MTP_chatAdminRights(MTP_flags(0))); - const auto selfUserId = chat->session().userId(); + const auto selfUserId = session->userId(); for (const auto &participant : list) { const auto userId = participant.match([&](const auto &data) { return data.vuser_id().v; @@ -430,10 +420,9 @@ void ApplyChatUpdate( } } chat->refreshBotStatus(); - Notify::peerUpdatedDelayed( + session->changes().peerUpdated( chat, - Notify::PeerUpdate::Flag::MembersChanged - | Notify::PeerUpdate::Flag::AdminsChanged); + UpdateFlag::Members | UpdateFlag::Admins); }); } diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index de643c064..7234f6401 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -236,6 +236,7 @@ not_null ChatFilters::chatsList(FilterId filterId) { auto &pointer = _chatsLists[filterId]; if (!pointer) { pointer = std::make_unique( + &_owner->session(), filterId, rpl::single(ChatFilter::kPinnedLimit)); } diff --git a/Telegram/SourceFiles/data/data_folder.cpp b/Telegram/SourceFiles/data/data_folder.cpp index 9d461258f..a28f68d3d 100644 --- a/Telegram/SourceFiles/data/data_folder.cpp +++ b/Telegram/SourceFiles/data/data_folder.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "data/data_channel.h" #include "data/data_histories.h" +#include "data/data_changes.h" #include "dialogs/dialogs_key.h" #include "history/history.h" #include "history/history_item.h" @@ -19,7 +20,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_account.h" //#include "storage/storage_feed_messages.h" // #feed #include "main/main_session.h" -#include "observer_peer.h" #include "apiwrap.h" #include "mainwidget.h" #include "facades.h" @@ -57,20 +57,20 @@ rpl::producer PinnedDialogsInFolderMaxValue( Folder::Folder(not_null owner, FolderId id) : Entry(owner, this) , _id(id) -, _chatsList(FilterId(), PinnedDialogsInFolderMaxValue(&owner->session())) +, _chatsList( + &owner->session(), + FilterId(), + PinnedDialogsInFolderMaxValue(&owner->session())) , _name(tr::lng_archived_name(tr::now)) { indexNameParts(); - Notify::PeerUpdateViewer( - Notify::PeerUpdate::Flag::NameChanged - ) | rpl::start_with_next([=](const Notify::PeerUpdate &update) { - for (const auto history : _lastHistories) { - if (history->peer == update.peer) { - ++_chatListViewVersion; - updateChatListEntryPostponed(); - return; - } - } + session().changes().peerUpdates( + PeerUpdate::Flag::Name + ) | rpl::filter([=](const PeerUpdate &update) { + return ranges::contains(_lastHistories, update.peer, &History::peer); + }) | rpl::start_with_next([=] { + ++_chatListViewVersion; + updateChatListEntryPostponed(); }, _lifetime); _chatsList.setAllAreMuted(true); diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index e9f195d8b..4b1aadc1c 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "data/data_chat.h" #include "data/data_channel.h" +#include "data/data_changes.h" #include "data/data_photo.h" #include "data/data_folder.h" #include "data/data_session.h" @@ -18,7 +19,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/unixtime.h" #include "base/crc32hash.h" #include "lang/lang_keys.h" -#include "observer_peer.h" #include "apiwrap.h" #include "boxes/confirm_box.h" #include "main/main_session.h" @@ -42,7 +42,7 @@ namespace { constexpr auto kUpdateFullPeerTimeout = crl::time(5000); // Not more than once in 5 seconds. constexpr auto kUserpicSize = 160; -using UpdateFlag = Notify::PeerUpdate::Flag; +using UpdateFlag = Data::PeerUpdate::Flag; } // namespace @@ -147,15 +147,17 @@ void PeerData::updateNameDelayed( _nameText.setText(st::msgNameStyle, name, Ui::NameTextOptions()); _userpicEmpty = nullptr; - Notify::PeerUpdate update(this); - if (nameVersion++ > 1) { - update.flags |= UpdateFlag::NameChanged; - update.oldNameFirstLetters = nameFirstLetters(); + auto flags = UpdateFlag::None | UpdateFlag::None; + auto oldFirstLetters = base::flat_set(); + const auto nameUpdated = (nameVersion++ > 1); + if (nameUpdated) { + oldFirstLetters = nameFirstLetters(); + flags |= UpdateFlag::Name; } if (isUser()) { if (asUser()->username != newUsername) { asUser()->username = newUsername; - update.flags |= UpdateFlag::UsernameChanged; + flags |= UpdateFlag::Username; } asUser()->setNameOrPhone(newNameOrPhone); } else if (isChannel()) { @@ -167,12 +169,15 @@ void PeerData::updateNameDelayed( } else { asChannel()->addFlags(MTPDchannel::Flag::f_username); } - update.flags |= UpdateFlag::UsernameChanged; + flags |= UpdateFlag::Username; } } fillNames(); - if (update.flags) { - Notify::PeerUpdated().notify(update, true); + if (nameUpdated) { + session().changes().nameUpdated(this, std::move(oldFirstLetters)); + } + if (flags) { + session().changes().peerUpdated(this, flags); } } @@ -204,7 +209,7 @@ void PeerData::setUserpicPhoto(const MTPPhoto &data) { }); if (_userpicPhotoId != photoId) { _userpicPhotoId = photoId; - Notify::peerUpdatedDelayed(this, UpdateFlag::PhotoChanged); + session().changes().peerUpdated(this, UpdateFlag::Photo); } } @@ -384,7 +389,7 @@ void PeerData::setUserpicChecked( const ImageLocation &location) { if (_userpicPhotoId != photoId || _userpic.location() != location) { setUserpic(photoId, location); - Notify::peerUpdatedDelayed(this, UpdateFlag::PhotoChanged); + session().changes().peerUpdated(this, UpdateFlag::Photo); //if (const auto channel = asChannel()) { // #feed // if (const auto feed = channel->feed()) { // owner().notifyFeedUpdated( @@ -454,9 +459,7 @@ void PeerData::setPinnedMessageId(MsgId messageId) { messageId = (messageId > min) ? messageId : MsgId(0); if (_pinnedMessageId != messageId) { _pinnedMessageId = messageId; - Notify::peerUpdatedDelayed( - this, - Notify::PeerUpdate::Flag::PinnedMessageChanged); + session().changes().peerUpdated(this, UpdateFlag::PinnedMessage); } } @@ -479,7 +482,7 @@ bool PeerData::setAbout(const QString &newAbout) { return false; } _about = newAbout; - Notify::peerUpdatedDelayed(this, UpdateFlag::AboutChanged); + session().changes().peerUpdated(this, UpdateFlag::About); return true; } diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index b7de383de..7e3e20cd4 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "data/data_session.h" -#include "observer_peer.h" #include "main/main_session.h" #include "apiwrap.h" #include "mainwidget.h" @@ -34,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/themes/window_theme.h" #include "lang/lang_keys.h" // tr::lng_deleted(tr::now) in user name #include "data/stickers/data_stickers.h" +#include "data/data_changes.h" #include "data/data_media_types.h" #include "data/data_folder.h" #include "data/data_channel.h" @@ -209,7 +209,7 @@ Session::Session(not_null session) , _bigFileCache(Core::App().databases().get( _session->local().cacheBigFilePath(), _session->local().cacheBigFileSettings())) -, _chatsList(FilterId(), PinnedDialogsCountMaxValue(session)) +, _chatsList(session, FilterId(), PinnedDialogsCountMaxValue(session)) , _contactsList(Dialogs::SortMode::Name) , _contactsNoChatsList(Dialogs::SortMode::Name) , _selfDestructTimer([=] { checkSelfDestructItems(); }) @@ -353,8 +353,8 @@ not_null Session::processUser(const MTPUser &data) { const MTPUserStatus *status = nullptr; const MTPUserStatus emptyStatus = MTP_userStatusEmpty(); - Notify::PeerUpdate update; - using UpdateFlag = Notify::PeerUpdate::Flag; + using UpdateFlag = PeerUpdate::Flag; + auto flags = UpdateFlag::None | UpdateFlag::None; data.match([&](const MTPDuserEmpty &data) { const auto canShareThisContact = result->canShareThisContactFast(); @@ -366,13 +366,13 @@ not_null Session::processUser(const MTPUser &data) { result->setFlags(MTPDuser::Flag::f_deleted); if (!result->phone().isEmpty()) { result->setPhone(QString()); - update.flags |= UpdateFlag::UserPhoneChanged; + flags |= UpdateFlag::PhoneNumber; } result->setBotInfoVersion(-1); status = &emptyStatus; result->setIsContact(false); if (canShareThisContact != result->canShareThisContactFast()) { - update.flags |= UpdateFlag::UserCanShareContact; + flags |= UpdateFlag::CanShareContact; } }, [&](const MTPDuser &data) { minimal = data.is_min(); @@ -405,7 +405,7 @@ not_null Session::processUser(const MTPUser &data) { if (data.is_deleted()) { if (!result->phone().isEmpty()) { result->setPhone(QString()); - update.flags |= UpdateFlag::UserPhoneChanged; + flags |= UpdateFlag::PhoneNumber; } result->setName(tr::lng_deleted(tr::now), QString(), QString(), QString()); result->setPhoto(MTP_userProfilePhotoEmpty()); @@ -423,7 +423,7 @@ not_null Session::processUser(const MTPUser &data) { const auto phoneChanged = (result->phone() != phone); if (phoneChanged) { result->setPhone(phone); - update.flags |= UpdateFlag::UserPhoneChanged; + flags |= UpdateFlag::PhoneNumber; } const auto nameChanged = (result->firstName != fname) || (result->lastName != lname); @@ -475,7 +475,7 @@ not_null Session::processUser(const MTPUser &data) { result->botInfo->readsAllHistory = data.is_bot_chat_history(); if (result->botInfo->cantJoinGroups != data.is_bot_nochats()) { result->botInfo->cantJoinGroups = data.is_bot_nochats(); - update.flags |= UpdateFlag::BotCanAddToGroups; + flags |= UpdateFlag::BotCanBeInvited; } if (const auto placeholder = data.vbot_inline_placeholder()) { result->botInfo->inlinePlaceholder = '_' + qs(*placeholder); @@ -490,7 +490,7 @@ not_null Session::processUser(const MTPUser &data) { } if (canShareThisContact != result->canShareThisContactFast()) { - update.flags |= UpdateFlag::UserCanShareContact; + flags |= UpdateFlag::CanShareContact; } }); @@ -510,15 +510,12 @@ not_null Session::processUser(const MTPUser &data) { oldOnlineTill); if (oldOnlineTill != newOnlineTill) { result->onlineTill = newOnlineTill; - update.flags |= UpdateFlag::UserOnlineChanged; + flags |= UpdateFlag::OnlineStatus; } } - if (App::main()) { - if (update.flags) { - update.peer = result; - Notify::peerUpdatedDelayed(update); - } + if (flags) { + session().changes().peerUpdated(result, flags); } return result; } @@ -537,9 +534,8 @@ not_null Session::processChat(const MTPChat &data) { }); auto minimal = false; - Notify::PeerUpdate update; - using UpdateFlag = Notify::PeerUpdate::Flag; - + using UpdateFlag = Data::PeerUpdate::Flag; + auto flags = UpdateFlag::None | UpdateFlag::None; data.match([&](const MTPDchat &data) { const auto chat = result->asChat(); @@ -585,7 +581,7 @@ not_null Session::processChat(const MTPChat &data) { chat->count = data.vparticipants_count().v; if (canAddMembers != chat->canAddMembers()) { - update.flags |= UpdateFlag::RightsChanged; + flags |= UpdateFlag::Rights; } }, [&](const MTPDchatForbidden &data) { const auto chat = result->asChat(); @@ -604,7 +600,7 @@ not_null Session::processChat(const MTPChat &data) { MTP_chatBannedRights(MTP_flags(0), MTP_int(0))); if (canAddMembers != chat->canAddMembers()) { - update.flags |= UpdateFlag::RightsChanged; + flags |= UpdateFlag::Rights; } }, [&](const MTPDchannel &data) { const auto channel = result->asChannel(); @@ -676,12 +672,12 @@ not_null Session::processChat(const MTPChat &data) { channel->setPhoto(data.vphoto()); if (wasInChannel != channel->amIn()) { - update.flags |= UpdateFlag::ChannelAmIn; + flags |= UpdateFlag::ChannelAmIn; } if (canViewAdmins != channel->canViewAdmins() || canViewMembers != channel->canViewMembers() || canAddMembers != channel->canAddMembers()) { - update.flags |= UpdateFlag::RightsChanged; + flags |= UpdateFlag::Rights; } }, [&](const MTPDchannelForbidden &data) { const auto channel = result->asChannel(); @@ -709,12 +705,12 @@ not_null Session::processChat(const MTPChat &data) { channel->setMembersCount(0); if (wasInChannel != channel->amIn()) { - update.flags |= UpdateFlag::ChannelAmIn; + flags |= UpdateFlag::ChannelAmIn; } if (canViewAdmins != channel->canViewAdmins() || canViewMembers != channel->canViewMembers() || canAddMembers != channel->canAddMembers()) { - update.flags |= UpdateFlag::RightsChanged; + flags |= UpdateFlag::Rights; } }, [](const MTPDchatEmpty &) { }); @@ -726,9 +722,8 @@ not_null Session::processChat(const MTPChat &data) { } else if (result->loadedStatus != PeerData::FullLoaded) { result->loadedStatus = PeerData::FullLoaded; } - if (update.flags) { - update.peer = result; - Notify::peerUpdatedDelayed(update); + if (flags) { + session().changes().peerUpdated(result, flags); } return result; } @@ -841,6 +836,22 @@ void Session::deleteConversationLocally(not_null peer) { } } } +void Session::newMessageSent(not_null history) { + _newMessageSent.fire_copy(history); +} + +rpl::producer> Session::newMessageSent() const { + return _newMessageSent.events(); +} + +void Session::cancelForwarding(not_null history) { + history->setForwardDraft({}); + _forwardDraftUpdated.fire_copy(history); +} + +rpl::producer> Session::forwardDraftUpdates() const { + return _forwardDraftUpdated.events(); +} void Session::registerSendAction( not_null history, @@ -1034,25 +1045,27 @@ void Session::forgetPassportCredentials() { } void Session::setupContactViewsViewer() { - Notify::PeerUpdateViewer( - Notify::PeerUpdate::Flag::UserIsContact - ) | rpl::map([](const Notify::PeerUpdate &update) { + session().changes().peerUpdates( + PeerUpdate::Flag::IsContact + ) | rpl::map([](const PeerUpdate &update) { return update.peer->asUser(); - }) | rpl::filter([](UserData *user) { - return user != nullptr; }) | rpl::start_with_next([=](not_null user) { - userIsContactUpdated(user); + const auto i = _contactViews.find(peerToUser(user->id)); + if (i != _contactViews.end()) { + for (const auto view : i->second) { + requestViewResize(view); + } + } }, _lifetime); } void Session::setupChannelLeavingViewer() { - Notify::PeerUpdateViewer( - Notify::PeerUpdate::Flag::ChannelAmIn - ) | rpl::map([](const Notify::PeerUpdate &update) { + session().changes().peerUpdates( + PeerUpdate::Flag::ChannelAmIn + ) | rpl::map([](const PeerUpdate &update) { return update.peer->asChannel(); - }) | rpl::filter([](ChannelData *channel) { - return (channel != nullptr) - && !(channel->amIn()); + }) | rpl::filter([](not_null channel) { + return !(channel->amIn()); }) | rpl::start_with_next([=](not_null channel) { // channel->clearFeed(); // #feed if (const auto history = historyLoaded(channel->id)) { @@ -1064,23 +1077,21 @@ void Session::setupChannelLeavingViewer() { } void Session::setupPeerNameViewer() { - Notify::PeerUpdateViewer( - Notify::PeerUpdate::Flag::NameChanged - ) | rpl::start_with_next([=](const Notify::PeerUpdate &update) { + session().changes().realtimeNameUpdates( + ) | rpl::start_with_next([=](const NameUpdate &update) { const auto peer = update.peer; - const auto &oldLetters = update.oldNameFirstLetters; + const auto &oldLetters = update.oldFirstLetters; _contactsNoChatsList.peerNameChanged(peer, oldLetters); _contactsList.peerNameChanged(peer, oldLetters); }, _lifetime); } void Session::setupUserIsContactViewer() { - Notify::PeerUpdateViewer( - Notify::PeerUpdate::Flag::UserIsContact - ) | rpl::filter([=](const Notify::PeerUpdate &update) { - return update.peer->isUser(); - }) | rpl::start_with_next([=](const Notify::PeerUpdate &update) { + session().changes().peerUpdates( + PeerUpdate::Flag::IsContact + ) | rpl::start_with_next([=](const PeerUpdate &update) { const auto user = update.peer->asUser(); + Assert(user != nullptr); if (user->loadedStatus != PeerData::FullLoaded) { LOG(("API Error: " "userIsContactChanged() called for a not loaded user!")); @@ -1505,15 +1516,6 @@ rpl::producer> Session::megagroupParticipantAdded( }); } -void Session::userIsContactUpdated(not_null user) { - const auto i = _contactViews.find(peerToUser(user->id)); - if (i != _contactViews.end()) { - for (const auto view : i->second) { - requestViewResize(view); - } - } -} - HistoryItemsList Session::idsToItems( const MessageIdsList &ids) const { return ranges::view::all( @@ -1972,9 +1974,9 @@ void Session::updateNotifySettingsLocal(not_null peer) { if (history && history->changeMute(muted)) { // Notification already sent. } else { - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( peer, - Notify::PeerUpdate::Flag::NotificationsEnabled); + PeerUpdate::Flag::Notifications); } if (muted) { @@ -3157,9 +3159,9 @@ void Session::registerContactItem( _contactItems[contactId].insert(item); if (contact && canShare != contact->canShareThisContact()) { - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( contact, - Notify::PeerUpdate::Flag::UserCanShareContact); + PeerUpdate::Flag::CanShareContact); } if (const auto i = _views.find(item); i != _views.end()) { @@ -3189,9 +3191,9 @@ void Session::unregisterContactItem( } if (contact && canShare != contact->canShareThisContact()) { - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( contact, - Notify::PeerUpdate::Flag::UserCanShareContact); + PeerUpdate::Flag::CanShareContact); } } @@ -3739,36 +3741,33 @@ MessageIdsList Session::takeMimeForwardIds() { } void Session::setTopPromoted( - PeerData *promoted, + History *promoted, const QString &type, const QString &message) { const auto changed = (_topPromoted != promoted); - const auto history = promoted ? this->history(promoted).get() : nullptr; - if (changed - || (history && history->topPromotionMessage() != message)) { - if (changed) { - if (const auto history = historyLoaded(_topPromoted)) { - history->cacheTopPromotion(false, QString(), QString()); - } - } - const auto old = std::exchange(_topPromoted, promoted); - if (history) { - history->cacheTopPromotion(true, type, message); - history->requestChatListMessage(); - Notify::peerUpdatedDelayed( - _topPromoted, - Notify::PeerUpdate::Flag::TopPromotedChanged); - } - if (changed && old) { - Notify::peerUpdatedDelayed( - old, - Notify::PeerUpdate::Flag::TopPromotedChanged); + if (!changed + && (!promoted || promoted->topPromotionMessage() == message)) { + return; + } + if (changed) { + if (_topPromoted) { + _topPromoted->cacheTopPromotion(false, QString(), QString()); } } -} - -PeerData *Session::topPromoted() const { - return _topPromoted; + const auto old = std::exchange(_topPromoted, promoted); + if (_topPromoted) { + histories().requestDialogEntry(_topPromoted); + _topPromoted->cacheTopPromotion(true, type, message); + _topPromoted->requestChatListMessage(); + session().changes().historyUpdated( + _topPromoted, + HistoryUpdate::Flag::TopPromoted); + } + if (changed && old) { + session().changes().historyUpdated( + old, + HistoryUpdate::Flag::TopPromoted); + } } bool Session::updateWallpapers(const MTPaccount_WallPapers &data) { diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 16fa66e42..c78e0fdb6 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -180,6 +180,11 @@ public: void deleteConversationLocally(not_null peer); + void newMessageSent(not_null history); + [[nodiscard]] rpl::producer> newMessageSent() const; + void cancelForwarding(not_null history); + [[nodiscard]] rpl::producer> forwardDraftUpdates() const; + void registerSendAction( not_null history, not_null user, @@ -624,10 +629,9 @@ public: MessageIdsList takeMimeForwardIds(); void setTopPromoted( - PeerData *promoted, + History *promoted, const QString &type, const QString &message); - PeerData *topPromoted() const; bool updateWallpapers(const MTPaccount_WallPapers &data); void removeWallpaper(const WallPaper &paper); @@ -742,8 +746,6 @@ private: not_null folder, const MTPDfolder &data); - void userIsContactUpdated(not_null user); - void setPinnedFromDialog(const Dialogs::Key &key, bool pinned); NotifySettings &defaultNotifySettings(not_null peer); @@ -878,6 +880,8 @@ private: rpl::event_stream> _webpageUpdates; rpl::event_stream> _channelDifferenceTooLong; rpl::event_stream> _historyOutboxReads; + rpl::event_stream> _newMessageSent; + rpl::event_stream> _forwardDraftUpdated; base::flat_multi_map> _pollsClosings; base::Timer _pollsClosingTimer; @@ -893,7 +897,7 @@ private: base::flat_set> _heavyViewParts; - PeerData *_topPromoted = nullptr; + History *_topPromoted = nullptr; NotifySettings _defaultUserNotifySettings; NotifySettings _defaultChatNotifySettings; diff --git a/Telegram/SourceFiles/data/data_user.cpp b/Telegram/SourceFiles/data/data_user.cpp index d4e8f5b1c..8bf8fc1df 100644 --- a/Telegram/SourceFiles/data/data_user.cpp +++ b/Telegram/SourceFiles/data/data_user.cpp @@ -7,9 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "data/data_user.h" -#include "observer_peer.h" #include "storage/localstorage.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "ui/text_options.h" #include "apiwrap.h" #include "lang/lang_keys.h" @@ -20,7 +20,7 @@ namespace { // User with hidden last seen stays online in UI for such amount of seconds. constexpr auto kSetOnlineAfterActivity = TimeId(30); -using UpdateFlag = Notify::PeerUpdate::Flag; +using UpdateFlag = Data::PeerUpdate::Flag; } // namespace @@ -65,9 +65,7 @@ void UserData::setIsContact(bool is) { : ContactStatus::NotContact; if (_contactStatus != status) { _contactStatus = status; - Notify::peerUpdatedDelayed( - this, - Notify::PeerUpdate::Flag::UserIsContact); + session().changes().peerUpdated(this, UpdateFlag::IsContact); } } @@ -92,16 +90,16 @@ void UserData::setUnavailableReasons( std::vector &&reasons) { if (_unavailableReasons != reasons) { _unavailableReasons = std::move(reasons); - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( this, - Notify::PeerUpdate::Flag::UnavailableReasonChanged); + UpdateFlag::UnavailableReason); } } void UserData::setCommonChatsCount(int count) { if (_commonChatsCount != count) { _commonChatsCount = count; - Notify::peerUpdatedDelayed(this, UpdateFlag::UserCommonChatsChanged); + session().changes().peerUpdated(this, UpdateFlag::CommonChats); } } @@ -213,10 +211,10 @@ void UserData::madeAction(TimeId when) { return; } else if (onlineTill <= 0 && -onlineTill < when) { onlineTill = -when - kSetOnlineAfterActivity; - Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::UserOnlineChanged); + session().changes().peerUpdated(this, UpdateFlag::OnlineStatus); } else if (onlineTill > 0 && onlineTill < when + 1) { onlineTill = when + kSetOnlineAfterActivity; - Notify::peerUpdatedDelayed(this, Notify::PeerUpdate::Flag::UserOnlineChanged); + session().changes().peerUpdated(this, UpdateFlag::OnlineStatus); } } @@ -241,14 +239,14 @@ void UserData::setIsBlocked(bool is) { } else { _fullFlags.remove(MTPDuserFull::Flag::f_blocked); } - Notify::peerUpdatedDelayed(this, UpdateFlag::UserIsBlocked); + session().changes().peerUpdated(this, UpdateFlag::IsBlocked); } } void UserData::setCallsStatus(CallsStatus callsStatus) { if (callsStatus != _callsStatus) { _callsStatus = callsStatus; - Notify::peerUpdatedDelayed(this, UpdateFlag::UserHasCalls); + session().changes().peerUpdated(this, UpdateFlag::HasCalls); } } diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.cpp b/Telegram/SourceFiles/data/stickers/data_stickers.cpp index b6344c616..39bbcb5e5 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers.cpp @@ -62,6 +62,119 @@ rpl::producer<> Stickers::savedGifsUpdated() const { return _savedGifsUpdated.events(); } +void Stickers::incrementSticker(not_null document) { + if (!document->sticker() + || document->sticker()->set.type() == mtpc_inputStickerSetEmpty) { + return; + } + + bool writeRecentStickers = false; + auto &sets = setsRef(); + auto it = sets.find(Data::Stickers::CloudRecentSetId); + if (it == sets.cend()) { + if (it == sets.cend()) { + it = sets.emplace( + Data::Stickers::CloudRecentSetId, + std::make_unique( + &session().data(), + Data::Stickers::CloudRecentSetId, + uint64(0), + tr::lng_recent_stickers(tr::now), + QString(), + 0, // count + 0, // hash + MTPDstickerSet_ClientFlag::f_special | 0, + TimeId(0))).first; + } else { + it->second->title = tr::lng_recent_stickers(tr::now); + } + } + const auto set = it->second.get(); + auto removedFromEmoji = std::vector>(); + auto index = set->stickers.indexOf(document); + if (index > 0) { + if (set->dates.empty()) { + session().api().requestRecentStickersForce(); + } else { + Assert(set->dates.size() == set->stickers.size()); + set->dates.erase(set->dates.begin() + index); + } + set->stickers.removeAt(index); + for (auto i = set->emoji.begin(); i != set->emoji.end();) { + if (const auto index = i->indexOf(document); index >= 0) { + removedFromEmoji.emplace_back(i.key()); + i->removeAt(index); + if (i->isEmpty()) { + i = set->emoji.erase(i); + continue; + } + } + ++i; + } + } + if (index) { + if (set->dates.size() == set->stickers.size()) { + set->dates.insert(set->dates.begin(), base::unixtime::now()); + } + set->stickers.push_front(document); + if (const auto emojiList = getEmojiListFromSet(document)) { + for (const auto emoji : *emojiList) { + set->emoji[emoji].push_front(document); + } + } else if (!removedFromEmoji.empty()) { + for (const auto emoji : removedFromEmoji) { + set->emoji[emoji].push_front(document); + } + } else { + session().api().requestRecentStickersForce(); + } + + writeRecentStickers = true; + } + + // Remove that sticker from old recent, now it is in cloud recent stickers. + bool writeOldRecent = false; + auto &recent = getRecentPack(); + for (auto i = recent.begin(), e = recent.end(); i != e; ++i) { + if (i->first == document) { + writeOldRecent = true; + recent.erase(i); + break; + } + } + while (!recent.isEmpty() && set->stickers.size() + recent.size() > Global::StickersRecentLimit()) { + writeOldRecent = true; + recent.pop_back(); + } + + if (writeOldRecent) { + session().local().writeSettings(); + } + + // Remove that sticker from custom stickers, now it is in cloud recent stickers. + bool writeInstalledStickers = false; + auto customIt = sets.find(Data::Stickers::CustomSetId); + if (customIt != sets.cend()) { + const auto custom = customIt->second.get(); + int removeIndex = custom->stickers.indexOf(document); + if (removeIndex >= 0) { + custom->stickers.removeAt(removeIndex); + if (custom->stickers.isEmpty()) { + sets.erase(customIt); + } + writeInstalledStickers = true; + } + } + + if (writeInstalledStickers) { + session().local().writeInstalledStickers(); + } + if (writeRecentStickers) { + session().local().writeRecentStickers(); + } + notifyRecentUpdated(); +} + void Stickers::addSavedGif(not_null document) { const auto index = _savedGifs.indexOf(document); if (!index) { diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.h b/Telegram/SourceFiles/data/stickers/data_stickers.h index 9abdcf7ac..c846a96bd 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.h +++ b/Telegram/SourceFiles/data/stickers/data_stickers.h @@ -55,6 +55,8 @@ public: void notifySavedGifsUpdated(); [[nodiscard]] rpl::producer<> savedGifsUpdated() const; + void incrementSticker(not_null document); + bool updateNeeded(crl::time now) const { return updateNeeded(_lastUpdate, now); } diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 0b336ce3a..10bcada04 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_histories.h" #include "data/data_chat_filters.h" #include "data/data_cloud_file.h" +#include "data/data_changes.h" #include "data/stickers/data_stickers.h" #include "base/unixtime.h" #include "lang/lang_keys.h" @@ -38,7 +39,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/storage_account.h" #include "apiwrap.h" #include "window/themes/window_theme.h" -#include "observer_peer.h" #include "main/main_session.h" #include "window/notifications_manager.h" #include "window/window_session_controller.h" @@ -223,36 +223,40 @@ InnerWidget::InnerWidget( } }); - using UpdateFlag = Notify::PeerUpdate::Flag; - auto changes = UpdateFlag::ChatPinnedChanged - | UpdateFlag::NameChanged - | UpdateFlag::PhotoChanged - | UpdateFlag::UserIsContact - | UpdateFlag::UserOccupiedChanged - | UpdateFlag::MigrationChanged; - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(changes, [=](const Notify::PeerUpdate &update) { - if (update.flags & UpdateFlag::ChatPinnedChanged) { + session().changes().historyUpdates( + Data::HistoryUpdate::Flag::IsPinned + | Data::HistoryUpdate::Flag::ChatOccupied + ) | rpl::start_with_next([=](const Data::HistoryUpdate &update) { + if (update.flags & Data::HistoryUpdate::Flag::IsPinned) { stopReorderPinned(); } - if (update.flags & UpdateFlag::NameChanged) { + if (update.flags & Data::HistoryUpdate::Flag::ChatOccupied) { this->update(); + _updated.fire({}); } - if (update.flags & (UpdateFlag::PhotoChanged | UpdateFlag::UserOccupiedChanged)) { + }, lifetime()); + + using UpdateFlag = Data::PeerUpdate::Flag; + session().changes().peerUpdates( + UpdateFlag::Name + | UpdateFlag::Photo + | UpdateFlag::IsContact + | UpdateFlag::Migration + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { + if (update.flags & (UpdateFlag::Name | UpdateFlag::Photo)) { this->update(); - emit controller->content()->dialogsUpdated(); + _updated.fire({}); } - if (update.flags & UpdateFlag::UserIsContact) { - if (update.peer->isUser()) { - // contactsNoChatsList could've changed. - Ui::PostponeCall(this, [=] { refresh(); }); - } + if (update.flags & UpdateFlag::IsContact) { + // contactsNoChatsList could've changed. + Ui::PostponeCall(this, [=] { refresh(); }); } - if (update.flags & UpdateFlag::MigrationChanged) { + if (update.flags & UpdateFlag::Migration) { if (const auto chat = update.peer->asChat()) { handleChatMigration(chat); } } - })); + }, lifetime()); _controller->activeChatEntryValue( ) | rpl::combine_previous( @@ -1498,7 +1502,7 @@ void InnerWidget::removeDialog(Key key) { refresh(); } - emit _controller->content()->dialogsUpdated(); + _updated.fire({}); refresh(); } @@ -1963,6 +1967,10 @@ auto InnerWidget::chosenRow() const -> rpl::producer { return _chosenRow.events(); } +rpl::producer<> InnerWidget::updated() const { + return _updated.events(); +} + rpl::producer<> InnerWidget::listBottomReached() const { return _listBottomReached.events(); } @@ -2948,16 +2956,15 @@ MsgId InnerWidget::lastSearchMigratedId() const { } void InnerWidget::setupOnlineStatusCheck() { - using namespace Notify; - subscribe(PeerUpdated(), PeerUpdatedHandler( - PeerUpdate::Flag::UserOnlineChanged, - [=](const PeerUpdate &update) { userOnlineUpdated(update); })); + session().changes().peerUpdates( + Data::PeerUpdate::Flag::OnlineStatus + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { + userOnlineUpdated(update.peer); + }, lifetime()); } -void InnerWidget::userOnlineUpdated(const Notify::PeerUpdate &update) { - const auto user = update.peer->isSelf() - ? nullptr - : update.peer->asUser(); +void InnerWidget::userOnlineUpdated(not_null peer) { + const auto user = peer->isSelf() ? nullptr : peer->asUser(); if (!user) { return; } diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 8028bd752..ad0824bbd 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -30,10 +30,6 @@ namespace Window { class SessionController; } // namespace Window -namespace Notify { -struct PeerUpdate; -} // namespace Notify - namespace Data { class CloudImageView; } // namespace Data @@ -131,7 +127,8 @@ public: base::Observable searchFromUserChanged; - rpl::producer chosenRow() const; + [[nodiscard]] rpl::producer chosenRow() const; + [[nodiscard]] rpl::producer<> updated() const; ~InnerWidget(); @@ -228,7 +225,7 @@ private: int defaultRowTop(not_null row) const; void setupOnlineStatusCheck(); - void userOnlineUpdated(const Notify::PeerUpdate &update); + void userOnlineUpdated(not_null peer); void setupShortcuts(); RowDescriptor computeJump( @@ -406,6 +403,7 @@ private: Fn _loadMoreCallback; rpl::event_stream<> _listBottomReached; rpl::event_stream _chosenRow; + rpl::event_stream<> _updated; base::unique_qptr _menu; diff --git a/Telegram/SourceFiles/dialogs/dialogs_main_list.cpp b/Telegram/SourceFiles/dialogs/dialogs_main_list.cpp index 168dcb7e2..6ce9ef020 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_main_list.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_main_list.cpp @@ -7,12 +7,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "dialogs/dialogs_main_list.h" -#include "observer_peer.h" +#include "data/data_changes.h" +#include "main/main_session.h" #include "history/history.h" namespace Dialogs { -MainList::MainList(FilterId filterId, rpl::producer pinnedLimit) +MainList::MainList( + not_null session, + FilterId filterId, + rpl::producer pinnedLimit) : _filterId(filterId) , _all(SortMode::Date, filterId) , _pinned(filterId, 1) { @@ -24,12 +28,9 @@ MainList::MainList(FilterId filterId, rpl::producer pinnedLimit) _pinned.setLimit(limit); }, _lifetime); - Notify::PeerUpdateViewer( - Notify::PeerUpdate::Flag::NameChanged - ) | rpl::start_with_next([=](const Notify::PeerUpdate &update) { - const auto peer = update.peer; - const auto &oldLetters = update.oldNameFirstLetters; - _all.peerNameChanged(_filterId, peer, oldLetters); + session->changes().realtimeNameUpdates( + ) | rpl::start_with_next([=](const Data::NameUpdate &update) { + _all.peerNameChanged(_filterId, update.peer, update.oldFirstLetters); }, _lifetime); } diff --git a/Telegram/SourceFiles/dialogs/dialogs_main_list.h b/Telegram/SourceFiles/dialogs/dialogs_main_list.h index c9ac27480..c9aef1edf 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_main_list.h +++ b/Telegram/SourceFiles/dialogs/dialogs_main_list.h @@ -10,11 +10,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "dialogs/dialogs_indexed_list.h" #include "dialogs/dialogs_pinned_list.h" +namespace Main { +class Session; +} // namespace Main + namespace Dialogs { class MainList final { public: - MainList(FilterId filterId, rpl::producer pinnedLimit); + MainList( + not_null session, + FilterId filterId, + rpl::producer pinnedLimit); bool empty() const; bool loaded() const; diff --git a/Telegram/SourceFiles/dialogs/dialogs_search_from_controllers.cpp b/Telegram/SourceFiles/dialogs/dialogs_search_from_controllers.cpp index 7f0206ace..770b6d759 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_search_from_controllers.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_search_from_controllers.cpp @@ -12,7 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_user.h" -#include "observer_peer.h" #include "main/main_session.h" #include "apiwrap.h" diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 824e84c0f..da73edb44 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -176,6 +176,11 @@ Widget::Widget( , _singleMessageSearch(&controller->session()) { _inner = _scroll->setOwnedWidget(object_ptr(this, controller)); + _inner->updated( + ) | rpl::start_with_next([=] { + onListScroll(); + }, lifetime()); + rpl::combine( session().api().dialogsLoadMayBlockByDate(), session().api().dialogsLoadBlockedByDate() @@ -183,6 +188,11 @@ Widget::Widget( refreshLoadMoreButton(mayBlock, isBlocked); }, lifetime()); + session().data().newMessageSent( + ) | rpl::start_with_next([=] { + jumpToTop(); + }, lifetime()); + fullSearchRefreshOn(session().settings().skipArchiveInSearchChanges( ) | rpl::map([] { return rpl::empty_value(); })); diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index af71ca3a1..d101f9df6 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -17,7 +17,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/platform/base_platform_info.h" #include "data/data_peer.h" #include "data/data_user.h" -#include "observer_peer.h" #include "mainwindow.h" #include "mainwidget.h" #include "apiwrap.h" @@ -338,7 +337,6 @@ namespace internal { struct Data { SingleQueuedInvokation HandleUnreadCounterUpdate = { [] { Core::App().call_handleUnreadCounterUpdate(); } }; - SingleQueuedInvokation HandleDelayedPeerUpdates = { [] { Core::App().call_handleDelayedPeerUpdates(); } }; Adaptive::WindowLayout AdaptiveWindowLayout = Adaptive::WindowLayout::Normal; Adaptive::ChatLayout AdaptiveChatLayout = Adaptive::ChatLayout::Normal; @@ -458,7 +456,6 @@ void finish() { } DefineRefVar(Global, SingleQueuedInvokation, HandleUnreadCounterUpdate); -DefineRefVar(Global, SingleQueuedInvokation, HandleDelayedPeerUpdates); DefineVar(Global, Adaptive::WindowLayout, AdaptiveWindowLayout); DefineVar(Global, Adaptive::ChatLayout, AdaptiveChatLayout); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index c913ab35a..7d5be71e5 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -145,7 +145,6 @@ void start(); void finish(); DeclareRefVar(SingleQueuedInvokation, HandleUnreadCounterUpdate); -DeclareRefVar(SingleQueuedInvokation, HandleDelayedPeerUpdates); DeclareVar(Adaptive::WindowLayout, AdaptiveWindowLayout); DeclareVar(Adaptive::ChatLayout, AdaptiveChatLayout); diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_section.h b/Telegram/SourceFiles/history/admin_log/history_admin_log_section.h index c9106674e..33a1b06c7 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_section.h +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_section.h @@ -12,10 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/admin_log/history_admin_log_item.h" #include "mtproto/sender.h" -namespace Notify { -struct PeerUpdate; -} // namespace Notify - namespace Ui { class ScrollArea; class PlainShadow; diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 1bef57046..79686904a 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "data/data_media_types.h" #include "data/data_channel_admins.h" +#include "data/data_changes.h" #include "data/data_chat_filters.h" #include "data/data_scheduled_messages.h" #include "data/data_folder.h" @@ -30,7 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "mainwidget.h" #include "mainwindow.h" -#include "observer_peer.h" #include "main/main_session.h" #include "window/notifications_manager.h" #include "calls/calls_instance.h" @@ -65,6 +65,8 @@ constexpr auto kSetMyActionForMs = 10000; constexpr auto kNewBlockEachMessage = 50; constexpr auto kSkipCloudDraftsFor = TimeId(3); +using UpdateFlag = Data::HistoryUpdate::Flag; + } // namespace History::History(not_null owner, PeerId peerId) @@ -874,7 +876,7 @@ void History::eraseFromUnreadMentions(MsgId msgId) { if (_unreadMentionsCount && *_unreadMentionsCount > 0) { setUnreadMentionsCount(*_unreadMentionsCount - 1); } - Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::UnreadMentionsChanged); + session().changes().historyUpdated(this, UpdateFlag::UnreadMentions); } void History::addUnreadMentionsSlice(const MTPmessages_Messages &result) { @@ -929,7 +931,7 @@ void History::addUnreadMentionsSlice(const MTPmessages_Messages &result) { count = _unreadMentions.size(); } setUnreadMentionsCount(count); - Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::UnreadMentionsChanged); + session().changes().historyUpdated(this, UpdateFlag::UnreadMentions); } not_null History::addNewToBack( @@ -987,7 +989,9 @@ not_null History::addNewToBack( lastAuthors->push_front(user); } if (auto megagroup = peer->asMegagroup()) { - Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); + session().changes().peerUpdated( + peer, + Data::PeerUpdate::Flag::Members); owner().addNewMegagroupParticipant(megagroup, user); } } @@ -1075,7 +1079,9 @@ void History::applyServiceChanges( if (const auto user = owner().userLoaded(userId.v)) { if (!base::contains(mgInfo->lastParticipants, user)) { mgInfo->lastParticipants.push_front(user); - Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); + session().changes().peerUpdated( + peer, + Data::PeerUpdate::Flag::Members); owner().addNewMegagroupParticipant(megagroup, user); } if (user->isBot()) { @@ -1097,7 +1103,9 @@ void History::applyServiceChanges( if (auto user = item->from()->asUser()) { if (!base::contains(mgInfo->lastParticipants, user)) { mgInfo->lastParticipants.push_front(user); - Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); + session().changes().peerUpdated( + peer, + Data::PeerUpdate::Flag::Members); owner().addNewMegagroupParticipant(megagroup, user); } if (user->isBot()) { @@ -1132,7 +1140,9 @@ void History::applyServiceChanges( [](not_null user) { return user.get(); }); if (i != mgInfo->lastParticipants.end()) { mgInfo->lastParticipants.erase(i); - Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); + session().changes().peerUpdated( + peer, + Data::PeerUpdate::Flag::Members); } owner().removeMegagroupParticipant(megagroup, user); if (megagroup->membersCount() > 1) { @@ -1146,7 +1156,9 @@ void History::applyServiceChanges( if (megagroup->adminsCount() > 1) { megagroup->setAdminsCount(megagroup->adminsCount() - 1); } - Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::AdminsChanged); + session().changes().peerUpdated( + peer, + Data::PeerUpdate::Flag::Admins); } mgInfo->bots.remove(user); if (mgInfo->bots.empty() && mgInfo->botStatus > 0) { @@ -1310,22 +1322,14 @@ void History::registerLocalMessage(not_null item) { Expects(IsClientMsgId(item->id)); _localMessages.emplace(item); - if (peer->isChannel()) { - Notify::peerUpdatedDelayed( - peer, - Notify::PeerUpdate::Flag::ChannelLocalMessages); - } + session().changes().historyUpdated(this, UpdateFlag::LocalMessages); } void History::unregisterLocalMessage(not_null item) { const auto removed = _localMessages.remove(item); Assert(removed); - if (peer->isChannel()) { - Notify::peerUpdatedDelayed( - peer, - Notify::PeerUpdate::Flag::ChannelLocalMessages); - } + session().changes().historyUpdated(this, UpdateFlag::LocalMessages); } HistoryItem *History::latestSendingMessage() const { @@ -1805,9 +1809,7 @@ void History::setUnreadCount(int newUnreadCount) { if (wasForBadge != (unreadCountForBadge() > 0)) { owner().chatsFilters().refreshHistory(this); } - Notify::peerUpdatedDelayed( - peer, - Notify::PeerUpdate::Flag::UnreadViewChanged); + session().changes().historyUpdated(this, UpdateFlag::UnreadView); }); const auto notifier = unreadStateChangeNotifier(true); _unreadCount = newUnreadCount; @@ -1844,9 +1846,7 @@ void History::setUnreadMark(bool unread) { owner().chatsFilters().refreshHistory(this); updateChatListEntry(); } - Notify::peerUpdatedDelayed( - peer, - Notify::PeerUpdate::Flag::UnreadViewChanged); + session().changes().historyUpdated(this, UpdateFlag::UnreadView); }); const auto notifier = unreadStateChangeNotifier(noUnreadMessages); _unreadMark = unread; @@ -1886,9 +1886,9 @@ bool History::changeMute(bool newMute) { owner().chatsFilters().refreshHistory(this); updateChatListEntry(); } - Notify::peerUpdatedDelayed( + session().changes().peerUpdated( peer, - Notify::PeerUpdate::Flag::NotificationsEnabled); + Data::PeerUpdate::Flag::Notifications); }); const auto notify = (unreadCountForBadge() > 0); const auto notifier = unreadStateChangeNotifier(notify); @@ -1986,9 +1986,7 @@ void History::setFolderPointer(Data::Folder *folder) { if (folder) { folder->registerOne(this); } - Notify::peerUpdatedDelayed( - peer, - Notify::PeerUpdate::Flag::FolderChanged); + session().changes().historyUpdated(this, UpdateFlag::Folder); } void History::applyPinnedUpdate(const MTPDupdateDialogPinned &data) { @@ -3294,9 +3292,7 @@ void History::applyGroupAdminChanges(const base::flat_set &changes) { } void History::changedChatListPinHook() { - Notify::peerUpdatedDelayed( - peer, - Notify::PeerUpdate::Flag::ChatPinnedChanged); + session().changes().historyUpdated(this, UpdateFlag::IsPinned); } void History::removeBlock(not_null block) { diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 354dd4f1f..f63774e09 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/crash_reports.h" #include "base/unixtime.h" #include "data/data_scheduled_messages.h" // kScheduledUntilOnlineTimestamp +#include "data/data_changes.h" #include "data/data_session.h" #include "data/data_messages.h" #include "data/data_media_types.h" @@ -41,7 +42,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_user.h" -#include "observer_peer.h" #include "facades.h" #include "styles/style_dialogs.h" #include "styles/style_history.h" @@ -725,11 +725,9 @@ void HistoryItem::sendFailed() { _clientFlags = (_clientFlags | MTPDmessage_ClientFlag::f_failed) & ~MTPDmessage_ClientFlag::f_sending; - if (history()->peer->isChannel()) { - Notify::peerUpdatedDelayed( - history()->peer, - Notify::PeerUpdate::Flag::ChannelLocalMessages); - } + history()->session().changes().historyUpdated( + history(), + Data::HistoryUpdate::Flag::LocalMessages); } bool HistoryItem::needCheck() const { diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index b05012e37..8e9baca51 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -32,9 +32,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "layout.h" #include "window/notifications_manager.h" #include "window/window_session_controller.h" -#include "observer_peer.h" #include "storage/storage_shared_media.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "data/data_game.h" #include "data/data_media_types.h" #include "data/data_channel.h" @@ -1152,9 +1152,9 @@ void HistoryMessage::contributeToSlowmode(TimeId realDate) { void HistoryMessage::addToUnreadMentions(UnreadMentionType type) { if (IsServerMsgId(id) && isUnreadMention()) { if (history()->addToUnreadMentions(id, type)) { - Notify::peerUpdatedDelayed( - history()->peer, - Notify::PeerUpdate::Flag::UnreadMentionsChanged); + history()->session().changes().historyUpdated( + history(), + Data::HistoryUpdate::Flag::UnreadMentions); } } } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 5bf028576..fdceb28da 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/event_filter.h" #include "base/unixtime.h" #include "base/call_delayed.h" +#include "data/data_changes.h" #include "data/data_drafts.h" #include "data/data_session.h" #include "data/data_web_page.h" @@ -78,7 +79,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "history/view/history_view_top_bar_widget.h" #include "history/view/history_view_contact_status.h" -#include "observer_peer.h" #include "base/qthelp_regex.h" #include "ui/widgets/popup_menu.h" #include "ui/text_options.h" @@ -162,9 +162,9 @@ object_ptr SetupDiscussButton( return history ? history->peer->asChannel() : nullptr; }) | rpl::map([=](ChannelData *channel) -> rpl::producer { if (channel && channel->isBroadcast()) { - return PeerUpdateValue( + return channel->session().changes().peerFlagsValue( channel, - Notify::PeerUpdate::Flag::ChannelLinkedChat + Data::PeerUpdate::Flag::ChannelLinkedChat ) | rpl::map([=] { return channel->linkedChat(); }); @@ -175,11 +175,19 @@ object_ptr SetupDiscussButton( ) | rpl::map([=](ChannelData *chat) -> rpl::producer> { if (chat) { - return PeerUpdateValue( - chat, - Notify::PeerUpdate::Flag::UnreadViewChanged - | Notify::PeerUpdate::Flag::NotificationsEnabled - | Notify::PeerUpdate::Flag::ChannelAmIn + using UpdateFlag = Data::PeerUpdate::Flag; + auto to_empty = rpl::map([=] { return rpl::empty_value(); }); + return rpl::merge( + chat->session().changes().historyUpdates( + Data::HistoryUpdate::Flag::UnreadView + ) | rpl::filter([=](const Data::HistoryUpdate &update) { + return (update.history->peer == chat); + }) | to_empty, + + chat->session().changes().peerFlagsValue( + chat, + UpdateFlag::Notifications | UpdateFlag::ChannelAmIn + ) | to_empty ) | rpl::map([=] { const auto history = chat->amIn() ? chat->owner().historyLoaded(chat) @@ -546,83 +554,111 @@ HistoryWidget::HistoryWidget( } }, lifetime()); + session().data().forwardDraftUpdates( + ) | rpl::filter([=](not_null history) { + return (_history == history.get()); + }) | rpl::start_with_next([=](not_null history) { + updateForwarding(); + }, lifetime()); + + session().data().newMessageSent( + ) | rpl::filter([=](not_null history) { + return (_history == history.get()); + }) | rpl::start_with_next([=] { + synteticScrollToY(_scroll->scrollTopMax()); + }, lifetime()); + subscribe(Media::Player::instance()->switchToNextNotifier(), [this](const Media::Player::Instance::Switch &pair) { if (pair.from.type() == AudioMsgId::Type::Voice) { scrollToCurrentVoiceMessage(pair.from.contextId(), pair.to); } }); - using UpdateFlag = Notify::PeerUpdate::Flag; - auto changes = UpdateFlag::RightsChanged - | UpdateFlag::UnreadMentionsChanged - | UpdateFlag::UnreadViewChanged - | UpdateFlag::MigrationChanged - | UpdateFlag::UnavailableReasonChanged - | UpdateFlag::PinnedMessageChanged - | UpdateFlag::TopPromotedChanged - | UpdateFlag::UserIsBlocked - | UpdateFlag::AdminsChanged - | UpdateFlag::MembersChanged - | UpdateFlag::UserOnlineChanged - | UpdateFlag::NotificationsEnabled + + session().changes().historyUpdates( + Data::HistoryUpdate::Flag::UnreadMentions + | Data::HistoryUpdate::Flag::UnreadView + | Data::HistoryUpdate::Flag::TopPromoted + | Data::HistoryUpdate::Flag::LocalMessages + ) | rpl::filter([=](const Data::HistoryUpdate &update) { + return (update.history->peer.get() == _peer); + }) | rpl::map([](const Data::HistoryUpdate &update) { + return update.flags; + }) | rpl::start_with_next([=](Data::HistoryUpdate::Flags flags) { + if (flags & Data::HistoryUpdate::Flag::LocalMessages) { + updateSendButtonType(); + } + if (flags & Data::HistoryUpdate::Flag::UnreadMentions) { + updateUnreadMentionsVisibility(); + } + if (flags & Data::HistoryUpdate::Flag::UnreadView) { + unreadCountUpdated(); + } + if (flags & Data::HistoryUpdate::Flag::TopPromoted) { + updateHistoryGeometry(); + updateControlsVisibility(); + updateControlsGeometry(); + this->update(); + } + }, lifetime()); + + using UpdateFlag = Data::PeerUpdate::Flag; + session().changes().peerUpdates( + UpdateFlag::Rights + | UpdateFlag::Migration + | UpdateFlag::UnavailableReason + | UpdateFlag::PinnedMessage + | UpdateFlag::IsBlocked + | UpdateFlag::Admins + | UpdateFlag::Members + | UpdateFlag::OnlineStatus + | UpdateFlag::Notifications | UpdateFlag::ChannelAmIn | UpdateFlag::ChannelLinkedChat - | UpdateFlag::ChannelSlowmode - | UpdateFlag::ChannelLocalMessages; - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(changes, [=](const Notify::PeerUpdate &update) { - if (update.peer == _peer) { - if (update.flags & UpdateFlag::RightsChanged) { - checkPreview(); - updateStickersByEmoji(); + | UpdateFlag::Slowmode + ) | rpl::filter([=](const Data::PeerUpdate &update) { + return (update.peer.get() == _peer); + }) | rpl::map([](const Data::PeerUpdate &update) { + return update.flags; + }) | rpl::start_with_next([=](Data::PeerUpdate::Flags flags) { + if (flags & UpdateFlag::Rights) { + checkPreview(); + updateStickersByEmoji(); + } + if (flags & UpdateFlag::Migration) { + handlePeerMigration(); + } + if (flags & UpdateFlag::Notifications) { + updateNotifyControls(); + } + if (flags & UpdateFlag::UnavailableReason) { + const auto unavailable = _peer->computeUnavailableReason(); + if (!unavailable.isEmpty()) { + controller->showBackFromStack(); + Ui::show(Box(unavailable)); + return; } - if (update.flags & UpdateFlag::UnreadMentionsChanged) { - updateUnreadMentionsVisibility(); - } - if (update.flags & UpdateFlag::UnreadViewChanged) { - unreadCountUpdated(); - } - if (update.flags & UpdateFlag::MigrationChanged) { - handlePeerMigration(); - } - if (update.flags & UpdateFlag::NotificationsEnabled) { - updateNotifyControls(); - } - if (update.flags & UpdateFlag::UnavailableReasonChanged) { - const auto unavailable = _peer->computeUnavailableReason(); - if (!unavailable.isEmpty()) { - controller->showBackFromStack(); - Ui::show(Box(unavailable)); - return; - } - } - if (update.flags & UpdateFlag::PinnedMessageChanged) { - if (pinnedMsgVisibilityUpdated()) { - updateHistoryGeometry(); - updateControlsVisibility(); - updateControlsGeometry(); - this->update(); - } - } - if (update.flags & UpdateFlag::TopPromotedChanged) { + } + if (flags & UpdateFlag::PinnedMessage) { + if (pinnedMsgVisibilityUpdated()) { updateHistoryGeometry(); updateControlsVisibility(); updateControlsGeometry(); this->update(); } - if (update.flags & (UpdateFlag::ChannelSlowmode - | UpdateFlag::ChannelLocalMessages)) { - updateSendButtonType(); - } - if (update.flags & (UpdateFlag::UserIsBlocked - | UpdateFlag::AdminsChanged - | UpdateFlag::MembersChanged - | UpdateFlag::UserOnlineChanged - | UpdateFlag::RightsChanged - | UpdateFlag::ChannelAmIn - | UpdateFlag::ChannelLinkedChat)) { - handlePeerUpdate(); - } } - })); + if (flags & UpdateFlag::Slowmode) { + updateSendButtonType(); + } + if (flags & (UpdateFlag::IsBlocked + | UpdateFlag::Admins + | UpdateFlag::Members + | UpdateFlag::OnlineStatus + | UpdateFlag::Rights + | UpdateFlag::ChannelAmIn + | UpdateFlag::ChannelLinkedChat)) { + handlePeerUpdate(); + } + }, lifetime()); rpl::merge( session().data().defaultUserNotifyUpdates(), @@ -1074,7 +1110,7 @@ void HistoryWidget::onHashtagOrBotCommandInsert( // Send bot command at once, if it was not inserted by pressing Tab. if (str.at(0) == '/' && method != FieldAutocomplete::ChooseMethod::ByTab) { App::sendBotCommand(_peer, nullptr, str, replyToId()); - controller()->content()->finishForwarding(Api::SendAction(_history)); + session().api().finishForwarding(Api::SendAction(_history)); setFieldText(_field->getTextWithTagsPart(_field->textCursor().position())); } else { _field->insertTag(str); @@ -2381,16 +2417,6 @@ void HistoryWidget::unreadMessageAdded(not_null item) { session().notifications().clearFromHistory(_history); } -void HistoryWidget::historyToDown(History *history) { - history->forgetScrollState(); - if (auto migrated = history->owner().historyLoaded(history->peer->migrateFrom())) { - migrated->forgetScrollState(); - } - if (history == _history) { - synteticScrollToY(_scroll->scrollTopMax()); - } -} - void HistoryWidget::unreadCountUpdated() { if (_history->chatListUnreadMark()) { crl::on_main(this, [=, history = _history] { @@ -3151,8 +3177,7 @@ void HistoryWidget::send(Api::SendOptions options) { if (!_keyboard->hasMarkup() && _keyboard->forceReply() && !_kbReplyTo) { toggleKeyboard(); } - controller()->content()->historyToDown(_history); - controller()->content()->dialogsToUp(); + session().data().newMessageSent(_history); } void HistoryWidget::sendWithModifiers(Qt::KeyboardModifiers modifiers) { @@ -4093,6 +4118,9 @@ void HistoryWidget::setMembersShowAreaActive(bool active) { } void HistoryWidget::onMembersDropdownShow() { + if (!_peer) { + return; + } if (!_membersDropdown) { _membersDropdown.create(this, st::membersInnerDropdown); _membersDropdown->setOwnedWidget(object_ptr(this, _peer, st::membersInnerItem)); @@ -4856,10 +4884,7 @@ void HistoryWidget::sendFileConfirmed( } session().data().sendHistoryChangeNotifications(); - if (_peer && file->to.peer == _peer->id) { - controller()->content()->historyToDown(_history); - } - controller()->content()->dialogsToUp(); + session().data().newMessageSent(history); } void HistoryWidget::photoUploaded( @@ -5591,7 +5616,7 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) { } else if (_inReplyEditForward) { if (readyToForward()) { const auto items = std::move(_toForward); - controller()->content()->cancelForwarding(_history); + session().data().cancelForwarding(_history); auto list = ranges::view::all( items ) | ranges::view::transform( @@ -6049,7 +6074,7 @@ void HistoryWidget::replyToMessage(not_null item) { return; } - controller()->content()->cancelForwarding(_history); + session().data().cancelForwarding(_history); if (_editMsgId) { if (auto localDraft = _history->localDraft()) { @@ -6317,7 +6342,7 @@ void HistoryWidget::cancelFieldAreaState() { } else if (_editMsgId) { cancelEdit(); } else if (readyToForward()) { - controller()->content()->cancelForwarding(_history); + session().data().cancelForwarding(_history); } else if (_replyToId) { cancelReply(); } else if (_kbReplyTo) { diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 3815789de..021064db3 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -135,8 +135,6 @@ public: void firstLoadMessages(); void delayedShowAt(MsgId showAtMsgId); - void historyToDown(History *history); - QRect historyRect() const; void updateFieldPlaceholder(); diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h index 146059209..124b7acef 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h @@ -22,10 +22,6 @@ namespace Api { struct SendOptions; } // namespace Api -namespace Notify { -struct PeerUpdate; -} // namespace Notify - namespace Storage { struct PreparedList; } // namespace Storage diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index c1e26fd35..4d2fc67d8 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -35,9 +35,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_user.h" +#include "data/data_changes.h" #include "base/unixtime.h" #include "support/support_helper.h" -#include "observer_peer.h" #include "apiwrap.h" #include "facades.h" #include "styles/style_window.h" @@ -113,20 +113,22 @@ TopBarWidget::TopBarWidget( }, lifetime()); } - using UpdateFlag = Notify::PeerUpdate::Flag; - auto flags = UpdateFlag::UserHasCalls - | UpdateFlag::UserOnlineChanged - | UpdateFlag::MembersChanged - | UpdateFlag::UserSupportInfoChanged; - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(flags, [=](const Notify::PeerUpdate &update) { - if (update.flags & UpdateFlag::UserHasCalls) { + using UpdateFlag = Data::PeerUpdate::Flag; + session().changes().peerUpdates( + UpdateFlag::HasCalls + | UpdateFlag::OnlineStatus + | UpdateFlag::Members + | UpdateFlag::SupportInfo + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { + if (update.flags & UpdateFlag::HasCalls) { if (update.peer->isUser()) { updateControlsVisibility(); } } else { updateOnlineDisplay(); } - })); + }, lifetime()); + subscribe(Global::RefPhoneCallsEnabledChanged(), [this] { updateControlsVisibility(); }); @@ -286,7 +288,7 @@ bool TopBarWidget::eventFilter(QObject *obj, QEvent *e) { break; } } - return TWidget::eventFilter(obj, e); + return RpWidget::eventFilter(obj, e); } int TopBarWidget::resizeGetHeight(int newWidth) { diff --git a/Telegram/SourceFiles/info/info_controller.cpp b/Telegram/SourceFiles/info/info_controller.cpp index d56199634..1de01a4f7 100644 --- a/Telegram/SourceFiles/info/info_controller.cpp +++ b/Telegram/SourceFiles/info/info_controller.cpp @@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/info_content_widget.h" #include "info/info_memento.h" #include "info/media/info_media_widget.h" -#include "observer_peer.h" +#include "data/data_changes.h" #include "data/data_peer.h" #include "data/data_channel.h" #include "data/data_chat.h" @@ -153,22 +153,22 @@ void Controller::setupMigrationViewer() { if (!peer || (!peer->isChat() && !peer->isChannel()) || _migrated) { return; } - Notify::PeerUpdateValue( + peer->session().changes().peerFlagsValue( peer, - Notify::PeerUpdate::Flag::MigrationChanged - ) | rpl::start_with_next([=] { - if (peer->migrateTo() || (peer->migrateFrom() != _migrated)) { - const auto window = parentController(); - const auto section = _section; - InvokeQueued(_widget, [=] { - window->showSection( - Memento(peer, section), - Window::SectionShow( - Window::SectionShow::Way::Backward, - anim::type::instant, - anim::activation::background)); - }); - } + Data::PeerUpdate::Flag::Migration + ) | rpl::filter([=] { + return peer->migrateTo() || (peer->migrateFrom() != _migrated); + }) | rpl::start_with_next([=] { + const auto window = parentController(); + const auto section = _section; + InvokeQueued(_widget, [=] { + window->showSection( + Memento(peer, section), + Window::SectionShow( + Window::SectionShow::Way::Backward, + anim::type::instant, + anim::activation::background)); + }); }, lifetime()); } diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index 32dda9bd2..c6bac04d4 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/confirm_box.h" #include "main/main_session.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "data/data_user.h" #include "mainwidget.h" #include "lang/lang_keys.h" @@ -482,9 +483,9 @@ void WrapWidget::addProfileCallsButton() { return; } - Notify::PeerUpdateValue( + user->session().changes().peerFlagsValue( user, - Notify::PeerUpdate::Flag::UserHasCalls + Data::PeerUpdate::Flag::HasCalls ) | rpl::filter([=] { return user->hasCalls(); }) | rpl::take( diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index dee907f16..d3c704820 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "data/data_folder.h" #include "data/data_channel.h" +#include "data/data_changes.h" #include "data/data_user.h" #include "ui/wrap/vertical_layout.h" #include "ui/wrap/padding_wrap.h" @@ -556,9 +557,9 @@ void ActionsFiller::addBotCommandActions(not_null user) { return QString(); }; auto hasBotCommandValue = [=](const QString &command) { - return Notify::PeerUpdateValue( + return user->session().changes().peerFlagsValue( user, - Notify::PeerUpdate::Flag::BotCommandsChanged + Data::PeerUpdate::Flag::BotCommands ) | rpl::map([=] { return !findBotCommand(command).isEmpty(); }); @@ -597,10 +598,10 @@ void ActionsFiller::addReportAction() { void ActionsFiller::addBlockAction(not_null user) { const auto window = &_controller->parentController()->window(); - auto text = Notify::PeerUpdateValue( + auto text = user->session().changes().peerFlagsValue( user, - Notify::PeerUpdate::Flag::UserIsBlocked - ) | rpl::map([user] { + Data::PeerUpdate::Flag::IsBlocked + ) | rpl::map([=] { switch (user->blockStatus()) { case UserData::BlockStatus::Blocked: return ((user->isBot() && !user->isSupport()) diff --git a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp index 61f1d839a..ad7e4cd0a 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_peer_values.h" #include "data/data_channel.h" #include "data/data_chat.h" +#include "data/data_changes.h" #include "info/profile/info_profile_values.h" #include "info/info_controller.h" #include "info/info_memento.h" @@ -24,7 +25,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/unread_badge.h" #include "base/unixtime.h" #include "window/window_session_controller.h" -#include "observer_peer.h" #include "core/application.h" #include "main/main_session.h" #include "apiwrap.h" @@ -298,7 +298,7 @@ Cover *Cover::setOnlineCount(rpl::producer &&count) { } void Cover::initViewers(rpl::producer title) { - using Flag = Notify::PeerUpdate::Flag; + using Flag = Data::PeerUpdate::Flag; std::move( title ) | rpl::start_with_next([=](const QString &title) { @@ -306,16 +306,16 @@ void Cover::initViewers(rpl::producer title) { refreshNameGeometry(width()); }, lifetime()); - Notify::PeerUpdateValue( + _peer->session().changes().peerFlagsValue( _peer, - Flag::UserOnlineChanged | Flag::MembersChanged + Flag::OnlineStatus | Flag::Members ) | rpl::start_with_next( [=] { refreshStatusText(); }, lifetime()); if (!_peer->isUser()) { - Notify::PeerUpdateValue( + _peer->session().changes().peerFlagsValue( _peer, - Flag::RightsChanged + Flag::Rights ) | rpl::start_with_next( [=] { refreshUploadPhotoOverlay(); }, lifetime()); diff --git a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp index 5c243d304..0cbb70afc 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp @@ -15,7 +15,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "main/main_session.h" #include "mainwidget.h" -#include "observer_peer.h" #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_user.h" diff --git a/Telegram/SourceFiles/info/profile/info_profile_values.cpp b/Telegram/SourceFiles/info/profile/info_profile_values.cpp index 19ff33713..9fdd180ef 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_values.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_values.cpp @@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "info/profile/info_profile_values.h" -#include "observer_peer.h" #include "core/application.h" #include "main/main_session.h" #include "ui/wrap/slide_wrap.h" @@ -16,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_peer_values.h" #include "data/data_shared_media.h" #include "data/data_folder.h" +#include "data/data_changes.h" #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_user.h" @@ -27,17 +27,21 @@ namespace Info { namespace Profile { namespace { +using UpdateFlag = Data::PeerUpdate::Flag; + auto PlainBioValue(not_null user) { - return Notify::PeerUpdateValue( + return user->session().changes().peerFlagsValue( user, - Notify::PeerUpdate::Flag::AboutChanged - ) | rpl::map([=] { return user->about(); }); + UpdateFlag::About + ) | rpl::map([=] { + return user->about(); + }); } auto PlainUsernameValue(not_null peer) { - return Notify::PeerUpdateValue( + return peer->session().changes().peerFlagsValue( peer, - Notify::PeerUpdate::Flag::UsernameChanged + UpdateFlag::Username ) | rpl::map([=] { return peer->userName(); }); @@ -46,19 +50,19 @@ auto PlainUsernameValue(not_null peer) { } // namespace rpl::producer NameValue(not_null peer) { - return Notify::PeerUpdateValue( + return peer->session().changes().peerFlagsValue( peer, - Notify::PeerUpdate::Flag::NameChanged + UpdateFlag::Name ) | rpl::map([=] { return peer->name; - }) | Ui::Text::ToWithEntities(); + }) | Ui::Text::ToWithEntities();; } rpl::producer PhoneValue(not_null user) { - return Notify::PeerUpdateValue( - user, - Notify::PeerUpdate::Flag::UserPhoneChanged - ) | rpl::map([user] { + return user->session().changes().peerFlagsValue( + user, + UpdateFlag::PhoneNumber + ) | rpl::map([=] { return App::formatPhone(user->phone()); }) | Ui::Text::ToWithEntities(); } @@ -102,10 +106,12 @@ rpl::producer PlainAboutValue(not_null peer) { return rpl::single(QString()); } } - return Notify::PeerUpdateValue( + return peer->session().changes().peerFlagsValue( peer, - Notify::PeerUpdate::Flag::AboutChanged - ) | rpl::map([=] { return peer->about(); }); + UpdateFlag::About + ) | rpl::map([=] { + return peer->about(); + }); } rpl::producer AboutValue(not_null peer) { @@ -136,9 +142,9 @@ rpl::producer LinkValue(not_null peer) { rpl::producer LocationValue( not_null channel) { - return Notify::PeerUpdateValue( + return channel->session().changes().peerFlagsValue( channel, - Notify::PeerUpdate::Flag::ChannelLocation + UpdateFlag::ChannelLocation ) | rpl::map([=] { return channel->getLocation(); }); @@ -146,9 +152,9 @@ rpl::producer LocationValue( rpl::producer NotificationsEnabledValue(not_null peer) { return rpl::merge( - Notify::PeerUpdateValue( + peer->session().changes().peerFlagsValue( peer, - Notify::PeerUpdate::Flag::NotificationsEnabled + UpdateFlag::Notifications ) | rpl::map([] { return rpl::empty_value(); }), peer->owner().defaultNotifyUpdates(peer) ) | rpl::map([=] { @@ -157,29 +163,31 @@ rpl::producer NotificationsEnabledValue(not_null peer) { } rpl::producer IsContactValue(not_null user) { - return Notify::PeerUpdateValue( - user, - Notify::PeerUpdate::Flag::UserIsContact - ) | rpl::map([user] { return user->isContact(); }); + return user->session().changes().peerFlagsValue( + user, + UpdateFlag::IsContact + ) | rpl::map([=] { + return user->isContact(); + }); } rpl::producer CanInviteBotToGroupValue(not_null user) { if (!user->isBot() || user->isSupport()) { return rpl::single(false); } - return Notify::PeerUpdateValue( - user, - Notify::PeerUpdate::Flag::BotCanAddToGroups - ) | rpl::map([user] { + return user->session().changes().peerFlagsValue( + user, + UpdateFlag::BotCanBeInvited + ) | rpl::map([=] { return !user->botInfo->cantJoinGroups; }); } rpl::producer CanShareContactValue(not_null user) { - return Notify::PeerUpdateValue( - user, - Notify::PeerUpdate::Flag::UserCanShareContact - ) | rpl::map([user] { + return user->session().changes().peerFlagsValue( + user, + UpdateFlag::CanShareContact + ) | rpl::map([=] { return user->canShareThisContact(); }); } @@ -195,28 +203,29 @@ rpl::producer CanAddContactValue(not_null user) { } rpl::producer AmInChannelValue(not_null channel) { - return Notify::PeerUpdateValue( + return channel->session().changes().peerFlagsValue( channel, - Notify::PeerUpdate::Flag::ChannelAmIn - ) | rpl::map([channel] { return channel->amIn(); }); + UpdateFlag::ChannelAmIn + ) | rpl::map([=] { + return channel->amIn(); + }); } rpl::producer MembersCountValue(not_null peer) { - using Flag = Notify::PeerUpdate::Flag; if (const auto chat = peer->asChat()) { - return Notify::PeerUpdateValue( + return peer->session().changes().peerFlagsValue( peer, - Flag::MembersChanged - ) | rpl::map([chat] { + UpdateFlag::Members + ) | rpl::map([=] { return chat->amIn() ? std::max(chat->count, int(chat->participants.size())) : 0; }); } else if (const auto channel = peer->asChannel()) { - return Notify::PeerUpdateValue( - channel, - Flag::MembersChanged - ) | rpl::map([channel] { + return peer->session().changes().peerFlagsValue( + peer, + UpdateFlag::Members + ) | rpl::map([=] { return channel->membersCount(); }); } @@ -224,20 +233,19 @@ rpl::producer MembersCountValue(not_null peer) { } rpl::producer AdminsCountValue(not_null peer) { - using Flag = Notify::PeerUpdate::Flag; if (const auto chat = peer->asChat()) { - return Notify::PeerUpdateValue( - chat, - Flag::AdminsChanged | Flag::RightsChanged + return peer->session().changes().peerFlagsValue( + peer, + UpdateFlag::Admins | UpdateFlag::Rights ) | rpl::map([=] { return chat->participants.empty() ? 0 : int(chat->admins.size() + 1); // + creator }); } else if (const auto channel = peer->asChannel()) { - return Notify::PeerUpdateValue( - channel, - Flag::AdminsChanged | Flag::RightsChanged + return peer->session().changes().peerFlagsValue( + peer, + UpdateFlag::Admins | UpdateFlag::Rights ) | rpl::map([=] { return channel->canViewAdmins() ? channel->adminsCount() @@ -257,18 +265,17 @@ rpl::producer RestrictionsCountValue(not_null peer) { return int(Data::ListOfRestrictions().size()) - count; }; - using Flag = Notify::PeerUpdate::Flag; if (const auto chat = peer->asChat()) { - return Notify::PeerUpdateValue( - chat, - Flag::RightsChanged + return peer->session().changes().peerFlagsValue( + peer, + UpdateFlag::Rights ) | rpl::map([=] { return countOfRestrictions(chat->defaultRestrictions()); }); } else if (const auto channel = peer->asChannel()) { - return Notify::PeerUpdateValue( - channel, - Flag::RightsChanged + return peer->session().changes().peerFlagsValue( + peer, + UpdateFlag::Rights ) | rpl::map([=] { return countOfRestrictions(channel->defaultRestrictions()); }); @@ -278,11 +285,10 @@ rpl::producer RestrictionsCountValue(not_null peer) { rpl::producer> MigratedOrMeValue( not_null peer) { - using Flag = Notify::PeerUpdate::Flag; if (const auto chat = peer->asChat()) { - return Notify::PeerUpdateValue( - chat, - Flag::MigrationChanged + return peer->session().changes().peerFlagsValue( + peer, + UpdateFlag::Migration ) | rpl::map([=] { return chat->migrateToOrMe(); }); @@ -292,10 +298,9 @@ rpl::producer> MigratedOrMeValue( } rpl::producer RestrictedCountValue(not_null channel) { - using Flag = Notify::PeerUpdate::Flag; - return Notify::PeerUpdateValue( + return channel->session().changes().peerFlagsValue( channel, - Flag::BannedUsersChanged | Flag::RightsChanged + UpdateFlag::BannedUsers | UpdateFlag::Rights ) | rpl::map([=] { return channel->canViewBanned() ? channel->restrictedCount() @@ -304,10 +309,9 @@ rpl::producer RestrictedCountValue(not_null channel) { } rpl::producer KickedCountValue(not_null channel) { - using Flag = Notify::PeerUpdate::Flag; - return Notify::PeerUpdateValue( + return channel->session().changes().peerFlagsValue( channel, - Flag::BannedUsersChanged | Flag::RightsChanged + UpdateFlag::BannedUsers | UpdateFlag::Rights ) | rpl::map([=] { return channel->canViewBanned() ? channel->kickedCount() @@ -338,26 +342,26 @@ rpl::producer SharedMediaCountValue( } rpl::producer CommonGroupsCountValue(not_null user) { - return Notify::PeerUpdateValue( + return user->session().changes().peerFlagsValue( user, - Notify::PeerUpdate::Flag::UserCommonChatsChanged - ) | rpl::map([user] { + UpdateFlag::CommonChats + ) | rpl::map([=] { return user->commonChatsCount(); }); } rpl::producer CanAddMemberValue(not_null peer) { if (const auto chat = peer->asChat()) { - return Notify::PeerUpdateValue( - chat, - Notify::PeerUpdate::Flag::RightsChanged + return peer->session().changes().peerFlagsValue( + peer, + UpdateFlag::Rights ) | rpl::map([=] { return chat->canAddMembers(); }); } else if (const auto channel = peer->asChannel()) { - return Notify::PeerUpdateValue( - channel, - Notify::PeerUpdate::Flag::RightsChanged + return peer->session().changes().peerFlagsValue( + peer, + UpdateFlag::Rights ) | rpl::map([=] { return channel->canAddMembers(); }); diff --git a/Telegram/SourceFiles/info/profile/info_profile_values.h b/Telegram/SourceFiles/info/profile/info_profile_values.h index 39bd89d83..2601d690d 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_values.h +++ b/Telegram/SourceFiles/info/profile/info_profile_values.h @@ -9,7 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include -#include "observer_peer.h" struct ChannelLocation; diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp index 225b5f471..5c865404b 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" #include "data/data_session.h" #include "data/data_file_origin.h" +#include "data/data_changes.h" #include "ui/widgets/buttons.h" #include "ui/widgets/shadow.h" #include "ui/effects/ripple_animation.h" @@ -29,7 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_session_controller.h" #include "ui/widgets/scroll_area.h" #include "ui/widgets/labels.h" -#include "observer_peer.h" #include "history/view/history_view_cursor_state.h" #include "facades.h" #include "app.h" @@ -49,7 +49,7 @@ constexpr auto kInlineBotRequestDelay = 400; Inner::Inner( QWidget *parent, not_null controller) -: TWidget(parent) +: RpWidget(parent) , _controller(controller) , _updateInlineItems([=] { updateInlineItems(); }) , _previewTimer([=] { showPreview(); }) { @@ -66,15 +66,18 @@ Inner::Inner( update(); } }); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::RightsChanged, [this](const Notify::PeerUpdate &update) { - if (update.peer == _inlineQueryPeer) { - auto isRestricted = (_restrictedLabel != nullptr); - if (isRestricted != isRestrictedView()) { - auto h = countHeight(); - if (h != height()) resize(width(), h); - } + + _controller->session().changes().peerUpdates( + Data::PeerUpdate::Flag::Rights + ) | rpl::filter([=](const Data::PeerUpdate &update) { + return (update.peer.get() == _inlineQueryPeer); + }) | rpl::start_with_next([=] { + auto isRestricted = (_restrictedLabel != nullptr); + if (isRestricted != isRestrictedView()) { + auto h = countHeight(); + if (h != height()) resize(width(), h); } - })); + }, lifetime()); } void Inner::visibleTopBottomUpdated( diff --git a/Telegram/SourceFiles/inline_bots/inline_results_widget.h b/Telegram/SourceFiles/inline_bots/inline_results_widget.h index c2e93dbe3..a86cda86a 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_widget.h +++ b/Telegram/SourceFiles/inline_bots/inline_results_widget.h @@ -25,7 +25,7 @@ class LinkButton; class RoundButton; class FlatLabel; class RippleAnimation; -} // namesapce Ui +} // namespace Ui namespace Window { class SessionController; @@ -52,7 +52,7 @@ struct CacheEntry { }; class Inner - : public TWidget + : public Ui::RpWidget , public Ui::AbstractTooltipShower , public Context , private base::Subscriber { diff --git a/Telegram/SourceFiles/main/main_account.cpp b/Telegram/SourceFiles/main/main_account.cpp index 73a70fdf3..3fa341200 100644 --- a/Telegram/SourceFiles/main/main_account.cpp +++ b/Telegram/SourceFiles/main/main_account.cpp @@ -15,11 +15,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/localstorage.h" #include "data/data_session.h" #include "data/data_user.h" +#include "data/data_changes.h" #include "window/window_controller.h" #include "media/audio/media_audio.h" #include "ui/image/image.h" #include "mainwidget.h" -#include "observer_peer.h" #include "api/api_updates.h" #include "main/main_app_config.h" #include "main/main_session.h" @@ -377,7 +377,7 @@ void Account::startMtp() { if (sessionExists()) { // Skip all pending self updates so that we won't local().writeSelf. - Notify::peerUpdatedSendDelayed(); + session().changes().sendNotifications(); } _mtpValue = _mtp.get(); diff --git a/Telegram/SourceFiles/main/main_session.cpp b/Telegram/SourceFiles/main/main_session.cpp index 82295708e..3e77a141a 100644 --- a/Telegram/SourceFiles/main/main_session.cpp +++ b/Telegram/SourceFiles/main/main_session.cpp @@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/storage_facade.h" #include "storage/storage_account.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "data/data_user.h" #include "window/notifications_manager.h" #include "window/window_session_controller.h" @@ -28,7 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL //#include "platform/platform_specific.h" #include "calls/calls_instance.h" #include "support/support_helper.h" -#include "observer_peer.h" #include "facades.h" #ifndef TDESKTOP_DISABLE_SPELLCHECK @@ -56,6 +56,7 @@ Session::Session( , _uploader(std::make_unique(_api.get())) , _storage(std::make_unique()) , _notifications(std::make_unique(this)) +, _changes(std::make_unique(this)) , _data(std::make_unique(this)) , _user(_data->processUser(user)) , _emojiStickersPack(std::make_unique(this)) @@ -74,21 +75,17 @@ Session::Session( _api->requestFullPeer(_user); crl::on_main(this, [=] { - using Flag = Notify::PeerUpdate::Flag; - const auto events = Flag::NameChanged - | Flag::UsernameChanged - | Flag::PhotoChanged - | Flag::AboutChanged - | Flag::UserPhoneChanged; - subscribe( - Notify::PeerUpdated(), - Notify::PeerUpdatedHandler( - events, - [=](const Notify::PeerUpdate &update) { - if (update.peer == _user) { - local().writeSelf(); - } - })); + using Flag = Data::PeerUpdate::Flag; + changes().peerUpdates( + _user, + Flag::Name + | Flag::Username + | Flag::Photo + | Flag::About + | Flag::PhoneNumber + ) | rpl::start_with_next([=] { + local().writeSelf(); + }, _lifetime); if (_settings.hadLegacyCallsPeerToPeerNobody()) { api().savePrivacy( diff --git a/Telegram/SourceFiles/main/main_session.h b/Telegram/SourceFiles/main/main_session.h index bb71e4998..710e071f8 100644 --- a/Telegram/SourceFiles/main/main_session.h +++ b/Telegram/SourceFiles/main/main_session.h @@ -30,6 +30,7 @@ class Templates; namespace Data { class Session; +class Changes; } // namespace Data namespace Storage { @@ -104,11 +105,12 @@ public: [[nodiscard]] Stickers::DicePacks &diceStickersPacks() const { return *_diceStickersPacks; } - [[nodiscard]] Window::Notifications::System ¬ifications() { return *_notifications; } - + [[nodiscard]] Data::Changes &changes() { + return *_changes; + } [[nodiscard]] Data::Session &data() { return *_data; } @@ -164,6 +166,7 @@ private: const std::unique_ptr _notifications; // _data depends on _downloader / _uploader / _notifications. + const std::unique_ptr _changes; const std::unique_ptr _data; const not_null _user; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 44f0e04db..13e4a01de 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -47,7 +47,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "chat_helpers/message_field.h" #include "info/info_memento.h" #include "info/info_controller.h" -#include "observer_peer.h" #include "apiwrap.h" #include "dialogs/dialogs_widget.h" #include "dialogs/dialogs_key.h" @@ -241,9 +240,9 @@ MainWidget::MainWidget( }, lifetime()); // Load current userpic and keep it loaded. - Notify::PeerUpdateValue( + session().changes().peerFlagsValue( session().user(), - Notify::PeerUpdate::Flag::PhotoChanged + Data::PeerUpdate::Flag::Photo ) | rpl::start_with_next([=] { [[maybe_unused]] const auto image = session().user()->currentUserpic( _selfUserpicView); @@ -253,7 +252,6 @@ MainWidget::MainWidget( setupConnectingWidget(); connect(_dialogs, SIGNAL(cancelled()), this, SLOT(dialogsCancelled())); - connect(this, SIGNAL(dialogsUpdated()), _dialogs, SLOT(onListScroll())); connect(_history, &HistoryWidget::cancelled, [=] { handleHistoryBack(); }); Media::Player::instance()->updatedNotifier( @@ -283,6 +281,16 @@ MainWidget::MainWidget( [this] { updateControlsGeometry(); }, lifetime()); + session().data().newMessageSent( + ) | rpl::start_with_next([=](not_null history) { + history->forgetScrollState(); + if (const auto from = history->peer->migrateFrom()) { + if (const auto migrated = history->owner().historyLoaded(from)) { + migrated->forgetScrollState(); + } + } + }, lifetime()); + // MSVC BUG + REGRESSION rpl::mappers::tuple :( using namespace rpl::mappers; _controller->activeChatValue( @@ -542,29 +550,6 @@ bool MainWidget::inlineSwitchChosen(PeerId peerId, const QString &botAndQuery) { return true; } -void MainWidget::cancelForwarding(not_null history) { - history->setForwardDraft({}); - _history->updateForwarding(); -} - -void MainWidget::finishForwarding(Api::SendAction action) { - const auto history = action.history; - auto toForward = history->validateForwardDraft(); - if (!toForward.empty()) { - const auto error = GetErrorTextForSending(history->peer, toForward); - if (!error.isEmpty()) { - return; - } - - session().api().forwardMessages(std::move(toForward), action); - cancelForwarding(history); - } - - session().data().sendHistoryChangeNotifications(); - historyToDown(history); - dialogsToUp(); -} - bool MainWidget::sendPaths(PeerId peerId) { Expects(peerId != 0); @@ -1989,10 +1974,6 @@ void MainWidget::windowShown() { _history->windowShown(); } -void MainWidget::historyToDown(History *history) { - _history->historyToDown(history); -} - void MainWidget::dialogsToUp() { _dialogs->jumpToTop(); } @@ -2775,120 +2756,6 @@ void MainWidget::usernameResolveFail(const RPCError &error, const QString &usern } } -void MainWidget::incrementSticker(DocumentData *sticker) { - if (!sticker - || !sticker->sticker() - || sticker->sticker()->set.type() == mtpc_inputStickerSetEmpty) { - return; - } - - bool writeRecentStickers = false; - auto &sets = session().data().stickers().setsRef(); - auto it = sets.find(Data::Stickers::CloudRecentSetId); - if (it == sets.cend()) { - if (it == sets.cend()) { - it = sets.emplace( - Data::Stickers::CloudRecentSetId, - std::make_unique( - &session().data(), - Data::Stickers::CloudRecentSetId, - uint64(0), - tr::lng_recent_stickers(tr::now), - QString(), - 0, // count - 0, // hash - MTPDstickerSet_ClientFlag::f_special | 0, - TimeId(0))).first; - } else { - it->second->title = tr::lng_recent_stickers(tr::now); - } - } - const auto set = it->second.get(); - auto removedFromEmoji = std::vector>(); - auto index = set->stickers.indexOf(sticker); - if (index > 0) { - if (set->dates.empty()) { - session().api().requestRecentStickersForce(); - } else { - Assert(set->dates.size() == set->stickers.size()); - set->dates.erase(set->dates.begin() + index); - } - set->stickers.removeAt(index); - for (auto i = set->emoji.begin(); i != set->emoji.end();) { - if (const auto index = i->indexOf(sticker); index >= 0) { - removedFromEmoji.emplace_back(i.key()); - i->removeAt(index); - if (i->isEmpty()) { - i = set->emoji.erase(i); - continue; - } - } - ++i; - } - } - if (index) { - if (set->dates.size() == set->stickers.size()) { - set->dates.insert(set->dates.begin(), base::unixtime::now()); - } - set->stickers.push_front(sticker); - if (const auto emojiList = session().data().stickers().getEmojiListFromSet(sticker)) { - for (const auto emoji : *emojiList) { - set->emoji[emoji].push_front(sticker); - } - } else if (!removedFromEmoji.empty()) { - for (const auto emoji : removedFromEmoji) { - set->emoji[emoji].push_front(sticker); - } - } else { - session().api().requestRecentStickersForce(); - } - - writeRecentStickers = true; - } - - // Remove that sticker from old recent, now it is in cloud recent stickers. - bool writeOldRecent = false; - auto &recent = session().data().stickers().getRecentPack(); - for (auto i = recent.begin(), e = recent.end(); i != e; ++i) { - if (i->first == sticker) { - writeOldRecent = true; - recent.erase(i); - break; - } - } - while (!recent.isEmpty() && set->stickers.size() + recent.size() > Global::StickersRecentLimit()) { - writeOldRecent = true; - recent.pop_back(); - } - - if (writeOldRecent) { - session().local().writeSettings(); - } - - // Remove that sticker from custom stickers, now it is in cloud recent stickers. - bool writeInstalledStickers = false; - auto customIt = sets.find(Data::Stickers::CustomSetId); - if (customIt != sets.cend()) { - const auto custom = customIt->second.get(); - int removeIndex = custom->stickers.indexOf(sticker); - if (removeIndex >= 0) { - custom->stickers.removeAt(removeIndex); - if (custom->stickers.isEmpty()) { - sets.erase(customIt); - } - writeInstalledStickers = true; - } - } - - if (writeInstalledStickers) { - session().local().writeInstalledStickers(); - } - if (writeRecentStickers) { - session().local().writeRecentStickers(); - } - _controller->tabbedSelector()->refreshStickers(); -} - void MainWidget::activate() { if (_a_show.animating()) { return; diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index e56b78b2a..75e58752a 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -32,10 +32,6 @@ namespace Main { class Session; } // namespace Main -namespace Notify { -struct PeerUpdate; -} // namespace Notify - namespace Data { class WallPaper; class CloudImageView; @@ -131,9 +127,6 @@ public: FullMsgId clickFromMessageId = FullMsgId()); bool started(); - - void incrementSticker(DocumentData *sticker); - void activate(); void refreshDialog(Dialogs::Key key); @@ -144,7 +137,6 @@ public: void windowShown(); - void historyToDown(History *hist); void dialogsToUp(); void checkHistoryActivation(); @@ -226,9 +218,6 @@ public: void pushReplyReturn(not_null item); - void cancelForwarding(not_null history); - void finishForwarding(Api::SendAction action); - // Does offerPeer or showPeerHistory. void choosePeer(PeerId peerId, MsgId showAtMsgId); void clearBotStartToken(PeerData *peer); @@ -260,9 +249,6 @@ public: void closeBothPlayers(); -signals: - void dialogsUpdated(); - public slots: void inlineResultLoadProgress(FileLoader *loader); void inlineResultLoadFailed(FileLoader *loader, bool started); diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 097197b18..9bdf1abef 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -32,7 +32,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/confirm_box.h" #include "boxes/add_contact_box.h" #include "boxes/connection_box.h" -#include "observer_peer.h" #include "storage/storage_account.h" #include "storage/localstorage.h" #include "apiwrap.h" diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 454888403..aa50b19c4 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -49,7 +49,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_account.h" // Account::sessionValue. #include "base/platform/base_platform_info.h" #include "base/unixtime.h" -#include "observer_peer.h" #include "main/main_session.h" #include "layout.h" #include "storage/file_download.h" diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index c9754106e..43491bccd 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -34,10 +34,6 @@ struct Preview; } // namespace Theme } // namespace Window -namespace Notify { -struct PeerUpdate; -} // namespace Notify - namespace Media { namespace Player { struct TrackState; diff --git a/Telegram/SourceFiles/observer_peer.cpp b/Telegram/SourceFiles/observer_peer.cpp deleted file mode 100644 index 158606cd1..000000000 --- a/Telegram/SourceFiles/observer_peer.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#include "observer_peer.h" - -#include "base/observer.h" -#include "facades.h" - -namespace Notify { -namespace { - -using SmallUpdatesList = QVector; -NeverFreedPointer SmallUpdates; -using AllUpdatesList = QMap; -NeverFreedPointer AllUpdates; - -void StartCallback() { - SmallUpdates.createIfNull(); - AllUpdates.createIfNull(); -} -void FinishCallback() { - SmallUpdates.clear(); - AllUpdates.clear(); -} - -base::Observable PeerUpdatedObservable; - -} // namespace - -void mergePeerUpdate(PeerUpdate &mergeTo, const PeerUpdate &mergeFrom) { - if (!(mergeTo.flags & PeerUpdate::Flag::NameChanged)) { - if (mergeFrom.flags & PeerUpdate::Flag::NameChanged) { - mergeTo.oldNameFirstLetters = mergeFrom.oldNameFirstLetters; - } - } - mergeTo.flags |= mergeFrom.flags; -} - -void peerUpdatedDelayed(const PeerUpdate &update) { - SmallUpdates.createIfNull(); - AllUpdates.createIfNull(); - - Global::RefHandleDelayedPeerUpdates().call(); - - int existingUpdatesCount = SmallUpdates->size(); - for (int i = 0; i < existingUpdatesCount; ++i) { - auto &existingUpdate = (*SmallUpdates)[i]; - if (existingUpdate.peer == update.peer) { - mergePeerUpdate(existingUpdate, update); - return; - } - } - - if (AllUpdates->isEmpty()) { - if (existingUpdatesCount < 5) { - SmallUpdates->push_back(update); - } else { - AllUpdates->insert(update.peer, update); - } - } else { - auto it = AllUpdates->find(update.peer); - if (it != AllUpdates->cend()) { - mergePeerUpdate(it.value(), update); - return; - } - AllUpdates->insert(update.peer, update); - } -} - -void peerUpdatedSendDelayed() { - if (!SmallUpdates || !AllUpdates || SmallUpdates->empty()) return; - - auto smallList = base::take(*SmallUpdates); - auto allList = base::take(*AllUpdates); - for (auto &update : smallList) { - PeerUpdated().notify(std::move(update), true); - } - for (auto &update : allList) { - PeerUpdated().notify(std::move(update), true); - } - - if (SmallUpdates->isEmpty()) { - std::swap(smallList, *SmallUpdates); - SmallUpdates->resize(0); - } -} - -base::Observable &PeerUpdated() { - return PeerUpdatedObservable; -} - -rpl::producer PeerUpdateViewer( - PeerUpdate::Flags flags) { - return [=](const auto &consumer) { - auto lifetime = rpl::lifetime(); - lifetime.make_state( - PeerUpdated().add_subscription({ flags, [=]( - const PeerUpdate &update) { - consumer.put_next_copy(update); - }})); - return lifetime; - }; -} - -rpl::producer PeerUpdateViewer( - not_null peer, - PeerUpdate::Flags flags) { - return PeerUpdateViewer( - flags - ) | rpl::filter([=](const PeerUpdate &update) { - return (update.peer == peer); - }); -} - -rpl::producer PeerUpdateValue( - not_null peer, - PeerUpdate::Flags flags) { - auto initial = PeerUpdate(peer); - initial.flags = flags; - return rpl::single( - initial - ) | rpl::then(PeerUpdateViewer(peer, flags)); -} - -} // namespace Notify diff --git a/Telegram/SourceFiles/observer_peer.h b/Telegram/SourceFiles/observer_peer.h deleted file mode 100644 index ec5d7981d..000000000 --- a/Telegram/SourceFiles/observer_peer.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -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 -#include -#include -#include -#include "base/observer.h" -#include "base/flags.h" - -namespace Notify { - -// Generic notifications about updates of some PeerData. -// You can subscribe to them by Notify::registerPeerObserver(). -// 0x0000FFFFU for general peer updates (valid for any peer). -// 0xFFFF0000U for specific peer updates (valid for user / chat / channel). -struct PeerUpdate { - PeerUpdate(PeerData *updated = nullptr) : peer(updated) { - } - PeerData *peer; - - enum class Flag : uint32 { - None = 0, - - // Common flags - NameChanged = (1 << 0), - UsernameChanged = (1 << 1), - PhotoChanged = (1 << 2), - AboutChanged = (1 << 3), - NotificationsEnabled = (1 << 4), - MigrationChanged = (1 << 6), - ChatPinnedChanged = (1 << 7), - UnavailableReasonChanged = (1 << 8), - UnreadViewChanged = (1 << 9), - PinnedMessageChanged = (1 << 10), - TopPromotedChanged = (1 << 11), - FolderChanged = (1 << 12), - - // For chats and channels - InviteLinkChanged = (1 << 13), - MembersChanged = (1 << 14), - AdminsChanged = (1 << 15), - BannedUsersChanged = (1 << 16), - UnreadMentionsChanged = (1 << 17), - RightsChanged = (1 << 18), - - // For users - UserCanShareContact = (1 << 19), - UserIsContact = (1 << 20), - UserPhoneChanged = (1 << 21), - UserIsBlocked = (1 << 22), - BotCommandsChanged = (1 << 23), - UserOnlineChanged = (1 << 24), - BotCanAddToGroups = (1 << 25), - UserCommonChatsChanged = (1 << 26), - UserHasCalls = (1 << 27), - UserOccupiedChanged = (1 << 28), - UserSupportInfoChanged = (1 << 29), - UserIsBotChanged = (1 << 30), - - // For channels - ChannelAmIn = (1 << 19), - ChannelStickersChanged = (1 << 20), - ChannelPromotedChanged = (1 << 21), - ChannelLinkedChat = (1 << 22), - ChannelLocation = (1 << 23), - ChannelSlowmode = (1 << 24), - ChannelLocalMessages = (1 << 25), - }; - using Flags = base::flags; - friend inline constexpr auto is_flag_type(Flag) { return true; } - - Flags flags = 0; - - // NameChanged data - base::flat_set oldNameFirstLetters; - -}; - -void peerUpdatedDelayed(const PeerUpdate &update); -inline void peerUpdatedDelayed(PeerData *peer, PeerUpdate::Flags events) { - PeerUpdate update(peer); - update.flags = events; - peerUpdatedDelayed(update); -} -void peerUpdatedSendDelayed(); - -class PeerUpdatedHandler { -public: - template - PeerUpdatedHandler(PeerUpdate::Flags events, Lambda &&handler) : _events(events), _handler(std::move(handler)) { - } - void operator()(const PeerUpdate &update) const { - if (update.flags & _events) { - _handler(update); - } - } - -private: - PeerUpdate::Flags _events; - Fn _handler; - -}; -base::Observable &PeerUpdated(); - -rpl::producer PeerUpdateViewer( - PeerUpdate::Flags flags); - -rpl::producer PeerUpdateViewer( - not_null peer, - PeerUpdate::Flags flags); - -rpl::producer PeerUpdateValue( - not_null peer, - PeerUpdate::Flags flags); - -} // namespace Notify diff --git a/Telegram/SourceFiles/platform/mac/mac_touchbar.mm b/Telegram/SourceFiles/platform/mac/mac_touchbar.mm index e6cb2017f..32912d538 100644 --- a/Telegram/SourceFiles/platform/mac/mac_touchbar.mm +++ b/Telegram/SourceFiles/platform/mac/mac_touchbar.mm @@ -21,6 +21,7 @@ #include "data/data_file_origin.h" #include "data/data_folder.h" #include "data/data_peer_values.h" +#include "data/data_changes.h" #include "data/data_session.h" #include "data/data_cloud_file.h" #include "data/stickers/data_stickers.h" @@ -30,7 +31,6 @@ #include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" -#include "observer_peer.h" #include "base/platform/mac/base_utilities_mac.h" #include "styles/style_dialogs.h" #include "styles/style_media_player.h" @@ -576,24 +576,24 @@ void AppendEmojiPacks( return; } _userpicView = _peer->createUserpicView(); - Notify::PeerUpdateViewer( + _peer->session().changes().peerUpdates( _peer, - Notify::PeerUpdate::Flag::PhotoChanged + Data::PeerUpdate::Flag::Photo ) | rpl::start_with_next([=] { isWaitingUserpicLoad = true; [self updateUserpic]; }, _peerChangedLifetime); - Notify::PeerUpdateViewer( - _peer, - Notify::PeerUpdate::Flag::UnreadViewChanged + _peer->session().changes().historyUpdates( + _peer->session().history(_peer), + Data::HistoryUpdate::Flag::UnreadView ) | rpl::start_with_next([=] { [self updateBadge]; }, _peerChangedLifetime); - Notify::PeerUpdateViewer( + _peer->session().changes().peerUpdates( _peer, - Notify::PeerUpdate::Flag::UserOnlineChanged + Data::PeerUpdate::Flag::OnlineStatus ) | rpl::filter([=] { return UnreadCount(_peer) == 0; }) | rpl::start_with_next([=] { diff --git a/Telegram/SourceFiles/profile/profile_block_group_members.cpp b/Telegram/SourceFiles/profile/profile_block_group_members.cpp index 836c3e630..a67c574af 100644 --- a/Telegram/SourceFiles/profile/profile_block_group_members.cpp +++ b/Telegram/SourceFiles/profile/profile_block_group_members.cpp @@ -18,9 +18,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_chat.h" #include "data/data_user.h" +#include "data/data_changes.h" #include "mainwidget.h" #include "apiwrap.h" -#include "observer_peer.h" #include "main/main_session.h" #include "lang/lang_keys.h" #include "facades.h" @@ -28,7 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Profile { namespace { -using UpdateFlag = Notify::PeerUpdate::Flag; +using UpdateFlag = Data::PeerUpdate::Flag; } // namespace @@ -41,18 +41,19 @@ not_null GroupMembersWidget::Member::user() const { GroupMembersWidget::GroupMembersWidget( QWidget *parent, - PeerData *peer, + not_null peer, const style::PeerListItem &st) : PeerListWidget(parent, peer, QString(), st, tr::lng_profile_kick(tr::now)) { _updateOnlineTimer.setSingleShot(true); connect(&_updateOnlineTimer, SIGNAL(timeout()), this, SLOT(onUpdateOnlineDisplay())); - auto observeEvents = UpdateFlag::AdminsChanged - | UpdateFlag::MembersChanged - | UpdateFlag::UserOnlineChanged; - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) { + peer->session().changes().peerUpdates( + UpdateFlag::Admins + | UpdateFlag::Members + | UpdateFlag::OnlineStatus + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { notifyPeerUpdated(update); - })); + }, lifetime()); setRemovedCallback([=](PeerData *selectedPeer) { removePeer(selectedPeer); @@ -104,9 +105,9 @@ void GroupMembersWidget::removePeer(PeerData *selectedPeer) { crl::guard(&peer->session(), callback))); } -void GroupMembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) { +void GroupMembersWidget::notifyPeerUpdated(const Data::PeerUpdate &update) { if (update.peer != peer()) { - if (update.flags & UpdateFlag::UserOnlineChanged) { + if (update.flags & UpdateFlag::OnlineStatus) { if (auto user = update.peer->asUser()) { refreshUserOnline(user); } @@ -114,11 +115,11 @@ void GroupMembersWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) { return; } - if (update.flags & UpdateFlag::MembersChanged) { + if (update.flags & UpdateFlag::Members) { refreshMembers(); contentSizeUpdated(); } - if (update.flags & UpdateFlag::AdminsChanged) { + if (update.flags & UpdateFlag::Admins) { if (const auto chat = peer()->asChat()) { for (const auto item : items()) { setItemFlags(getMember(item), chat); diff --git a/Telegram/SourceFiles/profile/profile_block_group_members.h b/Telegram/SourceFiles/profile/profile_block_group_members.h index d3ab35219..33006c3a1 100644 --- a/Telegram/SourceFiles/profile/profile_block_group_members.h +++ b/Telegram/SourceFiles/profile/profile_block_group_members.h @@ -15,9 +15,9 @@ namespace Ui { class FlatLabel; } // namespace Ui -namespace Notify { +namespace Data { struct PeerUpdate; -} // namespace Notify +} // namespace Data namespace Profile { @@ -25,7 +25,10 @@ class GroupMembersWidget : public PeerListWidget { Q_OBJECT public: - GroupMembersWidget(QWidget *parent, PeerData *peer, const style::PeerListItem &st); + GroupMembersWidget( + QWidget *parent, + not_null peer, + const style::PeerListItem &st); int onlineCount() const { return _onlineCount; @@ -41,7 +44,7 @@ private slots: private: // Observed notifications. - void notifyPeerUpdated(const Notify::PeerUpdate &update); + void notifyPeerUpdated(const Data::PeerUpdate &update); void removePeer(PeerData *selectedPeer); void refreshMembers(); diff --git a/Telegram/SourceFiles/profile/profile_block_peer_list.h b/Telegram/SourceFiles/profile/profile_block_peer_list.h index 0d03ce8f8..7ead3ab7a 100644 --- a/Telegram/SourceFiles/profile/profile_block_peer_list.h +++ b/Telegram/SourceFiles/profile/profile_block_peer_list.h @@ -18,10 +18,6 @@ class RippleAnimation; class PopupMenu; } // namespace Ui -namespace Notify { -struct PeerUpdate; -} // namespace Notify - namespace style { struct PeerListItem; } // namespace style diff --git a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp index 93aa24c59..d946cb66c 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp @@ -10,11 +10,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_common.h" #include "lang/lang_keys.h" #include "apiwrap.h" -#include "observer_peer.h" #include "mainwidget.h" #include "main/main_session.h" #include "data/data_user.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "history/admin_log/history_admin_log_item.h" #include "history/view/history_view_element.h" #include "history/view/history_view_message.h" @@ -86,14 +86,16 @@ Main::Session &BlockUserBoxController::session() const { void BlockUserBoxController::prepareViewHook() { delegate()->peerListSetTitle(tr::lng_blocked_list_add_title()); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::UserIsBlocked, [this](const Notify::PeerUpdate &update) { - if (auto user = update.peer->asUser()) { + session().changes().peerUpdates( + Data::PeerUpdate::Flag::IsBlocked + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { + if (const auto user = update.peer->asUser()) { if (auto row = delegate()->peerListFindRow(user->id)) { updateIsBlocked(row, user); delegate()->peerListUpdateRow(row); } } - })); + }, lifetime()); } void BlockUserBoxController::updateIsBlocked(not_null row, UserData *user) const { @@ -192,11 +194,13 @@ void BlockedBoxController::prepare() { setDescriptionText(tr::lng_contacts_loading(tr::now)); delegate()->peerListRefreshRows(); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::UserIsBlocked, [this](const Notify::PeerUpdate &update) { + session().changes().peerUpdates( + Data::PeerUpdate::Flag::IsBlocked + ) | rpl::start_with_next([=](const Data::PeerUpdate &update) { if (const auto user = update.peer->asUser()) { handleBlockedEvent(user); } - })); + }, lifetime()); _loadRequestId = -1; _window->session().api().blockedUsersSlice( diff --git a/Telegram/SourceFiles/support/support_helper.cpp b/Telegram/SourceFiles/support/support_helper.cpp index d79a5ef23..174257a39 100644 --- a/Telegram/SourceFiles/support/support_helper.cpp +++ b/Telegram/SourceFiles/support/support_helper.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_drafts.h" #include "data/data_user.h" #include "data/data_session.h" +#include "data/data_changes.h" #include "api/api_text_entities.h" #include "history/history.h" #include "boxes/abstract_box.h" @@ -27,7 +28,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/localimageloader.h" #include "core/sandbox.h" #include "main/main_session.h" -#include "observer_peer.h" #include "apiwrap.h" #include "facades.h" #include "styles/style_layers.h" @@ -334,14 +334,14 @@ void Helper::cloudDraftChanged(not_null history) { void Helper::chatOccupiedUpdated(not_null history) { if (const auto till = OccupiedBySomeoneTill(history)) { _occupiedChats[history] = till + 2; - Notify::peerUpdatedDelayed( - history->peer, - Notify::PeerUpdate::Flag::UserOccupiedChanged); + history->session().changes().historyUpdated( + history, + Data::HistoryUpdate::Flag::ChatOccupied); checkOccupiedChats(); } else if (_occupiedChats.take(history)) { - Notify::peerUpdatedDelayed( - history->peer, - Notify::PeerUpdate::Flag::UserOccupiedChanged); + history->session().changes().historyUpdated( + history, + Data::HistoryUpdate::Flag::ChatOccupied); } } @@ -355,9 +355,9 @@ void Helper::checkOccupiedChats() { if (nearest->second <= now) { const auto history = nearest->first; _occupiedChats.erase(nearest); - Notify::peerUpdatedDelayed( - history->peer, - Notify::PeerUpdate::Flag::UserOccupiedChanged); + history->session().changes().historyUpdated( + history, + Data::HistoryUpdate::Flag::ChatOccupied); } else { _checkOccupiedTimer.callOnce( (nearest->second - now) * crl::time(1000)); @@ -440,9 +440,9 @@ void Helper::applyInfo( not_null user, const MTPhelp_UserInfo &result) { const auto notify = [&] { - Notify::peerUpdatedDelayed( + user->session().changes().peerUpdated( user, - Notify::PeerUpdate::Flag::UserSupportInfoChanged); + Data::PeerUpdate::Flag::SupportInfo); }; const auto remove = [&] { if (_userInformation.take(user)) { @@ -468,9 +468,9 @@ void Helper::applyInfo( } rpl::producer Helper::infoValue(not_null user) const { - return Notify::PeerUpdateValue( + return user->session().changes().peerFlagsValue( user, - Notify::PeerUpdate::Flag::UserSupportInfoChanged + Data::PeerUpdate::Flag::SupportInfo ) | rpl::map([=] { return infoCurrent(user); }); diff --git a/Telegram/SourceFiles/ui/special_buttons.cpp b/Telegram/SourceFiles/ui/special_buttons.cpp index cd98e6ca3..95761541d 100644 --- a/Telegram/SourceFiles/ui/special_buttons.cpp +++ b/Telegram/SourceFiles/ui/special_buttons.cpp @@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_folder.h" #include "data/data_channel.h" #include "data/data_cloud_file.h" +#include "data/data_changes.h" #include "history/history.h" #include "core/file_utilities.h" #include "core/application.h" @@ -30,7 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "apiwrap.h" #include "mainwidget.h" -#include "observer_peer.h" #include "facades.h" #include "app.h" @@ -631,9 +631,9 @@ void UserpicButton::openPeerPhoto() { } void UserpicButton::setupPeerViewers() { - Notify::PeerUpdateViewer( + _peer->session().changes().peerUpdates( _peer, - Notify::PeerUpdate::Flag::PhotoChanged + Data::PeerUpdate::Flag::Photo ) | rpl::start_with_next([=] { processNewPeerPhoto(); update(); @@ -653,6 +653,7 @@ void UserpicButton::setupPeerViewers() { void UserpicButton::paintEvent(QPaintEvent *e) { Painter p(this); + if (!_waiting && _notShownYet) { _notShownYet = false; startAnimation(); diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp index 28d1b646c..1d8cbe634 100644 --- a/Telegram/SourceFiles/window/window_main_menu.cpp +++ b/Telegram/SourceFiles/window/window_main_menu.cpp @@ -27,11 +27,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "calls/calls_box_controller.h" #include "lang/lang_keys.h" #include "core/click_handler_types.h" -#include "observer_peer.h" #include "main/main_session.h" #include "data/data_folder.h" #include "data/data_session.h" #include "data/data_user.h" +#include "data/data_changes.h" #include "mainwidget.h" #include "facades.h" #include "app.h" @@ -213,11 +213,14 @@ MainMenu::MainMenu( _version->setLink(2, std::make_shared([] { Ui::show(Box()); })); subscribe(_controller->session().downloaderTaskFinished(), [=] { update(); }); - subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::UserPhoneChanged, [this](const Notify::PeerUpdate &update) { - if (update.peer->isSelf()) { - updatePhone(); - } - })); + + _controller->session().changes().peerUpdates( + _controller->session().user(), + Data::PeerUpdate::Flag::PhoneNumber + ) | rpl::start_with_next([=] { + updatePhone(); + }, lifetime()); + subscribe(Global::RefPhoneCallsEnabledChanged(), [this] { refreshMenu(); }); subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) { if (update.type == Window::Theme::BackgroundUpdate::Type::ApplyingTheme) { diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 62ba85845..f6c10bbc8 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -24,7 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "mainwidget.h" #include "mainwindow.h" -#include "observer_peer.h" #include "api/api_common.h" #include "api/api_chat_filters.h" #include "history/history.h" @@ -37,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/info_controller.h" //#include "info/feed/info_feed_channels_controllers.h" // #feed #include "info/profile/info_profile_values.h" +#include "data/data_changes.h" #include "data/data_session.h" #include "data/data_folder.h" #include "data/data_poll.h" @@ -306,31 +306,23 @@ void Filler::addHidePromotion() { void Filler::addTogglePin() { const auto filterId = _filterId; const auto peer = _peer; - auto isPinned = false; - if (const auto history = peer->owner().historyLoaded(peer)) { - isPinned = history->isPinnedDialog(filterId); - } - const auto pinText = [](bool isPinned) { - return isPinned + const auto history = peer->owner().history(peer); + const auto pinText = [=] { + return history->isPinnedDialog(filterId) ? tr::lng_context_unpin_from_top(tr::now) : tr::lng_context_pin_to_top(tr::now); }; const auto pinToggle = [=] { - TogglePinnedDialog( - _controller, - peer->owner().history(peer), - filterId); + TogglePinnedDialog(_controller, history, filterId); }; - const auto pinAction = _addAction(pinText(isPinned), pinToggle); + const auto pinAction = _addAction(pinText(), pinToggle); const auto lifetime = Ui::CreateChild(pinAction); - Notify::PeerUpdateViewer( - peer, - Notify::PeerUpdate::Flag::ChatPinnedChanged + history->session().changes().historyUpdates( + history, + Data::HistoryUpdate::Flag::IsPinned ) | rpl::start_with_next([=] { - const auto history = peer->owner().history(peer); - const auto isPinned = history->isPinnedDialog(filterId); - pinAction->setText(pinText(isPinned)); + pinAction->setText(pinText()); }, *lifetime); } @@ -357,20 +349,18 @@ void Filler::addInfo() { void Filler::addToggleUnreadMark() { const auto peer = _peer; - const auto isUnread = [](not_null peer) { - if (const auto history = peer->owner().historyLoaded(peer)) { - return (history->chatListUnreadCount() > 0) - || (history->chatListUnreadMark()); - } - return false; + const auto history = peer->owner().history(peer); + const auto isUnread = [=] { + return (history->chatListUnreadCount() > 0) + || (history->chatListUnreadMark()); }; - const auto label = [=](not_null peer) { - return isUnread(peer) + const auto label = [=] { + return isUnread() ? tr::lng_context_mark_read(tr::now) : tr::lng_context_mark_unread(tr::now); }; - auto action = _addAction(label(peer), [=] { - const auto markAsRead = isUnread(peer); + auto action = _addAction(label(), [=] { + const auto markAsRead = isUnread(); const auto handle = [&](not_null history) { if (markAsRead) { peer->owner().histories().readInbox(history); @@ -380,7 +370,6 @@ void Filler::addToggleUnreadMark() { !markAsRead); } }; - const auto history = peer->owner().history(peer); handle(history); if (markAsRead) { if (const auto migrated = history->migrateSibling()) { @@ -390,24 +379,22 @@ void Filler::addToggleUnreadMark() { }); const auto lifetime = Ui::CreateChild(action); - Notify::PeerUpdateViewer( - _peer, - Notify::PeerUpdate::Flag::UnreadViewChanged + history->session().changes().historyUpdates( + history, + Data::HistoryUpdate::Flag::UnreadView ) | rpl::start_with_next([=] { - action->setText(label(peer)); + action->setText(label()); }, *lifetime); } void Filler::addToggleArchive() { const auto peer = _peer; + const auto history = peer->owner().history(peer); const auto isArchived = [=] { - const auto history = peer->owner().historyLoaded(peer); - return history && history->folder(); + return (history->folder() != nullptr); }; const auto toggle = [=] { - ToggleHistoryArchived( - peer->owner().history(peer), - !isArchived()); + ToggleHistoryArchived(history, !isArchived()); }; const auto archiveAction = _addAction( (isArchived() @@ -416,9 +403,9 @@ void Filler::addToggleArchive() { toggle); const auto lifetime = Ui::CreateChild(archiveAction); - Notify::PeerUpdateViewer( - peer, - Notify::PeerUpdate::Flag::FolderChanged + history->session().changes().historyUpdates( + history, + Data::HistoryUpdate::Flag::Folder ) | rpl::start_with_next([=] { archiveAction->setText(isArchived() ? tr::lng_archived_remove(tr::now) @@ -448,9 +435,9 @@ void Filler::addBlockUser(not_null user) { }); const auto lifetime = Ui::CreateChild(blockAction); - Notify::PeerUpdateViewer( + _peer->session().changes().peerUpdates( _peer, - Notify::PeerUpdate::Flag::UserIsBlocked + Data::PeerUpdate::Flag::IsBlocked ) | rpl::start_with_next([=] { blockAction->setText(blockText(user)); }, *lifetime);