mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Preload complex last message on demand.
This commit is contained in:
parent
369862a3a7
commit
f2ed77649e
11 changed files with 101 additions and 55 deletions
|
@ -854,7 +854,7 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) {
|
|||
if (((*i)->index() * _rowHeight) >= yTo) {
|
||||
break;
|
||||
}
|
||||
(*i)->entry()->loadUserpic();
|
||||
(*i)->entry()->chatListPreloadData();
|
||||
}
|
||||
}
|
||||
} else if (!_filtered.empty()) {
|
||||
|
@ -865,7 +865,7 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) {
|
|||
if (to > _filtered.size()) to = _filtered.size();
|
||||
|
||||
for (; from < to; ++from) {
|
||||
_filtered[from]->entry()->loadUserpic();
|
||||
_filtered[from]->entry()->chatListPreloadData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ not_null<Dialogs::MainList*> Folder::chatsList() {
|
|||
return &_chatsList;
|
||||
}
|
||||
|
||||
void Folder::loadUserpic() {
|
||||
void Folder::chatListPreloadData() {
|
||||
}
|
||||
|
||||
void Folder::paintUserpic(
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
const base::flat_set<QString> &chatListNameWords() const override;
|
||||
const base::flat_set<QChar> &chatListFirstLetters() const override;
|
||||
|
||||
void loadUserpic() override;
|
||||
void chatListPreloadData() override;
|
||||
void paintUserpic(
|
||||
Painter &p,
|
||||
Ui::PeerUserpicView &view,
|
||||
|
|
|
@ -471,17 +471,7 @@ void ForumTopic::applyTopicTopMessage(MsgId topMessageId) {
|
|||
const auto itemId = FullMsgId(channel()->id, topMessageId);
|
||||
if (const auto item = owner().message(itemId)) {
|
||||
setLastServerMessage(item);
|
||||
|
||||
// If we set a single album part, request the full album.
|
||||
if (item->groupId() != MessageGroupId()) {
|
||||
if (owner().groups().isGroupOfOne(item)
|
||||
&& !item->toPreview({
|
||||
.hideSender = true,
|
||||
.hideCaption = true }).images.empty()
|
||||
&& _requestedGroups.emplace(item->fullId()).second) {
|
||||
owner().histories().requestGroupAround(item);
|
||||
}
|
||||
}
|
||||
resolveChatListMessageGroup();
|
||||
} else {
|
||||
setLastServerMessage(nullptr);
|
||||
}
|
||||
|
@ -490,6 +480,23 @@ void ForumTopic::applyTopicTopMessage(MsgId topMessageId) {
|
|||
}
|
||||
}
|
||||
|
||||
void ForumTopic::resolveChatListMessageGroup() {
|
||||
if (!(_flags & Flag::ResolveChatListMessage)) {
|
||||
return;
|
||||
}
|
||||
// If we set a single album part, request the full album.
|
||||
const auto item = _lastServerMessage.value_or(nullptr);
|
||||
if (item && item->groupId() != MessageGroupId()) {
|
||||
if (owner().groups().isGroupOfOne(item)
|
||||
&& !item->toPreview({
|
||||
.hideSender = true,
|
||||
.hideCaption = true }).images.empty()
|
||||
&& _requestedGroups.emplace(item->fullId()).second) {
|
||||
owner().histories().requestGroupAround(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ForumTopic::growLastKnownServerMessageId(MsgId id) {
|
||||
_lastKnownServerMessageId = std::max(_lastKnownServerMessageId, id);
|
||||
}
|
||||
|
@ -548,10 +555,11 @@ void ForumTopic::setChatListMessage(HistoryItem *item) {
|
|||
_forum->listMessageChanged(was, item);
|
||||
}
|
||||
|
||||
void ForumTopic::loadUserpic() {
|
||||
void ForumTopic::chatListPreloadData() {
|
||||
if (_icon) {
|
||||
[[maybe_unused]] const auto preload = _icon->ready();
|
||||
}
|
||||
allowChatListMessageResolve();
|
||||
}
|
||||
|
||||
void ForumTopic::paintUserpic(
|
||||
|
@ -840,6 +848,14 @@ Dialogs::UnreadState ForumTopic::unreadStateFor(
|
|||
return result;
|
||||
}
|
||||
|
||||
void ForumTopic::allowChatListMessageResolve() {
|
||||
if (_flags & Flag::ResolveChatListMessage) {
|
||||
return;
|
||||
}
|
||||
_flags |= Flag::ResolveChatListMessage;
|
||||
resolveChatListMessageGroup();
|
||||
}
|
||||
|
||||
HistoryItem *ForumTopic::chatListMessage() const {
|
||||
return _lastMessage.value_or(nullptr);
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ public:
|
|||
return _notify;
|
||||
}
|
||||
|
||||
void loadUserpic() override;
|
||||
void chatListPreloadData() override;
|
||||
void paintUserpic(
|
||||
Painter &p,
|
||||
Ui::PeerUserpicView &view,
|
||||
|
@ -169,6 +169,7 @@ private:
|
|||
HasPinnedMessages = (1 << 3),
|
||||
GeneralIconActive = (1 << 4),
|
||||
GeneralIconSelected = (1 << 5),
|
||||
ResolveChatListMessage = (1 << 6),
|
||||
};
|
||||
friend inline constexpr bool is_flag_type(Flag) { return true; }
|
||||
using Flags = base::flags<Flag>;
|
||||
|
@ -183,6 +184,8 @@ private:
|
|||
void setLastMessage(HistoryItem *item);
|
||||
void setLastServerMessage(HistoryItem *item);
|
||||
void setChatListMessage(HistoryItem *item);
|
||||
void allowChatListMessageResolve();
|
||||
void resolveChatListMessageGroup();
|
||||
|
||||
int chatListNameVersion() const override;
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
virtual void loadUserpic() = 0;
|
||||
virtual void chatListPreloadData() = 0;
|
||||
virtual void paintUserpic(
|
||||
Painter &p,
|
||||
Ui::PeerUserpicView &view,
|
||||
|
|
|
@ -2506,7 +2506,7 @@ void InnerWidget::visibleTopBottomUpdated(
|
|||
int visibleBottom) {
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
loadPeerPhotos();
|
||||
preloadRowsData();
|
||||
const auto loadTill = _visibleTop
|
||||
+ PreloadHeightsCount * (_visibleBottom - _visibleTop);
|
||||
if (_state == WidgetState::Filtered && loadTill >= peerSearchOffset()) {
|
||||
|
@ -2726,7 +2726,7 @@ void InnerWidget::refresh(bool toTop) {
|
|||
if (toTop) {
|
||||
stopReorderPinned();
|
||||
_mustScrollTo.fire({ 0, 0 });
|
||||
loadPeerPhotos();
|
||||
preloadRowsData();
|
||||
}
|
||||
_controller->setDialogsListDisplayForced(
|
||||
_searchInChat || !_filter.isEmpty());
|
||||
|
@ -3115,8 +3115,10 @@ void InnerWidget::scrollToDefaultSelected() {
|
|||
}
|
||||
}
|
||||
|
||||
void InnerWidget::loadPeerPhotos() {
|
||||
if (!parentWidget()) return;
|
||||
void InnerWidget::preloadRowsData() {
|
||||
if (!parentWidget()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto yFrom = _visibleTop;
|
||||
auto yTo = _visibleTop + (_visibleBottom - _visibleTop) * (PreloadHeightsCount + 1);
|
||||
|
@ -3129,7 +3131,7 @@ void InnerWidget::loadPeerPhotos() {
|
|||
if (((*i)->index() * _st->height) >= yTo) {
|
||||
break;
|
||||
}
|
||||
(*i)->entry()->loadUserpic();
|
||||
(*i)->entry()->chatListPreloadData();
|
||||
}
|
||||
yFrom = 0;
|
||||
} else {
|
||||
|
@ -3144,7 +3146,7 @@ void InnerWidget::loadPeerPhotos() {
|
|||
if (to > _filterResults.size()) to = _filterResults.size();
|
||||
|
||||
for (; from < to; ++from) {
|
||||
_filterResults[from].key().entry()->loadUserpic();
|
||||
_filterResults[from].key().entry()->chatListPreloadData();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@ private:
|
|||
Qt::KeyboardModifiers modifiers);
|
||||
void clearIrrelevantState();
|
||||
void selectByMouse(QPoint globalPosition);
|
||||
void loadPeerPhotos();
|
||||
void preloadRowsData();
|
||||
void scrollToItem(int top, int height);
|
||||
void scrollToDefaultSelected();
|
||||
void setCollapsedPressed(int pressed);
|
||||
|
|
|
@ -743,6 +743,7 @@ void RowPainter::Paint(
|
|||
const auto thread = row->thread();
|
||||
const auto peer = history ? history->peer.get() : nullptr;
|
||||
const auto badgesState = entry->chatListBadgesState();
|
||||
entry->chatListPreloadData(); // Allow chat list message resolve.
|
||||
const auto item = entry->chatListMessage();
|
||||
const auto cloudDraft = [&]() -> const Data::Draft*{
|
||||
if (!thread) {
|
||||
|
|
|
@ -607,16 +607,6 @@ not_null<HistoryItem*> History::addNewItem(
|
|||
} else {
|
||||
addNewToBack(item, unread);
|
||||
checkForLoadedAtTop(item);
|
||||
if (!unread) {
|
||||
// When we add just one last item, like we do while loading dialogs,
|
||||
// we want to remove a single added grouped media, otherwise it will
|
||||
// jump once we open the message history (first we show only that
|
||||
// media, then we load the rest of the group and show the group).
|
||||
//
|
||||
// That way when we open the message history we show nothing until a
|
||||
// whole history part is loaded, it certainly will contain the group.
|
||||
removeOrphanMediaGroupPart();
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
@ -2241,6 +2231,44 @@ Dialogs::UnreadState History::computeUnreadState() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
void History::allowChatListMessageResolve() {
|
||||
if (_flags & Flag::ResolveChatListMessage) {
|
||||
return;
|
||||
}
|
||||
_flags |= Flag::ResolveChatListMessage;
|
||||
if (!chatListMessageKnown()) {
|
||||
requestChatListMessage();
|
||||
} else {
|
||||
resolveChatListMessageGroup();
|
||||
}
|
||||
}
|
||||
|
||||
void History::resolveChatListMessageGroup() {
|
||||
const auto item = _chatListMessage.value_or(nullptr);
|
||||
if (!(_flags & Flag::ResolveChatListMessage)
|
||||
|| !item
|
||||
|| !hasOrphanMediaGroupPart()) {
|
||||
return;
|
||||
}
|
||||
// If we set a single album part, request the full album.
|
||||
const auto withImages = !item->toPreview({
|
||||
.hideSender = true,
|
||||
.hideCaption = true }).images.empty();
|
||||
if (withImages) {
|
||||
owner().histories().requestGroupAround(item);
|
||||
}
|
||||
if (unreadCountKnown() && !unreadCount()) {
|
||||
// When we add just one last item, like we do while loading dialogs,
|
||||
// we want to remove a single added grouped media, otherwise it will
|
||||
// jump once we open the message history (first we show only that
|
||||
// media, then we load the rest of the group and show the group).
|
||||
//
|
||||
// That way when we open the message history we show nothing until a
|
||||
// whole history part is loaded, it certainly will contain the group.
|
||||
clear(ClearType::Unload);
|
||||
}
|
||||
}
|
||||
|
||||
HistoryItem *History::chatListMessage() const {
|
||||
return _chatListMessage.value_or(nullptr);
|
||||
}
|
||||
|
@ -2269,8 +2297,9 @@ const base::flat_set<QChar> &History::chatListFirstLetters() const {
|
|||
return peer->nameFirstLetters();
|
||||
}
|
||||
|
||||
void History::loadUserpic() {
|
||||
void History::chatListPreloadData() {
|
||||
peer->loadUserpic();
|
||||
allowChatListMessageResolve();
|
||||
}
|
||||
|
||||
void History::paintUserpic(
|
||||
|
@ -2452,14 +2481,7 @@ void History::setChatListMessage(HistoryItem *item) {
|
|||
}
|
||||
_chatListMessage = item;
|
||||
setChatListTimeId(item->date());
|
||||
|
||||
// If we have a single message from a group, request the full album.
|
||||
if (hasOrphanMediaGroupPart()
|
||||
&& !item->toPreview({
|
||||
.hideSender = true,
|
||||
.hideCaption = true }).images.empty()) {
|
||||
owner().histories().requestGroupAround(item);
|
||||
}
|
||||
resolveChatListMessageGroup();
|
||||
} else if (!_chatListMessage || *_chatListMessage) {
|
||||
_chatListMessage = nullptr;
|
||||
updateChatListEntry();
|
||||
|
@ -2560,13 +2582,21 @@ void History::requestChatListMessage() {
|
|||
}
|
||||
|
||||
void History::setFakeChatListMessage() {
|
||||
if (const auto chat = peer->asChat()) {
|
||||
if (!(_flags & Flag::ResolveChatListMessage)) {
|
||||
if (!chatListTimeId()) {
|
||||
if (const auto last = lastMessage()) {
|
||||
setChatListTimeId(last->date());
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else if (const auto chat = peer->asChat()) {
|
||||
// In chats we try to take the item before the 'last', which
|
||||
// is the empty-displayed migration message.
|
||||
owner().histories().requestFakeChatListMessage(this);
|
||||
} else if (const auto from = migrateFrom()) {
|
||||
// In megagroups we just try to use
|
||||
// the message from the original group.
|
||||
from->allowChatListMessageResolve();
|
||||
from->requestChatListMessage();
|
||||
}
|
||||
}
|
||||
|
@ -3309,14 +3339,6 @@ bool History::hasOrphanMediaGroupPart() const {
|
|||
return last->groupId() != MessageGroupId();
|
||||
}
|
||||
|
||||
bool History::removeOrphanMediaGroupPart() {
|
||||
if (hasOrphanMediaGroupPart()) {
|
||||
clear(ClearType::Unload);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<MsgId> History::collectMessagesFromParticipantToDelete(
|
||||
not_null<PeerData*> participant) const {
|
||||
auto result = std::vector<MsgId>();
|
||||
|
|
|
@ -111,7 +111,6 @@ public:
|
|||
Element *findLastNonEmpty() const;
|
||||
Element *findLastDisplayed() const;
|
||||
bool hasOrphanMediaGroupPart() const;
|
||||
bool removeOrphanMediaGroupPart();
|
||||
[[nodiscard]] std::vector<MsgId> collectMessagesFromParticipantToDelete(
|
||||
not_null<PeerData*> participant) const;
|
||||
|
||||
|
@ -387,7 +386,7 @@ public:
|
|||
const QString &chatListNameSortKey() const override;
|
||||
const base::flat_set<QString> &chatListNameWords() const override;
|
||||
const base::flat_set<QChar> &chatListFirstLetters() const override;
|
||||
void loadUserpic() override;
|
||||
void chatListPreloadData() override;
|
||||
void paintUserpic(
|
||||
Painter &p,
|
||||
Ui::PeerUserpicView &view,
|
||||
|
@ -467,6 +466,7 @@ private:
|
|||
IsForum = (1 << 3),
|
||||
FakeUnreadWhileOpened = (1 << 4),
|
||||
HasPinnedMessages = (1 << 5),
|
||||
ResolveChatListMessage = (1 << 6),
|
||||
};
|
||||
using Flags = base::flags<Flag>;
|
||||
friend inline constexpr auto is_flag_type(Flag) {
|
||||
|
@ -553,6 +553,8 @@ private:
|
|||
void setChatListMessageFromLast();
|
||||
void setChatListMessageUnknown();
|
||||
void setFakeChatListMessage();
|
||||
void allowChatListMessageResolve();
|
||||
void resolveChatListMessageGroup();
|
||||
|
||||
// Add all items to the unread mentions if we were not loaded at bottom and now are.
|
||||
void checkAddAllToUnreadMentions();
|
||||
|
|
Loading…
Add table
Reference in a new issue