From c534f3f22e147e83c71ca8fba0a9798a921b09cb Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 7 Nov 2021 12:06:00 +0400 Subject: [PATCH] Some internal HistoryItem refactoring. Replace most IsServerMsgId / id <=> 0 with isRegular(). Track isLocal / isHistoryEntry in flags. Remove toHistoryMessage. --- Telegram/SourceFiles/api/api_bot.cpp | 4 +- Telegram/SourceFiles/api/api_polls.cpp | 3 +- Telegram/SourceFiles/api/api_sending.cpp | 6 - Telegram/SourceFiles/apiwrap.cpp | 62 +++-- Telegram/SourceFiles/boxes/url_auth_box.cpp | 4 +- .../chat_helpers/emoji_interactions.cpp | 8 +- Telegram/SourceFiles/data/data_changes.h | 32 +-- Telegram/SourceFiles/data/data_groups.cpp | 9 +- Telegram/SourceFiles/data/data_histories.cpp | 10 +- Telegram/SourceFiles/data/data_peer.cpp | 2 +- .../SourceFiles/data/data_replies_list.cpp | 21 +- Telegram/SourceFiles/data/data_replies_list.h | 2 +- .../data/data_scheduled_messages.cpp | 3 +- Telegram/SourceFiles/data/data_session.cpp | 4 +- .../data/data_sponsored_messages.cpp | 2 +- Telegram/SourceFiles/data/data_types.h | 13 +- .../SourceFiles/dialogs/ui/dialogs_layout.cpp | 2 +- Telegram/SourceFiles/facades.cpp | 2 +- .../admin_log/history_admin_log_inner.cpp | 43 ++-- Telegram/SourceFiles/history/history.cpp | 78 +++---- Telegram/SourceFiles/history/history.h | 10 +- .../history/history_inner_widget.cpp | 106 +++++---- Telegram/SourceFiles/history/history_item.cpp | 76 ++++--- Telegram/SourceFiles/history/history_item.h | 23 +- .../SourceFiles/history/history_message.cpp | 25 +- .../SourceFiles/history/history_message.h | 11 +- .../SourceFiles/history/history_service.cpp | 6 +- .../SourceFiles/history/history_service.h | 2 +- .../SourceFiles/history/history_widget.cpp | 13 +- .../view/history_view_context_menu.cpp | 45 ++-- .../history/view/history_view_element.cpp | 2 +- .../history/view/history_view_list_widget.cpp | 19 +- .../history/view/history_view_message.cpp | 24 +- .../view/history_view_pinned_section.cpp | 4 +- .../view/history_view_replies_section.cpp | 12 +- .../view/media/history_view_document.cpp | 2 +- .../history/view/media/history_view_game.cpp | 2 +- .../history/view/media/history_view_gif.cpp | 13 +- .../view/media/history_view_media_grouped.cpp | 3 +- .../media/history_view_media_unwrapped.cpp | 9 +- .../history/view/media/history_view_photo.cpp | 13 +- .../history/view/media/history_view_poll.cpp | 2 +- Telegram/SourceFiles/info/info_controller.cpp | 3 - .../polls/info_polls_results_inner_widget.cpp | 2 +- .../media/player/media_player_instance.cpp | 2 +- .../media/player/media_player_panel.cpp | 2 +- .../media/view/media_view_group_thumbs.cpp | 2 +- .../media/view/media_view_overlay_widget.cpp | 215 ++++++++---------- .../media/view/media_view_overlay_widget.h | 11 +- .../SourceFiles/overview/overview_layout.cpp | 2 +- .../SourceFiles/storage/localimageloader.cpp | 3 +- .../window/notifications_manager.cpp | 10 +- 52 files changed, 460 insertions(+), 524 deletions(-) diff --git a/Telegram/SourceFiles/api/api_bot.cpp b/Telegram/SourceFiles/api/api_bot.cpp index 8dbf6fa77..ff5209a10 100644 --- a/Telegram/SourceFiles/api/api_bot.cpp +++ b/Telegram/SourceFiles/api/api_bot.cpp @@ -36,7 +36,7 @@ void SendBotCallbackData( int column, std::optional password = std::nullopt, Fn handleError = nullptr) { - if (!IsServerMsgId(item->id)) { + if (!item->isRegular()) { return; } const auto history = item->history(); @@ -150,7 +150,7 @@ void SendBotCallbackDataWithPassword( not_null item, int row, int column) { - if (!IsServerMsgId(item->id)) { + if (!item->isRegular()) { return; } const auto history = item->history(); diff --git a/Telegram/SourceFiles/api/api_polls.cpp b/Telegram/SourceFiles/api/api_polls.cpp index 1113cf655..fcfe7f983 100644 --- a/Telegram/SourceFiles/api/api_polls.cpp +++ b/Telegram/SourceFiles/api/api_polls.cpp @@ -182,8 +182,7 @@ void Polls::close(not_null item) { void Polls::reloadResults(not_null item) { const auto itemId = item->fullId(); - if (!IsServerMsgId(item->id) - || _pollReloadRequestIds.contains(itemId)) { + if (!item->isRegular() || _pollReloadRequestIds.contains(itemId)) { return; } const auto requestId = _api.request(MTPmessages_GetPollResults( diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index 8e3b8c848..795750ad2 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -111,8 +111,6 @@ void SendExistingMedia( if (message.action.options.scheduled) { flags |= MessageFlag::IsOrWasScheduled; sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date; - } else { - flags |= MessageFlag::LocalHistoryEntry; } session->data().registerMessageRandomId(randomId, newId); @@ -271,8 +269,6 @@ bool SendDice(Api::MessageToSend &message) { if (message.action.options.scheduled) { flags |= MessageFlag::IsOrWasScheduled; sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date; - } else { - flags |= MessageFlag::LocalHistoryEntry; } session->data().registerMessageRandomId(randomId, newId); @@ -387,8 +383,6 @@ void SendConfirmedFile( // Scheduled messages have no the 'edited' badge. flags |= MessageFlag::HideEdited; - } else { - flags |= MessageFlag::LocalHistoryEntry; } if (file->type == SendMediaType::Audio) { if (!peer->isChannel() || peer->isMegagroup()) { diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 370c82019..011ae8a65 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -1288,7 +1288,7 @@ void ApiWrap::markMediaRead( continue; } item->markMediaRead(); - if (!IsServerMsgId(item->id)) { + if (!item->isRegular()) { continue; } if (const auto channel = item->history()->peer->asChannel()) { @@ -1318,7 +1318,7 @@ void ApiWrap::markMediaRead(not_null item) { return; } item->markMediaRead(); - if (!IsServerMsgId(item->id)) { + if (!item->isRegular()) { return; } const auto ids = MTP_vector(1, MTP_int(item->id)); @@ -2329,7 +2329,7 @@ void ApiWrap::deleteHistory( if (!last) { // History is empty. return; - } else if (!IsServerMsgId(last->id)) { + } else if (!last->isRegular()) { // Destroy client-side message locally. last->destroy(); } else { @@ -2354,7 +2354,7 @@ void ApiWrap::deleteHistory( if (const auto migrated = peer->migrateFrom()) { deleteHistory(migrated, justClear, revoke); } - if (IsServerMsgId(deleteTillId) || (!justClear && revoke)) { + if (deleteTillId || (!justClear && revoke)) { history->owner().histories().deleteAllMessages( history, deleteTillId, @@ -3681,8 +3681,6 @@ void ApiWrap::forwardMessages( if (action.options.scheduled) { flags |= MessageFlag::IsOrWasScheduled; sendFlags |= MTPmessages_ForwardMessages::Flag::f_schedule_date; - } else { - flags |= MessageFlag::LocalHistoryEntry; } if (draft.options != Data::ForwardOptions::PreserveInfo) { sendFlags |= MTPmessages_ForwardMessages::Flag::f_drop_author; @@ -3741,30 +3739,28 @@ void ApiWrap::forwardMessages( for (const auto item : draft.items) { const auto randomId = base::RandomValue(); if (genClientSideMessage) { - if (const auto message = item->toHistoryMessage()) { - const auto newId = FullMsgId( - peerToChannel(peer->id), - _session->data().nextLocalMessageId()); - const auto self = _session->user(); - const auto messageFromId = anonymousPost - ? PeerId(0) - : self->id; - const auto messagePostAuthor = peer->isBroadcast() - ? self->name - : QString(); - history->addNewLocalMessage( - newId.msg, - flags, - HistoryItem::NewMessageDate(action.options.scheduled), - messageFromId, - messagePostAuthor, - message); - _session->data().registerMessageRandomId(randomId, newId); - if (!localIds) { - localIds = std::make_shared>(); - } - localIds->emplace(randomId, newId); + const auto newId = FullMsgId( + peerToChannel(peer->id), + _session->data().nextLocalMessageId()); + const auto self = _session->user(); + const auto messageFromId = anonymousPost + ? PeerId(0) + : self->id; + const auto messagePostAuthor = peer->isBroadcast() + ? self->name + : QString(); + history->addNewLocalMessage( + newId.msg, + flags, + HistoryItem::NewMessageDate(action.options.scheduled), + messageFromId, + messagePostAuthor, + item); + _session->data().registerMessageRandomId(randomId, newId); + if (!localIds) { + localIds = std::make_shared>(); } + localIds->emplace(randomId, newId); } const auto newFrom = item->history()->peer; if (forwardFrom != newFrom) { @@ -3827,8 +3823,6 @@ void ApiWrap::sendSharedContact( FillMessagePostFlags(action, peer, flags); if (action.options.scheduled) { flags |= MessageFlag::IsOrWasScheduled; - } else { - flags |= MessageFlag::LocalHistoryEntry; } const auto messageFromId = anonymousPost ? 0 : _session->userPeerId(); const auto messagePostAuthor = peer->isBroadcast() @@ -4009,7 +4003,7 @@ void ApiWrap::sendUploadedDocument( } void ApiWrap::cancelLocalItem(not_null item) { - Expects(!IsServerMsgId(item->id)); + Expects(item->isSending()); if (const auto groupId = item->groupId()) { sendAlbumWithCancelled(item, groupId); @@ -4100,8 +4094,6 @@ void ApiWrap::sendMessage(MessageToSend &&message) { if (action.options.scheduled) { flags |= MessageFlag::IsOrWasScheduled; sendFlags |= MTPmessages_SendMessage::Flag::f_schedule_date; - } else { - flags |= MessageFlag::LocalHistoryEntry; } const auto viaBotId = UserId(); lastMessage = history->addNewLocalMessage( @@ -4219,8 +4211,6 @@ void ApiWrap::sendInlineResult( if (action.options.scheduled) { flags |= MessageFlag::IsOrWasScheduled; sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_schedule_date; - } else { - flags |= MessageFlag::LocalHistoryEntry; } const auto messageFromId = anonymousPost ? 0 : _session->userPeerId(); diff --git a/Telegram/SourceFiles/boxes/url_auth_box.cpp b/Telegram/SourceFiles/boxes/url_auth_box.cpp index 84584acdf..909d04747 100644 --- a/Telegram/SourceFiles/boxes/url_auth_box.cpp +++ b/Telegram/SourceFiles/boxes/url_auth_box.cpp @@ -32,7 +32,7 @@ void UrlAuthBox::Activate( itemId, row, column); - if (button->requestId || !IsServerMsgId(itemId.msg)) { + if (button->requestId || !message->isRegular()) { return; } const auto session = &message->history()->session(); @@ -121,7 +121,7 @@ void UrlAuthBox::Request( itemId, row, column); - if (button->requestId || !IsServerMsgId(itemId.msg)) { + if (button->requestId || !message->isRegular()) { return; } const auto session = &message->history()->session(); diff --git a/Telegram/SourceFiles/chat_helpers/emoji_interactions.cpp b/Telegram/SourceFiles/chat_helpers/emoji_interactions.cpp index 0f4e961e4..455bee476 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_interactions.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_interactions.cpp @@ -114,7 +114,7 @@ EmojiPtr EmojiInteractions::chooseInteractionEmoji( void EmojiInteractions::startOutgoing( not_null view) { const auto item = view->data(); - if (!IsServerMsgId(item->id) || !item->history()->peer->isUser()) { + if (!item->isRegular() || !item->history()->peer->isUser()) { return; } const auto emoticon = item->originalText().text; @@ -161,13 +161,11 @@ void EmojiInteractions::startIncoming( MsgId messageId, const QString &emoticon, EmojiInteractionsBunch &&bunch) { - if (!peer->isUser() - || bunch.interactions.empty() - || !IsServerMsgId(messageId)) { + if (!peer->isUser() || bunch.interactions.empty()) { return; } const auto item = _session->data().message(nullptr, messageId); - if (!item) { + if (!item || !item->isRegular()) { return; } const auto emoji = chooseInteractionEmoji(item); diff --git a/Telegram/SourceFiles/data/data_changes.h b/Telegram/SourceFiles/data/data_changes.h index 49fb72827..1b8b768f1 100644 --- a/Telegram/SourceFiles/data/data_changes.h +++ b/Telegram/SourceFiles/data/data_changes.h @@ -110,23 +110,23 @@ struct HistoryUpdate { enum class Flag : uint32 { None = 0, - IsPinned = (1U << 0), - UnreadView = (1U << 1), - TopPromoted = (1U << 2), - Folder = (1U << 3), - UnreadMentions = (1U << 4), - LocalMessages = (1U << 5), - ChatOccupied = (1U << 6), - MessageSent = (1U << 7), - ScheduledSent = (1U << 8), - ForwardDraft = (1U << 9), - OutboxRead = (1U << 10), - BotKeyboard = (1U << 11), - CloudDraft = (1U << 12), - LocalDraftSet = (1U << 13), - PinnedMessages = (1U << 14), + IsPinned = (1U << 0), + UnreadView = (1U << 1), + TopPromoted = (1U << 2), + Folder = (1U << 3), + UnreadMentions = (1U << 4), + ClientSideMessages = (1U << 5), + ChatOccupied = (1U << 6), + MessageSent = (1U << 7), + ScheduledSent = (1U << 8), + ForwardDraft = (1U << 9), + OutboxRead = (1U << 10), + BotKeyboard = (1U << 11), + CloudDraft = (1U << 12), + LocalDraftSet = (1U << 13), + PinnedMessages = (1U << 14), - LastUsedBit = (1U << 14), + LastUsedBit = (1U << 14), }; using Flags = base::flags; friend inline constexpr auto is_flag_type(Flag) { return true; } diff --git a/Telegram/SourceFiles/data/data_groups.cpp b/Telegram/SourceFiles/data/data_groups.cpp index 6e07ab1a9..ed675143e 100644 --- a/Telegram/SourceFiles/data/data_groups.cpp +++ b/Telegram/SourceFiles/data/data_groups.cpp @@ -73,7 +73,7 @@ void Groups::refreshMessage( unregisterMessage(item); return; } - if (!IsServerMsgId(item->id) && !item->isScheduled()) { + if (!item->isRegular() && !item->isScheduled()) { return; } const auto groupId = item->groupId(); @@ -112,14 +112,13 @@ void Groups::refreshMessage( HistoryItemsList::const_iterator Groups::findPositionForItem( const HistoryItemsList &group, not_null item) { - const auto itemId = item->id; const auto last = end(group); - if (!IsServerMsgId(itemId)) { + if (!item->isRegular()) { return last; } + const auto itemId = item->id; for (auto result = begin(group); result != last; ++result) { - const auto alreadyId = (*result)->id; - if (IsServerMsgId(alreadyId) && alreadyId > itemId) { + if ((*result)->isRegular() && (*result)->id > itemId) { return result; } } diff --git a/Telegram/SourceFiles/data/data_histories.cpp b/Telegram/SourceFiles/data/data_histories.cpp index eaa39dcbb..2af0634b7 100644 --- a/Telegram/SourceFiles/data/data_histories.cpp +++ b/Telegram/SourceFiles/data/data_histories.cpp @@ -100,7 +100,7 @@ void Histories::readInbox(not_null history) { void Histories::readInboxTill(not_null item) { const auto history = item->history(); - if (!IsServerMsgId(item->id)) { + if (!item->isRegular()) { readClientSideMessage(item); auto view = item->mainView(); if (!view) { @@ -123,11 +123,11 @@ void Histories::readInboxTill(not_null item) { } } item = view->data(); - if (IsServerMsgId(item->id)) { + if (item->isRegular()) { break; } } - if (!IsServerMsgId(item->id)) { + if (!item->isRegular()) { LOG(("App Error: " "Can't read history till unknown local message.")); return; @@ -235,7 +235,7 @@ void Histories::readInboxTill( } void Histories::readInboxOnNewMessage(not_null item) { - if (!IsServerMsgId(item->id)) { + if (!item->isRegular()) { readClientSideMessage(item); } else { readInboxTill(item->history(), item->id, true); @@ -728,7 +728,7 @@ void Histories::deleteMessages(const MessageIdsList &ids, bool revoke) { continue; } remove.push_back(item); - if (IsServerMsgId(item->id)) { + if (item->isRegular()) { idsByPeer[history].push_back(MTP_int(itemId.msg)); } } diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index f91a4da29..74aec4c17 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -528,7 +528,7 @@ bool PeerData::canExportChatHistory() const { } for (const auto &block : _owner->history(id)->blocks) { for (const auto &message : block->messages) { - if (!message->data()->serviceMsg()) { + if (!message->data()->isService()) { return true; } } diff --git a/Telegram/SourceFiles/data/data_replies_list.cpp b/Telegram/SourceFiles/data/data_replies_list.cpp index 7d348fbe2..348374654 100644 --- a/Telegram/SourceFiles/data/data_replies_list.cpp +++ b/Telegram/SourceFiles/data/data_replies_list.cpp @@ -71,7 +71,7 @@ rpl::producer RepliesList::source( const auto push = [=] { viewer->scheduled = false; if (buildFromData(viewer)) { - appendLocalMessages(viewer->slice); + appendClientSideMessages(viewer->slice); consumer.put_next_copy(viewer->slice); } }; @@ -95,7 +95,7 @@ rpl::producer RepliesList::source( _history->session().changes().historyUpdates( _history, - Data::HistoryUpdate::Flag::LocalMessages + Data::HistoryUpdate::Flag::ClientSideMessages ) | rpl::start_with_next(pushDelayed, lifetime); _partLoaded.events( @@ -115,16 +115,16 @@ rpl::producer RepliesList::source( }; } -void RepliesList::appendLocalMessages(MessagesSlice &slice) { - const auto &local = _history->localMessages(); - if (local.empty()) { +void RepliesList::appendClientSideMessages(MessagesSlice &slice) { + const auto &messages = _history->clientSideMessages(); + if (messages.empty()) { return; } else if (slice.ids.empty()) { if (slice.skippedBefore != 0 || slice.skippedAfter != 0) { return; } - slice.ids.reserve(local.size()); - for (const auto &item : local) { + slice.ids.reserve(messages.size()); + for (const auto &item : messages) { if (item->replyToTop() != _rootId) { continue; } @@ -142,7 +142,7 @@ void RepliesList::appendLocalMessages(MessagesSlice &slice) { dates.push_back(message->date()); } - for (const auto &item : local) { + for (const auto &item : messages) { if (item->replyToTop() != _rootId) { continue; } @@ -369,8 +369,7 @@ bool RepliesList::buildFromData(not_null viewer) { bool RepliesList::applyUpdate( not_null viewer, const MessageUpdate &update) { - if (update.item->history() != _history - || !IsServerMsgId(update.item->id)) { + if (update.item->history() != _history || !update.item->isRegular()) { return false; } if (update.flags & MessageUpdate::Flag::Destroyed) { @@ -454,7 +453,7 @@ void RepliesList::loadAround(MsgId id) { _list.clear(); if (processMessagesIsEmpty(result)) { _fullCount = _skippedBefore = _skippedAfter = 0; - } else if (id > 0) { + } else if (id) { Assert(!_list.empty()); if (_list.front() <= id) { _skippedAfter = 0; diff --git a/Telegram/SourceFiles/data/data_replies_list.h b/Telegram/SourceFiles/data/data_replies_list.h index 71c8d32b3..ed87dc0e8 100644 --- a/Telegram/SourceFiles/data/data_replies_list.h +++ b/Telegram/SourceFiles/data/data_replies_list.h @@ -46,7 +46,7 @@ private: MessagePosition aroundId, int limitBefore, int limitAfter); - void appendLocalMessages(MessagesSlice &slice); + void appendClientSideMessages(MessagesSlice &slice); [[nodiscard]] bool buildFromData(not_null viewer); [[nodiscard]] bool applyUpdate( diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/data_scheduled_messages.cpp index fc5e04bb9..374b4cc30 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp +++ b/Telegram/SourceFiles/data/data_scheduled_messages.cpp @@ -176,8 +176,7 @@ void ScheduledMessages::sendNowSimpleMessage( auto action = Api::SendAction(history); action.replyTo = local->replyToId(); const auto replyHeader = NewMessageReplyHeader(action); - const auto localFlags = NewMessageFlags(history->peer) - | MessageFlag::LocalHistoryEntry; + const auto localFlags = NewMessageFlags(history->peer); const auto flags = MTPDmessage::Flag::f_entities | MTPDmessage::Flag::f_from_id | (local->replyToId() diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index e52adafdc..d3d13dda5 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -3496,7 +3496,7 @@ HistoryItem *Session::findWebPageItem(not_null page) const { const auto i = _webpageItems.find(page); if (i != _webpageItems.end()) { for (const auto &item : i->second) { - if (IsServerMsgId(item->id)) { + if (item->isRegular()) { return item; } } @@ -3983,7 +3983,7 @@ void Session::insertCheckedServiceNotification( | MTPDmessage::Flag::f_from_id | MTPDmessage::Flag::f_media; const auto localFlags = MessageFlag::ClientSideUnread - | MessageFlag::LocalHistoryEntry; + | MessageFlag::Local; auto sending = TextWithEntities(), left = message; while (TextUtilities::CutPart(sending, left, MaxMessageSize)) { const auto id = nextLocalMessageId(); diff --git a/Telegram/SourceFiles/data/data_sponsored_messages.cpp b/Telegram/SourceFiles/data/data_sponsored_messages.cpp index cbddbc322..1dc5b49d1 100644 --- a/Telegram/SourceFiles/data/data_sponsored_messages.cpp +++ b/Telegram/SourceFiles/data/data_sponsored_messages.cpp @@ -75,7 +75,7 @@ bool SponsoredMessages::append(not_null history) { | (history->isChannel() ? MessageFlag::Post : MessageFlags(0)) | MessageFlag::HasFromId | MessageFlag::IsSponsored - | MessageFlag::LocalHistoryEntry; + | MessageFlag::Local; auto local = history->addNewLocalMessage( _session->data().nextLocalMessageId(), flags, diff --git a/Telegram/SourceFiles/data/data_types.h b/Telegram/SourceFiles/data/data_types.h index b01118488..d1bdb5b8e 100644 --- a/Telegram/SourceFiles/data/data_types.h +++ b/Telegram/SourceFiles/data/data_types.h @@ -268,17 +268,20 @@ enum class MessageFlag : uint32 { // No media and only a several emoji text. IsolatedEmoji = (1U << 25), - // Local message existing in the message history. - LocalHistoryEntry = (1U << 26), + // Message existing in the message history. + HistoryEntry = (1U << 26), + + // Local message, not existing on the server. + Local = (1U << 27), // Fake message for some UI element. - FakeHistoryItem = (1U << 27), + FakeHistoryItem = (1U << 28), // Contact sign-up message, notification should be skipped for Silent. - IsContactSignUp = (1U << 28), + IsContactSignUp = (1U << 29), // In channels. - IsSponsored = (1U << 29), + IsSponsored = (1U << 30), }; inline constexpr bool is_flag_type(MessageFlag) { return true; } using MessageFlags = base::flags; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index 6f4562205..f7f024af7 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -417,7 +417,7 @@ void paintRow( : st::dialogsSendingIcon)); } } else if (item && !item->isEmpty() && item->needCheck()) { - if (item->id > 0) { + if (!item->isSending() && !item->hasFailed()) { if (item->unread()) { return &(active ? st::dialogsSentIconActive diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index fc5a0f2dd..bbf301720 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -91,7 +91,7 @@ void activateBotCommand( // Copy string before passing it to the sending method // because the original button can be destroyed inside. if (sessionController) { - MsgId replyTo = (msg->id > 0) ? msg->id : 0; + MsgId replyTo = msg->isRegular() ? msg->id : 0; sessionController->content()->sendBotCommand({ .peer = msg->history()->peer, .command = QString(button->text), diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index 36a8b7623..9b4a0638b 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -147,8 +147,9 @@ void InnerWidget::enumerateUserpics(Method method) { auto userpicCallback = [&](not_null view, int itemtop, int itembottom) { // Skip all service messages. - const auto message = view->data()->toHistoryMessage(); - if (!message) return true; + if (view->data()->isService()) { + return true; + } if (lowestAttachedItemTop < 0 && view->isAttachedToNext()) { lowestAttachedItemTop = itemtop + view->marginTop(); @@ -963,10 +964,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { // paint the userpic if it intersects the painted rect if (userpicTop + st::msgPhotoSize > clip.top()) { - const auto message = view->data()->toHistoryMessage(); - Assert(message != nullptr); - - const auto from = message->from(); + const auto from = view->data()->from(); from->paintUserpicLeft( p, _userpics[from], @@ -1677,26 +1675,21 @@ void InnerWidget::updateSelected() { dragState = view->textState(itemPoint, request); lnkhost = view; if (!dragState.link && itemPoint.x() >= st::historyPhotoLeft && itemPoint.x() < st::historyPhotoLeft + st::msgPhotoSize) { - if (item->toHistoryMessage()) { - if (view->hasFromPhoto()) { - enumerateUserpics([&](not_null view, int userpicTop) { - // stop enumeration if the userpic is below our point - if (userpicTop > point.y()) { - return false; - } + if (!item->isService() && view->hasFromPhoto()) { + enumerateUserpics([&](not_null view, int userpicTop) { + // stop enumeration if the userpic is below our point + if (userpicTop > point.y()) { + return false; + } - // stop enumeration if we've found a userpic under the cursor - if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) { - const auto message = view->data()->toHistoryMessage(); - Assert(message != nullptr); - - dragState.link = message->from()->openLink(); - lnkhost = view; - return false; - } - return true; - }); - } + // stop enumeration if we've found a userpic under the cursor + if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) { + dragState.link = view->data()->from()->openLink(); + lnkhost = view; + return false; + } + return true; + }); } } } diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 26529e096..35fec779d 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -146,7 +146,7 @@ void History::itemRemoved(not_null item) { checkChatListMessageRemoved(item); itemVanished(item); if (IsClientMsgId(item->id)) { - unregisterLocalMessage(item); + unregisterClientSideMessage(item); } if (const auto chat = peer->asChat()) { if (const auto to = chat->getMigrateToChannel()) { @@ -428,7 +428,7 @@ void History::destroyMessage(not_null item) { if (item->isHistoryEntry()) { // All this must be done for all items manually in History::clear()! item->destroyHistoryEntry(); - if (IsServerMsgId(item->id)) { + if (item->isRegular()) { if (const auto types = item->sharedMediaTypes()) { session().storage().remove(Storage::SharedMediaRemoveOne( peerId, @@ -550,7 +550,7 @@ not_null History::addNewLocalMessage( return addNewItem( makeMessage( id, - flags, + flags | MessageFlag::Local, replyTo, viaBotId, date, @@ -569,11 +569,11 @@ not_null History::addNewLocalMessage( TimeId date, PeerId from, const QString &postAuthor, - not_null forwardOriginal) { + not_null forwardOriginal) { return addNewItem( makeMessage( id, - flags, + flags | MessageFlag::Local, date, from, postAuthor, @@ -595,7 +595,7 @@ not_null History::addNewLocalMessage( return addNewItem( makeMessage( id, - flags, + flags | MessageFlag::Local, replyTo, viaBotId, date, @@ -621,7 +621,7 @@ not_null History::addNewLocalMessage( return addNewItem( makeMessage( id, - flags, + flags | MessageFlag::Local, replyTo, viaBotId, date, @@ -646,7 +646,7 @@ not_null History::addNewLocalMessage( return addNewItem( makeMessage( id, - flags, + flags | MessageFlag::Local, replyTo, viaBotId, date, @@ -766,7 +766,7 @@ not_null History::addNewToBack( addItemToBlock(item); - if (!unread && IsServerMsgId(item->id)) { + if (!unread && item->isRegular()) { if (const auto sharedMediaTypes = item->sharedMediaTypes()) { auto from = loadedAtTop() ? 0 : minMsgId(); auto till = loadedAtBottom() ? ServerMaxMsgId : maxMsgId(); @@ -1144,28 +1144,28 @@ void History::newItemAdded(not_null item) { } } -void History::registerLocalMessage(not_null item) { +void History::registerClientSideMessage(not_null item) { Expects(item->isHistoryEntry()); Expects(IsClientMsgId(item->id)); - _localMessages.emplace(item); - session().changes().historyUpdated(this, UpdateFlag::LocalMessages); + _clientSideMessages.emplace(item); + session().changes().historyUpdated(this, UpdateFlag::ClientSideMessages); } -void History::unregisterLocalMessage(not_null item) { - const auto removed = _localMessages.remove(item); +void History::unregisterClientSideMessage(not_null item) { + const auto removed = _clientSideMessages.remove(item); Assert(removed); - session().changes().historyUpdated(this, UpdateFlag::LocalMessages); + session().changes().historyUpdated(this, UpdateFlag::ClientSideMessages); } -const base::flat_set> &History::localMessages() { - return _localMessages; +const base::flat_set> &History::clientSideMessages() { + return _clientSideMessages; } HistoryItem *History::latestSendingMessage() const { auto sending = ranges::views::all( - _localMessages + _clientSideMessages ) | ranges::views::filter([](not_null item) { return item->isSending(); }); @@ -1446,7 +1446,7 @@ void History::calculateFirstUnreadMessage() { for (const auto &block : ranges::views::reverse(blocks)) { for (const auto &message : ranges::views::reverse(block->messages)) { const auto item = message->data(); - if (!IsServerMsgId(item->id)) { + if (!item->isRegular()) { continue; } else if (!item->out()) { if (item->id >= *_inboxReadBefore) { @@ -1474,7 +1474,7 @@ bool History::readInboxTillNeedsRequest(MsgId tillId) { void History::readClientSideMessages() { auto &histories = owner().histories(); - for (const auto &item : _localMessages) { + for (const auto &item : _clientSideMessages) { histories.readClientSideMessage(item); } } @@ -1502,7 +1502,7 @@ std::optional History::countStillUnreadLocal(MsgId readTillId) const { for (const auto &block : blocks) { for (const auto &message : block->messages) { const auto item = message->data(); - if (!IsServerMsgId(item->id) + if (!item->isRegular() || (item->out() && !item->isFromScheduled())) { continue; } else if (item->id > readTillId) { @@ -1534,7 +1534,7 @@ std::optional History::countStillUnreadLocal(MsgId readTillId) const { for (const auto &block : ranges::views::reverse(blocks)) { for (const auto &message : ranges::views::reverse(block->messages)) { const auto item = message->data(); - if (IsServerMsgId(item->id)) { + if (item->isRegular()) { if (item->id <= readTillId) { return result; } else if (!item->out()) { @@ -1588,7 +1588,7 @@ void History::inboxRead(MsgId upTo, std::optional stillUnread) { } void History::inboxRead(not_null wasRead) { - if (IsServerMsgId(wasRead->id)) { + if (wasRead->isRegular()) { inboxRead(wasRead->id); } } @@ -1596,7 +1596,7 @@ void History::inboxRead(not_null wasRead) { void History::outboxRead(MsgId upTo) { setOutboxReadTill(upTo); if (const auto last = chatListMessage()) { - if (last->out() && IsServerMsgId(last->id) && last->id <= upTo) { + if (last->out() && last->isRegular() && last->id <= upTo) { session().changes().messageUpdated( last, Data::MessageUpdate::Flag::DialogRowRepaint); @@ -1607,7 +1607,7 @@ void History::outboxRead(MsgId upTo) { } void History::outboxRead(not_null wasRead) { - if (IsServerMsgId(wasRead->id)) { + if (wasRead->isRegular()) { outboxRead(wasRead->id); } } @@ -1663,7 +1663,7 @@ void History::setUnreadCount(int newUnreadCount) { const auto lastOutgoing = [&] { const auto last = lastMessage(); return last - && IsServerMsgId(last->id) + && last->isRegular() && loadedAtBottom() && !isEmpty() && blocks.back()->messages.back()->data() == last @@ -1757,7 +1757,7 @@ void History::getNextFirstUnreadMessage() { const auto block = _firstUnreadView->block(); const auto index = _firstUnreadView->indexInBlock(); const auto setFromMessage = [&](const auto &view) { - if (IsServerMsgId(view->data()->id)) { + if (view->data()->isRegular()) { _firstUnreadView = view.get(); return true; } @@ -2213,7 +2213,7 @@ void History::setLastServerMessage(HistoryItem *item) { _lastServerMessage = item; if (_lastMessage && *_lastMessage - && !IsServerMsgId((*_lastMessage)->id) + && !(*_lastMessage)->isRegular() && (!item || (*_lastMessage)->date() > item->date())) { return; } @@ -2225,7 +2225,7 @@ void History::setLastMessage(HistoryItem *item) { return; } _lastMessage = item; - if (!item || IsServerMsgId(item->id)) { + if (!item || item->isRegular()) { _lastServerMessage = item; } if (peer->migrateTo()) { @@ -2260,7 +2260,7 @@ void History::setChatListMessage(HistoryItem *item) { } if (_chatListMessage && *_chatListMessage - && !IsServerMsgId((*_chatListMessage)->id) + && !(*_chatListMessage)->isRegular() && (*_chatListMessage)->date() > item->date()) { return; } @@ -2539,7 +2539,7 @@ void History::unknownMessageDeleted(MsgId messageId) { } bool History::isServerSideUnread(not_null item) const { - Expects(IsServerMsgId(item->id)); + Expects(item->isRegular()); return item->out() ? (!_outboxReadBefore || (item->id >= *_outboxReadBefore)) @@ -2743,7 +2743,7 @@ MsgId History::minMsgId() const { for (const auto &block : blocks) { for (const auto &message : block->messages) { const auto item = message->data(); - if (IsServerMsgId(item->id)) { + if (item->isRegular()) { return item->id; } } @@ -2755,7 +2755,7 @@ MsgId History::maxMsgId() const { for (const auto &block : ranges::views::reverse(blocks)) { for (const auto &message : ranges::views::reverse(block->messages)) { const auto item = message->data(); - if (IsServerMsgId(item->id)) { + if (item->isRegular()) { return item->id; } } @@ -2765,7 +2765,7 @@ MsgId History::maxMsgId() const { MsgId History::msgIdForRead() const { const auto last = lastMessage(); - const auto result = (last && IsServerMsgId(last->id)) + const auto result = (last && last->isRegular()) ? last->id : MsgId(0); return loadedAtBottom() @@ -2944,7 +2944,7 @@ void History::checkLocalMessages() { const auto goodDate = [&](TimeId date) { return (date >= firstDate && date < lastDate); }; - for (const auto &item : _localMessages) { + for (const auto &item : _clientSideMessages) { if (!item->mainView() && goodDate(item->date())) { insertLocalMessage(item); } @@ -2989,7 +2989,7 @@ bool History::isDisplayedEmpty() const { } const auto isChangePhoto = [](not_null item) { if (const auto media = item->media()) { - return (media->photo() != nullptr) && !item->toHistoryMessage(); + return (media->photo() != nullptr) && item->isService(); } return false; }; @@ -3108,7 +3108,7 @@ void History::clear(ClearType type) { } else { // Leave the 'sending' messages in local messages. auto local = base::flat_set>(); - for (const auto &item : _localMessages) { + for (const auto &item : _clientSideMessages) { if (!item->isSending()) { local.emplace(item); } @@ -3124,7 +3124,7 @@ void History::clear(ClearType type) { if (type == ClearType::DeleteChat) { setLastServerMessage(nullptr); } else if (_lastMessage && *_lastMessage) { - if (IsServerMsgId((*_lastMessage)->id)) { + if ((*_lastMessage)->isRegular()) { (*_lastMessage)->applyEditionToHistoryCleared(); } else { _lastMessage = std::nullopt; @@ -3158,7 +3158,7 @@ void History::clearUpTill(MsgId availableMinId) { remove.reserve(_messages.size()); for (const auto &item : _messages) { const auto itemId = item->id; - if (!IsServerMsgId(itemId)) { + if (!item->isRegular()) { continue; } else if (itemId == availableMinId) { item->applyEditionToHistoryCleared(); diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 0c8fda48c..edc6caae4 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -158,7 +158,7 @@ public: TimeId date, PeerId from, const QString &postAuthor, - not_null forwardOriginal); + not_null forwardOriginal); not_null addNewLocalMessage( MsgId id, MessageFlags flags, @@ -206,9 +206,9 @@ public: void newItemAdded(not_null item); - void registerLocalMessage(not_null item); - void unregisterLocalMessage(not_null item); - [[nodiscard]] auto localMessages() + void registerClientSideMessage(not_null item); + void unregisterClientSideMessage(not_null item); + [[nodiscard]] auto clientSideMessages() -> const base::flat_set> &; [[nodiscard]] HistoryItem *latestSendingMessage() const; @@ -600,7 +600,7 @@ private: base::flat_set _unreadMentions; std::optional _lastMessage; std::optional _lastServerMessage; - base::flat_set> _localMessages; + base::flat_set> _clientSideMessages; std::unordered_set> _messages; // This almost always is equal to _lastMessage. The only difference is diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index b39460d43..0d1cf828a 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -428,7 +428,9 @@ void HistoryInner::enumerateUserpics(Method method) { auto userpicCallback = [&](not_null view, int itemtop, int itembottom) { // Skip all service messages. const auto item = view->data(); - if (view->isHidden() || !item->toHistoryMessage()) return true; + if (view->isHidden() || item->isService()) { + return true; + } if (lowestAttachedItemTop < 0 && view->isAttachedToNext()) { lowestAttachedItemTop = itemtop + view->marginTop(); @@ -565,7 +567,7 @@ TextSelection HistoryInner::itemRenderSelection( const auto item = view->data(); const auto y = view->block()->y() + view->y(); if (y >= selfromy && y < seltoy) { - if (_dragSelecting && !item->serviceMsg() && item->id > 0) { + if (_dragSelecting && !item->isService() && item->isRegular()) { return FullSelection; } } else if (!_selected.empty()) { @@ -792,8 +794,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) { // paint the userpic if it intersects the painted rect if (userpicTop + st::msgPhotoSize > clip.top()) { - const auto message = view->data()->toHistoryMessage(); - if (const auto from = message->displayFrom()) { + if (const auto from = view->data()->displayFrom()) { from->paintUserpicLeft( p, _userpics[from], @@ -801,7 +802,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) { userpicTop, width(), st::msgPhotoSize); - } else if (const auto info = message->hiddenForwardedInfo()) { + } else if (const auto info = view->data()->hiddenForwardedInfo()) { info->userpic.paint( p, st::historyPhotoLeft, @@ -1462,8 +1463,8 @@ void HistoryInner::mouseActionFinish( _selected.erase(i); repaintItem(_mouseActionItem); } else if ((i == _selected.cend()) - && !_dragStateItem->serviceMsg() - && (_dragStateItem->id > 0) + && !_dragStateItem->isService() + && _dragStateItem->isRegular() && inSelectionMode()) { if (_selected.size() < MaxSelectedItems) { _selected.emplace(_dragStateItem, FullSelection); @@ -1621,7 +1622,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { HistoryItem *item, HistoryItem *albumPartItem) { if (!item - || !IsServerMsgId(item->id) + || !item->isRegular() || isUponSelected == 2 || isUponSelected == -2) { return; @@ -1633,8 +1634,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { }); } const auto repliesCount = item->repliesCount(); - const auto withReplies = IsServerMsgId(item->id) - && (repliesCount > 0); + const auto withReplies = (repliesCount > 0); if (withReplies && item->history()->peer->isMegagroup()) { const auto rootId = repliesCount ? item->id : item->replyToTop(); const auto phrase = (repliesCount > 0) @@ -1807,7 +1807,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { }); } } - if (IsServerMsgId(item->id) && !item->serviceMsg()) { + if (item->isRegular() && !item->isService()) { _menu->addAction(tr::lng_context_select_msg(tr::now), [=] { if (const auto item = session->data().message(itemId)) { if (const auto view = item->mainView()) { @@ -1837,13 +1837,12 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { const auto itemId = item ? item->fullId() : FullMsgId(); const auto canDelete = item && item->canDelete() - && (item->id > 0 || !item->serviceMsg()); + && (item->isRegular() || !item->isService()); const auto canForward = item && item->allowsForward(); const auto canReport = item && item->suggestReport(); const auto canBlockSender = item && item->history()->peer->isRepliesChat(); const auto view = item ? item->mainView() : nullptr; - const auto msg = dynamic_cast(item); if (isUponSelected > 0) { _menu->addAction( ((isUponSelected > 1) @@ -1885,12 +1884,15 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { }); } } - if (msg && view && !link && (view->hasVisibleText() || mediaHasTextForCopy)) { - if (item->isSponsored()) { - _menu->addAction(tr::lng_sponsored_title({}), [=] { - _controller->show(Box(Ui::AboutSponsoredBox)); - }); - } + if (item->isSponsored()) { + _menu->addAction(tr::lng_sponsored_title({}), [=] { + _controller->show(Box(Ui::AboutSponsoredBox)); + }); + } + if (!item->isService() + && view + && !link + && (view->hasVisibleText() || mediaHasTextForCopy)) { _menu->addAction(tr::lng_context_copy_text(tr::now), [=] { copyContextText(itemId); }); @@ -1926,7 +1928,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { _menu->addAction(tr::lng_context_clear_selection(tr::now), [=] { _widget->clearSelected(); }); - } else if (item && ((isUponSelected != -2 && (canForward || canDelete)) || item->id > 0)) { + } else if (item && ((isUponSelected != -2 && (canForward || canDelete)) || item->isRegular())) { if (isUponSelected != -2) { if (canForward) { _menu->addAction(tr::lng_context_forward_msg(tr::now), [=] { @@ -1937,7 +1939,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { const auto callback = [=] { deleteAsGroup(itemId); }; - if (msg && msg->uploading()) { + if (item->isUploading()) { _menu->addAction(tr::lng_context_cancel_upload(tr::now), callback); } else { _menu->addAction(Ui::DeleteMessageContextAction( @@ -1953,7 +1955,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { }); } } - if (item->id > 0 && !item->serviceMsg()) { + if (item->isRegular() && !item->isService()) { _menu->addAction(tr::lng_context_select_msg(tr::now), [=] { if (const auto item = session->data().message(itemId)) { if (const auto view = item->mainView()) { @@ -1971,8 +1973,8 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } } else { if (App::mousedItem() - && IsServerMsgId(App::mousedItem()->data()->id) - && !App::mousedItem()->data()->serviceMsg()) { + && App::mousedItem()->data()->isRegular() + && !App::mousedItem()->data()->isService()) { const auto itemId = App::mousedItem()->data()->fullId(); _menu->addAction(tr::lng_context_select_msg(tr::now), [=] { if (const auto item = session->data().message(itemId)) { @@ -2783,7 +2785,7 @@ MessageIdsList HistoryInner::getSelectedItems() const { _selected.end() ) | views::filter([](const auto &selected) { const auto item = selected.first; - return item && item->toHistoryMessage() && (item->id > 0); + return item && !item->isService() && item->isRegular(); }) | views::transform([](const auto &selected) { return selected.first->fullId(); }) | to_vector; @@ -2935,27 +2937,22 @@ void HistoryInner::mouseActionUpdate() { _dragStateItem = session().data().message(dragState.itemId); lnkhost = view; if (!dragState.link && m.x() >= st::historyPhotoLeft && m.x() < st::historyPhotoLeft + st::msgPhotoSize) { - if (item->toHistoryMessage()) { - if (view->hasFromPhoto()) { - enumerateUserpics([&](not_null view, int userpicTop) -> bool { - // stop enumeration if the userpic is below our point - if (userpicTop > point.y()) { - return false; - } + if (!item->isService() && view->hasFromPhoto()) { + enumerateUserpics([&](not_null view, int userpicTop) -> bool { + // stop enumeration if the userpic is below our point + if (userpicTop > point.y()) { + return false; + } - // stop enumeration if we've found a userpic under the cursor - if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) { - const auto message = view->data()->toHistoryMessage(); - Assert(message != nullptr); - - dragState = TextState(nullptr, view->fromPhotoLink()); - _dragStateItem = session().data().message(dragState.itemId); - lnkhost = view; - return false; - } - return true; - }); - } + // stop enumeration if we've found a userpic under the cursor + if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) { + dragState = TextState(nullptr, view->fromPhotoLink()); + _dragStateItem = nullptr; + lnkhost = view; + return false; + } + return true; + }); } } } @@ -3040,7 +3037,9 @@ void HistoryInner::mouseActionUpdate() { } auto dragSelecting = false; auto dragFirstAffected = dragSelFrom; - while (dragFirstAffected && (dragFirstAffected->data()->id < 0 || dragFirstAffected->data()->serviceMsg())) { + while (dragFirstAffected + && (!dragFirstAffected->data()->isRegular() + || dragFirstAffected->data()->isService())) { dragFirstAffected = (dragFirstAffected != dragSelTo) ? (selectingDown ? nextItem(dragFirstAffected) @@ -3186,7 +3185,7 @@ auto HistoryInner::findViewForPinnedTracking(int top) const const auto fromHistory = [&](not_null history, int historyTop) -> std::pair { auto [view, offset] = history->findItemAndOffset(top - historyTop); - while (view && !IsServerMsgId(view->data()->id)) { + while (view && !view->data()->isRegular()) { offset -= view->height(); view = view->nextInBlocks(); } @@ -3262,10 +3261,9 @@ bool HistoryInner::goodForSelection( not_null toItems, not_null item, int &totalCount) const { - if (item->id <= 0 || item->serviceMsg()) { + if (!item->isRegular() || item->isService()) { return false; - } - if (toItems->find(item) == toItems->end()) { + } else if (toItems->find(item) == toItems->end()) { ++totalCount; } return true; @@ -3367,11 +3365,9 @@ void HistoryInner::deleteItem(FullMsgId itemId) { } void HistoryInner::deleteItem(not_null item) { - if (auto message = item->toHistoryMessage()) { - if (message->uploading()) { - _controller->cancelUploadLayer(item); - return; - } + if (item->isUploading()) { + _controller->cancelUploadLayer(item); + return; } const auto suggestModerateActions = true; _controller->show(Box(item, suggestModerateActions)); diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 1c129a038..5666402e6 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -164,6 +164,15 @@ MediaCheckResult CheckMessageMedia(const MTPMessageMedia &media) { }); } +[[nodiscard]] MessageFlags FinalizeMessageFlags(MessageFlags flags) { + if (!(flags & MessageFlag::FakeHistoryItem) + && !(flags & MessageFlag::IsOrWasScheduled) + && !(flags & MessageFlag::AdminLogEntry)) { + flags |= MessageFlag::HistoryEntry; + } + return flags; +} + } // namespace void HistoryItem::HistoryItem::Destroyer::operator()(HistoryItem *value) { @@ -181,10 +190,10 @@ HistoryItem::HistoryItem( : id(id) , _history(history) , _from(from ? history->owner().peer(from) : history->peer) -, _flags(flags) +, _flags(FinalizeMessageFlags(flags)) , _date(date) { if (isHistoryEntry() && IsClientMsgId(id)) { - _history->registerLocalMessage(this); + _history->registerClientSideMessage(this); } } @@ -433,8 +442,7 @@ UserData *HistoryItem::getMessageBot() const { } bool HistoryItem::isHistoryEntry() const { - return IsServerMsgId(id) - || (_flags & MessageFlag::LocalHistoryEntry); + return (_flags & MessageFlag::HistoryEntry); } bool HistoryItem::isAdminLogEntry() const { @@ -553,7 +561,7 @@ void HistoryItem::applySentMessage( } void HistoryItem::indexAsNewItem() { - if (IsServerMsgId(id)) { + if (isRegular()) { addToUnreadMentions(UnreadMentionType::New); if (const auto types = sharedMediaTypes()) { _history->session().storage().add(Storage::SharedMediaAddNew( @@ -572,9 +580,9 @@ void HistoryItem::setRealId(MsgId newId) { Expects(IsClientMsgId(id)); const auto oldId = std::exchange(id, newId); - _flags &= ~MessageFlag::BeingSent; - if (IsServerMsgId(id)) { - _history->unregisterLocalMessage(this); + _flags &= ~(MessageFlag::BeingSent | MessageFlag::Local); + if (isRegular()) { + _history->unregisterClientSideMessage(this); } _history->owner().notifyItemIdChange({ this, oldId }); @@ -591,7 +599,7 @@ void HistoryItem::setRealId(MsgId newId) { } bool HistoryItem::canPin() const { - if (id < 0 || !toHistoryMessage()) { + if (!isRegular() || isService()) { return false; } else if (const auto m = media(); m && m->call()) { return false; @@ -612,7 +620,7 @@ bool HistoryItem::allowsEdit(TimeId now) const { } bool HistoryItem::canStopPoll() const { - if (id < 0 + if (!isRegular() || Has() || Has()) { return false; @@ -636,7 +644,7 @@ bool HistoryItem::canStopPoll() const { bool HistoryItem::canDelete() const { if (isSponsored()) { return false; - } else if (!IsServerMsgId(id) && serviceMsg()) { + } else if (isService() && !isRegular()) { return false; } else if (!isHistoryEntry() && !isScheduled()) { return false; @@ -652,7 +660,7 @@ bool HistoryItem::canDelete() const { if (channel->canDeleteMessages()) { return true; } - if (out() && toHistoryMessage()) { + if (out() && !isService()) { return isPost() ? channel->canPublish() : true; } return false; @@ -667,7 +675,7 @@ bool HistoryItem::canDeleteForEveryone(TimeId now) const { : peer->isUser() ? (now - date() >= config.revokePrivateTimeLimit) : (now - date() >= config.revokeTimeLimit); - if (id < 0 || messageToMyself || messageTooOld || isPost()) { + if (!isRegular() || messageToMyself || messageTooOld || isPost()) { return false; } if (peer->isChannel()) { @@ -699,7 +707,7 @@ bool HistoryItem::canDeleteForEveryone(TimeId now) const { } bool HistoryItem::suggestReport() const { - if (out() || serviceMsg() || !IsServerMsgId(id)) { + if (out() || isService() || !isRegular()) { return false; } else if (const auto channel = history()->peer->asChannel()) { return true; @@ -729,7 +737,7 @@ bool HistoryItem::suggestDeleteAllReport() const { } bool HistoryItem::hasDirectLink() const { - return IsServerMsgId(id) && _history->peer->isChannel(); + return isRegular() && _history->peer->isChannel(); } ChannelId HistoryItem::channelId() const { @@ -855,6 +863,14 @@ void HistoryItem::applyTTL(TimeId destroyAt) { } } +bool HistoryItem::isUploading() const { + return _media && _media->uploading(); +} + +bool HistoryItem::isRegular() const { + return isHistoryEntry() && !isLocal(); +} + void HistoryItem::sendFailed() { Expects(_flags & MessageFlag::BeingSent); Expects(!(_flags & MessageFlag::SendingFailed)); @@ -862,11 +878,11 @@ void HistoryItem::sendFailed() { _flags = (_flags | MessageFlag::SendingFailed) & ~MessageFlag::BeingSent; history()->session().changes().historyUpdated( history(), - Data::HistoryUpdate::Flag::LocalMessages); + Data::HistoryUpdate::Flag::ClientSideMessages); } bool HistoryItem::needCheck() const { - return (out() && !isEmpty()) || (id < 0 && history()->peer->isSelf()); + return (out() && !isEmpty()) || (!isRegular() && history()->peer->isSelf()); } bool HistoryItem::unread() const { @@ -881,7 +897,7 @@ bool HistoryItem::unread() const { return false; } - if (IsServerMsgId(id)) { + if (isRegular()) { if (!history()->isServerSideUnread(this)) { return false; } @@ -898,7 +914,7 @@ bool HistoryItem::unread() const { return true; } - if (IsServerMsgId(id)) { + if (isRegular()) { if (!history()->isServerSideUnread(this)) { return false; } @@ -933,7 +949,7 @@ bool HistoryItem::isEmpty() const { QString HistoryItem::notificationText() const { const auto result = [&] { - if (_media && !serviceMsg()) { + if (_media && !isService()) { return _media->notificationText(); } else if (!emptyText()) { return _text.toString(); @@ -1040,10 +1056,14 @@ ClickHandlerPtr goToMessageClickHandler( }); } -MessageFlags FlagsFromMTP(MTPDmessage::Flags flags) { +MessageFlags FlagsFromMTP( + MsgId id, + MTPDmessage::Flags flags, + MessageFlags localFlags) { using Flag = MessageFlag; using MTP = MTPDmessage::Flag; - return Flag() + return localFlags + | (IsServerMsgId(id) ? Flag::HistoryEntry : Flag()) | ((flags & MTP::f_out) ? Flag::Outgoing : Flag()) | ((flags & MTP::f_mentioned) ? Flag::MentionsMe : Flag()) | ((flags & MTP::f_media_unread) ? Flag::MediaIsUnread : Flag()) @@ -1060,10 +1080,14 @@ MessageFlags FlagsFromMTP(MTPDmessage::Flags flags) { | ((flags & MTP::f_views) ? Flag::HasViews : Flag()); } -MessageFlags FlagsFromMTP(MTPDmessageService::Flags flags) { +MessageFlags FlagsFromMTP( + MsgId id, + MTPDmessageService::Flags flags, + MessageFlags localFlags) { using Flag = MessageFlag; using MTP = MTPDmessageService::Flag; - return Flag() + return localFlags + | (IsServerMsgId(id) ? Flag::HistoryEntry : Flag()) | ((flags & MTP::f_out) ? Flag::Outgoing : Flag()) | ((flags & MTP::f_mentioned) ? Flag::MentionsMe : Flag()) | ((flags & MTP::f_media_unread) ? Flag::MediaIsUnread : Flag()) @@ -1088,7 +1112,7 @@ not_null HistoryItem::Create( return CreateUnsupportedMessage( history, id, - FlagsFromMTP(data.vflags().v) | localFlags, + FlagsFromMTP(id, data.vflags().v, localFlags), MsgId(0), // No need to pass reply_to data here. data.vvia_bot_id().value_or_empty(), data.vdate().v, @@ -1099,7 +1123,7 @@ not_null HistoryItem::Create( }; return history->makeServiceMessage( id, - FlagsFromMTP(data.vflags().v) | localFlags, + FlagsFromMTP(id, data.vflags().v, localFlags), data.vdate().v, text, data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)); diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 29b9825f0..b763116e6 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -87,8 +87,14 @@ struct ToPreviewOptions { struct HiddenSenderInfo; class History; -[[nodiscard]] MessageFlags FlagsFromMTP(MTPDmessage::Flags flags); -[[nodiscard]] MessageFlags FlagsFromMTP(MTPDmessageService::Flags flags); +[[nodiscard]] MessageFlags FlagsFromMTP( + MsgId id, + MTPDmessage::Flags flags, + MessageFlags localFlags); +[[nodiscard]] MessageFlags FlagsFromMTP( + MsgId id, + MTPDmessageService::Flags flags, + MessageFlags localFlags); class HistoryItem : public RuntimeComposer { public: @@ -230,6 +236,11 @@ public: [[nodiscard]] bool hideEditedBadge() const { return (_flags & MessageFlag::HideEdited); } + [[nodiscard]] bool isLocal() const { + return _flags & MessageFlag::Local; + } + [[nodiscard]] bool isRegular() const; + [[nodiscard]] bool isUploading() const; void sendFailed(); [[nodiscard]] virtual int viewsCount() const { return hasViews() ? 1 : -1; @@ -278,7 +289,7 @@ public: [[nodiscard]] virtual bool needCheck() const; - [[nodiscard]] virtual bool serviceMsg() const { + [[nodiscard]] virtual bool isService() const { return false; } virtual void applyEdition(HistoryMessageEdition &&edition) { @@ -392,12 +403,6 @@ public: return false; } - [[nodiscard]] virtual HistoryMessage *toHistoryMessage() { // dynamic_cast optimize - return nullptr; - } - [[nodiscard]] virtual const HistoryMessage *toHistoryMessage() const { // dynamic_cast optimize - return nullptr; - } [[nodiscard]] MsgId replyToId() const; [[nodiscard]] MsgId replyToTop() const; diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 73745ba24..19a422d72 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -58,7 +58,7 @@ namespace { [[nodiscard]] MessageFlags NewForwardedFlags( not_null peer, PeerId from, - not_null fwd) { + not_null fwd) { auto result = NewMessageFlags(peer); if (from) { result |= MessageFlag::HasFromId; @@ -458,7 +458,7 @@ HistoryMessage::HistoryMessage( : HistoryItem( history, id, - FlagsFromMTP(data.vflags().v) | localFlags, + FlagsFromMTP(id, data.vflags().v, localFlags), data.vdate().v, data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)) { auto config = CreateConfig(); @@ -516,7 +516,7 @@ HistoryMessage::HistoryMessage( : HistoryItem( history, id, - FlagsFromMTP(data.vflags().v) | localFlags, + FlagsFromMTP(id, data.vflags().v, localFlags), data.vdate().v, data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)) { auto config = CreateConfig(); @@ -553,11 +553,11 @@ HistoryMessage::HistoryMessage( TimeId date, PeerId from, const QString &postAuthor, - not_null original) + not_null original) : HistoryItem( history, id, - NewForwardedFlags(history->peer, from, original) | flags, + (NewForwardedFlags(history->peer, from, original) | flags), date, from) { const auto peer = history->peer; @@ -1026,10 +1026,7 @@ void HistoryMessage::applySentMessage( } bool HistoryMessage::allowsForward() const { - if (id < 0 || !isHistoryEntry()) { - return false; - } - return !_media || _media->allowsForward(); + return isRegular() && (!_media || _media->allowsForward()); } bool HistoryMessage::allowsSendNow() const { @@ -1050,10 +1047,6 @@ bool HistoryMessage::allowsEdit(TimeId now) const { && !isEditingMedia(); } -bool HistoryMessage::uploading() const { - return _media && _media->uploading(); -} - void HistoryMessage::createComponents(CreateConfig &&config) { uint64 mask = 0; if (config.replyTo) { @@ -1486,14 +1479,14 @@ void HistoryMessage::updateReplyMarkup(HistoryMessageMarkupData &&markup) { void HistoryMessage::contributeToSlowmode(TimeId realDate) { if (const auto channel = history()->peer->asChannel()) { - if (out() && IsServerMsgId(id)) { + if (out() && isRegular()) { channel->growSlowmodeLastMessage(realDate ? realDate : date()); } } } void HistoryMessage::addToUnreadMentions(UnreadMentionType type) { - if (IsServerMsgId(id) && isUnreadMention()) { + if (isRegular() && isUnreadMention()) { if (history()->addToUnreadMentions(id, type)) { history()->session().changes().historyUpdated( history(), @@ -1921,7 +1914,7 @@ void HistoryMessage::incrementReplyToTopCounter() { void HistoryMessage::changeReplyToTopCounter( not_null reply, int delta) { - if (!IsServerMsgId(id) || !reply->replyToTop()) { + if (!isRegular() || !reply->replyToTop()) { return; } const auto channelId = history()->channelId(); diff --git a/Telegram/SourceFiles/history/history_message.h b/Telegram/SourceFiles/history/history_message.h index 072a4eebe..c06cccb87 100644 --- a/Telegram/SourceFiles/history/history_message.h +++ b/Telegram/SourceFiles/history/history_message.h @@ -64,7 +64,7 @@ public: TimeId date, PeerId from, const QString &postAuthor, - not_null original); // local forwarded + not_null original); // local forwarded HistoryMessage( not_null history, MsgId id, @@ -126,7 +126,6 @@ public: [[nodiscard]] bool allowsForward() const override; [[nodiscard]] bool allowsSendNow() const override; [[nodiscard]] bool allowsEdit(TimeId now) const override; - [[nodiscard]] bool uploading() const; void setViewsCount(int count) override; void setForwardsCount(int count) override; @@ -205,14 +204,6 @@ public: const MTPDupdateShortSentMessage &data, bool wasAlready) override; - // dynamic_cast optimization. - [[nodiscard]] HistoryMessage *toHistoryMessage() override { - return this; - } - [[nodiscard]] const HistoryMessage *toHistoryMessage() const override { - return this; - } - [[nodiscard]] std::unique_ptr createView( not_null delegate, HistoryView::Element *replacing = nullptr) override; diff --git a/Telegram/SourceFiles/history/history_service.cpp b/Telegram/SourceFiles/history/history_service.cpp index bb484a865..c378c72e7 100644 --- a/Telegram/SourceFiles/history/history_service.cpp +++ b/Telegram/SourceFiles/history/history_service.cpp @@ -889,7 +889,7 @@ HistoryService::HistoryService( : HistoryItem( history, id, - FlagsFromMTP(data.vflags().v) | localFlags, + FlagsFromMTP(id, data.vflags().v, localFlags), data.vdate().v, data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)) { createFromMtp(data); @@ -904,7 +904,7 @@ HistoryService::HistoryService( : HistoryItem( history, id, - FlagsFromMTP(data.vflags().v) | localFlags, + FlagsFromMTP(id, data.vflags().v, localFlags), data.vdate().v, data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)) { createFromMtp(data); @@ -1280,7 +1280,7 @@ not_null GenerateJoinedMessage( bool viaRequest) { return history->makeServiceMessage( history->owner().nextLocalMessageId(), - MessageFlag::LocalHistoryEntry, + MessageFlag::Local, inviteDate, GenerateJoinedText(history, inviter, viaRequest)); } diff --git a/Telegram/SourceFiles/history/history_service.h b/Telegram/SourceFiles/history/history_service.h index 0109f1f5b..0e3fc4306 100644 --- a/Telegram/SourceFiles/history/history_service.h +++ b/Telegram/SourceFiles/history/history_service.h @@ -108,7 +108,7 @@ public: void dependencyItemRemoved(HistoryItem *dependency) override; bool needCheck() const override; - bool serviceMsg() const override { + bool isService() const override { return true; } ItemPreview toPreview(ToPreviewOptions options) const override; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index cf978d0bd..292804630 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -562,7 +562,7 @@ HistoryWidget::HistoryWidget( | HistoryUpdateFlag::UnreadMentions | HistoryUpdateFlag::UnreadView | HistoryUpdateFlag::TopPromoted - | HistoryUpdateFlag::LocalMessages + | HistoryUpdateFlag::ClientSideMessages | HistoryUpdateFlag::PinnedMessages ) | rpl::filter([=](const Data::HistoryUpdate &update) { if (_migrated && update.history.get() == _migrated) { @@ -586,7 +586,7 @@ HistoryWidget::HistoryWidget( if (flags & HistoryUpdateFlag::CloudDraft) { applyCloudDraft(update.history); } - if (flags & HistoryUpdateFlag::LocalMessages) { + if (flags & HistoryUpdateFlag::ClientSideMessages) { updateSendButtonType(); } if (flags & HistoryUpdateFlag::UnreadMentions) { @@ -5337,7 +5337,7 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) { } void HistoryWidget::botCallbackSent(not_null item) { - if (item->id < 0 || _peer != item->history()->peer) { + if (!item->isRegular() || _peer != item->history()->peer) { return; } @@ -6239,11 +6239,10 @@ void HistoryWidget::replyToMessage(FullMsgId itemId) { } void HistoryWidget::replyToMessage(not_null item) { - if (!IsServerMsgId(item->id) || !_canSendMessages) { + if (!item->isRegular() || !_canSendMessages) { return; - } - if (item->history() == _migrated) { - if (item->serviceMsg()) { + } else if (item->history() == _migrated) { + if (item->isService()) { controller()->show(Box( tr::lng_reply_cant(tr::now))); } else { diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index 399de7ba8..daadcbe0b 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -62,14 +62,6 @@ namespace { constexpr auto kRescheduleLimit = 20; -MsgId ItemIdAcrossData(not_null item) { - if (!item->isScheduled() || item->isSending() || item->hasFailed()) { - return item->id; - } - const auto session = &item->history()->session(); - return session->data().scheduledMessages().lookupId(item); -} - bool HasEditMessageAction( const ContextMenuRequest &request, not_null list) { @@ -548,7 +540,7 @@ bool AddReplyToMessageAction( const auto context = list->elementContext(); const auto item = request.item; if (!item - || !IsServerMsgId(item->id) + || !item->isRegular() || !item->history()->peer->canWrite() || (context != Context::History && context != Context::Replies)) { return false; @@ -572,7 +564,7 @@ bool AddViewRepliesAction( const auto context = list->elementContext(); const auto item = request.item; if (!item - || !IsServerMsgId(item->id) + || !item->isRegular() || (context != Context::History && context != Context::Pinned)) { return false; } @@ -626,7 +618,7 @@ bool AddPinMessageAction( const auto context = list->elementContext(); const auto item = request.item; if (!item - || !IsServerMsgId(item->id) + || !item->isRegular() || (context != Context::History && context != Context::Pinned)) { return false; } @@ -653,7 +645,7 @@ bool AddGoToMessageAction( const auto context = list->elementContext(); const auto view = request.view; if (!view - || !IsServerMsgId(view->data()->id) + || !view->data()->isRegular() || context != Context::Pinned || !view->hasOutLayout()) { return false; @@ -719,8 +711,7 @@ bool AddDeleteMessageAction( if (asGroup) { if (const auto group = owner->groups().find(item)) { if (ranges::any_of(group->items, [](auto item) { - const auto id = ItemIdAcrossData(item); - return !IsServerMsgId(id) || !item->canDelete(); + return item->isLocal() || !item->canDelete(); })) { return false; } @@ -738,24 +729,20 @@ bool AddDeleteMessageAction( return; } } - if (const auto message = item->toHistoryMessage()) { - if (message->uploading()) { - controller->cancelUploadLayer(item); - return; - } + if (item->isUploading()) { + controller->cancelUploadLayer(item); + return; } const auto suggestModerateActions = true; controller->show( Box(item, suggestModerateActions)); } }); - if (const auto message = item->toHistoryMessage()) { - if (message->uploading()) { - menu->addAction( - tr::lng_context_cancel_upload(tr::now), - callback); - return true; - } + if (item->isUploading()) { + menu->addAction( + tr::lng_context_cancel_upload(tr::now), + callback); + return true; } menu->addAction(Ui::DeleteMessageContextAction( menu->menu(), @@ -820,11 +807,7 @@ bool AddSelectMessageAction( const auto item = request.item; if (request.overSelection && !request.selectedItems.empty()) { return false; - } else if (!item - || item->isSending() - || item->hasFailed() - || !IsServerMsgId(ItemIdAcrossData(item)) - || item->serviceMsg()) { + } else if (!item || item->isLocal() || item->isService()) { return false; } const auto owner = &item->history()->owner(); diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 6d3ccab22..7cfa00632 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -536,7 +536,7 @@ void Element::refreshDataId() { bool Element::computeIsAttachToPrevious(not_null previous) { const auto mayBeAttached = [](not_null item) { - return !item->serviceMsg() + return !item->isService() && !item->isEmpty() && !item->isPost() && (item->from() != item->history()->peer diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index a1719702d..43d615f77 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -166,8 +166,9 @@ void ListWidget::enumerateUserpics(Method method) { auto userpicCallback = [&](not_null view, int itemtop, int itembottom) { // Skip all service messages. - auto message = view->data()->toHistoryMessage(); - if (!message) return true; + if (view->data()->isService()) { + return true; + } if (lowestAttachedItemTop < 0 && view->isAttachedToNext()) { lowestAttachedItemTop = itemtop + view->marginTop(); @@ -1659,10 +1660,7 @@ void ListWidget::paintEvent(QPaintEvent *e) { // paint the userpic if it intersects the painted rect if (userpicTop + st::msgPhotoSize > clip.top()) { - const auto message = view->data()->toHistoryMessage(); - Assert(message != nullptr); - - if (const auto from = message->displayFrom()) { + if (const auto from = view->data()->displayFrom()) { from->paintUserpicLeft( p, _userpics[from], @@ -1670,7 +1668,7 @@ void ListWidget::paintEvent(QPaintEvent *e) { userpicTop, view->width(), st::msgPhotoSize); - } else if (const auto info = message->hiddenForwardedInfo()) { + } else if (const auto info = view->data()->hiddenForwardedInfo()) { info->userpic.paint( p, st::historyPhotoLeft, @@ -1917,7 +1915,7 @@ void ListWidget::mouseDoubleClickEvent(QMouseEvent *e) { || _mouseCursorState == CursorState::Date) && _selected.empty() && _overElement - && IsServerMsgId(_overElement->data()->id)) { + && _overElement->data()->isRegular()) { mouseActionCancel(); replyToMessageRequestNotify(_overElement->data()->fullId()); } @@ -2543,11 +2541,8 @@ void ListWidget::mouseActionUpdate() { // stop enumeration if we've found a userpic under the cursor if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) { - const auto message = view->data()->toHistoryMessage(); - Assert(message != nullptr); - dragState = TextState(nullptr, view->fromPhotoLink()); - _overItemExact = session().data().message(dragState.itemId); + _overItemExact = nullptr; lnkhost = view; return false; } diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 3563bf525..364554177 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -1783,14 +1783,14 @@ void Message::drawInfo( if (views->replies.count > 0 && !views->commentsMegagroupId && this->context() != Context::Replies) { - const auto &icon = (item->id > 0) + const auto &icon = (!item->isSending() && !item->hasFailed()) ? (invertedsprites ? st->historyRepliesInvertedIcon() : stm->historyRepliesIcon) : (invertedsprites ? st->historyViewsSendingInvertedIcon() : st->historyViewsSendingIcon()); - if (item->id > 0) { + if (!item->isSending() && !item->hasFailed()) { icon.paint(p, left, viewIconTop, width); p.drawText(left + st::historyViewsWidth, textTop, views->replies.text); } else if (!context.outbg && views->views.count < 0) { // sending outbg icon will be painted below @@ -1802,14 +1802,14 @@ void Message::drawInfo( + st::historyViewsWidth; } if (views->views.count >= 0) { - const auto &icon = (item->id > 0) + const auto &icon = (!item->isSending() && !item->hasFailed()) ? (invertedsprites ? st->historyViewsInvertedIcon() : stm->historyViewsIcon) : (invertedsprites ? st->historyViewsSendingInvertedIcon() : st->historyViewsSendingIcon()); - if (item->id > 0) { + if (!item->isSending() && !item->hasFailed()) { icon.paint(p, left, viewIconTop, width); p.drawText(left + st::historyViewsWidth, textTop, views->views.text); } else if (!context.outbg) { // sending outbg icon will be painted below @@ -1820,7 +1820,9 @@ void Message::drawInfo( + views->views.textWidth + st::historyViewsWidth; } - } else if (item->id < 0 && item->history()->peer->isSelf() && !context.outbg) { + } else if ((item->isSending() || item->hasFailed()) + && item->history()->peer->isSelf() + && !context.outbg) { const auto &icon = invertedsprites ? st->historyViewsSendingInvertedIcon() : st->historyViewsSendingIcon(); @@ -1834,7 +1836,7 @@ void Message::drawInfo( left += st::historyPinWidth; } if (context.outbg) { - const auto &icon = (item->id <= 0) + const auto &icon = (item->isSending() || item->hasFailed()) ? (invertedsprites ? st->historySendingInvertedIcon() : st->historySendingIcon()) @@ -1896,7 +1898,8 @@ int Message::infoWidth() const { + views->replies.textWidth + st::historyViewsWidth; } - } else if (item->id < 0 && item->history()->peer->isSelf()) { + } else if ((item->isSending() || item->hasFailed()) + && item->history()->peer->isSelf()) { if (!hasOutLayout()) { result += st::historySendStateSpace; } @@ -1948,7 +1951,8 @@ int Message::timeLeft() const { && context() != Context::Replies) { result += st::historyViewsSpace + views->replies.textWidth + st::historyViewsWidth; } - } else if (item->id < 0 && item->history()->peer->isSelf()) { + } else if ((item->isSending() || item->hasFailed()) + && item->history()->peer->isSelf()) { if (!hasOutLayout()) { result += st::historySendStateSpace; } @@ -2180,7 +2184,7 @@ bool Message::hasFastReply() const { bool Message::displayFastReply() const { return hasFastReply() - && IsServerMsgId(data()->id) + && data()->isRegular() && data()->history()->peer->canWrite() && !delegate()->elementInSelectionMode(); } @@ -2213,7 +2217,7 @@ std::optional Message::rightActionSize() const { bool Message::displayFastShare() const { const auto item = message(); const auto peer = item->history()->peer; - if (!IsServerMsgId(item->id)) { + if (!item->isRegular()) { return false; } else if (peer->isChannel()) { return !peer->isMegagroup(); diff --git a/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp b/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp index a674630dc..db237777b 100644 --- a/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_pinned_section.cpp @@ -613,7 +613,7 @@ bool PinnedWidget::listAllowsMultiSelect() { bool PinnedWidget::listIsItemGoodForSelection( not_null item) { - return IsServerMsgId(item->id); + return item->isRegular(); } bool PinnedWidget::listIsLessInOrder( @@ -661,7 +661,7 @@ bool PinnedWidget::listElementShownUnread(not_null view) { bool PinnedWidget::listIsGoodForAroundPosition( not_null view) { - return IsServerMsgId(view->data()->id); + return view->data()->isRegular(); } void PinnedWidget::listSendBotCommand( diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 743691390..a54941487 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -460,7 +460,7 @@ void RepliesWidget::setupComposeControls() { auto hasSendingMessage = session().changes().historyFlagsValue( _history, - Data::HistoryUpdate::Flag::LocalMessages + Data::HistoryUpdate::Flag::ClientSideMessages ) | rpl::map([=] { return _history->latestSendingMessage() != nullptr; }) | rpl::distinct_until_changed(); @@ -1782,7 +1782,7 @@ bool RepliesWidget::listAllowsMultiSelect() { bool RepliesWidget::listIsItemGoodForSelection( not_null item) { - return IsServerMsgId(item->id); + return item->isRegular(); } bool RepliesWidget::listIsLessInOrder( @@ -1845,9 +1845,7 @@ void RepliesWidget::readTill(not_null item) { void RepliesWidget::listVisibleItemsChanged(HistoryItemsList &&items) { const auto reversed = ranges::views::reverse(items); - const auto good = ranges::find_if(reversed, [](auto item) { - return IsServerMsgId(item->id); - }); + const auto good = ranges::find_if(reversed, &HistoryItem::isRegular); if (good != end(reversed)) { readTill(*good); } @@ -1862,7 +1860,7 @@ MessagesBarData RepliesWidget::listMessagesBar( const auto hidden = (till < 2); for (auto i = 0, count = int(elements.size()); i != count; ++i) { const auto item = elements[i]->data(); - if (IsServerMsgId(item->id) && item->id > till) { + if (item->isRegular() && item->id > till) { if (item->out() || !item->replyToId()) { readTill(item); } else { @@ -1904,7 +1902,7 @@ bool RepliesWidget::listElementShownUnread(not_null view) { bool RepliesWidget::listIsGoodForAroundPosition( not_null view) { - return IsServerMsgId(view->data()->id); + return view->data()->isRegular(); } void RepliesWidget::listSendBotCommand( diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index 22e75c910..c5244fd01 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -595,7 +595,7 @@ bool Document::downloadInCorner() const { return _data->isAudioFile() && _data->canBeStreamed() && !_data->inappPlaybackFailed() - && IsServerMsgId(_realParent->id); + && _realParent->isRegular(); } void Document::drawCornerDownload( diff --git a/Telegram/SourceFiles/history/view/media/history_view_game.cpp b/Telegram/SourceFiles/history/view/media/history_view_game.cpp index e5a38a6dc..cf8be3686 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_game.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_game.cpp @@ -49,7 +49,7 @@ QSize Game::countOptimalSize() { auto lineHeight = unitedLineHeight(); const auto item = _parent->data(); - if (!_openl && IsServerMsgId(item->id)) { + if (!_openl && item->isRegular()) { const auto row = 0; const auto column = 0; _openl = std::make_shared( diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index b4f19b2ea..1e025b7fd 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -909,7 +909,9 @@ void Gif::drawGrouped( ensureDataMediaCreated(); const auto item = _parent->data(); const auto loaded = dataLoaded(); - const auto displayLoading = (item->id < 0) || _data->displayLoading(); + const auto displayLoading = item->isSending() + || item->hasFailed() + || _data->displayLoading(); const auto st = context.st; const auto sti = context.imageStyle(); const auto autoPaused = _parent->delegate()->elementIsGifPaused(); @@ -1508,20 +1510,23 @@ void Gif::checkAnimation() { float64 Gif::dataProgress() const { ensureDataMediaCreated(); - return (_data->uploading() || _parent->data()->id > 0) + return (_data->uploading() + || (!_parent->data()->isSending() && !_parent->data()->hasFailed())) ? _dataMedia->progress() : 0; } bool Gif::dataFinished() const { - return (_parent->data()->id > 0) + return (!_parent->data()->isSending() && !_parent->data()->hasFailed()) ? (!_data->loading() && !_data->uploading()) : false; } bool Gif::dataLoaded() const { ensureDataMediaCreated(); - return (_parent->data()->id > 0) ? _dataMedia->loaded() : false; + return !_parent->data()->isSending() + && !_parent->data()->hasFailed() + && _dataMedia->loaded(); } bool Gif::needInfoDisplay() const { diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp index a60a5d089..a2992af1a 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp @@ -760,7 +760,8 @@ bool GroupedMedia::computeNeedBubble() const { bool GroupedMedia::needInfoDisplay() const { return (_mode != Mode::Column) - && (_parent->data()->id < 0 + && (_parent->data()->isSending() + || _parent->data()->hasFailed() || _parent->isUnderCursor() || _parent->isLastAndSelfMessage()); } diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp index 38331c3ce..7957cec88 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.cpp @@ -437,10 +437,11 @@ QPoint UnwrappedMedia::calculateFastActionPosition( } bool UnwrappedMedia::needInfoDisplay() const { - return (_parent->data()->id < 0) - || (_parent->isUnderCursor()) - || (_parent->rightActionSize()) - || (_parent->isLastAndSelfMessage()) + return _parent->data()->isSending() + || _parent->data()->hasFailed() + || _parent->isUnderCursor() + || _parent->rightActionSize() + || _parent->isLastAndSelfMessage() || (_parent->hasOutLayout() && !_parent->delegate()->elementIsChatWide() && _content->alwaysShowOutTimestamp()); diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp index 3bd31aeef..22221a31d 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp @@ -619,9 +619,10 @@ bool Photo::dataLoaded() const { } bool Photo::needInfoDisplay() const { - return (_parent->data()->id < 0 + return _parent->data()->isSending() + || _parent->data()->hasFailed() || _parent->isUnderCursor() - || _parent->isLastAndSelfMessage()); + || _parent->isLastAndSelfMessage(); } void Photo::validateGroupedCache( @@ -813,15 +814,13 @@ bool Photo::needsBubble() const { return true; } const auto item = _parent->data(); - if (item->toHistoryMessage()) { - return item->repliesAreComments() + return !item->isService() + && (item->repliesAreComments() || item->externalReply() || item->viaBot() || _parent->displayedReply() || _parent->displayForwardedFrom() - || _parent->displayFromName(); - } - return false; + || _parent->displayFromName()); } bool Photo::isReadyForOpen() const { diff --git a/Telegram/SourceFiles/history/view/media/history_view_poll.cpp b/Telegram/SourceFiles/history/view/media/history_view_poll.cpp index e6e35c9cf..e04851da1 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_poll.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_poll.cpp @@ -282,7 +282,7 @@ bool Poll::showVotes() const { } bool Poll::canVote() const { - return !showVotes() && IsServerMsgId(_parent->data()->id); + return !showVotes() && _parent->data()->isRegular(); } bool Poll::canSendVotes() const { diff --git a/Telegram/SourceFiles/info/info_controller.cpp b/Telegram/SourceFiles/info/info_controller.cpp index a2c15a80c..e4a981775 100644 --- a/Telegram/SourceFiles/info/info_controller.cpp +++ b/Telegram/SourceFiles/info/info_controller.cpp @@ -71,9 +71,6 @@ rpl::producer AbstractController::mediaSource( Expects(peer() != nullptr); const auto isScheduled = [&] { - if (IsServerMsgId(aroundId)) { - return false; - } const auto channelId = peerToChannel(peer()->id); if (const auto item = session().data().message(channelId, aroundId)) { return item->isScheduled(); diff --git a/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp b/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp index 3eee8fc5a..920f34ef2 100644 --- a/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp +++ b/Telegram/SourceFiles/info/polls/info_polls_results_inner_widget.cpp @@ -249,7 +249,7 @@ void ListController::loadMoreRows() { return; } const auto item = session().data().message(_context); - if (!item || !IsServerMsgId(item->id)) { + if (!item || !item->isRegular()) { _leftToLoad = 0; return; } diff --git a/Telegram/SourceFiles/media/player/media_player_instance.cpp b/Telegram/SourceFiles/media/player/media_player_instance.cpp index 954618ce4..7410ed7f1 100644 --- a/Telegram/SourceFiles/media/player/media_player_instance.cpp +++ b/Telegram/SourceFiles/media/player/media_player_instance.cpp @@ -332,7 +332,7 @@ auto Instance::playlistKey(not_null data) const return {}; } const auto item = data->history->owner().message(contextId); - if (!item || (!IsServerMsgId(contextId.msg) && !item->isScheduled())) { + if (!item || (!item->isRegular() && !item->isScheduled())) { return {}; } diff --git a/Telegram/SourceFiles/media/player/media_player_panel.cpp b/Telegram/SourceFiles/media/player/media_player_panel.cpp index e10743023..3bf9caa22 100644 --- a/Telegram/SourceFiles/media/player/media_player_panel.cpp +++ b/Telegram/SourceFiles/media/player/media_player_panel.cpp @@ -244,7 +244,7 @@ void Panel::refreshList() { const auto document = media ? media->document() : nullptr; if (!document || !document->isSharedMediaMusic() - || (!IsServerMsgId(item->id) && !item->isScheduled())) { + || (!item->isRegular() && !item->isScheduled())) { return nullptr; } const auto result = item->history()->peer; diff --git a/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp b/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp index e84bf87d0..9f097dbb1 100644 --- a/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp +++ b/Telegram/SourceFiles/media/view/media_view_group_thumbs.cpp @@ -110,7 +110,7 @@ Context ComputeContext( return v::null; } else if (const auto msgId = std::get_if(&value)) { if (const auto item = session->data().message(*msgId)) { - if (!item->toHistoryMessage()) { + if (item->isService()) { return item->history()->peer->id; } else if (const auto groupId = item->groupId()) { return groupId; diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 31e129007..d3d1d9900 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -670,8 +670,7 @@ void OverlayWidget::documentUpdated(DocumentData *doc) { } void OverlayWidget::changingMsgId(not_null row, MsgId oldId) { - if (FullMsgId(row->channelId(), oldId) == _msgid) { - _msgid = row->fullId(); + if (row == _message) { refreshMediaViewer(); } } @@ -800,10 +799,8 @@ void OverlayWidget::updateControls() { const auto dNow = QDateTime::currentDateTime(); const auto d = [&] { - if (!_session) { - return dNow; - } else if (const auto item = _session->data().message(_msgid)) { - return ItemDateTime(item); + if (_message) { + return ItemDateTime(_message); } else if (_photo) { return base::unixtime::parse(_photo->date); } else if (_document) { @@ -885,7 +882,7 @@ void OverlayWidget::fillContextMenuActions(const MenuCallback &addAction) { if (_document && _document->loading()) { addAction(tr::lng_cancel(tr::now), [=] { saveCancel(); }); } - if (IsServerMsgId(_msgid.msg)) { + if (_message && _message->isRegular()) { addAction(tr::lng_context_to_msg(tr::now), [=] { toMessage(); }); } if (_document && !_document->filepath(true).isEmpty()) { @@ -903,13 +900,13 @@ void OverlayWidget::fillContextMenuActions(const MenuCallback &addAction) { tr::lng_context_attached_stickers(tr::now), [=] { showAttachedStickers(); }); } - if (_canForwardItem) { + if (_message && _message->allowsForward()) { addAction(tr::lng_mediaview_forward(tr::now), [=] { forwardMedia(); }); } const auto canDelete = [&] { - if (_canDeleteItem) { + if (_message && _message->canDelete()) { return true; - } else if (!_msgid + } else if (!_message && _photo && _user && _user == _user->session().user()) { @@ -1447,11 +1444,7 @@ void OverlayWidget::subscribeToScreenGeometry() { } void OverlayWidget::toMessage() { - if (!_session) { - return; - } - - if (const auto item = _session->data().message(_msgid)) { + if (const auto item = _message) { close(); if (const auto window = findWindow()) { window->showPeerHistoryAtItem(item); @@ -1579,10 +1572,7 @@ void OverlayWidget::handleDocumentClick() { if (_document->loading()) { saveCancel(); } else { - Data::ResolveDocument( - findWindow(), - _document, - _document->owner().message(_msgid)); + Data::ResolveDocument(findWindow(), _document, _message); if (_document->loading() && !_radial.animating()) { _radial.start(_documentMedia->progress()); } @@ -1703,15 +1693,13 @@ void OverlayWidget::forwardMedia() { if (active.empty()) { return; } - const auto item = _session->data().message(_msgid); - if (!item || !IsServerMsgId(item->id) || item->serviceMsg()) { - return; + const auto id = (_message && _message->allowsForward()) + ? _message->fullId() + : FullMsgId(); + if (id) { + close(); + Window::ShowForwardMessagesBox(active.front(), { 1, id }); } - - close(); - Window::ShowForwardMessagesBox( - active.front(), - { 1, item->fullId() }); } void OverlayWidget::deleteMedia() { @@ -1721,9 +1709,9 @@ void OverlayWidget::deleteMedia() { const auto session = _session; const auto photo = _photo; - const auto msgid = _msgid; + const auto message = _message; const auto deletingPeerPhoto = [&] { - if (!_msgid) { + if (!_message) { return true; } else if (_photo && _history) { if (_history->peer->userpicPhotoId() == _photo->id) { @@ -1747,10 +1735,10 @@ void OverlayWidget::deleteMedia() { })), Ui::LayerOption::CloseOther); } - } else if (const auto item = session->data().message(msgid)) { + } else if (message) { const auto suggestModerateActions = true; window->show( - Box(item, suggestModerateActions), + Box(message, suggestModerateActions), Ui::LayerOption::CloseOther); } } @@ -1801,19 +1789,17 @@ void OverlayWidget::showAttachedStickers() { auto OverlayWidget::sharedMediaType() const -> std::optional { using Type = SharedMediaType; - if (!_session) { - return std::nullopt; - } else if (const auto item = _session->data().message(_msgid)) { - if (const auto media = item->media()) { + if (_message) { + if (const auto media = _message->media()) { if (media->webpage()) { return std::nullopt; } } if (_photo) { - if (item->toHistoryMessage()) { - return Type::PhotoVideo; + if (_message->isService()) { + return Type::ChatPhoto; } - return Type::ChatPhoto; + return Type::PhotoVideo; } else if (_document) { if (_document->isGifv()) { return Type::GIF; @@ -1827,7 +1813,7 @@ auto OverlayWidget::sharedMediaType() const } auto OverlayWidget::sharedMediaKey() const -> std::optional { - if (!_msgid + if (!_message && _peer && !_user && _photo @@ -1839,36 +1825,30 @@ auto OverlayWidget::sharedMediaKey() const -> std::optional { _photo }; } - const auto isServerMsgId = IsServerMsgId(_msgid.msg); - const auto isScheduled = [&] { - if (isServerMsgId) { - return false; - } - if (const auto item = _session->data().message(_msgid)) { - return item->isScheduled(); - } - return false; - }(); + if (!_message) { + return std::nullopt; + } + const auto isScheduled = _message->isScheduled(); const auto keyForType = [&](SharedMediaType type) -> SharedMediaKey { return { _history->peer->id, _migrated ? _migrated->peer->id : 0, type, - (_msgid.channel == _history->channelId()) - ? _msgid.msg - : (_msgid.msg - ServerMaxMsgId), + (_message->history() == _history + ? _message->id + : (_message->id - ServerMaxMsgId)), isScheduled }; }; - if (!isServerMsgId && !isScheduled) { + if (!_message->isRegular() && !isScheduled) { return std::nullopt; } return sharedMediaType() | keyForType; } Data::FileOrigin OverlayWidget::fileOrigin() const { - if (_msgid) { - return _msgid; + if (_message) { + return _message->fullId(); } else if (_photo && _user) { return Data::FileOriginUserPhoto(peerToUser(_user->id), _photo->id); } else if (_photo && _peer && _peer->userpicPhotoId() == _photo->id) { @@ -1966,7 +1946,7 @@ void OverlayWidget::handleSharedMediaUpdate(SharedMediaWithLastSlice &&update) { } std::optional OverlayWidget::userPhotosKey() const { - if (!_msgid && _user && _photo) { + if (!_message && _user && _photo) { return UserPhotosKey{ peerToUser(_user->id), _photo->id }; } return std::nullopt; @@ -2026,10 +2006,8 @@ void OverlayWidget::handleUserPhotosUpdate(UserPhotosSlice &&update) { } std::optional OverlayWidget::collageKey() const { - if (!_session) { - return std::nullopt; - } else if (const auto item = _session->data().message(_msgid)) { - if (const auto media = item->media()) { + if (_message) { + if (const auto media = _message->media()) { if (const auto page = media->webpage()) { for (const auto &item : page->collage.items) { if (item == _photo || item == _document) { @@ -2065,8 +2043,8 @@ void OverlayWidget::validateCollage() { if (const auto key = collageKey()) { _collage = std::make_unique(*key); _collageData = WebPageCollage(); - if (const auto item = _session->data().message(_msgid)) { - if (const auto media = item->media()) { + if (_message) { + if (const auto media = _message->media()) { if (const auto page = media->webpage()) { _collageData = page->collage; } @@ -2092,10 +2070,10 @@ void OverlayWidget::refreshMediaViewer() { updateControls(); } -void OverlayWidget::refreshFromLabel(HistoryItem *item) { - if (_msgid && item) { - _from = item->senderOriginal(); - if (const auto info = item->hiddenForwardedInfo()) { +void OverlayWidget::refreshFromLabel() { + if (_message) { + _from = _message->senderOriginal(); + if (const auto info = _message->hiddenForwardedInfo()) { _fromName = info->name; } else { Assert(_from != nullptr); @@ -2108,16 +2086,16 @@ void OverlayWidget::refreshFromLabel(HistoryItem *item) { } } -void OverlayWidget::refreshCaption(HistoryItem *item) { +void OverlayWidget::refreshCaption() { _caption = Ui::Text::String(); - if (!item) { + if (!_message) { return; - } else if (const auto media = item->media()) { + } else if (const auto media = _message->media()) { if (media->webpage()) { return; } } - const auto caption = item->originalText(); + const auto caption = _message->originalText(); if (caption.text.isEmpty()) { return; } @@ -2128,15 +2106,15 @@ void OverlayWidget::refreshCaption(HistoryItem *item) { ? _document->getDuration() : 0; const auto base = duration - ? DocumentTimestampLinkBase(_document, item->fullId()) + ? DocumentTimestampLinkBase(_document, _message->fullId()) : QString(); const auto context = Core::MarkedTextContext{ - .session = &item->history()->session() + .session = &_message->history()->session() }; _caption.setMarkedText( st::mediaviewCaptionStyle, AddTimestampLinks(caption, duration, base), - Ui::ItemTextOptions(item), + Ui::ItemTextOptions(_message), context); } @@ -2157,10 +2135,11 @@ void OverlayWidget::refreshGroupThumbs() { *_index, _groupThumbsAvailableWidth); } else if (_index && _collageData) { + const auto messageId = _message ? _message->fullId() : FullMsgId(); View::GroupThumbs::Refresh( _session, _groupThumbs, - { _msgid, &*_collageData }, + { messageId, &*_collageData }, *_index, _groupThumbsAvailableWidth); } else if (_groupThumbs) { @@ -2296,7 +2275,7 @@ void OverlayWidget::show(OpenRequest request) { _firstOpenedPeerPhoto = (contextPeer != nullptr); assignMediaPointer(photo); - displayPhoto(photo, contextPeer ? nullptr : contextItem); + displayPhoto(photo); preloadData(0); activateControls(); } else if (document) { @@ -2313,7 +2292,6 @@ void OverlayWidget::show(OpenRequest request) { _streamingStartPaused = false; displayDocument( document, - contextItem, request.cloudTheme() ? *request.cloudTheme() : Data::CloudTheme(), @@ -2328,9 +2306,9 @@ void OverlayWidget::show(OpenRequest request) { } } -void OverlayWidget::displayPhoto(not_null photo, HistoryItem *item) { +void OverlayWidget::displayPhoto(not_null photo) { if (photo->isNull()) { - displayDocument(nullptr, item); + displayDocument(nullptr); return; } _touchbarDisplay.fire(TouchBarItemType::Photo); @@ -2350,7 +2328,7 @@ void OverlayWidget::displayPhoto(not_null photo, HistoryItem *item) initStreaming(); } - refreshCaption(item); + refreshCaption(); _blurred = true; _down = OverNone; @@ -2368,7 +2346,7 @@ void OverlayWidget::displayPhoto(not_null photo, HistoryItem *item) _h = size.height(); } contentSizeChanged(); - refreshFromLabel(item); + refreshFromLabel(); displayFinished(); } @@ -2384,19 +2362,16 @@ void OverlayWidget::destroyThemePreview() { void OverlayWidget::redisplayContent() { if (isHidden() || !_session) { return; - } - const auto item = _session->data().message(_msgid); - if (_photo) { - displayPhoto(_photo, item); + } else if (_photo) { + displayPhoto(_photo); } else { - displayDocument(_document, item); + displayDocument(_document); } } // Empty messages shown as docs: doc can be nullptr. void OverlayWidget::displayDocument( DocumentData *doc, - HistoryItem *item, const Data::CloudTheme &cloud, bool continueStreaming) { _fullScreenVideo = false; @@ -2405,7 +2380,9 @@ void OverlayWidget::displayDocument( destroyThemePreview(); assignMediaPointer(doc); - _rotation = _document ? _document->owner().mediaRotation().get(_document) : 0; + _rotation = _document + ? _document->owner().mediaRotation().get(_document) + : 0; _themeCloudData = cloud; _radial.stop(); @@ -2426,13 +2403,13 @@ void OverlayWidget::displayDocument( if (_documentMedia->canBePlayed() && initStreaming(continueStreaming)) { } else if (_document->isVideoFile()) { - _documentMedia->automaticLoad(fileOrigin(), item); + _documentMedia->automaticLoad(fileOrigin(), _message); initStreamingThumbnail(); } else if (_document->isTheme()) { - _documentMedia->automaticLoad(fileOrigin(), item); + _documentMedia->automaticLoad(fileOrigin(), _message); initThemePreview(); } else { - _documentMedia->automaticLoad(fileOrigin(), item); + _documentMedia->automaticLoad(fileOrigin(), _message); _document->saveFromDataSilent(); auto &location = _document->location(true); if (location.accessEnable()) { @@ -2454,7 +2431,7 @@ void OverlayWidget::displayDocument( } } } - refreshCaption(item); + refreshCaption(); const auto docGeneric = Layout::DocumentGenericPreview::Create(_document); _docExt = docGeneric.ext; @@ -2519,7 +2496,7 @@ void OverlayWidget::displayDocument( if (videoShown()) { applyVideoSize(); } - refreshFromLabel(item); + refreshFromLabel(); _blurred = false; if (_showAsPip && _streamed && !videoIsGifOrUserpic()) { switchToPip(); @@ -3026,7 +3003,7 @@ void OverlayWidget::seekRelativeTime(crl::time time) { void OverlayWidget::restartAtProgress(float64 progress) { Expects(_streamed != nullptr); - restartAtSeekPosition(_streamed->instance.info().video.state.duration + restartAtSeekPosition(_streamed->instance.info().video.state.duration * std::clamp(progress, 0., 1.)); } @@ -3047,7 +3024,8 @@ void OverlayWidget::restartAtSeekPosition(crl::time position) { options.loop = true; } else { Assert(_document != nullptr); - options.audioId = AudioMsgId(_document, _msgid); + const auto messageId = _message ? _message->fullId() : FullMsgId(); + options.audioId = AudioMsgId(_document, messageId); options.speed = Core::App().settings().videoPlaybackSpeed(); if (_pip) { _pip = nullptr; @@ -3130,20 +3108,20 @@ void OverlayWidget::switchToPip() { Expects(_document != nullptr); const auto document = _document; - const auto msgId = _msgid; + const auto message = _message; const auto closeAndContinue = [=] { _showAsPip = false; show(OpenRequest( findWindow(false), document, - document->owner().message(msgId), + message, true)); }; _showAsPip = true; _pip = std::make_unique( _widget, document, - msgId, + message ? message->fullId() : FullMsgId(), _streamed->instance.shared(), closeAndContinue, [=] { _pip = nullptr; }); @@ -3251,7 +3229,7 @@ void OverlayWidget::validatePhotoCurrentImage() { validatePhotoImage(_photoMedia->image(Data::PhotoSize::Small), true); validatePhotoImage(_photoMedia->thumbnailInline(), true); if (_staticContent.isNull() - && !_msgid + && !_message && _peer && _peer->hasUserpic()) { if (const auto view = _peer->activeUserpicView()) { @@ -3933,15 +3911,14 @@ OverlayWidget::Entity OverlayWidget::entityForCollage(int index) const { Expects(_collageData.has_value()); Expects(_session != nullptr); - const auto item = _session->data().message(_msgid); const auto &items = _collageData->items; - if (!item || index < 0 || index >= items.size()) { + if (!_message || index < 0 || index >= items.size()) { return { v::null, nullptr }; } if (const auto document = std::get_if(&items[index])) { - return { *document, item }; + return { *document, _message }; } else if (const auto photo = std::get_if(&items[index])) { - return { *photo, item }; + return { *photo, _message }; } return { v::null, nullptr }; } @@ -3979,19 +3956,15 @@ void OverlayWidget::setContext( not_null, not_null> context) { if (const auto item = std::get_if>(&context)) { - _msgid = (*item)->fullId(); - _canForwardItem = (*item)->allowsForward(); - _canDeleteItem = (*item)->canDelete(); - _history = (*item)->history(); + _message = (*item); + _history = _message->history(); _peer = _history->peer; } else if (const auto peer = std::get_if>(&context)) { - _msgid = FullMsgId(); - _canForwardItem = _canDeleteItem = false; - _history = (*peer)->owner().history(*peer); _peer = *peer; + _history = _peer->owner().history(_peer); + _message = nullptr; } else { - _msgid = FullMsgId(); - _canForwardItem = _canDeleteItem = false; + _message = nullptr; _history = nullptr; _peer = nullptr; } @@ -4039,10 +4012,10 @@ void OverlayWidget::setSession(not_null session) { session->data().itemRemoved( ) | rpl::filter([=](not_null item) { - return (_document != nullptr || _photo != nullptr) - && (item->fullId() == _msgid); + return (_message == item); }) | rpl::start_with_next([=] { close(); + clearSession(); }, _sessionLifetime); session->account().sessionChanges( @@ -4073,11 +4046,11 @@ bool OverlayWidget::moveToEntity(const Entity &entity, int preloadDelta) { clearStreaming(); _streamingStartPaused = false; if (auto photo = std::get_if>(&entity.data)) { - displayPhoto(*photo, entity.item); + displayPhoto(*photo); } else if (auto document = std::get_if>(&entity.data)) { - displayDocument(*document, entity.item); + displayDocument(*document); } else { - displayDocument(nullptr, entity.item); + displayDocument(nullptr); } preloadData(preloadDelta); return true; @@ -4305,7 +4278,7 @@ void OverlayWidget::updateOver(QPoint pos) { updateOverState(OverRightNav); } else if (_from && _nameNav.contains(pos)) { updateOverState(OverName); - } else if (IsServerMsgId(_msgid.msg) && _dateNav.contains(pos)) { + } else if (_message && _message->isRegular() && _dateNav.contains(pos)) { updateOverState(OverDate); } else if (_headerHasLink && _headerNav.contains(pos)) { updateOverState(OverHeader); @@ -4348,7 +4321,7 @@ void OverlayWidget::handleMouseRelease( ActivateClickHandler(_widget, activated, { button, QVariant::fromValue(ClickHandlerContext{ - .itemId = _msgid, + .itemId = _message ? _message->fullId() : FullMsgId(), .sessionWindow = base::make_weak(findWindow()), }) }); @@ -4682,8 +4655,8 @@ void OverlayWidget::updateImage() { void OverlayWidget::findCurrent() { using namespace rpl::mappers; if (_sharedMediaData) { - _index = _msgid - ? _sharedMediaData->indexOf(_msgid) + _index = _message + ? _sharedMediaData->indexOf(_message->fullId()) : _photo ? _sharedMediaData->indexOf(_photo) : std::nullopt; _fullIndex = _sharedMediaData->skippedBefore() ? (_index | func::add(*_sharedMediaData->skippedBefore())) @@ -4735,7 +4708,7 @@ void OverlayWidget::updateHeader() { } else { if (_document) { _headerText = _document->filename().isEmpty() ? tr::lng_mediaview_doc_image(tr::now) : _document->filename(); - } else if (_msgid) { + } else if (_message) { _headerText = tr::lng_mediaview_single_photo(tr::now); } else if (_user) { _headerText = tr::lng_mediaview_profile_photo(tr::now); diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index e61460b56..dbd63bdf9 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -263,8 +263,8 @@ private: [[nodiscard]] Data::FileOrigin fileOrigin() const; [[nodiscard]] Data::FileOrigin fileOrigin(const Entity& entity) const; - void refreshFromLabel(HistoryItem *item); - void refreshCaption(HistoryItem *item); + void refreshFromLabel(); + void refreshCaption(); void refreshMediaViewer(); void refreshNavVisibility(); void refreshGroupThumbs(); @@ -280,10 +280,9 @@ private: void resizeCenteredControls(); void resizeContentByScreenSize(); - void displayPhoto(not_null photo, HistoryItem *item); + void displayPhoto(not_null photo); void displayDocument( DocumentData *document, - HistoryItem *item, const Data::CloudTheme &cloud = Data::CloudTheme(), bool continueStreaming = false); void displayFinished(); @@ -516,9 +515,7 @@ private: std::optional _index; // Index in current _sharedMedia data. std::optional _fullIndex; // Index in full shared media. std::optional _fullCount; - FullMsgId _msgid; - bool _canForwardItem = false; - bool _canDeleteItem = false; + HistoryItem *_message = nullptr; mtpRequestId _loadRequest = 0; diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index 8911db8cf..06e1ac499 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -971,7 +971,7 @@ bool Document::downloadInCorner() const { return _data->isAudioFile() && _data->canBeStreamed() && !_data->inappPlaybackFailed() - && IsServerMsgId(parent()->id); + && parent()->isRegular(); } void Document::initDimensions() { diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp index f268563c2..dc00d7af0 100644 --- a/Telegram/SourceFiles/storage/localimageloader.cpp +++ b/Telegram/SourceFiles/storage/localimageloader.cpp @@ -491,7 +491,8 @@ FileLoadTask::FileLoadTask( , _type(type) , _caption(caption) { Expects(to.options.scheduled - || (to.replaceMediaOf == 0 || IsServerMsgId(to.replaceMediaOf))); + || !to.replaceMediaOf + || IsServerMsgId(to.replaceMediaOf)); } FileLoadTask::FileLoadTask( diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index a97851a1d..04af477ed 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -674,13 +674,13 @@ void Manager::openNotificationMessage( not_null history, MsgId messageId) { const auto openExactlyMessage = [&] { - if (history->peer->isUser() - || history->peer->isChannel() - || !IsServerMsgId(messageId)) { + if (history->peer->isUser() || history->peer->isChannel()) { return false; } - const auto item = history->owner().message(history->channelId(), messageId); - if (!item || !item->mentionsMe()) { + const auto item = history->owner().message( + history->channelId(), + messageId); + if (!item || !item->isRegular() || !item->mentionsMe()) { return false; } return true;