From 1f8626b3837a70309b7ec93f6189d340ae791d90 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 3 Jan 2019 16:36:01 +0400 Subject: [PATCH] Move App::histories to Data::Session. --- Telegram/SourceFiles/apiwrap.cpp | 27 +- Telegram/SourceFiles/app.cpp | 587 +---------- Telegram/SourceFiles/app.h | 82 +- Telegram/SourceFiles/auth_session.cpp | 16 +- Telegram/SourceFiles/auth_session.h | 4 +- Telegram/SourceFiles/boxes/background_box.cpp | 76 +- .../calls/calls_box_controller.cpp | 4 +- .../chat_helpers/message_field.cpp | 3 +- Telegram/SourceFiles/data/data_feed.cpp | 12 +- .../SourceFiles/data/data_media_types.cpp | 66 +- Telegram/SourceFiles/data/data_peer.cpp | 47 +- Telegram/SourceFiles/data/data_peer.h | 20 +- .../data/data_search_controller.cpp | 4 +- Telegram/SourceFiles/data/data_session.cpp | 947 +++++++++++++++++- Telegram/SourceFiles/data/data_session.h | 127 ++- .../dialogs/dialogs_inner_widget.cpp | 20 +- .../SourceFiles/dialogs/dialogs_layout.cpp | 3 +- Telegram/SourceFiles/history/history.cpp | 371 ++----- Telegram/SourceFiles/history/history.h | 82 +- Telegram/SourceFiles/history/history_item.cpp | 33 +- .../history/history_item_components.cpp | 6 +- .../SourceFiles/history/history_message.cpp | 53 +- .../SourceFiles/history/history_service.cpp | 20 +- .../history/media/history_media.cpp | 4 + .../SourceFiles/history/media/history_media.h | 2 + .../history/media/history_media_contact.cpp | 10 +- .../history/media/history_media_document.cpp | 8 +- .../history/media/history_media_file.cpp | 8 +- .../history/media/history_media_game.cpp | 8 +- .../history/media/history_media_gif.cpp | 18 +- .../history/media/history_media_grouped.cpp | 4 +- .../history/media/history_media_photo.cpp | 4 +- .../history/media/history_media_poll.cpp | 12 +- .../history/media/history_media_video.cpp | 4 +- .../history/media/history_media_web_page.cpp | 6 +- .../history/view/history_view_element.cpp | 27 +- .../history/view/history_view_element.h | 1 + .../history/view/history_view_message.cpp | 3 +- .../view/history_view_top_bar_widget.cpp | 20 +- Telegram/SourceFiles/info/info_controller.cpp | 2 +- Telegram/SourceFiles/mainwidget.cpp | 37 +- Telegram/SourceFiles/mainwidget.h | 8 +- Telegram/SourceFiles/mainwindow.cpp | 4 - Telegram/SourceFiles/messenger.cpp | 20 +- .../SourceFiles/support/support_common.cpp | 12 - Telegram/SourceFiles/support/support_common.h | 2 - .../SourceFiles/support/support_helper.cpp | 6 + Telegram/SourceFiles/support/support_helper.h | 2 + Telegram/SourceFiles/window/main_window.cpp | 3 +- 49 files changed, 1479 insertions(+), 1366 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index b8e75f0a2..6dff51471 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -629,7 +629,7 @@ void ApiWrap::requestContacts() { const auto userId = contact.c_contact().vuser_id.v; if (userId == _session->userId()) { - Auth().user()->setContactStatus( + _session->user()->setContactStatus( UserData::ContactStatus::Contact); } } @@ -1026,6 +1026,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt channel->setKickedCount(f.has_kicked_count() ? f.vkicked_count.v : 0); channel->setInviteLink((f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString()); if (const auto history = App::historyLoaded(channel->id)) { + history->clearUpTill(f.vavailable_min_id.v); history->applyDialogFields( f.vunread_count.v, f.vread_inbox_max_id.v, @@ -1546,7 +1547,7 @@ void ApiWrap::requestSelfParticipant(ChannelData *channel) { channel->inviter = _session->userId(); channel->inviteDate = channel->date; if (channel->mgInfo) { - channel->mgInfo->creator = Auth().user(); + channel->mgInfo->creator = _session->user(); } } break; case mtpc_channelParticipantAdmin: { @@ -2144,7 +2145,7 @@ void ApiWrap::updatePrivacyLastSeens(const QVector &rules) { } auto now = unixtime(); - App::enumerateUsers([&](UserData *user) { + _session->data().enumerateUsers([&](UserData *user) { if (user->isSelf() || user->loadedStatus != PeerData::FullLoaded) { return; } @@ -2276,7 +2277,7 @@ void ApiWrap::saveDraftsToCloud() { if (cloudDraft && cloudDraft->saveRequestId) { request(base::take(cloudDraft->saveRequestId)).cancel(); } - if (!Auth().supportMode()) { + if (!_session->supportMode()) { cloudDraft = history->createCloudDraft(localDraft); } else if (!cloudDraft) { cloudDraft = history->createCloudDraft(nullptr); @@ -2793,7 +2794,7 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs } for (const auto [position, index] : indices) { - const auto item = App::histories().addNewMessage( + const auto item = _session->data().addNewMessage( v->at(index), NewMessageExisting); if (item) { @@ -3230,7 +3231,7 @@ void ApiWrap::applyUpdatesNoPtsCheck(const MTPUpdates &updates) { const auto peerUserId = d.is_out() ? d.vuser_id : MTP_int(_session->userId()); - App::histories().addNewMessage( + _session->data().addNewMessage( MTP_message( MTP_flags(flags), d.vid, @@ -3254,7 +3255,7 @@ void ApiWrap::applyUpdatesNoPtsCheck(const MTPUpdates &updates) { case mtpc_updateShortChatMessage: { auto &d = updates.c_updateShortChatMessage(); auto flags = mtpCastFlags(d.vflags.v) | MTPDmessage::Flag::f_from_id; - App::histories().addNewMessage( + _session->data().addNewMessage( MTP_message( MTP_flags(flags), d.vid, @@ -3296,7 +3297,7 @@ void ApiWrap::applyUpdateNoPtsCheck(const MTPUpdate &update) { } } if (needToAdd) { - App::histories().addNewMessage(d.vmessage, NewMessageUnread); + _session->data().addNewMessage(d.vmessage, NewMessageUnread); } } break; @@ -3354,7 +3355,7 @@ void ApiWrap::applyUpdateNoPtsCheck(const MTPUpdate &update) { } } if (needToAdd) { - App::histories().addNewMessage(d.vmessage, NewMessageUnread); + _session->data().addNewMessage(d.vmessage, NewMessageUnread); } } break; @@ -3521,7 +3522,7 @@ void ApiWrap::requestMessageAfterDate( // App::feedUsers(data.vusers); // App::feedChats(data.vchats); // for (const auto &msg : messages) { - // if (const auto item = App::histories().addNewMessage(msg, type)) { + // if (const auto item = _session->data().addNewMessage(msg, type)) { // if (item->date() >= offsetDate || true) { // callback(item->position()); // return; @@ -4060,7 +4061,7 @@ void ApiWrap::userPhotosDone( // if (!messages.empty()) { // ids.reserve(messages.size()); // for (const auto &msg : messages) { -// if (const auto item = App::histories().addNewMessage(msg, type)) { +// if (const auto item = _session->data().addNewMessage(msg, type)) { // const auto position = item->position(); // if (tooLargePosition(position)) { // accumulateTill(noSkipRange.till, position); @@ -5126,7 +5127,7 @@ void ApiWrap::photoUploadReady( } void ApiWrap::clearPeerPhoto(not_null photo) { - const auto self = Auth().user(); + const auto self = _session->user(); if (self->userpicPhotoId() == photo->id) { request(MTPphotos_UpdateProfilePhoto( MTP_inputPhotoEmpty() @@ -5226,7 +5227,7 @@ void ApiWrap::saveSelfBio(const QString &text, FnMut done) { _saveBioRequestId = 0; App::feedUsers(MTP_vector(1, result)); - Auth().user()->setAbout(_saveBioText); + _session->user()->setAbout(_saveBioText); if (_saveBioDone) { _saveBioDone(); } diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 3b08006a3..814d30ed9 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -50,14 +50,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace { App::LaunchState _launchState = App::Launched; - std::unordered_map> peersData; - using DependentItemsSet = OrderedSet; using DependentItems = QMap; DependentItems dependentItems; - Histories histories; - using MsgsData = QHash; MsgsData msgsData; using ChannelMsgsData = QMap; @@ -131,468 +127,20 @@ namespace App { return nullptr; } - namespace { - // we should get a full restriction in "{fulltype}: {reason}" format and we - // need to find a "-all" tag in {fulltype}, otherwise ignore this restriction - QString extractRestrictionReason(const QString &fullRestriction) { - int fullTypeEnd = fullRestriction.indexOf(':'); - if (fullTypeEnd <= 0) { - return QString(); - } - - // {fulltype} is in "{type}-{tag}-{tag}-{tag}" format - // if we find "all" tag we return the restriction string - auto typeTags = fullRestriction.mid(0, fullTypeEnd).split('-').mid(1); -#ifndef OS_MAC_STORE - auto restrictionApplies = typeTags.contains(qsl("all")); -#else // OS_MAC_STORE - auto restrictionApplies = typeTags.contains(qsl("all")) || typeTags.contains(qsl("ios")); -#endif // OS_MAC_STORE - if (restrictionApplies) { - return fullRestriction.midRef(fullTypeEnd + 1).trimmed().toString(); - } - return QString(); - } - } - UserData *feedUser(const MTPUser &user) { - UserData *data = nullptr; - bool minimal = false; - const MTPUserStatus *status = 0, emptyStatus = MTP_userStatusEmpty(); - - Notify::PeerUpdate update; - using UpdateFlag = Notify::PeerUpdate::Flag; - - switch (user.type()) { - case mtpc_userEmpty: { - auto &d = user.c_userEmpty(); - - auto peer = peerFromUser(d.vid.v); - data = App::user(peer); - auto canShareThisContact = data->canShareThisContactFast(); - - data->input = MTP_inputPeerUser(d.vid, MTP_long(0)); - data->inputUser = MTP_inputUser(d.vid, MTP_long(0)); - data->setName(lang(lng_deleted), QString(), QString(), QString()); - data->setPhoto(MTP_userProfilePhotoEmpty()); - //data->setFlags(MTPDuser_ClientFlag::f_inaccessible | 0); - data->setFlags(MTPDuser::Flag::f_deleted); - if (!data->phone().isEmpty()) { - data->setPhone(QString()); - update.flags |= UpdateFlag::UserPhoneChanged; - } - data->setBotInfoVersion(-1); - status = &emptyStatus; - data->setContactStatus(UserData::ContactStatus::PhoneUnknown); - - if (canShareThisContact != data->canShareThisContactFast()) { - update.flags |= UpdateFlag::UserCanShareContact; - } - } break; - case mtpc_user: { - auto &d = user.c_user(); - minimal = d.is_min(); - - auto peer = peerFromUser(d.vid.v); - data = App::user(peer); - auto canShareThisContact = data->canShareThisContactFast(); - if (minimal) { - auto mask = 0 - //| MTPDuser_ClientFlag::f_inaccessible - | MTPDuser::Flag::f_deleted; - data->setFlags((data->flags() & ~mask) | (d.vflags.v & mask)); - } else { - data->setFlags(d.vflags.v); - if (d.is_self()) { - data->input = MTP_inputPeerSelf(); - data->inputUser = MTP_inputUserSelf(); - } else if (!d.has_access_hash()) { - data->input = MTP_inputPeerUser(d.vid, MTP_long(data->accessHash())); - data->inputUser = MTP_inputUser(d.vid, MTP_long(data->accessHash())); - } else { - data->input = MTP_inputPeerUser(d.vid, d.vaccess_hash); - data->inputUser = MTP_inputUser(d.vid, d.vaccess_hash); - } - if (d.is_restricted()) { - data->setRestrictionReason(extractRestrictionReason(qs(d.vrestriction_reason))); - } else { - data->setRestrictionReason(QString()); - } - } - if (d.is_deleted()) { - if (!data->phone().isEmpty()) { - data->setPhone(QString()); - update.flags |= UpdateFlag::UserPhoneChanged; - } - data->setName(lang(lng_deleted), QString(), QString(), QString()); - data->setPhoto(MTP_userProfilePhotoEmpty()); - status = &emptyStatus; - } else { - // apply first_name and last_name from minimal user only if we don't have - // local values for first name and last name already, otherwise skip - bool noLocalName = data->firstName.isEmpty() && data->lastName.isEmpty(); - QString fname = (!minimal || noLocalName) ? (d.has_first_name() ? TextUtilities::SingleLine(qs(d.vfirst_name)) : QString()) : data->firstName; - QString lname = (!minimal || noLocalName) ? (d.has_last_name() ? TextUtilities::SingleLine(qs(d.vlast_name)) : QString()) : data->lastName; - - QString phone = minimal ? data->phone() : (d.has_phone() ? qs(d.vphone) : QString()); - QString uname = minimal ? data->username : (d.has_username() ? TextUtilities::SingleLine(qs(d.vusername)) : QString()); - - bool phoneChanged = (data->phone() != phone); - if (phoneChanged) { - data->setPhone(phone); - update.flags |= UpdateFlag::UserPhoneChanged; - } - bool nameChanged = (data->firstName != fname) || (data->lastName != lname); - - bool showPhone = !isServiceUser(data->id) - && !d.is_self() - && !d.is_contact() - && !d.is_mutual_contact(); - bool showPhoneChanged = !isServiceUser(data->id) - && !d.is_self() - && ((showPhone - && data->contactStatus() == UserData::ContactStatus::Contact) - || (!showPhone - && data->contactStatus() == UserData::ContactStatus::CanAdd)); - if (minimal) { - showPhoneChanged = false; - showPhone = !isServiceUser(data->id) - && (data->id != Auth().userPeerId()) - && (data->contactStatus() == UserData::ContactStatus::CanAdd); - } - - // see also Local::readPeer - - const auto pname = (showPhoneChanged || phoneChanged || nameChanged) - ? ((showPhone && !phone.isEmpty()) - ? formatPhone(phone) - : QString()) - : data->nameOrPhone; - - if (!minimal && d.is_self() && uname != data->username) { - CrashReports::SetAnnotation("Username", uname); - } - data->setName(fname, lname, pname, uname); - if (d.has_photo()) { - data->setPhoto(d.vphoto); - } else { - data->setPhoto(MTP_userProfilePhotoEmpty()); - } - if (d.has_access_hash()) { - data->setAccessHash(d.vaccess_hash.v); - } - status = d.has_status() ? &d.vstatus : &emptyStatus; - } - if (!minimal) { - if (d.has_bot_info_version()) { - data->setBotInfoVersion(d.vbot_info_version.v); - data->botInfo->readsAllHistory = d.is_bot_chat_history(); - if (data->botInfo->cantJoinGroups != d.is_bot_nochats()) { - data->botInfo->cantJoinGroups = d.is_bot_nochats(); - update.flags |= UpdateFlag::BotCanAddToGroups; - } - data->botInfo->inlinePlaceholder = d.has_bot_inline_placeholder() ? '_' + qs(d.vbot_inline_placeholder) : QString(); - } else { - data->setBotInfoVersion(-1); - } - data->setContactStatus((d.is_contact() || d.is_mutual_contact()) - ? UserData::ContactStatus::Contact - : data->phone().isEmpty() - ? UserData::ContactStatus::PhoneUnknown - : UserData::ContactStatus::CanAdd); - } - - if (canShareThisContact != data->canShareThisContactFast()) { - update.flags |= UpdateFlag::UserCanShareContact; - } - } break; - } - - if (!data) { - return nullptr; - } - - if (minimal) { - if (data->loadedStatus == PeerData::NotLoaded) { - data->loadedStatus = PeerData::MinimalLoaded; - } - } else if (data->loadedStatus != PeerData::FullLoaded - && (!data->isSelf() || !data->phone().isEmpty())) { - data->loadedStatus = PeerData::FullLoaded; - } - - if (status && !minimal) { - const auto oldOnlineTill = data->onlineTill; - const auto newOnlineTill = ApiWrap::OnlineTillFromStatus( - *status, - oldOnlineTill); - if (oldOnlineTill != newOnlineTill) { - data->onlineTill = newOnlineTill; - update.flags |= UpdateFlag::UserOnlineChanged; - } - } - - if (data->contactStatus() == UserData::ContactStatus::PhoneUnknown - && !data->phone().isEmpty() - && !data->isSelf()) { - data->setContactStatus(UserData::ContactStatus::CanAdd); - } - if (App::main()) { - if (update.flags) { - update.peer = data; - Notify::peerUpdatedDelayed(update); - } - } - return data; + return Auth().data().user(user); } UserData *feedUsers(const MTPVector &users) { - UserData *result = nullptr; - for_const (auto &user, users.v) { - if (auto feededUser = feedUser(user)) { - result = feededUser; - } - } - - return result; + return Auth().data().processUsers(users); } PeerData *feedChat(const MTPChat &chat) { - PeerData *data = nullptr; - bool minimal = false; - - Notify::PeerUpdate update; - using UpdateFlag = Notify::PeerUpdate::Flag; - - switch (chat.type()) { - case mtpc_chat: { - auto &d(chat.c_chat()); - - data = App::chat(peerFromChat(d.vid.v)); - auto cdata = data->asChat(); - auto canEdit = cdata->canEdit(); - - if (cdata->version < d.vversion.v) { - cdata->version = d.vversion.v; - cdata->invalidateParticipants(); - } - - data->input = MTP_inputPeerChat(d.vid); - cdata->setName(qs(d.vtitle)); - cdata->setPhoto(d.vphoto); - cdata->date = d.vdate.v; - - if (d.has_migrated_to() && d.vmigrated_to.type() == mtpc_inputChannel) { - auto &c = d.vmigrated_to.c_inputChannel(); - auto channel = App::channel(peerFromChannel(c.vchannel_id)); - channel->addFlags(MTPDchannel::Flag::f_megagroup); - if (!channel->access) { - channel->input = MTP_inputPeerChannel(c.vchannel_id, c.vaccess_hash); - channel->inputChannel = d.vmigrated_to; - channel->access = d.vmigrated_to.c_inputChannel().vaccess_hash.v; - } - bool updatedTo = (cdata->migrateToPtr != channel), updatedFrom = (channel->mgInfo->migrateFromPtr != cdata); - if (updatedTo) { - cdata->migrateToPtr = channel; - } - if (updatedFrom) { - channel->mgInfo->migrateFromPtr = cdata; - if (auto h = App::historyLoaded(cdata->id)) { - if (auto hto = App::historyLoaded(channel->id)) { - if (!h->isEmpty()) { - h->unloadBlocks(); - } - if (hto->inChatList(Dialogs::Mode::All) && h->inChatList(Dialogs::Mode::All)) { - App::main()->removeDialog(h); - } - } - } - Notify::migrateUpdated(channel); - update.flags |= UpdateFlag::MigrationChanged; - } - if (updatedTo) { - Notify::migrateUpdated(cdata); - update.flags |= UpdateFlag::MigrationChanged; - } - } - - if (!(cdata->flags() & MTPDchat::Flag::f_admins_enabled) && (d.vflags.v & MTPDchat::Flag::f_admins_enabled)) { - cdata->invalidateParticipants(); - } - cdata->setFlags(d.vflags.v); - - cdata->count = d.vparticipants_count.v; - if (canEdit != cdata->canEdit()) { - update.flags |= UpdateFlag::ChatCanEdit; - } - } break; - case mtpc_chatForbidden: { - auto &d(chat.c_chatForbidden()); - - data = App::chat(peerFromChat(d.vid.v)); - auto cdata = data->asChat(); - auto canEdit = cdata->canEdit(); - - data->input = MTP_inputPeerChat(d.vid); - cdata->setName(qs(d.vtitle)); - cdata->setPhoto(MTP_chatPhotoEmpty()); - cdata->date = 0; - cdata->count = -1; - cdata->invalidateParticipants(); - cdata->setFlags(MTPDchat_ClientFlag::f_forbidden | 0); - if (canEdit != cdata->canEdit()) { - update.flags |= UpdateFlag::ChatCanEdit; - } - } break; - case mtpc_channel: { - const auto &d = chat.c_channel(); - - const auto peerId = peerFromChannel(d.vid.v); - minimal = d.is_min(); - if (minimal) { - data = App::channelLoaded(peerId); - if (!data) { - // Can't apply minimal to a not loaded channel. - // Need to make getDifference. - return nullptr; - } - } else { - data = App::channel(peerId); - const auto accessHash = d.has_access_hash() - ? d.vaccess_hash - : MTP_long(0); - data->input = MTP_inputPeerChannel(d.vid, accessHash); - } - - const auto cdata = data->asChannel(); - const auto wasInChannel = cdata->amIn(); - const auto canViewAdmins = cdata->canViewAdmins(); - const auto canViewMembers = cdata->canViewMembers(); - const auto canAddMembers = cdata->canAddMembers(); - - if (d.has_participants_count()) { - cdata->setMembersCount(d.vparticipants_count.v); - } - if (minimal) { - auto mask = 0 - | MTPDchannel::Flag::f_broadcast - | MTPDchannel::Flag::f_verified - | MTPDchannel::Flag::f_megagroup - | MTPDchannel::Flag::f_democracy - | MTPDchannel_ClientFlag::f_forbidden; - cdata->setFlags((cdata->flags() & ~mask) | (d.vflags.v & mask)); - } else { - if (d.has_admin_rights()) { - cdata->setAdminRights(d.vadmin_rights); - } else if (cdata->hasAdminRights()) { - cdata->setAdminRights(MTP_channelAdminRights(MTP_flags(0))); - } - if (d.has_banned_rights()) { - cdata->setRestrictedRights(d.vbanned_rights); - } else if (cdata->hasRestrictions()) { - cdata->setRestrictedRights(MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); - } - cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash); - cdata->access = d.vaccess_hash.v; - cdata->date = d.vdate.v; - if (cdata->version < d.vversion.v) { - cdata->version = d.vversion.v; - } - if (d.is_restricted()) { - cdata->setRestrictionReason(extractRestrictionReason(qs(d.vrestriction_reason))); - } else { - cdata->setRestrictionReason(QString()); - } - cdata->setFlags(d.vflags.v); - //if (d.has_feed_id()) { // #feed - // cdata->setFeed(Auth().data().feed(d.vfeed_id.v)); - //} else { - // cdata->clearFeed(); - //} - } - - QString uname = d.has_username() ? TextUtilities::SingleLine(qs(d.vusername)) : QString(); - cdata->setName(qs(d.vtitle), uname); - - cdata->setPhoto(d.vphoto); - - if (wasInChannel != cdata->amIn()) { - update.flags |= UpdateFlag::ChannelAmIn; - } - if (canViewAdmins != cdata->canViewAdmins() - || canViewMembers != cdata->canViewMembers() - || canAddMembers != cdata->canAddMembers()) { - update.flags |= UpdateFlag::ChannelRightsChanged; - } - } break; - case mtpc_channelForbidden: { - auto &d(chat.c_channelForbidden()); - - auto peerId = peerFromChannel(d.vid.v); - data = App::channel(peerId); - data->input = MTP_inputPeerChannel(d.vid, d.vaccess_hash); - - auto cdata = data->asChannel(); - auto wasInChannel = cdata->amIn(); - auto canViewAdmins = cdata->canViewAdmins(); - auto canViewMembers = cdata->canViewMembers(); - auto canAddMembers = cdata->canAddMembers(); - - cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash); - - auto mask = mtpCastFlags(MTPDchannelForbidden::Flag::f_broadcast | MTPDchannelForbidden::Flag::f_megagroup); - cdata->setFlags((cdata->flags() & ~mask) | (mtpCastFlags(d.vflags) & mask) | MTPDchannel_ClientFlag::f_forbidden); - - if (cdata->hasAdminRights()) { - cdata->setAdminRights(MTP_channelAdminRights(MTP_flags(0))); - } - if (cdata->hasRestrictions()) { - cdata->setRestrictedRights(MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); - } - - cdata->setName(qs(d.vtitle), QString()); - - cdata->access = d.vaccess_hash.v; - cdata->setPhoto(MTP_chatPhotoEmpty()); - cdata->date = 0; - cdata->setMembersCount(0); - - if (wasInChannel != cdata->amIn()) { - update.flags |= UpdateFlag::ChannelAmIn; - } - if (canViewAdmins != cdata->canViewAdmins() - || canViewMembers != cdata->canViewMembers() - || canAddMembers != cdata->canAddMembers()) { - update.flags |= UpdateFlag::ChannelRightsChanged; - } - } break; - } - if (!data) { - return nullptr; - } - - if (minimal) { - if (data->loadedStatus == PeerData::NotLoaded) { - data->loadedStatus = PeerData::MinimalLoaded; - } - } else if (data->loadedStatus != PeerData::FullLoaded) { - data->loadedStatus = PeerData::FullLoaded; - } - if (update.flags) { - update.peer = data; - Notify::peerUpdatedDelayed(update); - } - return data; + return Auth().data().chat(chat); } PeerData *feedChats(const MTPVector &chats) { - PeerData *result = nullptr; - for_const (auto &chat, chats.v) { - if (auto feededChat = feedChat(chat)) { - result = feededChat; - } - } - return result; + return Auth().data().processChats(chats); } void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos) { @@ -934,7 +482,7 @@ namespace App { indices.emplace((uint64(uint32(msgId)) << 32) | uint64(i), i); } for (const auto [position, index] : indices) { - histories().addNewMessage(msgs[index], type); + Auth().data().addNewMessage(msgs[index], type); } } @@ -1088,95 +636,41 @@ namespace App { } } - PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction) { - if (!id) { - return nullptr; - } - - auto i = peersData.find(id); - if (i == peersData.cend()) { - auto newData = [&]() -> std::unique_ptr { - if (peerIsUser(id)) { - return std::make_unique(id); - } else if (peerIsChat(id)) { - return std::make_unique(id); - } else if (peerIsChannel(id)) { - return std::make_unique(id); - } - Unexpected("Peer id type."); - }(); - - newData->input = MTPinputPeer(MTP_inputPeerEmpty()); - i = peersData.emplace(id, std::move(newData)).first; - } - switch (restriction) { - case PeerData::MinimalLoaded: { - if (i->second->loadedStatus == PeerData::NotLoaded) { - return nullptr; - } - } break; - case PeerData::FullLoaded: { - if (i->second->loadedStatus != PeerData::FullLoaded) { - return nullptr; - } - } break; - } - return i->second.get(); + not_null peer(PeerId id) { + return Auth().data().peer(id); } - - void enumerateUsers(Fn)> action) { - for (const auto &[peerId, peer] : peersData) { - if (const auto user = peer->asUser()) { - action(user); - } - } + not_null user(UserId id) { + return Auth().data().user(id); } - - void enumerateGroups(Fn)> action) { - for (const auto &[peerId, peer] : peersData) { - if (peer->isChat() || peer->isMegagroup()) { - action(peer.get()); - } - } + not_null chat(ChatId id) { + return Auth().data().chat(id); } - - void enumerateChannels(Fn)> action) { - for (const auto &[peerId, peer] : peersData) { - if (const auto channel = peer->asChannel()) { - if (!channel->isMegagroup()) { - action(channel); - } - } - } + not_null channel(ChannelId id) { + return Auth().data().channel(id); } - - PeerData *peerByName(const QString &username) { - const auto uname = username.trimmed(); - for (const auto &[peerId, peer] : peersData) { - if (!peer->userName().compare(uname, Qt::CaseInsensitive)) { - return peer.get(); - } - } - return nullptr; + PeerData *peerLoaded(PeerId id) { + return Auth().data().peerLoaded(id); + } + UserData *userLoaded(UserId id) { + return Auth().data().userLoaded(id); + } + ChatData *chatLoaded(ChatId id) { + return Auth().data().chatLoaded(id); + } + ChannelData *channelLoaded(ChannelId id) { + return Auth().data().channelLoaded(id); } QString peerName(const PeerData *peer, bool forDialogs) { return peer ? ((forDialogs && peer->isUser() && !peer->asUser()->nameOrPhone.isEmpty()) ? peer->asUser()->nameOrPhone : peer->name) : lang(lng_deleted); } - Histories &histories() { - return ::histories; + not_null history(PeerId peer) { + return Auth().data().history(peer); } - not_null history(const PeerId &peer) { - return ::histories.findOrInsert(peer); - } - - History *historyLoaded(const PeerId &peer) { - if (!peer) { - return nullptr; - } - return ::histories.find(peer); + History *historyLoaded(PeerId peer) { + return Auth().data().historyLoaded(peer); } HistoryItem *histItemById(ChannelId channelId, MsgId itemId) { @@ -1224,7 +718,7 @@ namespace App { dependent->dependencyItemRemoved(item); } } - Auth().notifications().clearFromItem(item); + item->history()->session().notifications().clearFromItem(item); } void historyUpdateDependent(not_null item) { @@ -1261,12 +755,6 @@ namespace App { cSetSavedPeers(SavedPeers()); cSetSavedPeersByTime(SavedPeersByTime()); cSetRecentInlineBots(RecentInlineBots()); - - peersData.clear(); - - if (AuthSession::Exists()) { - Auth().api().clearWebPageRequests(); - } cSetRecentStickers(RecentStickerPack()); cSetReportSpamStatuses(ReportSpamStatuses()); } @@ -1444,21 +932,6 @@ namespace App { }); } - void clearHistories() { - ClickHandler::clearActive(); - ClickHandler::unpressed(); - - if (AuthSession::Exists()) { - // Clear notifications to prevent any showNotification() calls while destroying items. - Auth().notifications().clearAllFast(); - } - - histories().clear(); - - Images::ClearRemote(); - cSetServerBackgrounds(WallPapers()); - } - void deinitMedia() { clearCorners(); @@ -1772,6 +1245,4 @@ namespace App { roundRect(p, x, y, w, h, bg, i.value(), nullptr, parts); } - WallPapers gServerBackgrounds; - } diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index f43005dca..5c057086d 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -17,7 +17,6 @@ class MainWindow; class MainWidget; class HistoryItem; class History; -class Histories; namespace HistoryView { class Element; } // namespace HistoryView @@ -90,68 +89,31 @@ namespace App { ImagePtr image(const MTPPhotoSize &size); - PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded); - inline UserData *user(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asUser(peer(id, restriction)); - } - inline ChatData *chat(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asChat(peer(id, restriction)); - } - inline ChannelData *channel(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asChannel(peer(id, restriction)); - } - inline UserData *user(UserId userId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asUser(peer(peerFromUser(userId), restriction)); - } - inline ChatData *chat(ChatId chatId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asChat(peer(peerFromChat(chatId), restriction)); - } - inline ChannelData *channel(ChannelId channelId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) { - return asChannel(peer(peerFromChannel(channelId), restriction)); - } - inline PeerData *peerLoaded(const PeerId &id) { - return peer(id, PeerData::FullLoaded); - } - inline UserData *userLoaded(const PeerId &id) { - return user(id, PeerData::FullLoaded); - } - inline ChatData *chatLoaded(const PeerId &id) { - return chat(id, PeerData::FullLoaded); - } - inline ChannelData *channelLoaded(const PeerId &id) { - return channel(id, PeerData::FullLoaded); - } - inline UserData *userLoaded(UserId userId) { - return user(userId, PeerData::FullLoaded); - } - inline ChatData *chatLoaded(ChatId chatId) { - return chat(chatId, PeerData::FullLoaded); - } - inline ChannelData *channelLoaded(ChannelId channelId) { - return channel(channelId, PeerData::FullLoaded); - } - void enumerateUsers(Fn)> action); - void enumerateGroups(Fn)> action); - void enumerateChannels(Fn)> action); + [[nodiscard]] not_null peer(PeerId id); + [[nodiscard]] not_null user(UserId userId); + [[nodiscard]] not_null chat(ChatId chatId); + [[nodiscard]] not_null channel(ChannelId channelId); + [[nodiscard]] PeerData *peerLoaded(PeerId id); + [[nodiscard]] UserData *userLoaded(UserId userId); + [[nodiscard]] ChatData *chatLoaded(ChatId chatId); + [[nodiscard]] ChannelData *channelLoaded(ChannelId channelId); - PeerData *peerByName(const QString &username); - QString peerName(const PeerData *peer, bool forDialogs = false); + [[nodiscard]] QString peerName(const PeerData *peer, bool forDialogs = false); - Histories &histories(); - not_null history(const PeerId &peer); - History *historyLoaded(const PeerId &peer); - HistoryItem *histItemById(ChannelId channelId, MsgId itemId); - inline not_null history(const PeerData *peer) { + [[nodiscard]] not_null history(PeerId peer); + [[nodiscard]] History *historyLoaded(PeerId peer); + [[nodiscard]] HistoryItem *histItemById(ChannelId channelId, MsgId itemId); + [[nodiscard]] inline not_null history(const PeerData *peer) { Assert(peer != nullptr); return history(peer->id); } - inline History *historyLoaded(const PeerData *peer) { + [[nodiscard]] inline History *historyLoaded(const PeerData *peer) { return peer ? historyLoaded(peer->id) : nullptr; } - inline HistoryItem *histItemById(const ChannelData *channel, MsgId itemId) { + [[nodiscard]] inline HistoryItem *histItemById(const ChannelData *channel, MsgId itemId) { return histItemById(channel ? peerToChannel(channel->id) : 0, itemId); } - inline HistoryItem *histItemById(const FullMsgId &msgId) { + [[nodiscard]] inline HistoryItem *histItemById(const FullMsgId &msgId) { return histItemById(msgId.channel, msgId.msg); } void historyRegItem(not_null item); @@ -183,8 +145,6 @@ namespace App { const style::font &monofont(); - void clearHistories(); - void initMedia(); void deinitMedia(); @@ -222,14 +182,4 @@ namespace App { return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts); } - struct WallPaper { - WallPaper(int32 id, ImagePtr thumb, ImagePtr full) : id(id), thumb(thumb), full(full) { - } - int32 id; - ImagePtr thumb; - ImagePtr full; - }; - typedef QList WallPapers; - DeclareSetting(WallPapers, ServerBackgrounds); - }; diff --git a/Telegram/SourceFiles/auth_session.cpp b/Telegram/SourceFiles/auth_session.cpp index d5cd2811b..27d3544c4 100644 --- a/Telegram/SourceFiles/auth_session.cpp +++ b/Telegram/SourceFiles/auth_session.cpp @@ -377,8 +377,7 @@ AuthSession &Auth() { } AuthSession::AuthSession(const MTPUser &user) -: _user(App::user(user.match([](const auto &data) { return data.vid.v; }))) -, _autoLockTimer([this] { checkAutoLock(); }) +: _autoLockTimer([this] { checkAutoLock(); }) , _api(std::make_unique(this)) , _calls(std::make_unique()) , _downloader(std::make_unique()) @@ -386,13 +385,9 @@ AuthSession::AuthSession(const MTPUser &user) , _storage(std::make_unique()) , _notifications(std::make_unique(this)) , _data(std::make_unique(this)) +, _user(_data->user(user)) , _changelogs(Core::Changelogs::Create(this)) -, _supportHelper( - (Support::ValidateAccount(user) - ? std::make_unique(this) - : nullptr)) { - App::feedUser(user); - +, _supportHelper(Support::Helper::Create(this)) { _saveDataTimer.setCallback([=] { Local::writeUserSettings(); }); @@ -515,4 +510,7 @@ Support::Templates& AuthSession::supportTemplates() const { return supportHelper().templates(); } -AuthSession::~AuthSession() = default; +AuthSession::~AuthSession() { + ClickHandler::clearActive(); + ClickHandler::unpressed(); +} diff --git a/Telegram/SourceFiles/auth_session.h b/Telegram/SourceFiles/auth_session.h index 411aa72b3..cd723d9e8 100644 --- a/Telegram/SourceFiles/auth_session.h +++ b/Telegram/SourceFiles/auth_session.h @@ -345,7 +345,6 @@ public: private: static constexpr auto kDefaultSaveDelay = TimeMs(1000); - const not_null _user; AuthSessionSettings _settings; base::Timer _saveDataTimer; @@ -359,8 +358,9 @@ private: const std::unique_ptr _storage; const std::unique_ptr _notifications; - // _data depends on _downloader / _uploader, including destructor. + // _data depends on _downloader / _uploader / _notifications. const std::unique_ptr _data; + const not_null _user; // _changelogs depends on _data, subscribes on chats loading event. const std::unique_ptr _changelogs; diff --git a/Telegram/SourceFiles/boxes/background_box.cpp b/Telegram/SourceFiles/boxes/background_box.cpp index 9a3db52fc..360fa7bb6 100644 --- a/Telegram/SourceFiles/boxes/background_box.cpp +++ b/Telegram/SourceFiles/boxes/background_box.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/round_checkbox.h" #include "ui/image/image.h" #include "auth_session.h" +#include "data/data_session.h" #include "styles/style_overview.h" #include "styles/style_boxes.h" @@ -53,18 +54,20 @@ BackgroundBox::BackgroundBox(QWidget*) { void BackgroundBox::prepare() { setTitle(langFactory(lng_backgrounds_header)); - addButton(langFactory(lng_close), [this] { closeBox(); }); + addButton(langFactory(lng_close), [=] { closeBox(); }); setDimensions(st::boxWideWidth, st::boxMaxListHeight); _inner = setInnerWidget(object_ptr(this), st::backgroundScroll); - _inner->setBackgroundChosenCallback([this](int index) { backgroundChosen(index); }); + _inner->setBackgroundChosenCallback([=](int index) { + backgroundChosen(index); + }); } void BackgroundBox::backgroundChosen(int index) { - if (index >= 0 && index < App::cServerBackgrounds().size()) { - auto &paper = App::cServerBackgrounds()[index]; - if (App::main()) App::main()->setChatBackground(paper); + if (index >= 0 && index < Auth().data().wallpapersCount()) { + const auto &paper = Auth().data().wallpaper(index); + App::main()->setChatBackground(paper); using Update = Window::Theme::BackgroundUpdate; Window::Theme::Background()->notify(Update(Update::Type::Start, !paper.id)); @@ -75,7 +78,7 @@ void BackgroundBox::backgroundChosen(int index) { BackgroundBox::Inner::Inner(QWidget *parent) : TWidget(parent) , _check(std::make_unique(st::overviewCheck, [this] { update(); })) { _check->setChecked(true, Ui::RoundCheckbox::SetStyle::Fast); - if (App::cServerBackgrounds().isEmpty()) { + if (!Auth().data().wallpapersCount()) { resize(BackgroundsInRow * (st::backgroundSize.width() + st::backgroundPadding) + st::backgroundPadding, 2 * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding); MTP::send(MTPaccount_GetWallPapers(), rpcDone(&Inner::gotWallpapers)); } else { @@ -92,65 +95,12 @@ BackgroundBox::Inner::Inner(QWidget *parent) : TWidget(parent) } void BackgroundBox::Inner::gotWallpapers(const MTPVector &result) { - App::WallPapers wallpapers; - - auto oldBackground = Images::Create(qsl(":/gui/art/bg_initial.jpg"), "JPG"); - wallpapers.push_back(App::WallPaper(Window::Theme::kInitialBackground, oldBackground, oldBackground)); - auto &v = result.v; - for_const (auto &w, v) { - switch (w.type()) { - case mtpc_wallPaper: { - auto &d = w.c_wallPaper(); - auto &sizes = d.vsizes.v; - const MTPPhotoSize *thumb = 0, *full = 0; - int32 thumbLevel = -1, fullLevel = -1; - for (QVector::const_iterator j = sizes.cbegin(), e = sizes.cend(); j != e; ++j) { - char size = 0; - int32 w = 0, h = 0; - switch (j->type()) { - case mtpc_photoSize: { - auto &s = j->c_photoSize().vtype.v; - if (s.size()) size = s[0]; - w = j->c_photoSize().vw.v; - h = j->c_photoSize().vh.v; - } break; - - case mtpc_photoCachedSize: { - auto &s = j->c_photoCachedSize().vtype.v; - if (s.size()) size = s[0]; - w = j->c_photoCachedSize().vw.v; - h = j->c_photoCachedSize().vh.v; - } break; - } - if (!size || !w || !h) continue; - - int32 newThumbLevel = qAbs((st::backgroundSize.width() * cIntRetinaFactor()) - w), newFullLevel = qAbs(2560 - w); - if (thumbLevel < 0 || newThumbLevel < thumbLevel) { - thumbLevel = newThumbLevel; - thumb = &(*j); - } - if (fullLevel < 0 || newFullLevel < fullLevel) { - fullLevel = newFullLevel; - full = &(*j); - } - } - if (thumb && full && full->type() != mtpc_photoSizeEmpty) { - wallpapers.push_back(App::WallPaper(d.vid.v ? d.vid.v : INT_MAX, App::image(*thumb), App::image(*full))); - } - } break; - - case mtpc_wallPaperSolid: { - auto &d = w.c_wallPaperSolid(); - } break; - } - } - - App::cSetServerBackgrounds(wallpapers); + Auth().data().setWallpapers(result.v); updateWallpapers(); } void BackgroundBox::Inner::updateWallpapers() { - _bgCount = App::cServerBackgrounds().size(); + _bgCount = Auth().data().wallpapersCount(); _rows = _bgCount / BackgroundsInRow; if (_bgCount % BackgroundsInRow) ++_rows; @@ -158,7 +108,7 @@ void BackgroundBox::Inner::updateWallpapers() { for (int i = 0; i < BackgroundsInRow * 3; ++i) { if (i >= _bgCount) break; - App::cServerBackgrounds()[i].thumb->load(Data::FileOrigin()); + Auth().data().wallpaper(i).thumb->load(Data::FileOrigin()); } } @@ -173,7 +123,7 @@ void BackgroundBox::Inner::paintEvent(QPaintEvent *e) { int index = i * BackgroundsInRow + j; if (index >= _bgCount) break; - const auto &paper = App::cServerBackgrounds()[index]; + const auto &paper = Auth().data().wallpaper(index); paper.thumb->load(Data::FileOrigin()); int x = st::backgroundPadding + j * (st::backgroundSize.width() + st::backgroundPadding); diff --git a/Telegram/SourceFiles/calls/calls_box_controller.cpp b/Telegram/SourceFiles/calls/calls_box_controller.cpp index 33cfe65a8..079d68b0e 100644 --- a/Telegram/SourceFiles/calls/calls_box_controller.cpp +++ b/Telegram/SourceFiles/calls/calls_box_controller.cpp @@ -302,11 +302,11 @@ void BoxController::receivedCalls(const QVector &result) { _allLoaded = true; } - for_const (auto &message, result) { + for (const auto &message : result) { auto msgId = IdFromMessage(message); auto peerId = PeerFromMessage(message); if (auto peer = App::peerLoaded(peerId)) { - auto item = App::histories().addNewMessage(message, NewMessageExisting); + auto item = Auth().data().addNewMessage(message, NewMessageExisting); insertRow(item, InsertWay::Append); } else { LOG(("API Error: a search results with not loaded peer %1").arg(peerId)); diff --git a/Telegram/SourceFiles/chat_helpers/message_field.cpp b/Telegram/SourceFiles/chat_helpers/message_field.cpp index 9c77df998..43d8a8758 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.cpp +++ b/Telegram/SourceFiles/chat_helpers/message_field.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/qthelp_url.h" #include "boxes/abstract_box.h" #include "ui/wrap/vertical_layout.h" +#include "data/data_session.h" #include "chat_helpers/emoji_suggestions_widget.h" #include "window/window_controller.h" #include "lang/lang_keys.h" @@ -376,7 +377,7 @@ InlineBotQuery ParseInlineBotQuery(not_null field) { auto username = text.midRef(inlineUsernameStart, inlineUsernameLength); if (username != result.username) { result.username = username.toString(); - if (const auto peer = App::peerByName(result.username)) { + if (const auto peer = Auth().data().peerByUsername(result.username)) { if (const auto user = peer->asUser()) { result.bot = peer->asUser(); } else { diff --git a/Telegram/SourceFiles/data/data_feed.cpp b/Telegram/SourceFiles/data/data_feed.cpp index 09cf66e9f..713544562 100644 --- a/Telegram/SourceFiles/data/data_feed.cpp +++ b/Telegram/SourceFiles/data/data_feed.cpp @@ -369,15 +369,15 @@ void Feed::changedInChatListHook(Dialogs::Mode list, bool added) { const auto nonMutedCount = count - mutedCount; const auto mutedDelta = added ? mutedCount : -mutedCount; const auto nonMutedDelta = added ? nonMutedCount : -nonMutedCount; - App::histories().unreadIncrement(nonMutedDelta, false); - App::histories().unreadIncrement(mutedDelta, true); + Auth().data().unreadIncrement(nonMutedDelta, false); + Auth().data().unreadIncrement(mutedDelta, true); const auto fullMuted = (nonMutedCount == 0); const auto entriesWithUnreadDelta = added ? 1 : -1; const auto mutedEntriesWithUnreadDelta = fullMuted ? entriesWithUnreadDelta : 0; - App::histories().unreadEntriesChanged( + Auth().data().unreadEntriesChanged( entriesWithUnreadDelta, mutedEntriesWithUnreadDelta); } @@ -402,11 +402,11 @@ void Feed::updateUnreadCounts(PerformUpdate &&performUpdate) { const auto nowFullMuted = (nowUnreadMutedCount > 0) && (nowUnreadCount == nowUnreadMutedCount); - App::histories().unreadIncrement( + Auth().data().unreadIncrement( (nowUnreadCount - nowUnreadMutedCount) - (wasUnreadCount - wasUnreadMutedCount), false); - App::histories().unreadIncrement( + Auth().data().unreadIncrement( nowUnreadMutedCount - wasUnreadMutedCount, true); @@ -420,7 +420,7 @@ void Feed::updateUnreadCounts(PerformUpdate &&performUpdate) { : (wasFullMuted && !nowFullMuted) ? -1 : 0; - App::histories().unreadEntriesChanged( + Auth().data().unreadEntriesChanged( entriesDelta, mutedEntriesDelta); } diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index e29fe3bfc..8d0b5346f 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "data/data_media_types.h" +#include "history/history.h" #include "history/history_item.h" #include "history/history_location_manager.h" #include "history/view/history_view_element.h" @@ -35,7 +36,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_web_page.h" #include "data/data_poll.h" #include "lang/lang_keys.h" -#include "auth_session.h" #include "layout.h" namespace Data { @@ -63,7 +63,9 @@ Call ComputeCallData(const MTPDmessageActionPhoneCall &call) { return result; } -Invoice ComputeInvoiceData(const MTPDmessageMediaInvoice &data) { +Invoice ComputeInvoiceData( + not_null item, + const MTPDmessageMediaInvoice &data) { auto result = Invoice(); result.isTest = data.is_test(); result.amount = data.vtotal_amount.v; @@ -74,7 +76,7 @@ Invoice ComputeInvoiceData(const MTPDmessageMediaInvoice &data) { result.receiptMsgId = data.vreceipt_msg_id.v; } if (data.has_photo()) { - result.photo = Auth().data().photoFromWeb(data.vphoto); + result.photo = item->history()->owner().photoFromWeb(data.vphoto); } return result; } @@ -241,7 +243,7 @@ MediaPhoto::MediaPhoto( not_null photo) : Media(parent) , _photo(photo) { - Auth().data().registerPhotoItem(_photo, parent); + parent->history()->owner().registerPhotoItem(_photo, parent); } MediaPhoto::MediaPhoto( @@ -251,11 +253,11 @@ MediaPhoto::MediaPhoto( : Media(parent) , _photo(photo) , _chat(chat) { - Auth().data().registerPhotoItem(_photo, parent); + parent->history()->owner().registerPhotoItem(_photo, parent); } MediaPhoto::~MediaPhoto() { - Auth().data().unregisterPhotoItem(_photo, parent()); + parent()->history()->owner().unregisterPhotoItem(_photo, parent()); } std::unique_ptr MediaPhoto::clone(not_null parent) { @@ -336,7 +338,7 @@ bool MediaPhoto::updateInlineResultMedia(const MTPMessageMedia &media) { } auto &data = media.c_messageMediaPhoto(); if (data.has_photo() && !data.has_ttl_seconds()) { - const auto photo = Auth().data().photo(data.vphoto); + const auto photo = parent()->history()->owner().photo(data.vphoto); if (photo == _photo) { return true; } else { @@ -362,7 +364,7 @@ bool MediaPhoto::updateSentMedia(const MTPMessageMedia &media) { return false; } const auto &photo = mediaPhoto.vphoto; - Auth().data().photoConvert(_photo, photo); + parent()->history()->owner().photoConvert(_photo, photo); if (photo.type() != mtpc_photo) { return false; @@ -374,7 +376,7 @@ bool MediaPhoto::updateSentMedia(const MTPMessageMedia &media) { const MTPFileLocation *location = nullptr; QByteArray bytes; }; - const auto saveImageToCache = []( + const auto saveImageToCache = [&]( const ImagePtr &image, SizeData size) { Expects(size.location != nullptr); @@ -394,7 +396,7 @@ bool MediaPhoto::updateSentMedia(const MTPMessageMedia &media) { LOG(("App Error: Bad photo data for saving to cache.")); return; } - Auth().data().cache().putIfEmpty( + parent()->history()->owner().cache().putIfEmpty( Data::StorageCacheKey(key), Storage::Cache::Database::TaggedValue( std::move(size.bytes), @@ -471,7 +473,7 @@ MediaFile::MediaFile( : Media(parent) , _document(document) , _emoji(document->sticker() ? document->sticker()->alt : QString()) { - Auth().data().registerDocumentItem(_document, parent); + parent->history()->owner().registerDocumentItem(_document, parent); if (!_emoji.isEmpty()) { if (const auto emoji = Ui::Emoji::Find(_emoji)) { @@ -481,7 +483,9 @@ MediaFile::MediaFile( } MediaFile::~MediaFile() { - Auth().data().unregisterDocumentItem(_document, parent()); + parent()->history()->owner().unregisterDocumentItem( + _document, + parent()); } std::unique_ptr MediaFile::clone(not_null parent) { @@ -670,7 +674,8 @@ bool MediaFile::updateInlineResultMedia(const MTPMessageMedia &media) { } auto &data = media.c_messageMediaDocument(); if (data.has_document() && !data.has_ttl_seconds()) { - const auto document = Auth().data().document(data.vdocument); + const auto document = parent()->history()->owner().document( + data.vdocument); if (document == _document) { return false; } else { @@ -695,7 +700,7 @@ bool MediaFile::updateSentMedia(const MTPMessageMedia &media) { "or with ttl_seconds in updateSentMedia()")); return false; } - Auth().data().documentConvert(_document, data.vdocument); + parent()->history()->owner().documentConvert(_document, data.vdocument); if (const auto good = _document->goodThumbnail()) { auto bytes = good->bytesForCache(); @@ -703,7 +708,7 @@ bool MediaFile::updateSentMedia(const MTPMessageMedia &media) { if (length > Storage::kMaxFileInMemory) { LOG(("App Error: Bad thumbnail data for saving to cache.")); } else { - Auth().data().cache().putIfEmpty( + parent()->history()->owner().cache().putIfEmpty( _document->goodThumbnailCacheKey(), Storage::Cache::Database::TaggedValue( std::move(bytes), @@ -739,7 +744,7 @@ MediaContact::MediaContact( const QString &lastName, const QString &phoneNumber) : Media(parent) { - Auth().data().registerContactItem(userId, parent); + parent->history()->owner().registerContactItem(userId, parent); _contact.userId = userId; _contact.firstName = firstName; @@ -748,7 +753,9 @@ MediaContact::MediaContact( } MediaContact::~MediaContact() { - Auth().data().unregisterContactItem(_contact.userId, parent()); + parent()->history()->owner().unregisterContactItem( + _contact.userId, + parent()); } std::unique_ptr MediaContact::clone(not_null parent) { @@ -793,9 +800,13 @@ bool MediaContact::updateSentMedia(const MTPMessageMedia &media) { return false; } if (_contact.userId != media.c_messageMediaContact().vuser_id.v) { - Auth().data().unregisterContactItem(_contact.userId, parent()); + parent()->history()->owner().unregisterContactItem( + _contact.userId, + parent()); _contact.userId = media.c_messageMediaContact().vuser_id.v; - Auth().data().registerContactItem(_contact.userId, parent()); + parent()->history()->owner().registerContactItem( + _contact.userId, + parent()); } return true; } @@ -823,7 +834,7 @@ MediaLocation::MediaLocation( const QString &title, const QString &description) : Media(parent) -, _location(Auth().data().location(coords)) +, _location(parent->history()->owner().location(coords)) , _title(title) , _description(description) { } @@ -970,11 +981,11 @@ MediaWebPage::MediaWebPage( not_null page) : Media(parent) , _page(page) { - Auth().data().registerWebPageItem(_page, parent); + parent->history()->owner().registerWebPageItem(_page, parent); } MediaWebPage::~MediaWebPage() { - Auth().data().unregisterWebPageItem(_page, parent()); + parent()->history()->owner().unregisterWebPageItem(_page, parent()); } std::unique_ptr MediaWebPage::clone(not_null parent) { @@ -1126,7 +1137,8 @@ bool MediaGame::updateSentMedia(const MTPMessageMedia &media) { if (media.type() != mtpc_messageMediaGame) { return false; } - Auth().data().gameConvert(_game, media.c_messageMediaGame().vgame); + parent()->history()->owner().gameConvert( + _game, media.c_messageMediaGame().vgame); return true; } @@ -1140,7 +1152,7 @@ MediaInvoice::MediaInvoice( not_null parent, const MTPDmessageMediaInvoice &data) : Media(parent) -, _invoice(ComputeInvoiceData(data)) { +, _invoice(ComputeInvoiceData(parent, data)) { } MediaInvoice::MediaInvoice( @@ -1233,9 +1245,9 @@ TextWithEntities MediaPoll::clipboardText() const { + ranges::accumulate( ranges::view::all( _poll->answers - ) | ranges::view::transform( - [](const PollAnswer &answer) { return "\n- " + answer.text; } - ), + ) | ranges::view::transform([](const PollAnswer &answer) { + return "\n- " + answer.text; + }), QString()); return { text, EntitiesInText() }; } diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index c8dc2315e..0cf7866b8 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -92,12 +92,21 @@ void PeerClickHandler::onClick(ClickContext context) const { } } -PeerData::PeerData(const PeerId &id) +PeerData::PeerData(not_null owner, PeerId id) : id(id) +, _owner(owner) , _userpicEmpty(createEmptyUserpic()) { nameText.setText(st::msgNameStyle, QString(), Ui::NameTextOptions()); } +Data::Session &PeerData::owner() const { + return *_owner; +} + +AuthSession &PeerData::session() const { + return _owner->session(); +} + void PeerData::updateNameDelayed( const QString &newName, const QString &newNameOrPhone, @@ -173,7 +182,7 @@ void PeerData::setUserpic( void PeerData::setUserpicPhoto(const MTPPhoto &data) { const auto photoId = data.match([&](const MTPDphoto &data) { - const auto photo = Auth().data().photo(data); + const auto photo = owner().photo(data); photo->peer = this; return photo->id; }, [](const MTPDphotoEmpty &data) { @@ -322,7 +331,7 @@ void PeerData::setUserpicChecked( Notify::peerUpdatedDelayed(this, UpdateFlag::PhotoChanged); if (const auto channel = asChannel()) { if (const auto feed = channel->feed()) { - Auth().data().notifyFeedUpdated( + owner().notifyFeedUpdated( feed, Data::FeedUpdateFlag::ChannelPhoto); } @@ -417,9 +426,13 @@ const Text &BotCommand::descriptionText() const { return _descriptionText; } +UserData::UserData(not_null owner, PeerId id) +: PeerData(owner, id) { +} + bool UserData::canShareThisContact() const { return canShareThisContactFast() - || !Auth().data().findContactPhone(peerToUser(id)).isEmpty(); + || !owner().findContactPhone(peerToUser(id)).isEmpty(); } void UserData::setContactStatus(ContactStatus status) { @@ -621,6 +634,11 @@ bool UserData::hasCalls() const { && (callsStatus() != CallsStatus::Unknown); } +ChatData::ChatData(not_null owner, PeerId id) +: PeerData(owner, id) +, inputChat(MTP_int(bareId())) { +} + void ChatData::setPhoto(const MTPChatPhoto &photo) { setPhoto(userpicPhotoId(), photo); } @@ -658,8 +676,8 @@ void ChatData::setInviteLink(const QString &newInviteLink) { } } -ChannelData::ChannelData(const PeerId &id) -: PeerData(id) +ChannelData::ChannelData(not_null owner, PeerId id) +: PeerData(owner, id) , inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))) { Data::PeerFlagValue( this, @@ -699,10 +717,10 @@ void PeerData::updateFull() { } void PeerData::updateFullForced() { - Auth().api().requestFullPeer(this); + session().api().requestFullPeer(this); if (auto channel = asChannel()) { if (!channel->amCreator() && !channel->inviter) { - Auth().api().requestSelfParticipant(channel); + session().api().requestSelfParticipant(channel); } } } @@ -874,7 +892,7 @@ void ChannelData::applyEditBanned(not_null user, const MTPChannelBann } } flags |= Notify::PeerUpdate::Flag::MembersChanged; - Auth().data().removeMegagroupParticipant(this, user); + owner().removeMegagroupParticipant(this, user); } } Data::ChannelAdminChanges(this).feed(peerToUser(user->id), false); @@ -907,9 +925,6 @@ void ChannelData::setRestrictionReason(const QString &text) { void ChannelData::setAvailableMinId(MsgId availableMinId) { if (_availableMinId != availableMinId) { _availableMinId = availableMinId; - if (auto history = App::historyLoaded(this)) { - history->clearUpTill(availableMinId); - } if (pinnedMessageId() <= _availableMinId) { clearPinnedMessage(); } @@ -1075,7 +1090,7 @@ void ChannelData::setAdminRights(const MTPChannelAdminRights &rights) { } _adminRights.set(rights.c_channelAdminRights().vflags.v); if (isMegagroup()) { - const auto self = Auth().user(); + const auto self = session().user(); if (hasAdminRights()) { if (!amCreator()) { auto me = MegagroupInfo::Admin { rights }; @@ -1088,7 +1103,7 @@ void ChannelData::setAdminRights(const MTPChannelAdminRights &rights) { } auto amAdmin = hasAdminRights() || amCreator(); - Data::ChannelAdminChanges(this).feed(Auth().userId(), amAdmin); + Data::ChannelAdminChanges(this).feed(session().userId(), amAdmin); } Notify::peerUpdatedDelayed(this, UpdateFlag::ChannelRightsChanged | UpdateFlag::AdminsChanged | UpdateFlag::BannedUsersChanged); } @@ -1101,14 +1116,14 @@ void ChannelData::setRestrictedRights(const MTPChannelBannedRights &rights) { _restrictedUntill = rights.c_channelBannedRights().vuntil_date.v; _restrictions.set(rights.c_channelBannedRights().vflags.v); if (isMegagroup()) { - const auto self = Auth().user(); + const auto self = session().user(); if (hasRestrictions()) { if (!amCreator()) { auto me = MegagroupInfo::Restricted { rights }; mgInfo->lastRestricted.emplace(self, me); } mgInfo->lastAdmins.remove(self); - Data::ChannelAdminChanges(this).feed(Auth().userId(), false); + Data::ChannelAdminChanges(this).feed(session().userId(), false); } else { mgInfo->lastRestricted.remove(self); } diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index c44a5cd7c..2e3f4ef19 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -16,6 +16,7 @@ namespace Ui { class EmptyUserpic; } // namespace Ui +class AuthSession; class PeerData; class UserData; class ChatData; @@ -24,6 +25,7 @@ class ChannelData; namespace Data { class Feed; +class Session; int PeerColorIndex(PeerId peerId); int PeerColorIndex(int32 bareId); @@ -47,13 +49,16 @@ private: class PeerData { protected: - PeerData(const PeerId &id); + PeerData(not_null owner, PeerId id); PeerData(const PeerData &other) = delete; PeerData &operator=(const PeerData &other) = delete; public: virtual ~PeerData(); + Data::Session &owner() const; + AuthSession &session() const; + bool isUser() const { return peerIsUser(id); } @@ -239,6 +244,8 @@ private: static constexpr auto kUnknownPhotoId = PhotoId(0xFFFFFFFFFFFFFFFFULL); + not_null _owner; + ImagePtr _userpic; PhotoId _userpicPhotoId = kUnknownPhotoId; mutable std::unique_ptr _userpicEmpty; @@ -320,8 +327,7 @@ public: MTPDuserFull::Flags, kEssentialFullFlags.value()>; - UserData(const PeerId &id) : PeerData(id) { - } + UserData(not_null owner, PeerId id); void setPhoto(const MTPUserProfilePhoto &photo); void setName( @@ -503,10 +509,8 @@ public: MTPDchat::Flags, kEssentialFlags>; - ChatData(const PeerId &id) - : PeerData(id) - , inputChat(MTP_int(bareId())) { - } + ChatData(not_null owner, PeerId id); + void setPhoto(const MTPChatPhoto &photo); void setPhoto(PhotoId photoId, const MTPChatPhoto &photo); @@ -753,7 +757,7 @@ public: MTPDchannelFull::Flags, kEssentialFullFlags>; - ChannelData(const PeerId &id); + ChannelData(not_null owner, PeerId id); void setPhoto(const MTPChatPhoto &photo); void setPhoto(PhotoId photoId, const MTPChatPhoto &photo); diff --git a/Telegram/SourceFiles/data/data_search_controller.cpp b/Telegram/SourceFiles/data/data_search_controller.cpp index 6fe2a7734..e1de81f53 100644 --- a/Telegram/SourceFiles/data/data_search_controller.cpp +++ b/Telegram/SourceFiles/data/data_search_controller.cpp @@ -149,8 +149,8 @@ SearchResult ParseSearchResult( auto addType = NewMessageExisting; result.messageIds.reserve(messages->size()); - for (auto &message : *messages) { - if (auto item = App::histories().addNewMessage(message, addType)) { + for (const auto &message : *messages) { + if (auto item = Auth().data().addNewMessage(message, addType)) { auto itemId = item->id; if ((type == Storage::SharedMediaType::kCount) || item->sharedMediaTypes().test(type)) { diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index a7cf6b652..634e496ca 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -11,6 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "auth_session.h" #include "apiwrap.h" #include "messenger.h" +#include "mainwidget.h" // for main()->removeDialog +#include "core/crash_reports.h" // for CrashReports::SetAnnotation #include "ui/image/image.h" #include "export/export_controller.h" #include "export/view/export_view_panel_controller.h" @@ -24,6 +26,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/storage_encrypted_file.h" #include "boxes/abstract_box.h" #include "passport/passport_form_controller.h" +#include "window/themes/window_theme.h" +#include "lang/lang_keys.h" // for lang(lng_deleted) in user name. #include "data/data_media_types.h" #include "data/data_feed.h" #include "data/data_photo.h" @@ -31,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_web_page.h" #include "data/data_game.h" #include "data/data_poll.h" +#include "styles/style_boxes.h" // for st::backgroundSize namespace Data { namespace { @@ -66,6 +71,52 @@ void UpdateImage(ImagePtr &old, ImagePtr now) { } } +void CheckForSwitchInlineButton(not_null item) { + if (item->out() || !item->hasSwitchInlineButton()) { + return; + } + if (const auto user = item->history()->peer->asUser()) { + if (!user->botInfo || !user->botInfo->inlineReturnPeerId) { + return; + } + if (const auto markup = item->Get()) { + for (const auto &row : markup->rows) { + for (const auto &button : row) { + using ButtonType = HistoryMessageMarkupButton::Type; + if (button.type == ButtonType::SwitchInline) { + Notify::switchInlineBotButtonReceived( + QString::fromUtf8(button.data)); + return; + } + } + } + } + } +} + +// We should get a full restriction in "{full}: {reason}" format and we +// need to find an "-all" tag in {full}, otherwise ignore this restriction. +QString ExtractRestrictionReason(const QString &restriction) { + const auto fullEnd = restriction.indexOf(':'); + if (fullEnd <= 0) { + return QString(); + } + + // {full} is in "{type}-{tag}-{tag}-{tag}" format + // if we find "all" tag we return the restriction string + const auto typeTags = restriction.mid(0, fullEnd).split('-').mid(1); +#ifndef OS_MAC_STORE + const auto restrictionApplies = typeTags.contains(qsl("all")); +#else // OS_MAC_STORE + const auto restrictionApplies = typeTags.contains(qsl("all")) + || typeTags.contains(qsl("ios")); +#endif // OS_MAC_STORE + if (restrictionApplies) { + return restriction.midRef(fullEnd + 1).trimmed().toString(); + } + return QString(); +} + } // namespace Session::Session(not_null session) @@ -73,6 +124,8 @@ Session::Session(not_null session) , _cache(Messenger::Instance().databases().get( Local::cachePath(), Local::cacheSettings())) +, _selfDestructTimer([=] { checkSelfDestructItems(); }) +, _a_sendActions(animation(this, &Session::step_typings)) , _groups(this) , _unmuteByFinishedTimer([=] { unmuteByFinished(); }) { _cache->open(Local::cacheKey()); @@ -81,6 +134,589 @@ Session::Session(not_null session) setupChannelLeavingViewer(); } +void Session::clear() { + _sendActions.clear(); + + for (const auto &[peerId, history] : _histories) { + history->unloadBlocks(); + } + App::historyClearMsgs(); + _histories.clear(); + + App::historyClearItems(); +} + +not_null Session::peer(PeerId id) { + const auto i = _peers.find(id); + if (i != _peers.cend()) { + return i->second.get(); + } + auto result = [&]() -> std::unique_ptr { + if (peerIsUser(id)) { + return std::make_unique(this, id); + } else if (peerIsChat(id)) { + return std::make_unique(this, id); + } else if (peerIsChannel(id)) { + return std::make_unique(this, id); + } + Unexpected("Peer id type."); + }(); + + result->input = MTPinputPeer(MTP_inputPeerEmpty()); + return _peers.emplace(id, std::move(result)).first->second.get(); +} + +not_null Session::user(UserId id) { + return peer(peerFromUser(id))->asUser(); +} + +not_null Session::chat(ChatId id) { + return peer(peerFromChat(id))->asChat(); +} + +not_null Session::channel(ChannelId id) { + return peer(peerFromChannel(id))->asChannel(); +} + +PeerData *Session::peerLoaded(PeerId id) const { + const auto i = _peers.find(id); + if (i == end(_peers)) { + return nullptr; + } else if (i->second->loadedStatus != PeerData::FullLoaded) { + return nullptr; + } + return i->second.get(); +} + +UserData *Session::userLoaded(UserId id) const { + if (const auto peer = peerLoaded(peerFromUser(id))) { + return peer->asUser(); + } + return nullptr; +} + +ChatData *Session::chatLoaded(ChatId id) const { + if (const auto peer = peerLoaded(peerFromChat(id))) { + return peer->asChat(); + } + return nullptr; +} + +ChannelData *Session::channelLoaded(ChannelId id) const { + if (const auto peer = peerLoaded(peerFromChannel(id))) { + return peer->asChannel(); + } + return nullptr; +} + +not_null Session::user(const MTPUser &data) { + const auto result = user(data.match([](const auto &data) { + return data.vid.v; + })); + auto minimal = false; + const MTPUserStatus *status = 0, emptyStatus = MTP_userStatusEmpty(); + + Notify::PeerUpdate update; + using UpdateFlag = Notify::PeerUpdate::Flag; + data.match([&](const MTPDuserEmpty &data) { + const auto canShareThisContact = result->canShareThisContactFast(); + + result->input = MTP_inputPeerUser(data.vid, MTP_long(0)); + result->inputUser = MTP_inputUser(data.vid, MTP_long(0)); + result->setName(lang(lng_deleted), QString(), QString(), QString()); + result->setPhoto(MTP_userProfilePhotoEmpty()); + //result->setFlags(MTPDuser_ClientFlag::f_inaccessible | 0); + result->setFlags(MTPDuser::Flag::f_deleted); + if (!result->phone().isEmpty()) { + result->setPhone(QString()); + update.flags |= UpdateFlag::UserPhoneChanged; + } + result->setBotInfoVersion(-1); + status = &emptyStatus; + result->setContactStatus(UserData::ContactStatus::PhoneUnknown); + if (canShareThisContact != result->canShareThisContactFast()) { + update.flags |= UpdateFlag::UserCanShareContact; + } + }, [&](const MTPDuser &data) { + minimal = data.is_min(); + + const auto canShareThisContact = result->canShareThisContactFast(); + if (minimal) { + const auto mask = 0 + //| MTPDuser_ClientFlag::f_inaccessible + | MTPDuser::Flag::f_deleted; + result->setFlags((result->flags() & ~mask) | (data.vflags.v & mask)); + } else { + result->setFlags(data.vflags.v); + if (data.is_self()) { + result->input = MTP_inputPeerSelf(); + result->inputUser = MTP_inputUserSelf(); + } else if (!data.has_access_hash()) { + result->input = MTP_inputPeerUser(data.vid, MTP_long(result->accessHash())); + result->inputUser = MTP_inputUser(data.vid, MTP_long(result->accessHash())); + } else { + result->input = MTP_inputPeerUser(data.vid, data.vaccess_hash); + result->inputUser = MTP_inputUser(data.vid, data.vaccess_hash); + } + if (data.is_restricted()) { + result->setRestrictionReason( + ExtractRestrictionReason(qs(data.vrestriction_reason))); + } else { + result->setRestrictionReason(QString()); + } + } + if (data.is_deleted()) { + if (!result->phone().isEmpty()) { + result->setPhone(QString()); + update.flags |= UpdateFlag::UserPhoneChanged; + } + result->setName(lang(lng_deleted), QString(), QString(), QString()); + result->setPhoto(MTP_userProfilePhotoEmpty()); + status = &emptyStatus; + } else { + // apply first_name and last_name from minimal user only if we don't have + // local values for first name and last name already, otherwise skip + bool noLocalName = result->firstName.isEmpty() && result->lastName.isEmpty(); + QString fname = (!minimal || noLocalName) ? (data.has_first_name() ? TextUtilities::SingleLine(qs(data.vfirst_name)) : QString()) : result->firstName; + QString lname = (!minimal || noLocalName) ? (data.has_last_name() ? TextUtilities::SingleLine(qs(data.vlast_name)) : QString()) : result->lastName; + + QString phone = minimal ? result->phone() : (data.has_phone() ? qs(data.vphone) : QString()); + QString uname = minimal ? result->username : (data.has_username() ? TextUtilities::SingleLine(qs(data.vusername)) : QString()); + + const auto phoneChanged = (result->phone() != phone); + if (phoneChanged) { + result->setPhone(phone); + update.flags |= UpdateFlag::UserPhoneChanged; + } + const auto nameChanged = (result->firstName != fname) + || (result->lastName != lname); + + auto showPhone = !isServiceUser(result->id) + && !data.is_self() + && !data.is_contact() + && !data.is_mutual_contact(); + auto showPhoneChanged = !isServiceUser(result->id) + && !data.is_self() + && ((showPhone + && result->contactStatus() == UserData::ContactStatus::Contact) + || (!showPhone + && result->contactStatus() == UserData::ContactStatus::CanAdd)); + if (minimal) { + showPhoneChanged = false; + showPhone = !isServiceUser(result->id) + && (result->id != _session->userPeerId()) + && (result->contactStatus() == UserData::ContactStatus::CanAdd); + } + + // see also Local::readPeer + + const auto pname = (showPhoneChanged || phoneChanged || nameChanged) + ? ((showPhone && !phone.isEmpty()) + ? App::formatPhone(phone) + : QString()) + : result->nameOrPhone; + + if (!minimal && data.is_self() && uname != result->username) { + CrashReports::SetAnnotation("Username", uname); + } + result->setName(fname, lname, pname, uname); + if (data.has_photo()) { + result->setPhoto(data.vphoto); + } else { + result->setPhoto(MTP_userProfilePhotoEmpty()); + } + if (data.has_access_hash()) { + result->setAccessHash(data.vaccess_hash.v); + } + status = data.has_status() ? &data.vstatus : &emptyStatus; + } + if (!minimal) { + if (data.has_bot_info_version()) { + result->setBotInfoVersion(data.vbot_info_version.v); + 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; + } + result->botInfo->inlinePlaceholder = data.has_bot_inline_placeholder() ? '_' + qs(data.vbot_inline_placeholder) : QString(); + } else { + result->setBotInfoVersion(-1); + } + result->setContactStatus((data.is_contact() || data.is_mutual_contact()) + ? UserData::ContactStatus::Contact + : result->phone().isEmpty() + ? UserData::ContactStatus::PhoneUnknown + : UserData::ContactStatus::CanAdd); + } + + if (canShareThisContact != result->canShareThisContactFast()) { + update.flags |= UpdateFlag::UserCanShareContact; + } + }); + + if (minimal) { + if (result->loadedStatus == PeerData::NotLoaded) { + result->loadedStatus = PeerData::MinimalLoaded; + } + } else if (result->loadedStatus != PeerData::FullLoaded + && (!result->isSelf() || !result->phone().isEmpty())) { + result->loadedStatus = PeerData::FullLoaded; + } + + if (status && !minimal) { + const auto oldOnlineTill = result->onlineTill; + const auto newOnlineTill = ApiWrap::OnlineTillFromStatus( + *status, + oldOnlineTill); + if (oldOnlineTill != newOnlineTill) { + result->onlineTill = newOnlineTill; + update.flags |= UpdateFlag::UserOnlineChanged; + } + } + + if (result->contactStatus() == UserData::ContactStatus::PhoneUnknown + && !result->phone().isEmpty() + && !result->isSelf()) { + result->setContactStatus(UserData::ContactStatus::CanAdd); + } + if (App::main()) { + if (update.flags) { + update.peer = result; + Notify::peerUpdatedDelayed(update); + } + } + return result; +} + +not_null Session::chat(const MTPChat &data) { + const auto result = data.match([&](const MTPDchat &data) { + return peer(peerFromChat(data.vid.v)); + }, [&](const MTPDchatForbidden &data) { + return peer(peerFromChat(data.vid.v)); + }, [&](const MTPDchatEmpty &data) { + return peer(peerFromChat(data.vid.v)); + }, [&](const MTPDchannel &data) { + return peer(peerFromChannel(data.vid.v)); + }, [&](const MTPDchannelForbidden &data) { + return peer(peerFromChannel(data.vid.v)); + }); + auto minimal = false; + + Notify::PeerUpdate update; + using UpdateFlag = Notify::PeerUpdate::Flag; + + data.match([&](const MTPDchat &data) { + const auto chat = result->asChat(); + const auto canEdit = chat->canEdit(); + + if (chat->version < data.vversion.v) { + chat->version = data.vversion.v; + chat->invalidateParticipants(); + } + + chat->input = MTP_inputPeerChat(data.vid); + chat->setName(qs(data.vtitle)); + chat->setPhoto(data.vphoto); + chat->date = data.vdate.v; + + const auto &migratedTo = data.has_migrated_to() + ? data.vmigrated_to + : MTPInputChannel(MTP_inputChannelEmpty()); + migratedTo.match([&](const MTPDinputChannel &input) { + const auto channel = this->channel(input.vchannel_id.v); + channel->addFlags(MTPDchannel::Flag::f_megagroup); + if (!channel->access) { + channel->input = MTP_inputPeerChannel(input.vchannel_id, input.vaccess_hash); + channel->inputChannel = data.vmigrated_to; + channel->access = input.vaccess_hash.v; + } + const auto updatedTo = (chat->migrateToPtr != channel); + const auto updatedFrom = (channel->mgInfo->migrateFromPtr != chat); + if (updatedTo) { + chat->migrateToPtr = channel; + } + if (updatedFrom) { + channel->mgInfo->migrateFromPtr = chat; + if (const auto h = historyLoaded(chat->id)) { + if (const auto hto = historyLoaded(channel->id)) { + if (!h->isEmpty()) { + h->unloadBlocks(); + } + if (hto->inChatList(Dialogs::Mode::All) + && h->inChatList(Dialogs::Mode::All)) { + App::main()->removeDialog(h); + } + } + } + Notify::migrateUpdated(channel); + update.flags |= UpdateFlag::MigrationChanged; + } + if (updatedTo) { + Notify::migrateUpdated(chat); + update.flags |= UpdateFlag::MigrationChanged; + } + }, [](const MTPDinputChannelEmpty &) { + }); + + if (!(chat->flags() & MTPDchat::Flag::f_admins_enabled) + && (data.vflags.v & MTPDchat::Flag::f_admins_enabled)) { + chat->invalidateParticipants(); + } + chat->setFlags(data.vflags.v); + + chat->count = data.vparticipants_count.v; + if (canEdit != chat->canEdit()) { + update.flags |= UpdateFlag::ChatCanEdit; + } + }, [&](const MTPDchatForbidden &data) { + const auto chat = result->asChat(); + const auto canEdit = chat->canEdit(); + + chat->input = MTP_inputPeerChat(data.vid); + chat->setName(qs(data.vtitle)); + chat->setPhoto(MTP_chatPhotoEmpty()); + chat->date = 0; + chat->count = -1; + chat->invalidateParticipants(); + chat->setFlags(MTPDchat_ClientFlag::f_forbidden | 0); + if (canEdit != chat->canEdit()) { + update.flags |= UpdateFlag::ChatCanEdit; + } + }, [&](const MTPDchannel &data) { + const auto channel = result->asChannel(); + + minimal = data.is_min(); + if (minimal) { + if (result->loadedStatus != PeerData::FullLoaded) { + LOG(("API Warning: not loaded minimal channel applied.")); + } + } else { + const auto accessHash = data.has_access_hash() + ? data.vaccess_hash + : MTP_long(0); + channel->input = MTP_inputPeerChannel(data.vid, accessHash); + } + + const auto wasInChannel = channel->amIn(); + const auto canViewAdmins = channel->canViewAdmins(); + const auto canViewMembers = channel->canViewMembers(); + const auto canAddMembers = channel->canAddMembers(); + + if (data.has_participants_count()) { + channel->setMembersCount(data.vparticipants_count.v); + } + if (minimal) { + auto mask = 0 + | MTPDchannel::Flag::f_broadcast + | MTPDchannel::Flag::f_verified + | MTPDchannel::Flag::f_megagroup + | MTPDchannel::Flag::f_democracy + | MTPDchannel_ClientFlag::f_forbidden; + channel->setFlags((channel->flags() & ~mask) | (data.vflags.v & mask)); + } else { + if (data.has_admin_rights()) { + channel->setAdminRights(data.vadmin_rights); + } else if (channel->hasAdminRights()) { + channel->setAdminRights(MTP_channelAdminRights(MTP_flags(0))); + } + if (data.has_banned_rights()) { + channel->setRestrictedRights(data.vbanned_rights); + } else if (channel->hasRestrictions()) { + channel->setRestrictedRights(MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); + } + channel->inputChannel = MTP_inputChannel(data.vid, data.vaccess_hash); + channel->access = data.vaccess_hash.v; + channel->date = data.vdate.v; + if (channel->version < data.vversion.v) { + channel->version = data.vversion.v; + } + if (data.is_restricted()) { + channel->setRestrictionReason( + ExtractRestrictionReason(qs(data.vrestriction_reason))); + } else { + channel->setRestrictionReason(QString()); + } + channel->setFlags(data.vflags.v); + //if (data.has_feed_id()) { // #feed + // channel->setFeed(feed(data.vfeed_id.v)); + //} else { + // channel->clearFeed(); + //} + } + + QString uname = data.has_username() ? TextUtilities::SingleLine(qs(data.vusername)) : QString(); + channel->setName(qs(data.vtitle), uname); + + channel->setPhoto(data.vphoto); + + if (wasInChannel != channel->amIn()) { + update.flags |= UpdateFlag::ChannelAmIn; + } + if (canViewAdmins != channel->canViewAdmins() + || canViewMembers != channel->canViewMembers() + || canAddMembers != channel->canAddMembers()) { + update.flags |= UpdateFlag::ChannelRightsChanged; + } + }, [&](const MTPDchannelForbidden &data) { + const auto channel = result->asChannel(); + channel->input = MTP_inputPeerChannel(data.vid, data.vaccess_hash); + + auto wasInChannel = channel->amIn(); + auto canViewAdmins = channel->canViewAdmins(); + auto canViewMembers = channel->canViewMembers(); + auto canAddMembers = channel->canAddMembers(); + + channel->inputChannel = MTP_inputChannel(data.vid, data.vaccess_hash); + + auto mask = mtpCastFlags(MTPDchannelForbidden::Flag::f_broadcast | MTPDchannelForbidden::Flag::f_megagroup); + channel->setFlags((channel->flags() & ~mask) | (mtpCastFlags(data.vflags) & mask) | MTPDchannel_ClientFlag::f_forbidden); + + if (channel->hasAdminRights()) { + channel->setAdminRights(MTP_channelAdminRights(MTP_flags(0))); + } + if (channel->hasRestrictions()) { + channel->setRestrictedRights(MTP_channelBannedRights(MTP_flags(0), MTP_int(0))); + } + + channel->setName(qs(data.vtitle), QString()); + + channel->access = data.vaccess_hash.v; + channel->setPhoto(MTP_chatPhotoEmpty()); + channel->date = 0; + channel->setMembersCount(0); + + if (wasInChannel != channel->amIn()) { + update.flags |= UpdateFlag::ChannelAmIn; + } + if (canViewAdmins != channel->canViewAdmins() + || canViewMembers != channel->canViewMembers() + || canAddMembers != channel->canAddMembers()) { + update.flags |= UpdateFlag::ChannelRightsChanged; + } + }, [](const MTPDchatEmpty &) { + }); + + if (minimal) { + if (result->loadedStatus == PeerData::NotLoaded) { + result->loadedStatus = PeerData::MinimalLoaded; + } + } else if (result->loadedStatus != PeerData::FullLoaded) { + result->loadedStatus = PeerData::FullLoaded; + } + if (update.flags) { + update.peer = result; + Notify::peerUpdatedDelayed(update); + } + return result; +} + +UserData *Session::processUsers(const MTPVector &data) { + auto result = (UserData*)nullptr; + for (const auto &user : data.v) { + result = this->user(user); + } + return result; +} + +PeerData *Session::processChats(const MTPVector &data) { + auto result = (PeerData*)nullptr; + for (const auto &chat : data.v) { + result = this->chat(chat); + } + return result; +} + +PeerData *Session::peerByUsername(const QString &username) const { + const auto uname = username.trimmed(); + for (const auto &[peerId, peer] : _peers) { + if (!peer->userName().compare(uname, Qt::CaseInsensitive)) { + return peer.get(); + } + } + return nullptr; +} + +void Session::enumerateUsers(Fn)> action) const { + for (const auto &[peerId, peer] : _peers) { + if (const auto user = peer->asUser()) { + action(user); + } + } +} + +void Session::enumerateGroups(Fn)> action) const { + for (const auto &[peerId, peer] : _peers) { + if (peer->isChat() || peer->isMegagroup()) { + action(peer.get()); + } + } +} + +void Session::enumerateChannels( + Fn)> action) const { + for (const auto &[peerId, peer] : _peers) { + if (const auto channel = peer->asChannel()) { + if (!channel->isMegagroup()) { + action(channel); + } + } + } +} + +not_null Session::history(PeerId peerId) { + Expects(peerId != 0); + + if (const auto result = historyLoaded(peerId)) { + return result; + } + const auto [i, ok] = _histories.emplace( + peerId, + std::make_unique(this, peerId)); + return i->second.get(); +} + +History *Session::historyLoaded(PeerId peerId) const { + const auto i = peerId ? _histories.find(peerId) : end(_histories); + return (i != end(_histories)) ? i->second.get() : nullptr; +} + +not_null Session::history(not_null peer) { + return history(peer->id); +} + +History *Session::historyLoaded(const PeerData *peer) { + return peer ? historyLoaded(peer->id) : nullptr; +} + +void Session::registerSendAction( + not_null history, + not_null user, + const MTPSendMessageAction &action, + TimeId when) { + if (history->updateSendActionNeedsAnimating(user, action)) { + user->madeAction(when); + + const auto i = _sendActions.find(history); + if (!_sendActions.contains(history)) { + _sendActions.emplace(history, getms()); + _a_sendActions.start(); + } + } +} + +void Session::step_typings(TimeMs ms, bool timer) { + for (auto i = begin(_sendActions); i != end(_sendActions);) { + if (i->first->updateSendActionNeedsAnimating(ms)) { + ++i; + } else { + i = _sendActions.erase(i); + } + } + if (_sendActions.empty()) { + _a_sendActions.stop(); + } +} + Storage::Cache::Database &Session::cache() { return *_cache; } @@ -220,7 +856,7 @@ void Session::setupChannelLeavingViewer() { && !(channel->amIn()); }) | rpl::start_with_next([=](not_null channel) { channel->clearFeed(); - if (const auto history = App::historyLoaded(channel->id)) { + if (const auto history = historyLoaded(channel->id)) { history->removeJoinedMessage(); history->updateChatListExistence(); history->updateChatListSortPosition(); @@ -228,7 +864,13 @@ void Session::setupChannelLeavingViewer() { }, _lifetime); } -Session::~Session() = default; +Session::~Session() { + // Optimization: clear notifications before destroying items. + _session->notifications().clearAllFast(); + + clear(); + Images::ClearRemote(); +} template void Session::enumerateItemViews( @@ -576,7 +1218,7 @@ void Session::applyPinnedDialogs(const QVector &list) { case mtpc_dialog: { const auto &dialogData = dialog.c_dialog(); if (const auto peer = peerFromMTP(dialogData.vpeer)) { - setPinnedDialog(App::history(peer), true); + setPinnedDialog(history(peer), true); } } break; @@ -599,7 +1241,7 @@ void Session::applyPinnedDialogs(const QVector &list) { case mtpc_dialogPeer: { const auto &peerData = dialogPeer.c_dialogPeer(); if (const auto peerId = peerFromMTP(peerData.vpeer)) { - setPinnedDialog(App::history(peerId), true); + setPinnedDialog(history(peerId), true); } } break; //case mtpc_dialogPeerFeed: { // #feed @@ -692,7 +1334,7 @@ const NotifySettings &Session::defaultNotifySettings( } void Session::updateNotifySettingsLocal(not_null peer) { - const auto history = App::historyLoaded(peer->id); + const auto history = historyLoaded(peer->id); auto changesIn = TimeMs(0); const auto muted = notifyIsMuted(peer, &changesIn); if (history && history->changeMute(muted)) { @@ -725,7 +1367,7 @@ void Session::unmuteByFinishedDelayed(TimeMs delay) { void Session::unmuteByFinished() { auto changesInMin = TimeMs(0); for (auto i = begin(_mutedPeers); i != end(_mutedPeers);) { - const auto history = App::historyLoaded((*i)->id); + const auto history = historyLoaded((*i)->id); auto changesIn = TimeMs(0); const auto muted = notifyIsMuted(*i, &changesIn); if (muted) { @@ -748,6 +1390,195 @@ void Session::unmuteByFinished() { } } +HistoryItem *Session::addNewMessage( + const MTPMessage &data, + NewMessageType type) { + const auto peerId = PeerFromMessage(data); + if (!peerId) { + return nullptr; + } + + const auto result = history(peerId)->addNewMessage(data, type); + if (result && type == NewMessageUnread) { + CheckForSwitchInlineButton(result); + } + return result; +} + +auto Session::sendActionAnimationUpdated() const +-> rpl::producer { + return _sendActionAnimationUpdate.events(); +} + +void Session::updateSendActionAnimation( + SendActionAnimationUpdate &&update) { + _sendActionAnimationUpdate.fire(std::move(update)); +} + +int Session::unreadBadge() const { + return computeUnreadBadge( + _unreadFull, + _unreadMuted, + _unreadEntriesFull, + _unreadEntriesMuted); +} + +bool Session::unreadBadgeMuted() const { + return computeUnreadBadgeMuted( + _unreadFull, + _unreadMuted, + _unreadEntriesFull, + _unreadEntriesMuted); +} + +int Session::unreadBadgeIgnoreOne(History *history) const { + const auto removeCount = (history + && history->inChatList(Dialogs::Mode::All)) + ? history->unreadCount() + : 0; + if (!removeCount) { + return unreadBadge(); + } + const auto removeMuted = history->mute(); + return computeUnreadBadge( + _unreadFull - removeCount, + _unreadMuted - (removeMuted ? removeCount : 0), + _unreadEntriesFull - 1, + _unreadEntriesMuted - (removeMuted ? 1 : 0)); +} + +bool Session::unreadBadgeMutedIgnoreOne(History *history) const { + const auto removeCount = (history + && history->inChatList(Dialogs::Mode::All)) + ? history->unreadCount() + : 0; + if (!removeCount) { + return unreadBadgeMuted(); + } + const auto removeMuted = history->mute(); + return computeUnreadBadgeMuted( + _unreadFull - removeCount, + _unreadMuted - (removeMuted ? removeCount : 0), + _unreadEntriesFull - 1, + _unreadEntriesMuted - (removeMuted ? 1 : 0)); +} + +int Session::unreadOnlyMutedBadge() const { + return _session->settings().countUnreadMessages() + ? _unreadMuted + : _unreadEntriesMuted; +} + +int Session::computeUnreadBadge( + int full, + int muted, + int entriesFull, + int entriesMuted) const { + const auto withMuted = _session->settings().includeMutedCounter(); + return _session->settings().countUnreadMessages() + ? (full - (withMuted ? 0 : muted)) + : (entriesFull - (withMuted ? 0 : entriesMuted)); +} + +bool Session::computeUnreadBadgeMuted( + int full, + int muted, + int entriesFull, + int entriesMuted) const { + if (!_session->settings().includeMutedCounter()) { + return false; + } + return _session->settings().countUnreadMessages() + ? (muted >= full) + : (entriesMuted >= entriesFull); +} + +void Session::unreadIncrement(int count, bool muted) { + if (!count) { + return; + } + _unreadFull += count; + if (muted) { + _unreadMuted += count; + } + if (_session->settings().countUnreadMessages()) { + if (!muted || _session->settings().includeMutedCounter()) { + Notify::unreadCounterUpdated(); + } + } +} + +void Session::unreadMuteChanged(int count, bool muted) { + const auto wasAll = (_unreadMuted == _unreadFull); + if (muted) { + _unreadMuted += count; + } else { + _unreadMuted -= count; + } + if (_session->settings().countUnreadMessages()) { + const auto nowAll = (_unreadMuted == _unreadFull); + const auto changed = !_session->settings().includeMutedCounter() + || (wasAll != nowAll); + if (changed) { + Notify::unreadCounterUpdated(); + } + } +} + +void Session::unreadEntriesChanged( + int withUnreadDelta, + int mutedWithUnreadDelta) { + if (!withUnreadDelta && !mutedWithUnreadDelta) { + return; + } + const auto wasAll = (_unreadEntriesMuted == _unreadEntriesFull); + _unreadEntriesFull += withUnreadDelta; + _unreadEntriesMuted += mutedWithUnreadDelta; + if (!_session->settings().countUnreadMessages()) { + const auto nowAll = (_unreadEntriesMuted == _unreadEntriesFull); + const auto withMuted = _session->settings().includeMutedCounter(); + const auto withMutedChanged = withMuted + && (withUnreadDelta != 0 || wasAll != nowAll); + const auto withoutMutedChanged = !withMuted + && (withUnreadDelta != mutedWithUnreadDelta); + if (withMutedChanged || withoutMutedChanged) { + Notify::unreadCounterUpdated(); + } + } +} + +void Session::selfDestructIn(not_null item, TimeMs delay) { + _selfDestructItems.push_back(item->fullId()); + if (!_selfDestructTimer.isActive() + || _selfDestructTimer.remainingTime() > delay) { + _selfDestructTimer.callOnce(delay); + } +} + +void Session::checkSelfDestructItems() { + auto now = getms(true); + auto nextDestructIn = TimeMs(0); + for (auto i = _selfDestructItems.begin(); i != _selfDestructItems.cend();) { + if (auto item = App::histItemById(*i)) { + if (auto destructIn = item->getSelfDestructIn(now)) { + if (nextDestructIn > 0) { + accumulate_min(nextDestructIn, destructIn); + } else { + nextDestructIn = destructIn; + } + ++i; + } else { + i = _selfDestructItems.erase(i); + } + } else { + i = _selfDestructItems.erase(i); + } + } + if (nextDestructIn > 0) { + _selfDestructTimer.callOnce(nextDestructIn); + } +} + not_null Session::photo(PhotoId id) { auto i = _photos.find(id); if (i == _photos.end()) { @@ -1680,7 +2511,7 @@ void Session::registerContactItem( if (!contactId) { return; } - const auto contact = App::userLoaded(contactId); + const auto contact = userLoaded(contactId); const auto canShare = contact ? contact->canShareThisContact() : false; _contactItems[contactId].insert(item); @@ -1706,7 +2537,7 @@ void Session::unregisterContactItem( if (!contactId) { return; } - const auto contact = App::userLoaded(contactId); + const auto contact = userLoaded(contactId); const auto canShare = contact ? contact->canShareThisContact() : false; const auto i = _contactItems.find(contactId); @@ -1908,7 +2739,7 @@ void Session::applyNotifySetting( if (_defaultUserNotifySettings.change(settings)) { _defaultUserNotifyUpdates.fire({}); - App::enumerateUsers([&](not_null user) { + enumerateUsers([&](not_null user) { if (!user->notifySettingsUnknown() && ((!user->notifyMuteUntil() && _defaultUserNotifySettings.muteUntil()) @@ -1923,7 +2754,7 @@ void Session::applyNotifySetting( if (_defaultChatNotifySettings.change(settings)) { _defaultChatNotifyUpdates.fire({}); - App::enumerateGroups([&](not_null peer) { + enumerateGroups([&](not_null peer) { if (!peer->notifySettingsUnknown() && ((!peer->notifyMuteUntil() && _defaultChatNotifySettings.muteUntil()) @@ -1938,7 +2769,7 @@ void Session::applyNotifySetting( if (_defaultBroadcastNotifySettings.change(settings)) { _defaultBroadcastNotifyUpdates.fire({}); - App::enumerateChannels([&](not_null channel) { + enumerateChannels([&](not_null channel) { if (!channel->notifySettingsUnknown() && ((!channel->notifyMuteUntil() && _defaultBroadcastNotifySettings.muteUntil()) @@ -1951,7 +2782,7 @@ void Session::applyNotifySetting( } break; case mtpc_notifyPeer: { const auto &data = notifyPeer.c_notifyPeer(); - if (const auto peer = App::peerLoaded(peerFromMTP(data.vpeer))) { + if (const auto peer = peerLoaded(peerFromMTP(data.vpeer))) { if (peer->notifyChange(settings)) { updateNotifySettingsLocal(peer); } @@ -2052,8 +2883,8 @@ void Session::serviceNotification( const TextWithEntities &message, const MTPMessageMedia &media) { const auto date = unixtime(); - if (!App::userLoaded(ServiceUserId)) { - App::feedUsers(MTP_vector(1, MTP_user( + if (!userLoaded(ServiceUserId)) { + user(MTP_user( MTP_flags( MTPDuser::Flag::f_first_name | MTPDuser::Flag::f_phone @@ -2070,9 +2901,9 @@ void Session::serviceNotification( MTPint(), MTPstring(), MTPstring(), - MTPstring()))); + MTPstring())); } - const auto history = App::history(peerFromUser(ServiceUserId)); + const auto history = this->history(peerFromUser(ServiceUserId)); if (!history->lastMessageKnown()) { _session->api().requestDialogEntry(history, [=] { insertCheckedServiceNotification(message, media, date); @@ -2094,7 +2925,7 @@ void Session::insertCheckedServiceNotification( const TextWithEntities &message, const MTPMessageMedia &media, TimeId date) { - const auto history = App::history(peerFromUser(ServiceUserId)); + const auto history = this->history(peerFromUser(ServiceUserId)); if (!history->isReadyFor(ShowAtUnreadMsgId)) { history->setUnreadCount(0); history->getReadyFor(ShowAtTheEndMsgId); @@ -2104,7 +2935,7 @@ void Session::insertCheckedServiceNotification( | MTPDmessage_ClientFlag::f_clientside_unread; auto sending = TextWithEntities(), left = message; while (TextUtilities::CutPart(sending, left, MaxMessageSize)) { - App::histories().addNewMessage( + addNewMessage( MTP_message( MTP_flags(flags), MTP_int(clientMsgId()), @@ -2137,12 +2968,12 @@ MessageIdsList Session::takeMimeForwardIds() { void Session::setProxyPromoted(PeerData *promoted) { if (_proxyPromoted != promoted) { - if (const auto history = App::historyLoaded(_proxyPromoted)) { + if (const auto history = historyLoaded(_proxyPromoted)) { history->cacheProxyPromoted(false); } const auto old = std::exchange(_proxyPromoted, promoted); if (_proxyPromoted) { - const auto history = App::history(_proxyPromoted); + const auto history = this->history(_proxyPromoted); history->cacheProxyPromoted(true); if (!history->lastMessageKnown()) { _session->api().requestDialogEntry(history); @@ -2163,4 +2994,80 @@ PeerData *Session::proxyPromoted() const { return _proxyPromoted; } +int Session::wallpapersCount() const { + return _wallpapers.size(); +} + +const WallPaper &Session::wallpaper(int index) const { + Expects(index >= 0 && index < _wallpapers.size()); + + return _wallpapers[index]; +} + +void Session::setWallpapers(const QVector &data) { + _wallpapers.clear(); + _wallpapers.reserve(data.size() + 1); + + auto oldBackground = Images::Create(qsl(":/gui/art/bg_initial.jpg"), "JPG"); + _wallpapers.push_back({ + Window::Theme::kInitialBackground, + oldBackground, + oldBackground + }); + for (const auto &paper : data) { + paper.match([&](const MTPDwallPaper &paper) { + const auto &sizes = paper.vsizes.v; + const MTPPhotoSize *thumb = 0, *full = 0; + int32 thumbLevel = -1, fullLevel = -1; + for (auto j = sizes.cbegin(), e = sizes.cend(); j != e; ++j) { + char size = 0; + int32 w = 0, h = 0; + switch (j->type()) { + case mtpc_photoSize: { + auto &s = j->c_photoSize().vtype.v; + if (s.size()) size = s[0]; + w = j->c_photoSize().vw.v; + h = j->c_photoSize().vh.v; + } break; + + case mtpc_photoCachedSize: { + auto &s = j->c_photoCachedSize().vtype.v; + if (s.size()) size = s[0]; + w = j->c_photoCachedSize().vw.v; + h = j->c_photoCachedSize().vh.v; + } break; + } + if (!size || !w || !h) continue; + + const auto newThumbLevel = qAbs( + (st::backgroundSize.width() * cIntRetinaFactor()) - w); + const auto newFullLevel = qAbs(2560 - w); + if (thumbLevel < 0 || newThumbLevel < thumbLevel) { + thumbLevel = newThumbLevel; + thumb = &(*j); + } + if (fullLevel < 0 || newFullLevel < fullLevel) { + fullLevel = newFullLevel; + full = &(*j); + } + } + if (thumb && full && full->type() != mtpc_photoSizeEmpty) { + _wallpapers.push_back({ + paper.vid.v ? paper.vid.v : INT_MAX, + App::image(*thumb), + App::image(*full) + }); + } + }, [](const MTPDwallPaperSolid &) { + }); + } +} + +void Session::clearLocalStorage() { + clear(); + + _cache->close(); + _cache->clear(); +} + } // namespace Data diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index e559e9ec7..d05a1d890 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -49,6 +49,12 @@ class Feed; enum class FeedUpdateFlag; struct FeedUpdate; +struct WallPaper { + int32 id = 0; + ImagePtr thumb; + ImagePtr full; +}; + class Session final { public: using ViewElement = HistoryView::Element; @@ -60,6 +66,8 @@ public: return *_session; } + void clear(); + void startExport(PeerData *peer = nullptr); void startExport(const MTPInputPeer &singlePeer); void suggestStartExport(TimeId availableAt); @@ -77,6 +85,39 @@ public: Storage::Cache::Database &cache(); + [[nodiscard]] not_null peer(PeerId id); + [[nodiscard]] not_null user(UserId id); + [[nodiscard]] not_null chat(ChatId id); + [[nodiscard]] not_null channel(ChannelId id); + + [[nodiscard]] PeerData *peerLoaded(PeerId id) const; + [[nodiscard]] UserData *userLoaded(UserId id) const; + [[nodiscard]] ChatData *chatLoaded(ChatId id) const; + [[nodiscard]] ChannelData *channelLoaded(ChannelId id) const; + + not_null user(const MTPUser &data); + not_null chat(const MTPChat &data); + + // Returns last user, if there were any. + UserData *processUsers(const MTPVector &data); + PeerData *processChats(const MTPVector &data); + + void enumerateUsers(Fn)> action) const; + void enumerateGroups(Fn)> action) const; + void enumerateChannels(Fn)> action) const; + [[nodiscard]] PeerData *peerByUsername(const QString &username) const; + + not_null history(PeerId peerId); + History *historyLoaded(PeerId peerId) const; + not_null history(not_null peer); + History *historyLoaded(const PeerData *peer); + + void registerSendAction( + not_null history, + not_null user, + const MTPSendMessageAction &action, + TimeId when); + [[nodiscard]] base::Variable &contactsLoaded() { return _contactsLoaded; } @@ -247,6 +288,34 @@ public: void markMediaRead(not_null document); void requestPollViewRepaint(not_null poll); + HistoryItem *addNewMessage(const MTPMessage &data, NewMessageType type); + + struct SendActionAnimationUpdate { + not_null history; + int width = 0; + int height = 0; + bool textUpdated = false; + }; + [[nodiscard]] auto sendActionAnimationUpdated() const + -> rpl::producer; + void updateSendActionAnimation(SendActionAnimationUpdate &&update); + + void updateSendActionAnimation(); + + int unreadBadge() const; + bool unreadBadgeMuted() const; + int unreadBadgeIgnoreOne(History *history) const; + bool unreadBadgeMutedIgnoreOne(History *history) const; + int unreadOnlyMutedBadge() const; + + void unreadIncrement(int count, bool muted); + void unreadMuteChanged(int count, bool muted); + void unreadEntriesChanged( + int withUnreadDelta, + int mutedWithUnreadDelta); + + void selfDestructIn(not_null item, TimeMs delay); + not_null photo(PhotoId id); not_null photo(const MTPPhoto &data); not_null photo(const MTPDphoto &data); @@ -452,11 +521,30 @@ public: return _groups; } + int wallpapersCount() const; + const WallPaper &wallpaper(int index) const; + void setWallpapers(const QVector &data); + + void clearLocalStorage(); + private: void suggestStartExport(); void setupContactViewsViewer(); void setupChannelLeavingViewer(); + + void checkSelfDestructItems(); + int computeUnreadBadge( + int full, + int muted, + int entriesFull, + int entriesMuted) const; + bool computeUnreadBadgeMuted( + int full, + int muted, + int entriesFull, + int entriesMuted) const; + void photoApplyFields( not_null photo, const MTPPhoto &data); @@ -554,6 +642,8 @@ private: const MTPMessageMedia &media, TimeId date); + void step_typings(TimeMs ms, bool timer); + not_null _session; Storage::DatabasePointer _cache; @@ -602,25 +692,37 @@ private: Stickers::Order _archivedStickerSetsOrder; Stickers::SavedGifs _savedGifs; + int _unreadFull = 0; + int _unreadMuted = 0; + int _unreadEntriesFull = 0; + int _unreadEntriesMuted = 0; + + base::Timer _selfDestructTimer; + std::vector _selfDestructItems; + + // When typing in this history started. + base::flat_map, TimeMs> _sendActions; + BasicAnimation _a_sendActions; + std::unordered_map< PhotoId, std::unique_ptr> _photos; - std::map< + std::unordered_map< not_null, base::flat_set>> _photoItems; std::unordered_map< DocumentId, std::unique_ptr> _documents; - std::map< + std::unordered_map< not_null, base::flat_set>> _documentItems; std::unordered_map< WebPageId, std::unique_ptr> _webpages; - std::map< + std::unordered_map< not_null, base::flat_set>> _webpageItems; - std::map< + std::unordered_map< not_null, base::flat_set>> _webpageViews; std::unordered_map< @@ -632,16 +734,16 @@ private: std::unordered_map< GameId, std::unique_ptr> _games; - std::map< + std::unordered_map< not_null, base::flat_set>> _gameViews; - std::map< + std::unordered_map< not_null, base::flat_set>> _pollViews; - std::map< + std::unordered_map< UserId, base::flat_set>> _contactItems; - std::map< + std::unordered_map< UserId, base::flat_set>> _contactViews; base::flat_map< @@ -656,7 +758,7 @@ private: base::flat_map> _feeds; rpl::variable _defaultFeedId = FeedId(); Groups _groups; - std::map< + std::unordered_map< not_null, std::vector>> _views; @@ -671,6 +773,9 @@ private: std::unordered_set> _mutedPeers; base::Timer _unmuteByFinishedTimer; + std::unordered_map> _peers; + std::unordered_map> _histories; + MessageIdsList _mimeForwardIds; using CredentialsWithGeneration = std::pair< @@ -680,6 +785,10 @@ private: rpl::event_stream<> _newAuthorizationChecks; + rpl::event_stream _sendActionAnimationUpdate; + + std::vector _wallpapers; + rpl::lifetime _lifetime; }; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 8674ab2fd..92ac4f2f1 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -91,10 +91,12 @@ DialogsInner::DialogsInner(QWidget *parent, not_null contro subscribe(Auth().downloaderTaskFinished(), [this] { update(); }); subscribe(Auth().data().contactsLoaded(), [this](bool) { refresh(); }); + Auth().data().itemRemoved( ) | rpl::start_with_next( [this](auto item) { itemRemoved(item); }, lifetime()); + Auth().data().itemRepaintRequest( ) | rpl::start_with_next([=](auto item) { const auto history = item->history(); @@ -107,13 +109,21 @@ DialogsInner::DialogsInner(QWidget *parent, not_null contro } } }, lifetime()); - subscribe(App::histories().sendActionAnimationUpdated(), [this](const Histories::SendActionAnimationUpdate &update) { - auto updateRect = Dialogs::Layout::RowPainter::sendActionAnimationRect(update.width, update.height, getFullWidth(), update.textUpdated); + + Auth().data().sendActionAnimationUpdated( + ) | rpl::start_with_next([=]( + const Data::Session::SendActionAnimationUpdate &update) { + using RowPainter = Dialogs::Layout::RowPainter; + const auto updateRect = RowPainter::sendActionAnimationRect( + update.width, + update.height, + getFullWidth(), + update.textUpdated); updateDialogRow( Dialogs::RowDescriptor(update.history, FullMsgId()), updateRect, UpdateRowSection::Default | UpdateRowSection::Filtered); - }); + }, lifetime()); subscribe(Window::Theme::Background(), [=](const Window::Theme::BackgroundUpdate &data) { if (data.paletteChanged()) { @@ -1915,13 +1925,13 @@ bool DialogsInner::searchReceived( auto unknownUnreadCounts = std::vector>(); TimeId lastDateFound = 0; - for_const (auto message, messages) { + for (const auto &message : messages) { auto msgId = IdFromMessage(message); auto peerId = PeerFromMessage(message); auto lastDate = DateFromMessage(message); if (const auto peer = App::peerLoaded(peerId)) { if (lastDate) { - const auto item = App::histories().addNewMessage( + const auto item = Auth().data().addNewMessage( message, NewMessageExisting); const auto history = item->history(); diff --git a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp index 5ae1e9edb..94c5060ae 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_abstract_structure.h" #include "data/data_drafts.h" +#include "data/data_session.h" #include "dialogs/dialogs_list.h" #include "styles/style_dialogs.h" #include "storage/localstorage.h" @@ -796,7 +797,7 @@ void paintImportantSwitch(Painter &p, Mode current, int fullWidth, bool selected if (!mutedHidden) { return; } - if (const auto unread = App::histories().unreadOnlyMutedBadge()) { + if (const auto unread = Auth().data().unreadOnlyMutedBadge()) { const auto unreadRight = fullWidth - st::dialogsPadding.x(); UnreadBadgeStyle st; st.muted = true; diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index f7ee0f442..2a561d56e 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -55,283 +55,14 @@ constexpr auto kSetMyActionForMs = 10000; constexpr auto kNewBlockEachMessage = 50; constexpr auto kSkipCloudDraftsFor = TimeId(3); -void checkForSwitchInlineButton(HistoryItem *item) { - if (item->out() || !item->hasSwitchInlineButton()) { - return; - } - if (const auto user = item->history()->peer->asUser()) { - if (!user->botInfo || !user->botInfo->inlineReturnPeerId) { - return; - } - if (const auto markup = item->Get()) { - for_const (auto &row, markup->rows) { - for_const (auto &button, row) { - if (button.type == HistoryMessageMarkupButton::Type::SwitchInline) { - Notify::switchInlineBotButtonReceived(QString::fromUtf8(button.data)); - return; - } - } - } - } - } -} - } // namespace -Histories::Histories() -: _a_typings(animation(this, &Histories::step_typings)) -, _selfDestructTimer([this] { checkSelfDestructItems(); }) { -} - -History *Histories::find(PeerId peerId) const { - if (const auto i = _map.find(peerId); i != _map.end()) { - return i->second.get(); - } - return nullptr; -} - -not_null Histories::findOrInsert(PeerId peerId) { - if (const auto result = find(peerId)) { - return result; - } - const auto [i, ok] = _map.emplace( - peerId, - std::make_unique(peerId)); - return i->second.get(); -} - -void Histories::clear() { - for (const auto &[peerId, history] : _map) { - history->unloadBlocks(); - } - App::historyClearMsgs(); - _map.clear(); - - _unreadFull = _unreadMuted = 0; - _unreadEntriesFull = _unreadEntriesMuted = 0; - Notify::unreadCounterUpdated(); - App::historyClearItems(); - typing.clear(); -} - -void Histories::registerSendAction( - not_null history, - not_null user, - const MTPSendMessageAction &action, - TimeId when) { - if (history->updateSendActionNeedsAnimating(user, action)) { - user->madeAction(when); - - auto i = typing.find(history); - if (i == typing.cend()) { - typing.insert(history, getms()); - _a_typings.start(); - } - } -} - -void Histories::step_typings(TimeMs ms, bool timer) { - for (auto i = typing.begin(), e = typing.end(); i != e;) { - if (i.key()->updateSendActionNeedsAnimating(ms)) { - ++i; - } else { - i = typing.erase(i); - } - } - if (typing.isEmpty()) { - _a_typings.stop(); - } -} - -void Histories::remove(const PeerId &peer) { - const auto i = _map.find(peer); - if (i != _map.cend()) { - typing.remove(i->second.get()); - _map.erase(i); - } -} - -HistoryItem *Histories::addNewMessage( - const MTPMessage &msg, - NewMessageType type) { - auto peer = PeerFromMessage(msg); - if (!peer) return nullptr; - - auto result = App::history(peer)->addNewMessage(msg, type); - if (result && type == NewMessageUnread) { - checkForSwitchInlineButton(result); - } - return result; -} - -int Histories::unreadBadge() const { - return computeUnreadBadge( - _unreadFull, - _unreadMuted, - _unreadEntriesFull, - _unreadEntriesMuted); -} - -bool Histories::unreadBadgeMuted() const { - return computeUnreadBadgeMuted( - _unreadFull, - _unreadMuted, - _unreadEntriesFull, - _unreadEntriesMuted); -} - -int Histories::unreadBadgeIgnoreOne(History *history) const { - const auto removeCount = (history - && history->inChatList(Dialogs::Mode::All)) - ? history->unreadCount() - : 0; - if (!removeCount) { - return unreadBadge(); - } - const auto removeMuted = history->mute(); - return computeUnreadBadge( - _unreadFull - removeCount, - _unreadMuted - (removeMuted ? removeCount : 0), - _unreadEntriesFull - 1, - _unreadEntriesMuted - (removeMuted ? 1 : 0)); -} - -bool Histories::unreadBadgeMutedIgnoreOne(History *history) const { - const auto removeCount = (history - && history->inChatList(Dialogs::Mode::All)) - ? history->unreadCount() - : 0; - if (!removeCount) { - return unreadBadgeMuted(); - } - const auto removeMuted = history->mute(); - return computeUnreadBadgeMuted( - _unreadFull - removeCount, - _unreadMuted - (removeMuted ? removeCount : 0), - _unreadEntriesFull - 1, - _unreadEntriesMuted - (removeMuted ? 1 : 0)); -} - -int Histories::unreadOnlyMutedBadge() const { - return Auth().settings().countUnreadMessages() - ? _unreadMuted - : _unreadEntriesMuted; -} - -int Histories::computeUnreadBadge( - int full, - int muted, - int entriesFull, - int entriesMuted) const { - const auto withMuted = Auth().settings().includeMutedCounter(); - return Auth().settings().countUnreadMessages() - ? (full - (withMuted ? 0 : muted)) - : (entriesFull - (withMuted ? 0 : entriesMuted)); -} - -bool Histories::computeUnreadBadgeMuted( - int full, - int muted, - int entriesFull, - int entriesMuted) const { - if (!Auth().settings().includeMutedCounter()) { - return false; - } - return Auth().settings().countUnreadMessages() - ? (muted >= full) - : (entriesMuted >= entriesFull); -} - -void Histories::unreadIncrement(int count, bool muted) { - if (!count) { - return; - } - _unreadFull += count; - if (muted) { - _unreadMuted += count; - } - if (Auth().settings().countUnreadMessages()) { - if (!muted || Auth().settings().includeMutedCounter()) { - Notify::unreadCounterUpdated(); - } - } -} - -void Histories::unreadMuteChanged(int count, bool muted) { - const auto wasAll = (_unreadMuted == _unreadFull); - if (muted) { - _unreadMuted += count; - } else { - _unreadMuted -= count; - } - if (Auth().settings().countUnreadMessages()) { - const auto nowAll = (_unreadMuted == _unreadFull); - const auto changed = !Auth().settings().includeMutedCounter() - || (wasAll != nowAll); - if (changed) { - Notify::unreadCounterUpdated(); - } - } -} - -void Histories::unreadEntriesChanged( - int withUnreadDelta, - int mutedWithUnreadDelta) { - if (!withUnreadDelta && !mutedWithUnreadDelta) { - return; - } - const auto wasAll = (_unreadEntriesMuted == _unreadEntriesFull); - _unreadEntriesFull += withUnreadDelta; - _unreadEntriesMuted += mutedWithUnreadDelta; - if (!Auth().settings().countUnreadMessages()) { - const auto nowAll = (_unreadEntriesMuted == _unreadEntriesFull); - const auto withMuted = Auth().settings().includeMutedCounter(); - const auto withMutedChanged = withMuted - && (withUnreadDelta != 0 || wasAll != nowAll); - const auto withoutMutedChanged = !withMuted - && (withUnreadDelta != mutedWithUnreadDelta); - if (withMutedChanged || withoutMutedChanged) { - Notify::unreadCounterUpdated(); - } - } -} - -void Histories::selfDestructIn(not_null item, TimeMs delay) { - _selfDestructItems.push_back(item->fullId()); - if (!_selfDestructTimer.isActive() || _selfDestructTimer.remainingTime() > delay) { - _selfDestructTimer.callOnce(delay); - } -} - -void Histories::checkSelfDestructItems() { - auto now = getms(true); - auto nextDestructIn = TimeMs(0); - for (auto i = _selfDestructItems.begin(); i != _selfDestructItems.cend();) { - if (auto item = App::histItemById(*i)) { - if (auto destructIn = item->getSelfDestructIn(now)) { - if (nextDestructIn > 0) { - accumulate_min(nextDestructIn, destructIn); - } else { - nextDestructIn = destructIn; - } - ++i; - } else { - i = _selfDestructItems.erase(i); - } - } else { - i = _selfDestructItems.erase(i); - } - } - if (nextDestructIn > 0) { - _selfDestructTimer.callOnce(nextDestructIn); - } -} - -History::History(const PeerId &peerId) +History::History(not_null owner, const PeerId &peerId) : Entry(this) , peer(App::peer(peerId)) , cloudDraftTextCache(st::dialogsTextWidthMin) -, _mute(Auth().data().notifyIsMuted(peer)) +, _owner(owner) +, _mute(_owner->notifyIsMuted(peer)) , _sendActionText(st::dialogsTextWidthMin) { if (const auto user = peer->asUser()) { if (user->botInfo) { @@ -444,13 +175,15 @@ void History::takeLocalDraft(History *from) { _localDraft->msgId = 0; } from->clearLocalDraft(); - Auth().api().saveDraftToCloudDelayed(from); + session().api().saveDraftToCloudDelayed(from); } } void History::createLocalDraftFromCloud() { auto draft = cloudDraft(); - if (Data::draftIsNull(draft) || !draft->date || Auth().supportMode()) { + if (Data::draftIsNull(draft) + || !draft->date + || session().supportMode()) { return; } @@ -561,9 +294,9 @@ void History::draftSavedToCloud() { } HistoryItemsList History::validateForwardDraft() { - auto result = Auth().data().idsToItems(_forwardDraft); + auto result = _owner->idsToItems(_forwardDraft); if (result.size() != _forwardDraft.size()) { - setForwardDraft(Auth().data().itemsToIds(result)); + setForwardDraft(_owner->itemsToIds(result)); } return result; } @@ -740,7 +473,7 @@ bool History::updateSendActionNeedsAnimating(TimeMs ms, bool force) { } auto result = (!_typing.isEmpty() || !_sendActions.isEmpty()); if (changed || (result && !anim::Disabled())) { - App::histories().sendActionAnimationUpdated().notify({ + _owner->updateSendActionAnimation({ this, _sendActionAnimation.width(), st::normalFont->height, @@ -1057,7 +790,7 @@ not_null History::addNewItem( if (const auto sharedMediaTypes = item->sharedMediaTypes()) { auto from = loadedAtTop() ? 0 : minMsgId(); auto till = loadedAtBottom() ? ServerMaxMsgId : maxMsgId(); - Auth().storage().add(Storage::SharedMediaAddExisting( + session().storage().add(Storage::SharedMediaAddExisting( peer->id, sharedMediaTypes, item->id, @@ -1102,7 +835,7 @@ not_null History::addNewItem( } if (auto megagroup = peer->asMegagroup()) { Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); - Auth().data().addNewMegagroupParticipant(megagroup, user); + _owner->addNewMegagroupParticipant(megagroup, user); } } } @@ -1162,7 +895,7 @@ not_null History::addNewItem( newItemAdded(item); } - Auth().data().notifyHistoryChangeDelayed(this); + _owner->notifyHistoryChangeDelayed(this); return item; } @@ -1191,7 +924,7 @@ void History::applyServiceChanges( if (!base::contains(mgInfo->lastParticipants, user)) { mgInfo->lastParticipants.push_front(user); Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); - Auth().data().addNewMegagroupParticipant(megagroup, user); + _owner->addNewMegagroupParticipant(megagroup, user); } if (user->botInfo) { peer->asChannel()->mgInfo->bots.insert(user); @@ -1213,7 +946,7 @@ void History::applyServiceChanges( if (!base::contains(mgInfo->lastParticipants, user)) { mgInfo->lastParticipants.push_front(user); Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); - Auth().data().addNewMegagroupParticipant(megagroup, user); + _owner->addNewMegagroupParticipant(megagroup, user); } if (user->botInfo) { mgInfo->bots.insert(user); @@ -1249,7 +982,7 @@ void History::applyServiceChanges( mgInfo->lastParticipants.erase(i); Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); } - Auth().data().removeMegagroupParticipant(megagroup, user); + _owner->removeMegagroupParticipant(megagroup, user); if (megagroup->membersCount() > 1) { megagroup->setMembersCount(megagroup->membersCount() - 1); } else { @@ -1277,7 +1010,7 @@ void History::applyServiceChanges( if (d.vphoto.type() == mtpc_photo) { auto &sizes = d.vphoto.c_photo().vsizes.v; if (!sizes.isEmpty()) { - auto photo = Auth().data().photo(d.vphoto.c_photo()); + auto photo = _owner->photo(d.vphoto.c_photo()); if (photo) photo->peer = peer; auto &smallSize = sizes.front(); auto &bigSize = sizes.back(); @@ -1446,7 +1179,7 @@ void History::addEdgesToSharedMedia() { auto till = loadedAtBottom() ? ServerMaxMsgId : maxMsgId(); for (auto i = 0; i != Storage::kSharedMediaTypeCount; ++i) { const auto type = static_cast(i); - Auth().storage().add(Storage::SharedMediaAddSlice( + session().storage().add(Storage::SharedMediaAddSlice( peer->id, type, {}, @@ -1634,7 +1367,7 @@ void History::addToSharedMedia( for (auto i = 0; i != Storage::kSharedMediaTypeCount; ++i) { if (!medias[i].empty()) { const auto type = static_cast(i); - Auth().storage().add(Storage::SharedMediaAddSlice( + session().storage().add(Storage::SharedMediaAddSlice( peer->id, type, std::move(medias[i]), @@ -1711,7 +1444,7 @@ void History::inboxRead(MsgId upTo) { } _firstUnreadView = nullptr; - Auth().notifications().clearFromHistory(this); + session().notifications().clearFromHistory(this); } void History::inboxRead(not_null wasRead) { @@ -1812,7 +1545,7 @@ void History::setUnreadCount(int newUnreadCount) { const auto delta = unreadMarkDelta + (unreadCountDelta ? *unreadCountDelta : newUnreadCount); - App::histories().unreadIncrement(delta, mute()); + _owner->unreadIncrement(delta, mute()); const auto nowUnread = (*_unreadCount > 0) || _unreadMark; const auto entriesDelta = (wasUnread && !nowUnread) @@ -1820,7 +1553,7 @@ void History::setUnreadCount(int newUnreadCount) { : (nowUnread && !wasUnread) ? 1 : 0; - App::histories().unreadEntriesChanged( + _owner->unreadEntriesChanged( entriesDelta, mute() ? entriesDelta : 0); } @@ -1839,8 +1572,8 @@ void History::setUnreadMark(bool unread) { if (!_unreadCount || !*_unreadCount) { if (inChatList(Dialogs::Mode::All)) { const auto delta = _unreadMark ? 1 : -1; - App::histories().unreadIncrement(delta, mute()); - App::histories().unreadEntriesChanged( + _owner->unreadIncrement(delta, mute()); + _owner->unreadEntriesChanged( delta, mute() ? delta : 0); @@ -1890,17 +1623,17 @@ bool History::changeMute(bool newMute) { feed->unreadCountChanged(unreadCountDelta, mutedCountDelta); } } else { - Auth().api().requestDialogEntry(this); - Auth().api().requestDialogEntry(feed); + session().api().requestDialogEntry(this); + session().api().requestDialogEntry(feed); } } if (inChatList(Dialogs::Mode::All)) { if (const auto count = historiesUnreadCount()) { - App::histories().unreadMuteChanged(count, _mute); + _owner->unreadMuteChanged(count, _mute); const auto entriesWithUnreadDelta = 0; const auto mutedEntriesWithUnreadDelta = _mute ? 1 : -1; - App::histories().unreadEntriesChanged( + _owner->unreadEntriesChanged( entriesWithUnreadDelta, mutedEntriesWithUnreadDelta); @@ -1960,7 +1693,7 @@ std::shared_ptr History::adminLogIdManager() { TimeId History::adjustChatListTimeId() const { const auto result = chatsListTimeId(); if (const auto draft = cloudDraft()) { - if (!Data::draftIsNull(draft) && !Auth().supportMode()) { + if (!Data::draftIsNull(draft) && !session().supportMode()) { return std::max(result, draft->date); } } @@ -2279,11 +2012,11 @@ void History::getReadyFor(MsgId msgId) { void History::setNotLoadedAtBottom() { _loadedAtBottom = false; - Auth().storage().invalidate( + session().storage().invalidate( Storage::SharedMediaInvalidateBottom(peer->id)); if (const auto channel = peer->asChannel()) { if (const auto feed = channel->feed()) { - Auth().storage().invalidate( + session().storage().invalidate( Storage::FeedMessagesInvalidateBottom( feed->id())); } @@ -2293,12 +2026,14 @@ void History::setNotLoadedAtBottom() { void History::markFullyLoaded() { _loadedAtTop = _loadedAtBottom = true; if (isEmpty()) { - Auth().storage().remove(Storage::SharedMediaRemoveAll(peer->id)); + session().storage().remove( + Storage::SharedMediaRemoveAll(peer->id)); if (const auto channel = peer->asChannel()) { if (const auto feed = channel->feed()) { - Auth().storage().remove(Storage::FeedMessagesRemoveAll( - feed->id(), - channel->bareId())); + session().storage().remove( + Storage::FeedMessagesRemoveAll( + feed->id(), + channel->bareId())); } } } @@ -2339,7 +2074,7 @@ void History::updateChatListExistence() { if (const auto channel = peer->asChannel()) { if (!channel->feed()) { // After ungrouping from a feed we need to load dialog. - Auth().api().requestDialogEntry(this); + session().api().requestDialogEntry(this); } } } @@ -2405,12 +2140,12 @@ void History::applyDialog(const MTPDdialog &data) { data.vtop_message.v); if (const auto item = App::histItemById(topMessageId)) { if (item->date() <= channel->date) { - Auth().api().requestSelfParticipant(channel); + session().api().requestSelfParticipant(channel); } } } } - Auth().data().applyNotifySetting( + _owner->applyNotifySetting( MTP_notifyPeer(data.vpeer), data.vnotify_settings); @@ -2420,7 +2155,7 @@ void History::applyDialog(const MTPDdialog &data) { } bool History::clearUnreadOnClientSide() const { - if (!Auth().supportMode()) { + if (!session().supportMode()) { return false; } if (const auto user = peer->asUser()) { @@ -2570,6 +2305,14 @@ void History::resizeToWidth(int newWidth) { _height = y; } +Data::Session &History::owner() const { + return *_owner; +} + +AuthSession &History::session() const { + return _owner->session(); +} + ChannelId History::channelId() const { return peerToChannel(peer->id); } @@ -2645,7 +2388,7 @@ HistoryService *History::insertJoinedMessage(bool unread) { } MTPDmessage::Flags flags = 0; - if (inviter->id == Auth().userPeerId()) { + if (inviter->id == session().userPeerId()) { unread = false; //} else if (unread) { // flags |= MTPDmessage::Flag::f_unread; @@ -2811,11 +2554,11 @@ void History::clearBlocks(bool leaveItems) { forgetScrollState(); } if (leaveItems) { - Auth().data().notifyHistoryUnloaded(this); + _owner->notifyHistoryUnloaded(this); } else { setLastMessage(nullptr); notifies.clear(); - Auth().data().notifyHistoryCleared(this); + _owner->notifyHistoryCleared(this); } blocks.clear(); if (leaveItems) { @@ -2831,7 +2574,7 @@ void History::clearBlocks(bool leaveItems) { } clearLastKeyboard(); } - Auth().data().notifyHistoryChangeDelayed(this); + _owner->notifyHistoryChangeDelayed(this); _loadedAtTop = false; _loadedAtBottom = !leaveItems; @@ -2872,9 +2615,9 @@ void History::clearUpTill(MsgId availableMinId) { } while (!isEmpty()); if (!lastMessageKnown()) { - Auth().api().requestDialogEntry(this); + session().api().requestDialogEntry(this); } - Auth().data().sendHistoryChangeNotifications(); + _owner->sendHistoryChangeNotifications(); } void History::applyGroupAdminChanges( @@ -2889,10 +2632,10 @@ void History::applyGroupAdminChanges( void History::changedInChatListHook(Dialogs::Mode list, bool added) { if (list == Dialogs::Mode::All) { if (const auto delta = historiesUnreadCount() * (added ? 1 : -1)) { - App::histories().unreadIncrement(delta, mute()); + _owner->unreadIncrement(delta, mute()); const auto entriesDelta = added ? 1 : -1; - App::histories().unreadEntriesChanged( + _owner->unreadEntriesChanged( entriesDelta, mute() ? entriesDelta : 0); } diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 3ea00137a..d748d79fe 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -27,6 +27,7 @@ class AuthSession; namespace Data { struct Draft; +class Session; } // namespace Data namespace Dialogs { @@ -48,92 +49,22 @@ enum NewMessageType : char { NewMessageExisting, }; -class Histories { -public: - Histories(); - - void registerSendAction( - not_null history, - not_null user, - const MTPSendMessageAction &action, - TimeId when); - void step_typings(TimeMs ms, bool timer); - - History *find(PeerId peerId) const; - not_null findOrInsert(PeerId peerId); - - void clear(); - void remove(const PeerId &peer); - - HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type); - - // When typing in this history started. - typedef QMap TypingHistories; - TypingHistories typing; - BasicAnimation _a_typings; - - int unreadBadge() const; - bool unreadBadgeMuted() const; - int unreadBadgeIgnoreOne(History *history) const; - bool unreadBadgeMutedIgnoreOne(History *history) const; - int unreadOnlyMutedBadge() const; - - void unreadIncrement(int count, bool muted); - void unreadMuteChanged(int count, bool muted); - void unreadEntriesChanged( - int withUnreadDelta, - int mutedWithUnreadDelta); - - struct SendActionAnimationUpdate { - History *history; - int width; - int height; - bool textUpdated; - }; - base::Observable &sendActionAnimationUpdated() { - return _sendActionAnimationUpdated; - } - void selfDestructIn(not_null item, TimeMs delay); - -private: - void checkSelfDestructItems(); - int computeUnreadBadge( - int full, - int muted, - int entriesFull, - int entriesMuted) const; - bool computeUnreadBadgeMuted( - int full, - int muted, - int entriesFull, - int entriesMuted) const; - - std::unordered_map> _map; - - int _unreadFull = 0; - int _unreadMuted = 0; - int _unreadEntriesFull = 0; - int _unreadEntriesMuted = 0; - base::Observable _sendActionAnimationUpdated; - - base::Timer _selfDestructTimer; - std::vector _selfDestructItems; - -}; - enum class UnreadMentionType { New, // when new message is added to history Existing, // when some messages slice was received }; -class History : public Dialogs::Entry { +class History final : public Dialogs::Entry { public: using Element = HistoryView::Element; - History(const PeerId &peerId); + History(not_null owner, const PeerId &peerId); History(const History &) = delete; History &operator=(const History &) = delete; + Data::Session &owner() const; + AuthSession &session() const; + ChannelId channelId() const; bool isChannel() const; bool isMegagroup() const; @@ -501,6 +432,7 @@ private: void viewReplaced(not_null was, Element *now); + not_null _owner; Flags _flags = 0; bool _mute = false; int _width = 0; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index bf67bbd0d..d2e4d7634 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -172,12 +172,12 @@ TimeId HistoryItem::date() const { } void HistoryItem::finishEdition(int oldKeyboardTop) { - Auth().data().requestItemViewRefresh(this); + _history->owner().requestItemViewRefresh(this); invalidateChatsListEntry(); - if (const auto group = Auth().data().groups().find(this)) { + if (const auto group = _history->owner().groups().find(this)) { const auto leader = group->items.back(); if (leader != this) { - Auth().data().requestItemViewRefresh(leader); + _history->owner().requestItemViewRefresh(leader); leader->invalidateChatsListEntry(); } } @@ -195,7 +195,7 @@ void HistoryItem::setGroupId(MessageGroupId groupId) { Expects(!_groupId); _groupId = groupId; - Auth().data().groups().registerMessage(this); + _history->owner().groups().registerMessage(this); } HistoryMessageReplyMarkup *HistoryItem::inlineReplyMarkup() { @@ -305,7 +305,7 @@ void HistoryItem::addLogEntryOriginal( Expects(isLogEntry()); AddComponents(HistoryMessageLogEntryOriginal::Bit()); - Get()->page = Auth().data().webpage( + Get()->page = _history->owner().webpage( localId, label, content); @@ -330,7 +330,6 @@ UserData *HistoryItem::getMessageBot() const { }; void HistoryItem::destroy() { - const auto history = this->history(); if (isLogEntry()) { Assert(!mainView()); } else { @@ -338,13 +337,13 @@ void HistoryItem::destroy() { eraseFromUnreadMentions(); if (IsServerMsgId(id)) { if (const auto types = sharedMediaTypes()) { - Auth().storage().remove(Storage::SharedMediaRemoveOne( - history->peer->id, + _history->session().storage().remove(Storage::SharedMediaRemoveOne( + _history->peer->id, types, id)); } } else { - Auth().api().cancelLocalItem(this); + _history->session().api().cancelLocalItem(this); } _history->itemRemoved(this); } @@ -353,14 +352,14 @@ void HistoryItem::destroy() { void HistoryItem::refreshMainView() { if (const auto view = mainView()) { - Auth().data().notifyHistoryChangeDelayed(_history); + _history->owner().notifyHistoryChangeDelayed(_history); view->refreshInBlock(); } } void HistoryItem::removeMainView() { if (const auto view = mainView()) { - Auth().data().notifyHistoryChangeDelayed(_history); + _history->owner().notifyHistoryChangeDelayed(_history); view->removeFromBlock(); } } @@ -378,14 +377,14 @@ void HistoryItem::indexAsNewItem() { addToUnreadMentions(UnreadMentionType::New); CrashReports::ClearAnnotation("addToUnreadMentions"); if (const auto types = sharedMediaTypes()) { - Auth().storage().add(Storage::SharedMediaAddNew( + _history->session().storage().add(Storage::SharedMediaAddNew( history()->peer->id, types, id)); } if (const auto channel = history()->peer->asChannel()) { if (const auto feed = channel->feed()) { - Auth().storage().add(Storage::FeedMessagesAddNew( + _history->session().storage().add(Storage::FeedMessagesAddNew( feed->id(), position())); } @@ -409,8 +408,8 @@ void HistoryItem::setRealId(MsgId newId) { } } - Auth().data().notifyItemIdChange({ this, oldId }); - Auth().data().requestItemRepaint(this); + _history->owner().notifyItemIdChange({ this, oldId }); + _history->owner().requestItemRepaint(this); } bool HistoryItem::isPinned() const { @@ -749,10 +748,10 @@ void HistoryItem::drawInDialog( } HistoryItem::~HistoryItem() { - Auth().data().notifyItemRemoved(this); + _history->owner().notifyItemRemoved(this); App::historyUnregItem(this); if (id < 0 && !App::quitting()) { - Auth().uploader().cancel(fullId()); + _history->session().uploader().cancel(fullId()); } } diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index a496ac051..a45fd312e 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -11,12 +11,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/ripple_animation.h" #include "ui/image/image.h" #include "ui/text_options.h" +#include "history/history.h" #include "history/history_message.h" #include "history/view/history_view_service_message.h" #include "history/media/history_media_document.h" #include "media/media_audio.h" #include "media/player/media_player_instance.h" -#include "auth_session.h" #include "data/data_media_types.h" #include "data/data_session.h" #include "styles/style_widgets.h" @@ -165,7 +165,7 @@ bool HistoryMessageReply::updateData( replyToMsgId = 0; } if (force) { - Auth().data().requestItemResize(holder); + holder->history()->owner().requestItemResize(holder); } return (replyToMsg || !replyToMsgId); } @@ -228,7 +228,7 @@ void HistoryMessageReply::itemRemoved( HistoryItem *removed) { if (replyToMsg == removed) { clearData(holder); - Auth().data().requestItemResize(holder); + holder->history()->owner().requestItemResize(holder); } } diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index c1d1f4c3c..2bcd98eae 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -90,10 +90,11 @@ void FastShareMessage(not_null item) { MessageIdsList msgIds; base::flat_set requests; }; + const auto history = item->history(); const auto data = std::make_shared( - item->history()->peer, - Auth().data().itemOrItsGroup(item)); - const auto isGroup = (Auth().data().groups().find(item) != nullptr); + history->peer, + history->owner().itemOrItsGroup(item)); + const auto isGroup = (history->owner().groups().find(item) != nullptr); const auto isGame = item->getMessageBot() && item->media() && (item->media()->game() != nullptr); @@ -127,7 +128,7 @@ void FastShareMessage(not_null item) { if (!data->requests.empty()) { return; // Share clicked already. } - auto items = Auth().data().idsToItems(data->msgIds); + auto items = history->owner().idsToItems(data->msgIds); if (items.empty() || result.empty()) { return; } @@ -153,8 +154,8 @@ void FastShareMessage(not_null item) { return; } - auto doneCallback = [data](const MTPUpdates &updates, mtpRequestId requestId) { - Auth().api().applyUpdates(updates); + auto doneCallback = [=](const MTPUpdates &updates, mtpRequestId requestId) { + history->session().api().applyUpdates(updates); data->requests.remove(requestId); if (data->requests.empty()) { Ui::Toast::Show(lang(lng_share_done)); @@ -189,7 +190,7 @@ void FastShareMessage(not_null item) { auto message = ApiWrap::MessageToSend(history); message.textWithTags = comment; message.clearDraft = false; - Auth().api().sendMessage(std::move(message)); + history->session().api().sendMessage(std::move(message)); } auto request = MTPmessages_ForwardMessages( MTP_flags(sendFlags), @@ -577,7 +578,7 @@ void HistoryMessage::applyGroupAdminChanges( } else { _flags &= ~MTPDmessage_ClientFlag::f_has_admin_badge; } - Auth().data().requestItemResize(this); + history()->owner().requestItemResize(this); } } @@ -653,7 +654,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) { if (const auto reply = Get()) { reply->replyToMsgId = config.replyTo; if (!reply->updateData(this)) { - Auth().api().requestMessageData( + history()->session().api().requestMessageData( history()->peer->asChannel(), reply->replyToMsgId, HistoryDependentItemCallback(fullId())); @@ -719,12 +720,12 @@ void HistoryMessage::refreshMedia(const MTPMessageMedia *media) { } void HistoryMessage::refreshSentMedia(const MTPMessageMedia *media) { - const auto wasGrouped = Auth().data().groups().isGrouped(this); + const auto wasGrouped = history()->owner().groups().isGrouped(this); refreshMedia(media); if (wasGrouped) { - Auth().data().groups().refreshMessage(this); + history()->owner().groups().refreshMessage(this); } else { - Auth().data().requestItemViewRefresh(this); + history()->owner().requestItemViewRefresh(this); } } @@ -789,7 +790,7 @@ std::unique_ptr HistoryMessage::CreateMedia( return media.vphoto.match([&](const MTPDphoto &photo) -> Result { return std::make_unique( item, - Auth().data().photo(photo)); + item->history()->owner().photo(photo)); }, [](const MTPDphotoEmpty &) -> Result { return nullptr; }); @@ -809,7 +810,7 @@ std::unique_ptr HistoryMessage::CreateMedia( return document.match([&](const MTPDdocument &document) -> Result { return std::make_unique( item, - Auth().data().document(document)); + item->history()->owner().document(document)); }, [](const MTPDdocumentEmpty &) -> Result { return nullptr; }); @@ -819,11 +820,11 @@ std::unique_ptr HistoryMessage::CreateMedia( }, [&](const MTPDwebPagePending &webpage) -> Result { return std::make_unique( item, - Auth().data().webpage(webpage)); + item->history()->owner().webpage(webpage)); }, [&](const MTPDwebPage &webpage) -> Result { return std::make_unique( item, - Auth().data().webpage(webpage)); + item->history()->owner().webpage(webpage)); }, [](const MTPDwebPageNotModified &) -> Result { LOG(("API Error: " "webPageNotModified is unexpected in message media.")); @@ -833,14 +834,14 @@ std::unique_ptr HistoryMessage::CreateMedia( return media.vgame.match([&](const MTPDgame &game) { return std::make_unique( item, - Auth().data().game(game)); + item->history()->owner().game(game)); }); }, [&](const MTPDmessageMediaInvoice &media) -> Result { return std::make_unique(item, media); }, [&](const MTPDmessageMediaPoll &media) -> Result { return std::make_unique( item, - Auth().data().poll(media)); + item->history()->owner().poll(media)); }, [](const MTPDmessageMediaEmpty &) -> Result { return nullptr; }, [](const MTPDmessageMediaUnsupported &) -> Result { @@ -917,7 +918,7 @@ void HistoryMessage::updateSentMedia(const MTPMessageMedia *media) { refreshSentMedia(media); } } - Auth().data().requestItemResize(this); + history()->owner().requestItemResize(this); } void HistoryMessage::addToUnreadMentions(UnreadMentionType type) { @@ -995,7 +996,7 @@ void HistoryMessage::setReplyMarkup(const MTPReplyMarkup *markup) { if (Has()) { RemoveComponents(HistoryMessageReplyMarkup::Bit()); } - Auth().data().requestItemResize(this); + history()->owner().requestItemResize(this); Notify::replyMarkupUpdated(this); } return; @@ -1014,7 +1015,7 @@ void HistoryMessage::setReplyMarkup(const MTPReplyMarkup *markup) { changed = true; } if (changed) { - Auth().data().requestItemResize(this); + history()->owner().requestItemResize(this); Notify::replyMarkupUpdated(this); } } else { @@ -1025,7 +1026,7 @@ void HistoryMessage::setReplyMarkup(const MTPReplyMarkup *markup) { AddComponents(HistoryMessageReplyMarkup::Bit()); } Get()->create(*markup); - Auth().data().requestItemResize(this); + history()->owner().requestItemResize(this); Notify::replyMarkupUpdated(this); } } @@ -1065,17 +1066,17 @@ void HistoryMessage::setViewsCount(int32 count) { ? 0 : st::msgDateFont->width(views->_viewsText); if (was == views->_viewsWidth) { - Auth().data().requestItemRepaint(this); + history()->owner().requestItemRepaint(this); } else { - Auth().data().requestItemResize(this); + history()->owner().requestItemResize(this); } } void HistoryMessage::setRealId(MsgId newId) { HistoryItem::setRealId(newId); - Auth().data().groups().refreshMessage(this); - Auth().data().requestItemResize(this); + history()->owner().groups().refreshMessage(this); + history()->owner().requestItemResize(this); if (const auto reply = Get()) { if (reply->replyToLink()) { reply->setReplyToLinkFrom(this); diff --git a/Telegram/SourceFiles/history/history_service.cpp b/Telegram/SourceFiles/history/history_service.cpp index ce3034aa1..4afafbe6b 100644 --- a/Telegram/SourceFiles/history/history_service.cpp +++ b/Telegram/SourceFiles/history/history_service.cpp @@ -246,7 +246,7 @@ void HistoryService::setMessageByAction(const MTPmessageAction &action) { if (auto channel = history()->peer->asMegagroup()) { auto &users = action.c_messageActionChatAddUser().vusers; for_const (auto &item, users.v) { - if (item.v == Auth().userId()) { + if (item.v == history()->session().userId()) { channel->mgInfo->joinedMessageFound = true; break; } @@ -266,7 +266,7 @@ void HistoryService::setMessageByAction(const MTPmessageAction &action) { _media = std::make_unique( this, history()->peer, - Auth().data().photo(photo.c_photo())); + history()->owner().photo(photo.c_photo())); } } break; @@ -321,7 +321,7 @@ bool HistoryService::updateDependent(bool force) { updateDependentText(); } if (force && gotDependencyItem) { - Auth().notifications().checkDelayed(); + history()->session().notifications().checkDelayed(); } return (dependent->msg || !dependent->msgId); } @@ -539,10 +539,10 @@ void HistoryService::setServiceText(const PreparedText &prepared) { } void HistoryService::markMediaAsReadHook() { - if (auto selfdestruct = Get()) { + if (const auto selfdestruct = Get()) { if (!selfdestruct->destructAt) { selfdestruct->destructAt = getms(true) + selfdestruct->timeToLive; - App::histories().selfDestructIn(this, selfdestruct->timeToLive); + history()->owner().selfDestructIn(this, selfdestruct->timeToLive); } } } @@ -626,7 +626,7 @@ void HistoryService::createFromMtp(const MTPDmessageService &message) { if (auto dependent = GetDependentData()) { dependent->msgId = message.vreply_to_msg_id.v; if (!updateDependent()) { - Auth().api().requestMessageData( + history()->session().api().requestMessageData( history()->peer->asChannel(), dependent->msgId, HistoryDependentItemCallback(fullId())); @@ -656,7 +656,7 @@ void HistoryService::removeMedia() { _media.reset(); _textWidth = -1; _textHeight = 0; - Auth().data().requestItemResize(this); + history()->owner().requestItemResize(this); } Storage::SharedMediaTypesMask HistoryService::sharedMediaTypes() const { @@ -679,7 +679,7 @@ void HistoryService::updateDependentText() { } setServiceText(text); - Auth().data().requestItemResize(this); + history()->owner().requestItemResize(this); if (history()->textCachedFor == this) { history()->textCachedFor = nullptr; } @@ -712,7 +712,7 @@ HistoryService::~HistoryService() { HistoryService::PreparedText GenerateJoinedText( not_null history, not_null inviter) { - if (inviter->id != Auth().userPeerId()) { + if (inviter->id != history->session().userPeerId()) { auto result = HistoryService::PreparedText{}; result.links.push_back(inviter->createOpenLink()); result.text = (history->isMegagroup() @@ -720,7 +720,7 @@ HistoryService::PreparedText GenerateJoinedText( : lng_action_add_you)(lt_from, textcmdLink(1, inviter->name)); return result; } else if (history->isMegagroup()) { - auto self = App::user(Auth().userPeerId()); + auto self = history->session().user(); auto result = HistoryService::PreparedText{}; result.links.push_back(self->createOpenLink()); result.text = lng_action_user_joined( diff --git a/Telegram/SourceFiles/history/media/history_media.cpp b/Telegram/SourceFiles/history/media/history_media.cpp index 31a31d066..dde311297 100644 --- a/Telegram/SourceFiles/history/media/history_media.cpp +++ b/Telegram/SourceFiles/history/media/history_media.cpp @@ -25,6 +25,10 @@ Storage::SharedMediaTypesMask HistoryMedia::sharedMediaTypes() const { return {}; } +not_null HistoryMedia::history() const { + return _parent->history(); +} + bool HistoryMedia::isDisplayed() const { return true; } diff --git a/Telegram/SourceFiles/history/media/history_media.h b/Telegram/SourceFiles/history/media/history_media.h index 50e3a2956..80be295ae 100644 --- a/Telegram/SourceFiles/history/media/history_media.h +++ b/Telegram/SourceFiles/history/media/history_media.h @@ -47,6 +47,8 @@ public: HistoryMedia(not_null parent) : _parent(parent) { } + not_null history() const; + virtual TextWithEntities selectedText(TextSelection selection) const { return TextWithEntities(); } diff --git a/Telegram/SourceFiles/history/media/history_media_contact.cpp b/Telegram/SourceFiles/history/media/history_media_contact.cpp index fba2194a7..5ccd6fc45 100644 --- a/Telegram/SourceFiles/history/media/history_media_contact.cpp +++ b/Telegram/SourceFiles/history/media/history_media_contact.cpp @@ -10,10 +10,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "layout.h" #include "mainwindow.h" -#include "auth_session.h" #include "boxes/add_contact_box.h" #include "history/history_item_components.h" #include "history/history_item.h" +#include "history/history.h" #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" #include "window/window_controller.h" @@ -67,7 +67,7 @@ HistoryContact::HistoryContact( , _fname(first) , _lname(last) , _phone(App::formatPhone(phone)) { - Auth().data().registerContactView(userId, parent); + history()->owner().registerContactView(userId, parent); _name.setText( st::semiboldTextStyle, @@ -77,14 +77,14 @@ HistoryContact::HistoryContact( } HistoryContact::~HistoryContact() { - Auth().data().unregisterContactView(_userId, _parent); + history()->owner().unregisterContactView(_userId, _parent); } void HistoryContact::updateSharedContactUserId(UserId userId) { if (_userId != userId) { - Auth().data().unregisterContactView(_userId, _parent); + history()->owner().unregisterContactView(_userId, _parent); _userId = userId; - Auth().data().registerContactView(_userId, _parent); + history()->owner().registerContactView(_userId, _parent); } } diff --git a/Telegram/SourceFiles/history/media/history_media_document.cpp b/Telegram/SourceFiles/history/media/history_media_document.cpp index 9a07e769c..78e7cea1f 100644 --- a/Telegram/SourceFiles/history/media/history_media_document.cpp +++ b/Telegram/SourceFiles/history/media/history_media_document.cpp @@ -9,11 +9,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "layout.h" -#include "auth_session.h" #include "storage/localstorage.h" #include "media/media_audio.h" #include "media/player/media_player_instance.h" #include "history/history_item_components.h" +#include "history/history.h" #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" #include "history/media/history_media_common.h" @@ -547,7 +547,7 @@ void HistoryDocument::updatePressed(QPoint point) { nameright = st::msgFilePadding.left(); } voice->setSeekingCurrent(snap((point.x() - nameleft) / float64(width() - nameleft - nameright), 0., 1.)); - Auth().data().requestViewRepaint(_parent); + history()->owner().requestViewRepaint(_parent); } } } @@ -695,7 +695,7 @@ void HistoryDocument::step_voiceProgress(float64 ms, bool timer) { voice->_playback->a_progress.update(qMin(dt, 1.), anim::linear); } if (timer) { - Auth().data().requestViewRepaint(_parent); + history()->owner().requestViewRepaint(_parent); } } } @@ -753,7 +753,7 @@ void HistoryDocument::parentTextUpdated() { } else { RemoveComponents(HistoryDocumentCaptioned::Bit()); } - Auth().data().requestViewResize(_parent); + history()->owner().requestViewResize(_parent); } TextWithEntities HistoryDocument::getCaption() const { diff --git a/Telegram/SourceFiles/history/media/history_media_file.cpp b/Telegram/SourceFiles/history/media/history_media_file.cpp index 8899cca56..9ef40adf7 100644 --- a/Telegram/SourceFiles/history/media/history_media_file.cpp +++ b/Telegram/SourceFiles/history/media/history_media_file.cpp @@ -9,8 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "layout.h" -#include "auth_session.h" #include "history/history_item.h" +#include "history/history.h" #include "data/data_document.h" #include "data/data_session.h" #include "styles/style_history.h" @@ -27,13 +27,13 @@ void HistoryFileMedia::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool } void HistoryFileMedia::thumbAnimationCallback() { - Auth().data().requestViewRepaint(_parent); + history()->owner().requestViewRepaint(_parent); } void HistoryFileMedia::clickHandlerPressedChanged( const ClickHandlerPtr &handler, bool pressed) { - Auth().data().requestViewRepaint(_parent); + history()->owner().requestViewRepaint(_parent); } void HistoryFileMedia::setLinks( @@ -76,7 +76,7 @@ void HistoryFileMedia::step_radial(TimeMs ms, bool timer) { }; if (timer) { if (!anim::Disabled() || updateRadial()) { - Auth().data().requestViewRepaint(_parent); + history()->owner().requestViewRepaint(_parent); } } else { updateRadial(); diff --git a/Telegram/SourceFiles/history/media/history_media_game.cpp b/Telegram/SourceFiles/history/media/history_media_game.cpp index 09072319d..579517eb6 100644 --- a/Telegram/SourceFiles/history/media/history_media_game.cpp +++ b/Telegram/SourceFiles/history/media/history_media_game.cpp @@ -9,8 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "layout.h" -#include "auth_session.h" #include "history/history_item_components.h" +#include "history/history.h" #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" #include "history/media/history_media_common.h" @@ -40,7 +40,7 @@ HistoryGame::HistoryGame( consumed, Ui::ItemTextOptions(parent->data())); } - Auth().data().registerGameView(_data, _parent); + history()->owner().registerGameView(_data, _parent); } QSize HistoryGame::countOptimalSize() { @@ -428,10 +428,10 @@ void HistoryGame::parentTextUpdated() { } else { _description = Text(st::msgMinWidth - st::webPageLeft); } - Auth().data().requestViewResize(_parent); + history()->owner().requestViewResize(_parent); } } HistoryGame::~HistoryGame() { - Auth().data().unregisterGameView(_data, _parent); + history()->owner().unregisterGameView(_data, _parent); } diff --git a/Telegram/SourceFiles/history/media/history_media_gif.cpp b/Telegram/SourceFiles/history/media/history_media_gif.cpp index 2cc546a39..82ee761bb 100644 --- a/Telegram/SourceFiles/history/media/history_media_gif.cpp +++ b/Telegram/SourceFiles/history/media/history_media_gif.cpp @@ -10,7 +10,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "layout.h" #include "mainwindow.h" -#include "auth_session.h" #include "media/media_audio.h" #include "media/media_clip_reader.h" #include "media/player/media_player_round_controller.h" @@ -18,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/confirm_box.h" #include "history/history_item_components.h" #include "history/history_item.h" +#include "history/history.h" #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" #include "window/window_controller.h" @@ -779,7 +779,7 @@ void HistoryGif::parentTextUpdated() { _caption = (_parent->media() == this) ? createCaption(_parent->data()) : Text(); - Auth().data().requestViewResize(_parent); + history()->owner().requestViewResize(_parent); } int HistoryGif::additionalWidth(const HistoryMessageVia *via, const HistoryMessageReply *reply, const HistoryMessageForwarded *forwarded) const { @@ -836,7 +836,7 @@ void HistoryGif::clipCallback(Media::Clip::Notification notification) { auto stopped = false; if (reader->autoPausedGif()) { auto amVisible = false; - Auth().data().queryItemVisibility().notify( + history()->owner().queryItemVisibility().notify( { _parent->data(), &amVisible }, true); if (!amVisible) { // Stop animation if it is not visible. @@ -845,13 +845,13 @@ void HistoryGif::clipCallback(Media::Clip::Notification notification) { } } if (!stopped) { - Auth().data().requestViewResize(_parent); + history()->owner().requestViewResize(_parent); } } break; case NotificationRepaint: { if (!reader->currentDisplayed()) { - Auth().data().requestViewRepaint(_parent); + history()->owner().requestViewRepaint(_parent); } } break; } @@ -868,7 +868,7 @@ void HistoryGif::playAnimation(bool autoplay) { stopAnimation(); } else if (_data->loaded(DocumentData::FilePathResolveChecked)) { if (!cAutoPlayGif()) { - Auth().data().stopAutoplayAnimations(); + history()->owner().stopAutoplayAnimations(); } setClipReader(Media::Clip::MakeReader( _data, @@ -884,18 +884,18 @@ void HistoryGif::playAnimation(bool autoplay) { void HistoryGif::stopAnimation() { if (_gif) { clearClipReader(); - Auth().data().requestViewResize(_parent); + history()->owner().requestViewResize(_parent); _data->unload(); } } void HistoryGif::setClipReader(Media::Clip::ReaderPointer gif) { if (_gif) { - Auth().data().unregisterAutoplayAnimation(_gif.get()); + history()->owner().unregisterAutoplayAnimation(_gif.get()); } _gif = std::move(gif); if (_gif) { - Auth().data().registerAutoplayAnimation(_gif.get(), _parent); + history()->owner().registerAutoplayAnimation(_gif.get(), _parent); } } diff --git a/Telegram/SourceFiles/history/media/history_media_grouped.cpp b/Telegram/SourceFiles/history/media/history_media_grouped.cpp index 7104b32e0..0d8761f81 100644 --- a/Telegram/SourceFiles/history/media/history_media_grouped.cpp +++ b/Telegram/SourceFiles/history/media/history_media_grouped.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_item_components.h" #include "history/history_message.h" +#include "history/history.h" #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" #include "data/data_media_types.h" @@ -17,7 +18,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "ui/grouped_layout.h" #include "ui/text_options.h" -#include "auth_session.h" #include "layout.h" #include "styles/style_history.h" @@ -408,7 +408,7 @@ void HistoryGroupedMedia::updateNeedBubbleState() { } void HistoryGroupedMedia::parentTextUpdated() { - Auth().data().requestViewResize(_parent); + history()->owner().requestViewResize(_parent); } bool HistoryGroupedMedia::needsBubble() const { diff --git a/Telegram/SourceFiles/history/media/history_media_photo.cpp b/Telegram/SourceFiles/history/media/history_media_photo.cpp index 244b3b9e5..58496eb87 100644 --- a/Telegram/SourceFiles/history/media/history_media_photo.cpp +++ b/Telegram/SourceFiles/history/media/history_media_photo.cpp @@ -8,9 +8,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/media/history_media_photo.h" #include "layout.h" -#include "auth_session.h" #include "history/history_item_components.h" #include "history/history_item.h" +#include "history/history.h" #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" #include "history/media/history_media_common.h" @@ -526,5 +526,5 @@ void HistoryPhoto::parentTextUpdated() { _caption = (_parent->media() == this) ? createCaption(_parent->data()) : Text(); - Auth().data().requestViewResize(_parent); + history()->owner().requestViewResize(_parent); } diff --git a/Telegram/SourceFiles/history/media/history_media_poll.cpp b/Telegram/SourceFiles/history/media/history_media_poll.cpp index d76aee5ca..c89337d3a 100644 --- a/Telegram/SourceFiles/history/media/history_media_poll.cpp +++ b/Telegram/SourceFiles/history/media/history_media_poll.cpp @@ -193,7 +193,7 @@ HistoryPoll::HistoryPoll( : HistoryMedia(parent) , _poll(poll) , _question(st::msgMinWidth / 2) { - Auth().data().registerPollView(_poll, _parent); + history()->owner().registerPollView(_poll, _parent); } QSize HistoryPoll::countOptimalSize() { @@ -371,7 +371,7 @@ ClickHandlerPtr HistoryPoll::createAnswerClickHandler( const auto option = answer.option; const auto itemId = _parent->data()->fullId(); return std::make_shared([=] { - Auth().api().sendPollVotes(itemId, { option }); + history()->session().api().sendPollVotes(itemId, { option }); }); } @@ -563,7 +563,7 @@ void HistoryPoll::resetAnswersAnimation() const { void HistoryPoll::step_radial(TimeMs ms, bool timer) { if (timer && !anim::Disabled()) { - Auth().data().requestViewRepaint(_parent); + history()->owner().requestViewRepaint(_parent); } } @@ -806,7 +806,7 @@ void HistoryPoll::startAnswersAnimation() const { data.opacity.start(can ? 0. : 1.); } _answersAnimation->progress.start( - [=] { Auth().data().requestViewRepaint(_parent); }, + [=] { history()->owner().requestViewRepaint(_parent); }, 0., 1., st::historyPollDuration); @@ -883,7 +883,7 @@ void HistoryPoll::toggleRipple(Answer &answer, bool pressed) { ? st::historyPollRippleOut : st::historyPollRippleIn), std::move(mask), - [=] { Auth().data().requestViewRepaint(_parent); }); + [=] { history()->owner().requestViewRepaint(_parent); }); } const auto top = countAnswerTop(answer, innerWidth); answer.ripple->add(_lastLinkPoint - QPoint(0, top)); @@ -895,5 +895,5 @@ void HistoryPoll::toggleRipple(Answer &answer, bool pressed) { } HistoryPoll::~HistoryPoll() { - Auth().data().unregisterPollView(_poll, _parent); + history()->owner().unregisterPollView(_poll, _parent); } diff --git a/Telegram/SourceFiles/history/media/history_media_video.cpp b/Telegram/SourceFiles/history/media/history_media_video.cpp index d648f743f..b34eaa0ba 100644 --- a/Telegram/SourceFiles/history/media/history_media_video.cpp +++ b/Telegram/SourceFiles/history/media/history_media_video.cpp @@ -9,9 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/media/history_media_common.h" #include "layout.h" -#include "auth_session.h" #include "history/history_item_components.h" #include "history/history_item.h" +#include "history/history.h" #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" #include "ui/image/image.h" @@ -501,7 +501,7 @@ void HistoryVideo::parentTextUpdated() { _caption = (_parent->media() == this) ? createCaption(_parent->data()) : Text(); - Auth().data().requestViewResize(_parent); + history()->owner().requestViewResize(_parent); } void HistoryVideo::updateStatusText() const { diff --git a/Telegram/SourceFiles/history/media/history_media_web_page.cpp b/Telegram/SourceFiles/history/media/history_media_web_page.cpp index e7ed6d71d..b783d15ae 100644 --- a/Telegram/SourceFiles/history/media/history_media_web_page.cpp +++ b/Telegram/SourceFiles/history/media/history_media_web_page.cpp @@ -8,10 +8,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/media/history_media_web_page.h" #include "layout.h" -#include "auth_session.h" #include "core/click_handler_types.h" #include "history/history_item_components.h" #include "history/history_item.h" +#include "history/history.h" #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" #include "history/media/history_media_common.h" @@ -76,7 +76,7 @@ HistoryWebPage::HistoryWebPage( , _data(data) , _title(st::msgMinWidth - st::webPageLeft) , _description(st::msgMinWidth - st::webPageLeft) { - Auth().data().registerWebPageView(_data, _parent); + history()->owner().registerWebPageView(_data, _parent); } QSize HistoryWebPage::countOptimalSize() { @@ -694,5 +694,5 @@ int HistoryWebPage::bottomInfoPadding() const { } HistoryWebPage::~HistoryWebPage() { - Auth().data().unregisterWebPageView(_data, _parent); + history()->owner().unregisterWebPageView(_data, _parent); } diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 00798a575..9a64f992d 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -17,7 +17,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_groups.h" #include "data/data_media_types.h" #include "lang/lang_keys.h" -#include "auth_session.h" #include "layout.h" #include "styles/style_history.h" @@ -139,10 +138,10 @@ Element::Element( , _data(data) , _dateTime(ItemDateTime(data)) , _context(delegate->elementContext()) { - Auth().data().registerItemView(this); + history()->owner().registerItemView(this); refreshMedia(); if (_context == Context::History) { - _data->_history->setHasPendingResizedItems(); + history()->setHasPendingResizedItems(); } } @@ -154,6 +153,10 @@ not_null Element::data() const { return _data; } +not_null Element::history() const { + return _data->history(); +} + QDateTime Element::dateTime() const { return _dateTime; } @@ -260,7 +263,7 @@ void Element::refreshMedia() { const auto item = data(); const auto media = item->media(); if (media && media->canBeGrouped()) { - if (const auto group = Auth().data().groups().find(item)) { + if (const auto group = history()->owner().groups().find(item)) { if (group->items.back() != item) { _media = nullptr; _flags |= Flag::HiddenByGroup; @@ -269,7 +272,7 @@ void Element::refreshMedia() { this, group->items); if (!pendingResize()) { - Auth().data().requestViewResize(this); + history()->owner().requestViewResize(this); } } return; @@ -324,7 +327,7 @@ void Element::destroyUnreadBar() { return; } RemoveComponents(UnreadBar::Bit()); - Auth().data().requestViewResize(this); + history()->owner().requestViewResize(this); if (data()->mainView() == this) { recountAttachToPreviousInBlocks(); } @@ -341,9 +344,9 @@ void Element::setUnreadBarCount(int count) { if (data()->mainView() == this) { recountAttachToPreviousInBlocks(); } - Auth().data().requestViewResize(this); + history()->owner().requestViewResize(this); } else { - Auth().data().requestViewRepaint(this); + history()->owner().requestViewRepaint(this); } } @@ -608,7 +611,7 @@ void Element::clickHandlerActiveChanged( } } App::hoveredLinkItem(active ? this : nullptr); - Auth().data().requestViewRepaint(this); + history()->owner().requestViewRepaint(this); if (const auto media = this->media()) { media->clickHandlerActiveChanged(handler, active); } @@ -623,7 +626,7 @@ void Element::clickHandlerPressedChanged( } } App::pressedLinkItem(pressed ? this : nullptr); - Auth().data().requestViewRepaint(this); + history()->owner().requestViewRepaint(this); if (const auto media = this->media()) { media->clickHandlerPressedChanged(handler, pressed); } @@ -634,9 +637,9 @@ Element::~Element() { _data->clearMainView(); } if (_context == Context::History) { - Auth().data().notifyViewRemoved(this); + history()->owner().notifyViewRemoved(this); } - Auth().data().unregisterItemView(this); + history()->owner().unregisterItemView(this); } } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index 9f9ba0989..73b5f475f 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -121,6 +121,7 @@ public: not_null delegate() const; not_null data() const; + not_null history() const; HistoryMedia *media() const; Context context() const; void refreshDataId(); diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index aa2108005..21476a187 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -18,7 +18,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwidget.h" #include "mainwindow.h" #include "window/window_controller.h" -#include "auth_session.h" #include "layout.h" #include "styles/style_widgets.h" #include "styles/style_history.h" @@ -57,7 +56,7 @@ const style::TextStyle &KeyboardStyle::textStyle() const { } void KeyboardStyle::repaint(not_null item) const { - Auth().data().requestItemRepaint(item); + item->history()->owner().requestItemRepaint(item); } int KeyboardStyle::buttonRadius() const { diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index 2efb04789..5c0ba0488 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "calls/calls_instance.h" #include "data/data_peer_values.h" #include "data/data_feed.h" +#include "data/data_session.h" #include "support/support_helper.h" #include "observer_peer.h" #include "apiwrap.h" @@ -96,13 +97,14 @@ TopBarWidget::TopBarWidget( if (Adaptive::OneColumn()) { createUnreadBadge(); } - subscribe( - App::histories().sendActionAnimationUpdated(), - [this](const Histories::SendActionAnimationUpdate &update) { - if (update.history == _activeChat.history()) { - this->update(); - } - }); + Auth().data().sendActionAnimationUpdated( + ) | rpl::start_with_next([=]( + const Data::Session::SendActionAnimationUpdate &update) { + if (update.history == _activeChat.history()) { + this->update(); + } + }, lifetime()); + using UpdateFlag = Notify::PeerUpdate::Flag; auto flags = UpdateFlag::UserHasCalls | UpdateFlag::UserOnlineChanged @@ -696,8 +698,8 @@ void TopBarWidget::updateUnreadBadge() { if (!_unreadBadge) return; const auto history = _activeChat.history(); - const auto active = !App::histories().unreadBadgeMutedIgnoreOne(history); - const auto counter = App::histories().unreadBadgeIgnoreOne(history); + const auto active = !Auth().data().unreadBadgeMutedIgnoreOne(history); + const auto counter = Auth().data().unreadBadgeIgnoreOne(history); const auto text = [&] { if (!counter) { return QString(); diff --git a/Telegram/SourceFiles/info/info_controller.cpp b/Telegram/SourceFiles/info/info_controller.cpp index c3a1f9e44..e47e4cb8f 100644 --- a/Telegram/SourceFiles/info/info_controller.cpp +++ b/Telegram/SourceFiles/info/info_controller.cpp @@ -100,7 +100,7 @@ Controller::Controller( , _widget(widget) , _key(memento->key()) , _migrated(memento->migratedPeerId() - ? App::peer(memento->migratedPeerId()) + ? App::peer(memento->migratedPeerId()).get() : nullptr) , _section(memento->section()) { updateSearchControllers(memento); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 739427d3f..8a6e62f48 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1420,8 +1420,8 @@ void MainWidget::updateScrollColors() { _history->updateScrollColors(); } -void MainWidget::setChatBackground(const App::WallPaper &wp) { - _background = std::make_unique(wp); +void MainWidget::setChatBackground(const Data::WallPaper &background) { + _background = std::make_unique(background); _background->full->loadEvenCancelled(Data::FileOrigin()); checkChatBackground(); } @@ -1450,7 +1450,7 @@ void MainWidget::checkChatBackground() { Window::Theme::Background()->setImage(_background->id, _background->full->pix(Data::FileOrigin()).toImage()); } _background = nullptr; - QTimer::singleShot(0, this, SLOT(update())); + crl::on_main(this, [=] { update(); }); } } } @@ -1730,9 +1730,9 @@ void MainWidget::ui_showPeerHistory( animationParams); } else { _history->show(); - if (App::wnd()) { - QTimer::singleShot(0, App::wnd(), SLOT(setInnerFocus())); - } + crl::on_main(App::wnd(), [] { + App::wnd()->setInnerFocus(); + }); } } } @@ -2073,9 +2073,9 @@ void MainWidget::showBackFromStack( if (selectingPeer()) return; if (_stack.empty()) { _controller->clearSectionStack(params); - if (App::wnd()) { - QTimer::singleShot(0, App::wnd(), SLOT(setInnerFocus())); - } + crl::on_main(App::wnd(), [] { + App::wnd()->setInnerFocus(); + }); return; } auto item = std::move(_stack.back()); @@ -3256,8 +3256,7 @@ void MainWidget::openPeerByName( FullMsgId clickFromMessageId) { Messenger::Instance().hideMediaView(); - PeerData *peer = App::peerByName(username); - if (peer) { + if (const auto peer = Auth().data().peerByUsername(username)) { if (msgId == ShowAtGameShareMsgId) { if (peer->isUser() && peer->asUser()->botInfo && !startToken.isEmpty()) { peer->asUser()->botInfo->shareGameShortName = startToken; @@ -3716,8 +3715,11 @@ bool fwdInfoDataLoaded(const MTPMessageFwdHeader &header) { if (!App::channelLoaded(peerFromChannel(info.vchannel_id))) { return false; } - if (info.has_from_id() && !App::user(peerFromUser(info.vfrom_id), PeerData::MinimalLoaded)) { - return false; + if (info.has_from_id()) { + const auto from = App::user(peerFromUser(info.vfrom_id)); + if (from->loadedStatus == PeerData::NotLoaded) { + return false; + } } } else { if (info.has_from_id() && !App::userLoaded(peerFromUser(info.vfrom_id))) { @@ -4188,7 +4190,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { const auto user = App::userLoaded(d.vuser_id.v); if (history && user) { const auto when = requestingDifference() ? 0 : unixtime(); - App::histories().registerSendAction(history, user, d.vaction, when); + Auth().data().registerSendAction(history, user, d.vaction, when); } } break; @@ -4207,7 +4209,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { : App::userLoaded(d.vuser_id.v); if (history && user) { const auto when = requestingDifference() ? 0 : unixtime(); - App::histories().registerSendAction(history, user, d.vaction, when); + Auth().data().registerSendAction(history, user, d.vaction, when); } } break; @@ -4505,8 +4507,11 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { case mtpc_updateChannelAvailableMessages: { auto &d = update.c_updateChannelAvailableMessages(); - if (auto channel = App::channelLoaded(d.vchannel_id.v)) { + if (const auto channel = App::channelLoaded(d.vchannel_id.v)) { channel->setAvailableMinId(d.vavailable_min_id.v); + if (const auto history = App::historyLoaded(channel)) { + history->clearUpTill(d.vavailable_min_id.v); + } } } break; diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 73498f093..ac475f2ba 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -24,6 +24,10 @@ namespace Notify { struct PeerUpdate; } // namespace Notify +namespace Data { +struct WallPaper; +} // namespace Data + namespace Dialogs { struct RowDescriptor; class Row; @@ -222,7 +226,7 @@ public: QPixmap cachedBackground(const QRect &forRect, int &x, int &y); void updateScrollColors(); - void setChatBackground(const App::WallPaper &wp); + void setChatBackground(const Data::WallPaper &background); bool chatBackgroundLoading(); float64 chatBackgroundProgress() const; void checkChatBackground(); @@ -547,7 +551,7 @@ private: ViewsIncrementByRequest _viewsIncrementByRequest; SingleTimer _viewsIncrementTimer; - std::unique_ptr _background; + std::unique_ptr _background; bool _firstColumnResizing = false; int _firstColumnResizingShift = 0; diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index c29f3cdf1..441661733 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -142,13 +142,9 @@ void MainWindow::firstShow() { void MainWindow::clearWidgetsHook() { Expects(_passcodeLock == nullptr || !Global::LocalPasscode()); - auto wasMain = (_main != nullptr); _main.destroy(); _passcodeLock.destroy(); _intro.destroy(); - if (wasMain) { - App::clearHistories(); - } } QPixmap MainWindow::grabInner() { diff --git a/Telegram/SourceFiles/messenger.cpp b/Telegram/SourceFiles/messenger.cpp index 2e6174188..2ddc0374c 100644 --- a/Telegram/SourceFiles/messenger.cpp +++ b/Telegram/SourceFiles/messenger.cpp @@ -735,19 +735,20 @@ void Messenger::authSessionCreate(const MTPUser &user) { void Messenger::authSessionDestroy() { unlockTerms(); - _authSession.reset(); + _authSession = nullptr; _private->storedAuthSession.reset(); _private->authSessionUserId = 0; _private->authSessionUserSerialized = {}; authSessionChanged().notify(true); + Notify::unreadCounterUpdated(); } int Messenger::unreadBadge() const { - return _authSession ? App::histories().unreadBadge() : 0; + return _authSession ? _authSession->data().unreadBadge() : 0; } bool Messenger::unreadBadgeMuted() const { - return _authSession ? App::histories().unreadBadgeMuted() : false; + return _authSession ? _authSession->data().unreadBadgeMuted() : false; } void Messenger::setInternalLinkDomain(const QString &domain) const { @@ -902,7 +903,6 @@ Messenger::~Messenger() { _mediaView.reset(); // Some MTP requests can be cancelled from data clearing. - App::clearHistories(); authSessionDestroy(); // The langpack manager should be destroyed before MTProto instance, @@ -1000,16 +1000,14 @@ void Messenger::loggedOut() { Media::Player::mixer()->stopAndClear(); Global::SetVoiceMsgPlaybackDoubled(false); Media::Player::mixer()->setVoicePlaybackDoubled(false); - if (const auto w = getActiveWindow()) { - w->tempDirDelete(Local::ClearManagerAll); - w->setupIntro(); + if (const auto window = getActiveWindow()) { + window->tempDirDelete(Local::ClearManagerAll); + window->setupIntro(); } - App::histories().clear(); if (const auto session = authSession()) { - session->data().cache().close(); - session->data().cache().clear(); + session->data().clearLocalStorage(); + authSessionDestroy(); } - authSessionDestroy(); if (_mediaView) { hideMediaView(); _mediaView->clearData(); diff --git a/Telegram/SourceFiles/support/support_common.cpp b/Telegram/SourceFiles/support/support_common.cpp index 21deb1499..c0d08c2fb 100644 --- a/Telegram/SourceFiles/support/support_common.cpp +++ b/Telegram/SourceFiles/support/support_common.cpp @@ -11,18 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Support { -bool ValidateAccount(const MTPUser &self) { - //return true; AssertIsDebug(); - return self.match([](const MTPDuser &data) { - DEBUG_LOG(("ValidateAccount: %1 %2" - ).arg(Logs::b(data.has_phone()) - ).arg(data.has_phone() ? qs(data.vphone) : QString())); - return data.has_phone() && qs(data.vphone).startsWith(qstr("424")); - }, [](const MTPDuserEmpty &data) { - return false; - }); -} - bool HandleSwitch(Qt::KeyboardModifiers modifiers) { return !(modifiers & Qt::ShiftModifier) || (!(modifiers & Qt::ControlModifier) diff --git a/Telegram/SourceFiles/support/support_common.h b/Telegram/SourceFiles/support/support_common.h index 7b2c17392..453a28529 100644 --- a/Telegram/SourceFiles/support/support_common.h +++ b/Telegram/SourceFiles/support/support_common.h @@ -9,8 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Support { -bool ValidateAccount(const MTPUser &self); - enum class SwitchSettings { None, Next, diff --git a/Telegram/SourceFiles/support/support_helper.cpp b/Telegram/SourceFiles/support/support_helper.cpp index 818a79ec9..febbcc5e3 100644 --- a/Telegram/SourceFiles/support/support_helper.cpp +++ b/Telegram/SourceFiles/support/support_helper.cpp @@ -282,6 +282,12 @@ Helper::Helper(not_null session) }).send(); } +std::unique_ptr Helper::Create(not_null session) { + //return std::make_unique(session); AssertIsDebug(); + const auto valid = session->user()->phone().startsWith(qstr("424")); + return valid ? std::make_unique(session) : nullptr; +} + void Helper::registerWindow(not_null controller) { controller->activeChatValue( ) | rpl::map([](Dialogs::Key key) { diff --git a/Telegram/SourceFiles/support/support_helper.h b/Telegram/SourceFiles/support/support_helper.h index fdf2eb3d9..c65777469 100644 --- a/Telegram/SourceFiles/support/support_helper.h +++ b/Telegram/SourceFiles/support/support_helper.h @@ -39,6 +39,8 @@ class Helper : private MTP::Sender { public: explicit Helper(not_null session); + static std::unique_ptr Create(not_null session); + void registerWindow(not_null controller); void cloudDraftChanged(not_null history); diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index e1bc675c2..4245eb16b 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/confirm_box.h" #include "core/click_handler_types.h" #include "lang/lang_keys.h" +#include "data/data_session.h" #include "mediaview.h" #include "auth_session.h" #include "apiwrap.h" @@ -428,7 +429,7 @@ void MainWindow::updateUnreadCounter() { if (!Global::started() || App::quitting()) return; const auto counter = AuthSession::Exists() - ? App::histories().unreadBadge() + ? Auth().data().unreadBadge() : 0; _titleText = (counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram");