Replace observer_peer with rpl interface.

This commit is contained in:
John Preston 2020-06-12 16:12:34 +04:00
parent b0f9ad71dd
commit 3c4e959468
81 changed files with 1405 additions and 1304 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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<PeerData*> peer,
not_null<ChannelData*> 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<ChannelData*> 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<ChannelData*> channel) {
void ApiWrap::leaveChannel(not_null<ChannelData*> 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<ChannelData*> channel) {
void ApiWrap::blockUser(not_null<UserData*> 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<UserData*> user) {
void ApiWrap::unblockUser(not_null<UserData*> user, Fn<void()> 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<MTPPrivacyRule> &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<MTPPrivacyRule> &rules) {
_contactsStatusesRequestId = request(MTPcontacts_GetStatuses(
)).done([=](const MTPVector<MTPContactStatus> &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<MTPPrivacyRule> &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<PhotoData*> photo) {
Ui::show(Box<InformBox>(tr::lng_stickers_not_found(tr::now)));
return;
} else if (result.v.size() > 1) {
Ui::show(Box<StickersBox>(&session(), result));
Ui::show(Box<StickersBox>(_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<void()> 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<void()> &&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<uint64>();
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<UserData*> 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<uint64>();
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<PeerData*> 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();

View file

@ -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,

View file

@ -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"

View file

@ -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) {

View file

@ -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) {

View file

@ -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<PeerData*> peer) {
auto byPeer = _rowsByPeer.find(peer);
if (byPeer != _rowsByPeer.cend()) {
for (auto row : byPeer->second) {
if (addingToSearchIndex()) {

View file

@ -34,10 +34,6 @@ struct ScrollToRequest;
class PopupMenu;
} // namespace Ui
namespace Notify {
struct PeerUpdate;
} // namespace Notify
using PaintRoundImageCallback = Fn<void(
Painter &p,
int x,
@ -551,7 +547,7 @@ protected:
private:
void refreshIndices();
void removeRowAtIndex(std::vector<std::unique_ptr<PeerListRow>> &from, int index);
void handleNameChanged(const Notify::PeerUpdate &update);
void handleNameChanged(not_null<PeerData*> peer);
void invalidatePixmapsCache();

View file

@ -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"

View file

@ -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<ChatData*> 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<ChatData*> chat) {

View file

@ -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<base::Subscription>();
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<ChannelData*> 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<ChatData*> 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<ChatData*> chat) {

View file

@ -50,7 +50,7 @@ enum class ParticipantsRole {
Kicked,
};
class ParticipantsOnlineSorter : private base::Subscriber {
class ParticipantsOnlineSorter {
public:
ParticipantsOnlineSorter(
not_null<PeerData*> peer,
@ -63,10 +63,11 @@ private:
void sortDelayed();
void refreshOnlineCount();
not_null<PeerData*> _peer;
not_null<PeerListDelegate*> _delegate;
const not_null<PeerData*> _peer;
const not_null<PeerListDelegate*> _delegate;
base::Timer _sortByOnlineTimer;
rpl::variable<int> _onlineCount = 0;
rpl::lifetime _lifetime;
};

View file

@ -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"

View file

@ -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();

View file

@ -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<PeerData*> peer) {
if (const auto i = _dataMap.find(peer); i != end(_dataMap)) {
updateChatName(i->second.get(), peer);

View file

@ -33,10 +33,6 @@ class Row;
class IndexedList;
} // namespace Dialogs
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace Ui {
class MultiSelect;
class InputField;

View file

@ -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"

View file

@ -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();

View file

@ -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()) {

View file

@ -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 {

View file

@ -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) {

View file

@ -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();
}

View file

@ -229,7 +229,6 @@ public:
void writeInstallBetaVersionsSetting();
void call_handleUnreadCounterUpdate();
void call_handleDelayedPeerUpdates();
void call_handleObservables();
protected:

View file

@ -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 <typename DataType, typename UpdateType>
void Changes::Manager<DataType, UpdateType>::updated(
not_null<DataType*> data,
Flags flags) {
sendRealtimeNotifications(data, flags);
}
template <typename DataType, typename UpdateType>
void Changes::Manager<DataType, UpdateType>::sendRealtimeNotifications(
not_null<DataType*> data,
Flags flags) {
auto clearRealtime = false;
for (auto i = 0; i != kCount; ++i) {
const auto flag = static_cast<Flag>(1U << i);
if (flags & flag) {
_realtimeStreams[i].fire({ data, flags });
}
}
}
template <typename DataType, typename UpdateType>
rpl::producer<UpdateType> Changes::Manager<DataType, UpdateType>::updates(
Flags flags) const {
return _stream.events(
) | rpl::filter([=](const UpdateType &update) {
return (update.flags & flags);
});
}
template <typename DataType, typename UpdateType>
rpl::producer<UpdateType> Changes::Manager<DataType, UpdateType>::updates(
not_null<DataType*> data,
Flags flags) const {
return _stream.events(
) | rpl::filter([=](const UpdateType &update) {
const auto [updateData, updateFlags] = update;
return (updateData == data) && (updateFlags & flags);
});
}
template <typename DataType, typename UpdateType>
auto Changes::Manager<DataType, UpdateType>::realtimeUpdates(Flag flag) const
-> rpl::producer<UpdateType> {
return _realtimeStreams[CountBit(flag)].events();
}
template <typename DataType, typename UpdateType>
rpl::producer<UpdateType> Changes::Manager<DataType, UpdateType>::flagsValue(
not_null<DataType*> data,
Flags flags) const {
return rpl::single(
UpdateType{ data, flags }
) | rpl::then(updates(data, flags));
}
template <typename DataType, typename UpdateType>
void Changes::Manager<DataType, UpdateType>::sendNotifications() {
for (const auto [data, flags] : base::take(_updates)) {
_stream.fire({ data, flags });
}
}
Changes::Changes(not_null<Main::Session*> session) : _session(session) {
}
Main::Session &Changes::session() const {
return *_session;
}
void Changes::nameUpdated(
not_null<PeerData*> peer,
base::flat_set<QChar> oldFirstLetters) {
_nameStream.fire({ peer, std::move(oldFirstLetters) });
}
rpl::producer<NameUpdate> Changes::realtimeNameUpdates() const {
return _nameStream.events();
}
rpl::producer<NameUpdate> Changes::realtimeNameUpdates(
not_null<PeerData*> peer) const {
return _nameStream.events() | rpl::filter([=](const NameUpdate &update) {
return (update.peer == peer);
});
}
void Changes::peerUpdated(not_null<PeerData*> peer, PeerUpdate::Flags flags) {
_peerChanges.updated(peer, flags);
scheduleNotifications();
}
rpl::producer<PeerUpdate> Changes::peerUpdates(
PeerUpdate::Flags flags) const {
return _peerChanges.updates(flags);
}
rpl::producer<PeerUpdate> Changes::peerUpdates(
not_null<PeerData*> peer,
PeerUpdate::Flags flags) const {
return _peerChanges.updates(peer, flags);
}
rpl::producer<PeerUpdate> Changes::peerFlagsValue(
not_null<PeerData*> peer,
PeerUpdate::Flags flags) const {
return _peerChanges.flagsValue(peer, flags);
}
rpl::producer<PeerUpdate> Changes::realtimePeerUpdates(
PeerUpdate::Flag flag) const {
return _peerChanges.realtimeUpdates(flag);
}
void Changes::historyUpdated(
not_null<History*> history,
HistoryUpdate::Flags flags) {
_historyChanges.updated(history, flags);
scheduleNotifications();
}
rpl::producer<HistoryUpdate> Changes::historyUpdates(
HistoryUpdate::Flags flags) const {
return _historyChanges.updates(flags);
}
rpl::producer<HistoryUpdate> Changes::historyUpdates(
not_null<History*> history,
HistoryUpdate::Flags flags) const {
return _historyChanges.updates(history, flags);
}
rpl::producer<HistoryUpdate> Changes::historyFlagsValue(
not_null<History*> 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

View file

@ -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<PeerData*> peer,
base::flat_set<QChar> oldFirstLetters)
: peer(peer)
, oldFirstLetters(std::move(oldFirstLetters)) {
}
not_null<PeerData*> peer;
base::flat_set<QChar> 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<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; }
not_null<PeerData*> 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<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; }
not_null<History*> history;
Flags flags = 0;
};
class Changes final {
public:
explicit Changes(not_null<Main::Session*> session);
[[nodiscard]] Main::Session &session() const;
void nameUpdated(
not_null<PeerData*> peer,
base::flat_set<QChar> oldFirstLetters);
[[nodiscard]] rpl::producer<NameUpdate> realtimeNameUpdates() const;
[[nodiscard]] rpl::producer<NameUpdate> realtimeNameUpdates(
not_null<PeerData*> peer) const;
void peerUpdated(not_null<PeerData*> peer, PeerUpdate::Flags flags);
[[nodiscard]] rpl::producer<PeerUpdate> peerUpdates(
PeerUpdate::Flags flags) const;
[[nodiscard]] rpl::producer<PeerUpdate> peerUpdates(
not_null<PeerData*> peer,
PeerUpdate::Flags flags) const;
[[nodiscard]] rpl::producer<PeerUpdate> peerFlagsValue(
not_null<PeerData*> peer,
PeerUpdate::Flags flags) const;
[[nodiscard]] rpl::producer<PeerUpdate> realtimePeerUpdates(
PeerUpdate::Flag flag) const;
void historyUpdated(
not_null<History*> history,
HistoryUpdate::Flags flags);
[[nodiscard]] rpl::producer<HistoryUpdate> historyUpdates(
HistoryUpdate::Flags flags) const;
[[nodiscard]] rpl::producer<HistoryUpdate> historyUpdates(
not_null<History*> history,
HistoryUpdate::Flags flags) const;
[[nodiscard]] rpl::producer<HistoryUpdate> historyFlagsValue(
not_null<History*> history,
HistoryUpdate::Flags flags) const;
void sendNotifications();
private:
template <typename Flag>
static constexpr int CountBit(Flag Last = Flag::LastUsedBit) {
auto i = 0;
while ((1ULL << i) != static_cast<uint64>(Last)) {
++i;
Assert(i != 64);
}
return (i + 1);
}
template <typename DataType, typename UpdateType>
class Manager final {
public:
using Flag = typename UpdateType::Flag;
using Flags = typename UpdateType::Flags;
void updated(not_null<DataType*> data, Flags flags);
[[nodiscard]] rpl::producer<UpdateType> updates(Flags flags) const;
[[nodiscard]] rpl::producer<UpdateType> updates(
not_null<DataType*> data,
Flags flags) const;
[[nodiscard]] rpl::producer<UpdateType> flagsValue(
not_null<DataType*> data,
Flags flags) const;
[[nodiscard]] rpl::producer<UpdateType> realtimeUpdates(
Flag flag) const;
void sendNotifications();
private:
static constexpr auto kCount = CountBit<Flag>();
void sendRealtimeNotifications(not_null<DataType*> data, Flags flags);
std::array<rpl::event_stream<UpdateType>, kCount> _realtimeStreams;
base::flat_map<not_null<DataType*>, Flags> _updates;
rpl::event_stream<UpdateType> _stream;
};
static constexpr auto kHistoryCount = CountBit<HistoryUpdate::Flag>();
void scheduleNotifications();
const not_null<Main::Session*> _session;
rpl::event_stream<NameUpdate> _nameStream;
Manager<PeerData, PeerUpdate> _peerChanges;
Manager<History, HistoryUpdate> _historyChanges;
bool _notify = false;
};
} // namespace Data

View file

@ -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<Data::Session*> 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<UserData*> 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<UserData*> 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<UserData*> 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<UserData*> 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<Data::UnavailableReason> &&reasons) {
void ChannelData::setUnavailableReasons(
std::vector<Data::UnavailableReason> &&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<ChannelData*> 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());

View file

@ -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<UserData*> 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<ChatData*> chat, const MTPDchatFull &update) {
void ApplyChatUpdate(
not_null<ChatData*> 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);
});
}

View file

@ -236,6 +236,7 @@ not_null<Dialogs::MainList*> ChatFilters::chatsList(FilterId filterId) {
auto &pointer = _chatsLists[filterId];
if (!pointer) {
pointer = std::make_unique<Dialogs::MainList>(
&_owner->session(),
filterId,
rpl::single(ChatFilter::kPinnedLimit));
}

View file

@ -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<int> PinnedDialogsInFolderMaxValue(
Folder::Folder(not_null<Data::Session*> 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);

View file

@ -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<QChar>();
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;
}

View file

@ -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<Main::Session*> 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<UserData*> 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<UserData*> 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<UserData*> 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<UserData*> 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<UserData*> 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<UserData*> Session::processUser(const MTPUser &data) {
}
if (canShareThisContact != result->canShareThisContactFast()) {
update.flags |= UpdateFlag::UserCanShareContact;
flags |= UpdateFlag::CanShareContact;
}
});
@ -510,15 +510,12 @@ not_null<UserData*> 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<PeerData*> 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<PeerData*> 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<PeerData*> 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<PeerData*> 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<PeerData*> 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<PeerData*> 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<PeerData*> peer) {
}
}
}
void Session::newMessageSent(not_null<History*> history) {
_newMessageSent.fire_copy(history);
}
rpl::producer<not_null<History*>> Session::newMessageSent() const {
return _newMessageSent.events();
}
void Session::cancelForwarding(not_null<History*> history) {
history->setForwardDraft({});
_forwardDraftUpdated.fire_copy(history);
}
rpl::producer<not_null<History*>> Session::forwardDraftUpdates() const {
return _forwardDraftUpdated.events();
}
void Session::registerSendAction(
not_null<History*> 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<UserData*> 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<ChannelData*> channel) {
return !(channel->amIn());
}) | rpl::start_with_next([=](not_null<ChannelData*> 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<not_null<UserData*>> Session::megagroupParticipantAdded(
});
}
void Session::userIsContactUpdated(not_null<UserData*> 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<PeerData*> 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) {

View file

@ -180,6 +180,11 @@ public:
void deleteConversationLocally(not_null<PeerData*> peer);
void newMessageSent(not_null<History*> history);
[[nodiscard]] rpl::producer<not_null<History*>> newMessageSent() const;
void cancelForwarding(not_null<History*> history);
[[nodiscard]] rpl::producer<not_null<History*>> forwardDraftUpdates() const;
void registerSendAction(
not_null<History*> history,
not_null<UserData*> 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*> folder,
const MTPDfolder &data);
void userIsContactUpdated(not_null<UserData*> user);
void setPinnedFromDialog(const Dialogs::Key &key, bool pinned);
NotifySettings &defaultNotifySettings(not_null<const PeerData*> peer);
@ -878,6 +880,8 @@ private:
rpl::event_stream<not_null<WebPageData*>> _webpageUpdates;
rpl::event_stream<not_null<ChannelData*>> _channelDifferenceTooLong;
rpl::event_stream<not_null<History*>> _historyOutboxReads;
rpl::event_stream<not_null<History*>> _newMessageSent;
rpl::event_stream<not_null<History*>> _forwardDraftUpdated;
base::flat_multi_map<TimeId, not_null<PollData*>> _pollsClosings;
base::Timer _pollsClosingTimer;
@ -893,7 +897,7 @@ private:
base::flat_set<not_null<ViewElement*>> _heavyViewParts;
PeerData *_topPromoted = nullptr;
History *_topPromoted = nullptr;
NotifySettings _defaultUserNotifySettings;
NotifySettings _defaultChatNotifySettings;

View file

@ -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<Data::UnavailableReason> &&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);
}
}

View file

@ -62,6 +62,119 @@ rpl::producer<> Stickers::savedGifsUpdated() const {
return _savedGifsUpdated.events();
}
void Stickers::incrementSticker(not_null<DocumentData*> 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<Data::StickersSet>(
&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<not_null<EmojiPtr>>();
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<DocumentData*> document) {
const auto index = _savedGifs.indexOf(document);
if (!index) {

View file

@ -55,6 +55,8 @@ public:
void notifySavedGifsUpdated();
[[nodiscard]] rpl::producer<> savedGifsUpdated() const;
void incrementSticker(not_null<DocumentData*> document);
bool updateNeeded(crl::time now) const {
return updateNeeded(_lastUpdate, now);
}

View file

@ -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<ChosenRow> {
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<PeerData*> peer) {
const auto user = peer->isSelf() ? nullptr : peer->asUser();
if (!user) {
return;
}

View file

@ -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<UserData*> searchFromUserChanged;
rpl::producer<ChosenRow> chosenRow() const;
[[nodiscard]] rpl::producer<ChosenRow> chosenRow() const;
[[nodiscard]] rpl::producer<> updated() const;
~InnerWidget();
@ -228,7 +225,7 @@ private:
int defaultRowTop(not_null<Row*> row) const;
void setupOnlineStatusCheck();
void userOnlineUpdated(const Notify::PeerUpdate &update);
void userOnlineUpdated(not_null<PeerData*> peer);
void setupShortcuts();
RowDescriptor computeJump(
@ -406,6 +403,7 @@ private:
Fn<void()> _loadMoreCallback;
rpl::event_stream<> _listBottomReached;
rpl::event_stream<ChosenRow> _chosenRow;
rpl::event_stream<> _updated;
base::unique_qptr<Ui::PopupMenu> _menu;

View file

@ -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<int> pinnedLimit)
MainList::MainList(
not_null<Main::Session*> session,
FilterId filterId,
rpl::producer<int> pinnedLimit)
: _filterId(filterId)
, _all(SortMode::Date, filterId)
, _pinned(filterId, 1) {
@ -24,12 +28,9 @@ MainList::MainList(FilterId filterId, rpl::producer<int> 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);
}

View file

@ -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<int> pinnedLimit);
MainList(
not_null<Main::Session*> session,
FilterId filterId,
rpl::producer<int> pinnedLimit);
bool empty() const;
bool loaded() const;

View file

@ -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"

View file

@ -176,6 +176,11 @@ Widget::Widget(
, _singleMessageSearch(&controller->session()) {
_inner = _scroll->setOwnedWidget(object_ptr<InnerWidget>(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(); }));

View file

@ -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);

View file

@ -145,7 +145,6 @@ void start();
void finish();
DeclareRefVar(SingleQueuedInvokation, HandleUnreadCounterUpdate);
DeclareRefVar(SingleQueuedInvokation, HandleDelayedPeerUpdates);
DeclareVar(Adaptive::WindowLayout, AdaptiveWindowLayout);
DeclareVar(Adaptive::ChatLayout, AdaptiveChatLayout);

View file

@ -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;

View file

@ -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<Data::Session*> 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<HistoryItem*> History::addNewToBack(
@ -987,7 +989,9 @@ not_null<HistoryItem*> 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<UserData*> 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<HistoryItem*> 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<HistoryItem*> 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<UserId> &changes) {
}
void History::changedChatListPinHook() {
Notify::peerUpdatedDelayed(
peer,
Notify::PeerUpdate::Flag::ChatPinnedChanged);
session().changes().historyUpdated(this, UpdateFlag::IsPinned);
}
void History::removeBlock(not_null<HistoryBlock*> block) {

View file

@ -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 {

View file

@ -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);
}
}
}

View file

@ -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<Ui::FlatButton> SetupDiscussButton(
return history ? history->peer->asChannel() : nullptr;
}) | rpl::map([=](ChannelData *channel) -> rpl::producer<ChannelData*> {
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<Ui::FlatButton> SetupDiscussButton(
) | rpl::map([=](ChannelData *chat)
-> rpl::producer<std::tuple<int, bool>> {
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*> history) {
return (_history == history.get());
}) | rpl::start_with_next([=](not_null<History*> history) {
updateForwarding();
}, lifetime());
session().data().newMessageSent(
) | rpl::filter([=](not_null<History*> 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<InformBox>(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<InformBox>(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<HistoryItem*> 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<Profile::GroupMembersWidget>(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<HistoryItem*> 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) {

View file

@ -135,8 +135,6 @@ public:
void firstLoadMessages();
void delayedShowAt(MsgId showAtMsgId);
void historyToDown(History *history);
QRect historyRect() const;
void updateFieldPlaceholder();

View file

@ -22,10 +22,6 @@ namespace Api {
struct SendOptions;
} // namespace Api
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace Storage {
struct PreparedList;
} // namespace Storage

View file

@ -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) {

View file

@ -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());
}

View file

@ -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(

View file

@ -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<UserData*> 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<UserData*> 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())

View file

@ -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<int> &&count) {
}
void Cover::initViewers(rpl::producer<QString> 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<QString> 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());

View file

@ -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"

View file

@ -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<UserData*> 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<PeerData*> 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<PeerData*> peer) {
} // namespace
rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> 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<TextWithEntities> PhoneValue(not_null<UserData*> 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<QString> PlainAboutValue(not_null<PeerData*> 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<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
@ -136,9 +142,9 @@ rpl::producer<QString> LinkValue(not_null<PeerData*> peer) {
rpl::producer<const ChannelLocation*> LocationValue(
not_null<ChannelData*> 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<const ChannelLocation*> LocationValue(
rpl::producer<bool> NotificationsEnabledValue(not_null<PeerData*> 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<bool> NotificationsEnabledValue(not_null<PeerData*> peer) {
}
rpl::producer<bool> IsContactValue(not_null<UserData*> 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<bool> CanInviteBotToGroupValue(not_null<UserData*> 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<bool> CanShareContactValue(not_null<UserData*> 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<bool> CanAddContactValue(not_null<UserData*> user) {
}
rpl::producer<bool> AmInChannelValue(not_null<ChannelData*> 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<int> MembersCountValue(not_null<PeerData*> 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<int> MembersCountValue(not_null<PeerData*> peer) {
}
rpl::producer<int> AdminsCountValue(not_null<PeerData*> 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<int> RestrictionsCountValue(not_null<PeerData*> 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<int> RestrictionsCountValue(not_null<PeerData*> peer) {
rpl::producer<not_null<PeerData*>> MigratedOrMeValue(
not_null<PeerData*> 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<not_null<PeerData*>> MigratedOrMeValue(
}
rpl::producer<int> RestrictedCountValue(not_null<ChannelData*> 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<int> RestrictedCountValue(not_null<ChannelData*> channel) {
}
rpl::producer<int> KickedCountValue(not_null<ChannelData*> 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<int> SharedMediaCountValue(
}
rpl::producer<int> CommonGroupsCountValue(not_null<UserData*> 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<bool> CanAddMemberValue(not_null<PeerData*> 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();
});

View file

@ -9,7 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <rpl/producer.h>
#include <rpl/map.h>
#include "observer_peer.h"
struct ChannelLocation;

View file

@ -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<Window::SessionController*> 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(

View file

@ -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 {

View file

@ -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();

View file

@ -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<Storage::Uploader>(_api.get()))
, _storage(std::make_unique<Storage::Facade>())
, _notifications(std::make_unique<Window::Notifications::System>(this))
, _changes(std::make_unique<Data::Changes>(this))
, _data(std::make_unique<Data::Session>(this))
, _user(_data->processUser(user))
, _emojiStickersPack(std::make_unique<Stickers::EmojiPack>(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(

View file

@ -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 &notifications() {
return *_notifications;
}
[[nodiscard]] Data::Changes &changes() {
return *_changes;
}
[[nodiscard]] Data::Session &data() {
return *_data;
}
@ -164,6 +166,7 @@ private:
const std::unique_ptr<Window::Notifications::System> _notifications;
// _data depends on _downloader / _uploader / _notifications.
const std::unique_ptr<Data::Changes> _changes;
const std::unique_ptr<Data::Session> _data;
const not_null<UserData*> _user;

View file

@ -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) {
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) {
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<Data::StickersSet>(
&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<not_null<EmojiPtr>>();
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;

View file

@ -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<HistoryItem*> item);
void cancelForwarding(not_null<History*> 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);

View file

@ -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"

View file

@ -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"

View file

@ -34,10 +34,6 @@ struct Preview;
} // namespace Theme
} // namespace Window
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace Media {
namespace Player {
struct TrackState;

View file

@ -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<PeerUpdate>;
NeverFreedPointer<SmallUpdatesList> SmallUpdates;
using AllUpdatesList = QMap<PeerData*, PeerUpdate>;
NeverFreedPointer<AllUpdatesList> AllUpdates;
void StartCallback() {
SmallUpdates.createIfNull();
AllUpdates.createIfNull();
}
void FinishCallback() {
SmallUpdates.clear();
AllUpdates.clear();
}
base::Observable<PeerUpdate, PeerUpdatedHandler> 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<PeerUpdate, PeerUpdatedHandler> &PeerUpdated() {
return PeerUpdatedObservable;
}
rpl::producer<PeerUpdate> PeerUpdateViewer(
PeerUpdate::Flags flags) {
return [=](const auto &consumer) {
auto lifetime = rpl::lifetime();
lifetime.make_state<base::Subscription>(
PeerUpdated().add_subscription({ flags, [=](
const PeerUpdate &update) {
consumer.put_next_copy(update);
}}));
return lifetime;
};
}
rpl::producer<PeerUpdate> PeerUpdateViewer(
not_null<PeerData*> peer,
PeerUpdate::Flags flags) {
return PeerUpdateViewer(
flags
) | rpl::filter([=](const PeerUpdate &update) {
return (update.peer == peer);
});
}
rpl::producer<PeerUpdate> PeerUpdateValue(
not_null<PeerData*> peer,
PeerUpdate::Flags flags) {
auto initial = PeerUpdate(peer);
initial.flags = flags;
return rpl::single(
initial
) | rpl::then(PeerUpdateViewer(peer, flags));
}
} // namespace Notify

View file

@ -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 <rpl/producer.h>
#include <rpl/filter.h>
#include <rpl/then.h>
#include <rpl/range.h>
#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<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; }
Flags flags = 0;
// NameChanged data
base::flat_set<QChar> 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 <typename Lambda>
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<void(const PeerUpdate&)> _handler;
};
base::Observable<PeerUpdate, PeerUpdatedHandler> &PeerUpdated();
rpl::producer<PeerUpdate> PeerUpdateViewer(
PeerUpdate::Flags flags);
rpl::producer<PeerUpdate> PeerUpdateViewer(
not_null<PeerData*> peer,
PeerUpdate::Flags flags);
rpl::producer<PeerUpdate> PeerUpdateValue(
not_null<PeerData*> peer,
PeerUpdate::Flags flags);
} // namespace Notify

View file

@ -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([=] {

View file

@ -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<UserData*> GroupMembersWidget::Member::user() const {
GroupMembersWidget::GroupMembersWidget(
QWidget *parent,
PeerData *peer,
not_null<PeerData*> 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);

View file

@ -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<PeerData*> 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();

View file

@ -18,10 +18,6 @@ class RippleAnimation;
class PopupMenu;
} // namespace Ui
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace style {
struct PeerListItem;
} // namespace style

View file

@ -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<PeerListRow*> 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(

View file

@ -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*> history) {
void Helper::chatOccupiedUpdated(not_null<History*> 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<UserData*> 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<UserInfo> Helper::infoValue(not_null<UserData*> user) const {
return Notify::PeerUpdateValue(
return user->session().changes().peerFlagsValue(
user,
Notify::PeerUpdate::Flag::UserSupportInfoChanged
Data::PeerUpdate::Flag::SupportInfo
) | rpl::map([=] {
return infoCurrent(user);
});

View file

@ -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();

View file

@ -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<LambdaClickHandler>([] { Ui::show(Box<AboutBox>()); }));
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) {

View file

@ -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<rpl::lifetime>(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<PeerData*> 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<PeerData*> 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*> 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<rpl::lifetime>(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<rpl::lifetime>(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<UserData*> user) {
});
const auto lifetime = Ui::CreateChild<rpl::lifetime>(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);