mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 15:17:07 +02:00
Some internal HistoryItem refactoring.
Replace most IsServerMsgId / id <=> 0 with isRegular(). Track isLocal / isHistoryEntry in flags. Remove toHistoryMessage.
This commit is contained in:
parent
22b37c4bf8
commit
c534f3f22e
52 changed files with 460 additions and 524 deletions
Telegram/SourceFiles
api
apiwrap.cppboxes
chat_helpers
data
data_changes.hdata_groups.cppdata_histories.cppdata_peer.cppdata_replies_list.cppdata_replies_list.hdata_scheduled_messages.cppdata_session.cppdata_sponsored_messages.cppdata_types.h
dialogs/ui
facades.cpphistory
admin_log
history.cpphistory.hhistory_inner_widget.cpphistory_item.cpphistory_item.hhistory_message.cpphistory_message.hhistory_service.cpphistory_service.hhistory_widget.cppview
info
media
player
view
overview
storage
window
|
@ -36,7 +36,7 @@ void SendBotCallbackData(
|
|||
int column,
|
||||
std::optional<MTPInputCheckPasswordSRP> password = std::nullopt,
|
||||
Fn<void(const MTP::Error &)> handleError = nullptr) {
|
||||
if (!IsServerMsgId(item->id)) {
|
||||
if (!item->isRegular()) {
|
||||
return;
|
||||
}
|
||||
const auto history = item->history();
|
||||
|
@ -150,7 +150,7 @@ void SendBotCallbackDataWithPassword(
|
|||
not_null<HistoryItem*> item,
|
||||
int row,
|
||||
int column) {
|
||||
if (!IsServerMsgId(item->id)) {
|
||||
if (!item->isRegular()) {
|
||||
return;
|
||||
}
|
||||
const auto history = item->history();
|
||||
|
|
|
@ -182,8 +182,7 @@ void Polls::close(not_null<HistoryItem*> item) {
|
|||
|
||||
void Polls::reloadResults(not_null<HistoryItem*> 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(
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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<HistoryItem*> item) {
|
|||
return;
|
||||
}
|
||||
item->markMediaRead();
|
||||
if (!IsServerMsgId(item->id)) {
|
||||
if (!item->isRegular()) {
|
||||
return;
|
||||
}
|
||||
const auto ids = MTP_vector<MTPint>(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<uint64>();
|
||||
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<base::flat_map<uint64, FullMsgId>>();
|
||||
}
|
||||
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<base::flat_map<uint64, FullMsgId>>();
|
||||
}
|
||||
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<HistoryItem*> 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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -114,7 +114,7 @@ EmojiPtr EmojiInteractions::chooseInteractionEmoji(
|
|||
void EmojiInteractions::startOutgoing(
|
||||
not_null<const HistoryView::Element*> 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);
|
||||
|
|
|
@ -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<Flag>;
|
||||
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
||||
|
|
|
@ -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<HistoryItem*> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ void Histories::readInbox(not_null<History*> history) {
|
|||
|
||||
void Histories::readInboxTill(not_null<HistoryItem*> 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<HistoryItem*> 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<HistoryItem*> 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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ rpl::producer<MessagesSlice> 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<MessagesSlice> 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<MessagesSlice> 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*> viewer) {
|
|||
bool RepliesList::applyUpdate(
|
||||
not_null<Viewer*> 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;
|
||||
|
|
|
@ -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*> viewer);
|
||||
[[nodiscard]] bool applyUpdate(
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -3496,7 +3496,7 @@ HistoryItem *Session::findWebPageItem(not_null<WebPageData*> 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();
|
||||
|
|
|
@ -75,7 +75,7 @@ bool SponsoredMessages::append(not_null<History*> history) {
|
|||
| (history->isChannel() ? MessageFlag::Post : MessageFlags(0))
|
||||
| MessageFlag::HasFromId
|
||||
| MessageFlag::IsSponsored
|
||||
| MessageFlag::LocalHistoryEntry;
|
||||
| MessageFlag::Local;
|
||||
auto local = history->addNewLocalMessage(
|
||||
_session->data().nextLocalMessageId(),
|
||||
flags,
|
||||
|
|
|
@ -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<MessageFlag>;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -147,8 +147,9 @@ void InnerWidget::enumerateUserpics(Method method) {
|
|||
|
||||
auto userpicCallback = [&](not_null<Element*> 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<Element*> 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<Element*> 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ void History::itemRemoved(not_null<HistoryItem*> 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<HistoryItem*> 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<HistoryItem*> History::addNewLocalMessage(
|
|||
return addNewItem(
|
||||
makeMessage(
|
||||
id,
|
||||
flags,
|
||||
flags | MessageFlag::Local,
|
||||
replyTo,
|
||||
viaBotId,
|
||||
date,
|
||||
|
@ -569,11 +569,11 @@ not_null<HistoryItem*> History::addNewLocalMessage(
|
|||
TimeId date,
|
||||
PeerId from,
|
||||
const QString &postAuthor,
|
||||
not_null<HistoryMessage*> forwardOriginal) {
|
||||
not_null<HistoryItem*> forwardOriginal) {
|
||||
return addNewItem(
|
||||
makeMessage(
|
||||
id,
|
||||
flags,
|
||||
flags | MessageFlag::Local,
|
||||
date,
|
||||
from,
|
||||
postAuthor,
|
||||
|
@ -595,7 +595,7 @@ not_null<HistoryItem*> History::addNewLocalMessage(
|
|||
return addNewItem(
|
||||
makeMessage(
|
||||
id,
|
||||
flags,
|
||||
flags | MessageFlag::Local,
|
||||
replyTo,
|
||||
viaBotId,
|
||||
date,
|
||||
|
@ -621,7 +621,7 @@ not_null<HistoryItem*> History::addNewLocalMessage(
|
|||
return addNewItem(
|
||||
makeMessage(
|
||||
id,
|
||||
flags,
|
||||
flags | MessageFlag::Local,
|
||||
replyTo,
|
||||
viaBotId,
|
||||
date,
|
||||
|
@ -646,7 +646,7 @@ not_null<HistoryItem*> History::addNewLocalMessage(
|
|||
return addNewItem(
|
||||
makeMessage(
|
||||
id,
|
||||
flags,
|
||||
flags | MessageFlag::Local,
|
||||
replyTo,
|
||||
viaBotId,
|
||||
date,
|
||||
|
@ -766,7 +766,7 @@ not_null<HistoryItem*> 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<HistoryItem*> item) {
|
|||
}
|
||||
}
|
||||
|
||||
void History::registerLocalMessage(not_null<HistoryItem*> item) {
|
||||
void History::registerClientSideMessage(not_null<HistoryItem*> 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<HistoryItem*> item) {
|
||||
const auto removed = _localMessages.remove(item);
|
||||
void History::unregisterClientSideMessage(not_null<HistoryItem*> 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<not_null<HistoryItem*>> &History::localMessages() {
|
||||
return _localMessages;
|
||||
const base::flat_set<not_null<HistoryItem*>> &History::clientSideMessages() {
|
||||
return _clientSideMessages;
|
||||
}
|
||||
|
||||
HistoryItem *History::latestSendingMessage() const {
|
||||
auto sending = ranges::views::all(
|
||||
_localMessages
|
||||
_clientSideMessages
|
||||
) | ranges::views::filter([](not_null<HistoryItem*> 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<int> 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<int> 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<int> stillUnread) {
|
|||
}
|
||||
|
||||
void History::inboxRead(not_null<const HistoryItem*> wasRead) {
|
||||
if (IsServerMsgId(wasRead->id)) {
|
||||
if (wasRead->isRegular()) {
|
||||
inboxRead(wasRead->id);
|
||||
}
|
||||
}
|
||||
|
@ -1596,7 +1596,7 @@ void History::inboxRead(not_null<const HistoryItem*> 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<const HistoryItem*> 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<const HistoryItem*> 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<HistoryItem*> 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<not_null<HistoryItem*>>();
|
||||
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();
|
||||
|
|
|
@ -158,7 +158,7 @@ public:
|
|||
TimeId date,
|
||||
PeerId from,
|
||||
const QString &postAuthor,
|
||||
not_null<HistoryMessage*> forwardOriginal);
|
||||
not_null<HistoryItem*> forwardOriginal);
|
||||
not_null<HistoryItem*> addNewLocalMessage(
|
||||
MsgId id,
|
||||
MessageFlags flags,
|
||||
|
@ -206,9 +206,9 @@ public:
|
|||
|
||||
void newItemAdded(not_null<HistoryItem*> item);
|
||||
|
||||
void registerLocalMessage(not_null<HistoryItem*> item);
|
||||
void unregisterLocalMessage(not_null<HistoryItem*> item);
|
||||
[[nodiscard]] auto localMessages()
|
||||
void registerClientSideMessage(not_null<HistoryItem*> item);
|
||||
void unregisterClientSideMessage(not_null<HistoryItem*> item);
|
||||
[[nodiscard]] auto clientSideMessages()
|
||||
-> const base::flat_set<not_null<HistoryItem*>> &;
|
||||
[[nodiscard]] HistoryItem *latestSendingMessage() const;
|
||||
|
||||
|
@ -600,7 +600,7 @@ private:
|
|||
base::flat_set<MsgId> _unreadMentions;
|
||||
std::optional<HistoryItem*> _lastMessage;
|
||||
std::optional<HistoryItem*> _lastServerMessage;
|
||||
base::flat_set<not_null<HistoryItem*>> _localMessages;
|
||||
base::flat_set<not_null<HistoryItem*>> _clientSideMessages;
|
||||
std::unordered_set<std::unique_ptr<HistoryItem>> _messages;
|
||||
|
||||
// This almost always is equal to _lastMessage. The only difference is
|
||||
|
|
|
@ -428,7 +428,9 @@ void HistoryInner::enumerateUserpics(Method method) {
|
|||
auto userpicCallback = [&](not_null<Element*> 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<HistoryMessage*>(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<Element*> 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<Element*> 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*> history, int historyTop)
|
||||
-> std::pair<Element*, int> {
|
||||
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<SelectedItems*> toItems,
|
||||
not_null<HistoryItem*> 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<HistoryItem*> 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<DeleteMessagesBox>(item, suggestModerateActions));
|
||||
|
|
|
@ -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<HistoryMessageVia>()
|
||||
|| Has<HistoryMessageForwarded>()) {
|
||||
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*> 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*> 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));
|
||||
|
|
|
@ -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<HistoryItem> {
|
||||
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;
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace {
|
|||
[[nodiscard]] MessageFlags NewForwardedFlags(
|
||||
not_null<PeerData*> peer,
|
||||
PeerId from,
|
||||
not_null<HistoryMessage*> fwd) {
|
||||
not_null<HistoryItem*> 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<HistoryMessage*> original)
|
||||
not_null<HistoryItem*> 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<HistoryMessageReply*> reply,
|
||||
int delta) {
|
||||
if (!IsServerMsgId(id) || !reply->replyToTop()) {
|
||||
if (!isRegular() || !reply->replyToTop()) {
|
||||
return;
|
||||
}
|
||||
const auto channelId = history()->channelId();
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
TimeId date,
|
||||
PeerId from,
|
||||
const QString &postAuthor,
|
||||
not_null<HistoryMessage*> original); // local forwarded
|
||||
not_null<HistoryItem*> original); // local forwarded
|
||||
HistoryMessage(
|
||||
not_null<History*> 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<HistoryView::Element> createView(
|
||||
not_null<HistoryView::ElementDelegate*> delegate,
|
||||
HistoryView::Element *replacing = nullptr) override;
|
||||
|
|
|
@ -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<HistoryService*> GenerateJoinedMessage(
|
|||
bool viaRequest) {
|
||||
return history->makeServiceMessage(
|
||||
history->owner().nextLocalMessageId(),
|
||||
MessageFlag::LocalHistoryEntry,
|
||||
MessageFlag::Local,
|
||||
inviteDate,
|
||||
GenerateJoinedText(history, inviter, viaRequest));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<HistoryItem*> 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<HistoryItem*> 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<Ui::InformBox>(
|
||||
tr::lng_reply_cant(tr::now)));
|
||||
} else {
|
||||
|
|
|
@ -62,14 +62,6 @@ namespace {
|
|||
|
||||
constexpr auto kRescheduleLimit = 20;
|
||||
|
||||
MsgId ItemIdAcrossData(not_null<HistoryItem*> 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<ListWidget*> 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<DeleteMessagesBox>(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();
|
||||
|
|
|
@ -536,7 +536,7 @@ void Element::refreshDataId() {
|
|||
|
||||
bool Element::computeIsAttachToPrevious(not_null<Element*> previous) {
|
||||
const auto mayBeAttached = [](not_null<HistoryItem*> item) {
|
||||
return !item->serviceMsg()
|
||||
return !item->isService()
|
||||
&& !item->isEmpty()
|
||||
&& !item->isPost()
|
||||
&& (item->from() != item->history()->peer
|
||||
|
|
|
@ -166,8 +166,9 @@ void ListWidget::enumerateUserpics(Method method) {
|
|||
|
||||
auto userpicCallback = [&](not_null<Element*> 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;
|
||||
}
|
||||
|
|
|
@ -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<QSize> 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();
|
||||
|
|
|
@ -613,7 +613,7 @@ bool PinnedWidget::listAllowsMultiSelect() {
|
|||
|
||||
bool PinnedWidget::listIsItemGoodForSelection(
|
||||
not_null<HistoryItem*> item) {
|
||||
return IsServerMsgId(item->id);
|
||||
return item->isRegular();
|
||||
}
|
||||
|
||||
bool PinnedWidget::listIsLessInOrder(
|
||||
|
@ -661,7 +661,7 @@ bool PinnedWidget::listElementShownUnread(not_null<const Element*> view) {
|
|||
|
||||
bool PinnedWidget::listIsGoodForAroundPosition(
|
||||
not_null<const Element*> view) {
|
||||
return IsServerMsgId(view->data()->id);
|
||||
return view->data()->isRegular();
|
||||
}
|
||||
|
||||
void PinnedWidget::listSendBotCommand(
|
||||
|
|
|
@ -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<HistoryItem*> item) {
|
||||
return IsServerMsgId(item->id);
|
||||
return item->isRegular();
|
||||
}
|
||||
|
||||
bool RepliesWidget::listIsLessInOrder(
|
||||
|
@ -1845,9 +1845,7 @@ void RepliesWidget::readTill(not_null<HistoryItem*> 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<const Element*> view) {
|
|||
|
||||
bool RepliesWidget::listIsGoodForAroundPosition(
|
||||
not_null<const Element*> view) {
|
||||
return IsServerMsgId(view->data()->id);
|
||||
return view->data()->isRegular();
|
||||
}
|
||||
|
||||
void RepliesWidget::listSendBotCommand(
|
||||
|
|
|
@ -595,7 +595,7 @@ bool Document::downloadInCorner() const {
|
|||
return _data->isAudioFile()
|
||||
&& _data->canBeStreamed()
|
||||
&& !_data->inappPlaybackFailed()
|
||||
&& IsServerMsgId(_realParent->id);
|
||||
&& _realParent->isRegular();
|
||||
}
|
||||
|
||||
void Document::drawCornerDownload(
|
||||
|
|
|
@ -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<ReplyMarkupClickHandler>(
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -71,9 +71,6 @@ rpl::producer<SparseIdsMergedSlice> 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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -332,7 +332,7 @@ auto Instance::playlistKey(not_null<Data*> 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 {};
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -110,7 +110,7 @@ Context ComputeContext(
|
|||
return v::null;
|
||||
} else if (const auto msgId = std::get_if<FullMsgId>(&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;
|
||||
|
|
|
@ -670,8 +670,7 @@ void OverlayWidget::documentUpdated(DocumentData *doc) {
|
|||
}
|
||||
|
||||
void OverlayWidget::changingMsgId(not_null<HistoryItem*> 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<DeleteMessagesBox>(item, suggestModerateActions),
|
||||
Box<DeleteMessagesBox>(message, suggestModerateActions),
|
||||
Ui::LayerOption::CloseOther);
|
||||
}
|
||||
}
|
||||
|
@ -1801,19 +1789,17 @@ void OverlayWidget::showAttachedStickers() {
|
|||
auto OverlayWidget::sharedMediaType() const
|
||||
-> std::optional<SharedMediaType> {
|
||||
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<SharedMediaKey> {
|
||||
if (!_msgid
|
||||
if (!_message
|
||||
&& _peer
|
||||
&& !_user
|
||||
&& _photo
|
||||
|
@ -1839,36 +1825,30 @@ auto OverlayWidget::sharedMediaKey() const -> std::optional<SharedMediaKey> {
|
|||
_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> 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> 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<Collage>(*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<PhotoData*> photo, HistoryItem *item) {
|
||||
void OverlayWidget::displayPhoto(not_null<PhotoData*> photo) {
|
||||
if (photo->isNull()) {
|
||||
displayDocument(nullptr, item);
|
||||
displayDocument(nullptr);
|
||||
return;
|
||||
}
|
||||
_touchbarDisplay.fire(TouchBarItemType::Photo);
|
||||
|
@ -2350,7 +2328,7 @@ void OverlayWidget::displayPhoto(not_null<PhotoData*> photo, HistoryItem *item)
|
|||
initStreaming();
|
||||
}
|
||||
|
||||
refreshCaption(item);
|
||||
refreshCaption();
|
||||
|
||||
_blurred = true;
|
||||
_down = OverNone;
|
||||
|
@ -2368,7 +2346,7 @@ void OverlayWidget::displayPhoto(not_null<PhotoData*> 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<PipWrap>(
|
||||
_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<DocumentData*>(&items[index])) {
|
||||
return { *document, item };
|
||||
return { *document, _message };
|
||||
} else if (const auto photo = std::get_if<PhotoData*>(&items[index])) {
|
||||
return { *photo, item };
|
||||
return { *photo, _message };
|
||||
}
|
||||
return { v::null, nullptr };
|
||||
}
|
||||
|
@ -3979,19 +3956,15 @@ void OverlayWidget::setContext(
|
|||
not_null<HistoryItem*>,
|
||||
not_null<PeerData*>> context) {
|
||||
if (const auto item = std::get_if<not_null<HistoryItem*>>(&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<not_null<PeerData*>>(&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<Main::Session*> session) {
|
|||
|
||||
session->data().itemRemoved(
|
||||
) | rpl::filter([=](not_null<const HistoryItem*> 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<not_null<PhotoData*>>(&entity.data)) {
|
||||
displayPhoto(*photo, entity.item);
|
||||
displayPhoto(*photo);
|
||||
} else if (auto document = std::get_if<not_null<DocumentData*>>(&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);
|
||||
|
|
|
@ -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<PhotoData*> photo, HistoryItem *item);
|
||||
void displayPhoto(not_null<PhotoData*> 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<int> _index; // Index in current _sharedMedia data.
|
||||
std::optional<int> _fullIndex; // Index in full shared media.
|
||||
std::optional<int> _fullCount;
|
||||
FullMsgId _msgid;
|
||||
bool _canForwardItem = false;
|
||||
bool _canDeleteItem = false;
|
||||
HistoryItem *_message = nullptr;
|
||||
|
||||
mtpRequestId _loadRequest = 0;
|
||||
|
||||
|
|
|
@ -971,7 +971,7 @@ bool Document::downloadInCorner() const {
|
|||
return _data->isAudioFile()
|
||||
&& _data->canBeStreamed()
|
||||
&& !_data->inappPlaybackFailed()
|
||||
&& IsServerMsgId(parent()->id);
|
||||
&& parent()->isRegular();
|
||||
}
|
||||
|
||||
void Document::initDimensions() {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -674,13 +674,13 @@ void Manager::openNotificationMessage(
|
|||
not_null<History*> 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;
|
||||
|
|
Loading…
Add table
Reference in a new issue