From 518ff146b2fe235ca9cd07f6b22415fa9aa00a32 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 18 Apr 2019 15:31:30 +0400 Subject: [PATCH] Don't allow reordering of the archive. --- Telegram/SourceFiles/apiwrap.cpp | 2 +- Telegram/SourceFiles/data/data_folder.cpp | 6 ++--- Telegram/SourceFiles/data/data_folder.h | 2 +- Telegram/SourceFiles/data/data_session.cpp | 26 ++++++++---------- Telegram/SourceFiles/data/data_session.h | 3 +-- .../SourceFiles/dialogs/dialogs_entry.cpp | 9 ++++--- Telegram/SourceFiles/dialogs/dialogs_entry.h | 5 +++- .../dialogs/dialogs_inner_widget.cpp | 27 ++++++++++++++----- .../SourceFiles/dialogs/dialogs_layout.cpp | 11 ++++---- .../SourceFiles/dialogs/dialogs_widget.cpp | 5 ++-- Telegram/SourceFiles/history/history.cpp | 4 +++ Telegram/SourceFiles/history/history.h | 3 ++- .../SourceFiles/window/window_peer_menu.cpp | 2 +- 13 files changed, 62 insertions(+), 43 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index c06f3cebd..9c1aa61f7 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -875,7 +875,7 @@ void ApiWrap::requestPinnedDialogs() { _session->data().processUsers(data.vusers); _session->data().processChats(data.vchats); - _session->data().applyPinnedDialogs(data.vdialogs.v); + _session->data().clearPinnedDialogs(); _session->data().applyDialogs( folderId, data.vmessages.v, diff --git a/Telegram/SourceFiles/data/data_folder.cpp b/Telegram/SourceFiles/data/data_folder.cpp index b48246ff3..67b7b18c7 100644 --- a/Telegram/SourceFiles/data/data_folder.cpp +++ b/Telegram/SourceFiles/data/data_folder.cpp @@ -94,7 +94,7 @@ void Folder::registerOne(not_null history) { } } if (_chatsList.size() == 1) { - updateChatListExistence(); + updateChatListSortPosition(); } owner().notifyFolderUpdated(this, FolderUpdateFlag::List); } @@ -426,8 +426,8 @@ bool Folder::toImportant() const { return !_importantChatsList.empty(); } -bool Folder::useProxyPromotion() const { - return false; +int Folder::fixedOnTopIndex() const { + return kArchiveFixOnTopIndex; } bool Folder::shouldBeInChatList() const { diff --git a/Telegram/SourceFiles/data/data_folder.h b/Telegram/SourceFiles/data/data_folder.h index 78d393d87..135b4c39b 100644 --- a/Telegram/SourceFiles/data/data_folder.h +++ b/Telegram/SourceFiles/data/data_folder.h @@ -62,7 +62,7 @@ public: int unreadCount() const; bool unreadCountKnown() const; - bool useProxyPromotion() const override; + int fixedOnTopIndex() const override; bool toImportant() const override; bool shouldBeInChatList() const override; int chatListUnreadCount() const override; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index dcc317124..01befbde7 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -1345,19 +1345,6 @@ void Session::setPinnedDialog(const Dialogs::Key &key, bool pinned) { setIsPinned(key, pinned); } -void Session::applyPinnedDialogs(const QVector &list) { - clearPinnedDialogs(); - for (auto i = list.size(); i != 0;) { - list[--i].match([&](const MTPDdialog &data) { - if (const auto peer = peerFromMTP(data.vpeer)) { - setPinnedDialog(history(peer), true); - } - }, [&](const MTPDdialogFolder &data) { - setPinnedDialog(processFolder(data.vfolder), true); - }); - } -} - void Session::applyPinnedDialogs(const QVector &list) { clearPinnedDialogs(); for (auto i = list.size(); i != 0;) { @@ -1376,6 +1363,15 @@ void Session::applyDialogs( FolderId requestFolderId, const QVector &messages, const QVector &dialogs) { + for (const auto &dialog : dialogs | ranges::view::reverse) { + dialog.match([&](const MTPDdialog &data) { + if (const auto peer = peerFromMTP(data.vpeer)) { + setPinnedDialog(history(peer), data.is_pinned()); + } + }, [&](const MTPDdialogFolder &data) { + setPinnedDialog(processFolder(data.vfolder), data.is_pinned()); + }); + } App::feedMsgs(messages, NewMessageLast); for (const auto &dialog : dialogs) { dialog.match([&](const auto &data) { @@ -1393,7 +1389,7 @@ void Session::applyDialog(FolderId requestFolderId, const MTPDdialog &data) { const auto history = session().data().history(peerId); history->applyDialog(requestFolderId, data); - if (!history->useProxyPromotion() && !history->isPinnedDialog()) { + if (!history->fixedOnTopIndex() && !history->isPinnedDialog()) { const auto date = history->chatListTimeId(); if (date != 0) { addSavedPeersAfter(ParseDateTime(date)); @@ -1419,7 +1415,7 @@ void Session::applyDialog( const auto folder = processFolder(dialog.vfolder); folder->applyDialog(dialog); - if (!folder->useProxyPromotion() && !folder->isPinnedDialog()) { + if (!folder->fixedOnTopIndex() && !folder->isPinnedDialog()) { const auto date = folder->chatListTimeId(); if (date != 0) { addSavedPeersAfter(ParseDateTime(date)); diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 3fc480cd9..96aba0935 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -307,7 +307,7 @@ public: int pinnedDialogsCount() const; const std::deque &pinnedDialogsOrder() const; void setPinnedDialog(const Dialogs::Key &key, bool pinned); - void applyPinnedDialogs(const QVector &list); + void clearPinnedDialogs(); void applyPinnedDialogs(const QVector &list); void reorderTwoPinnedDialogs( const Dialogs::Key &key1, @@ -694,7 +694,6 @@ private: } void userIsContactUpdated(not_null user); - void clearPinnedDialogs(); void setIsPinned(const Dialogs::Key &key, bool pinned); NotifySettings &defaultNotifySettings(not_null peer); diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp index 88a0877d8..0f605ef73 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp @@ -29,8 +29,8 @@ uint64 DialogPosFromDate(TimeId date) { return (uint64(date) << 32) | (++DialogsPosToTopShift); } -uint64 ProxyPromotedDialogPos() { - return 0xFFFFFFFFFFFF0001ULL; +uint64 FixedOnTopDialogPos(int index) { + return 0xFFFFFFFFFFFF000FULL - index; } uint64 PinnedDialogPos(int pinnedIndex) { @@ -87,8 +87,9 @@ void Entry::updateChatListSortPosition() { updateChatListEntry(); return; } - _sortKeyInChatList = useProxyPromotion() - ? ProxyPromotedDialogPos() + const auto fixedIndex = fixedOnTopIndex(); + _sortKeyInChatList = fixedIndex + ? FixedOnTopDialogPos(fixedIndex) : isPinnedDialog() ? PinnedDialogPos(_pinnedIndex) : DialogPosFromDate(adjustedChatListTimeId()); diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index 8cb01e6a3..bd40f4278 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -70,7 +70,6 @@ public: bool isProxyPromoted() const { return _isProxyPromoted; } - virtual bool useProxyPromotion() const = 0; void cacheProxyPromoted(bool promoted); uint64 sortKeyInChatList() const { return _sortKeyInChatList; @@ -81,6 +80,10 @@ public: bool needUpdateInChatList() const; virtual TimeId adjustedChatListTimeId() const; + virtual int fixedOnTopIndex() const = 0; + static constexpr auto kArchiveFixOnTopIndex = 1; + static constexpr auto kProxyPromotionFixOnTopIndex = 2; + virtual bool toImportant() const = 0; virtual bool shouldBeInChatList() const = 0; virtual int chatListUnreadCount() const = 0; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 9776b3c68..f3b007967 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -134,6 +134,19 @@ DialogsInner::DialogsInner(QWidget *parent, not_null contro UpdateRowSection::Default | UpdateRowSection::Filtered); }, lifetime()); + session().data().chatsListChanges( + ) | rpl::filter([=](Data::Folder *folder) { + return (folder == _openedFolder); + }) | rpl::start_with_next([=] { + if (_openedFolder + && _openedFolder->chatsList(Global::DialogsMode())->empty()) { + _openedFolder->updateChatListSortPosition(); + cancelFolder(); + } else { + refresh(); + } + }, lifetime()); + subscribe(Window::Theme::Background(), [=](const Window::Theme::BackgroundUpdate &data) { if (data.paletteChanged()) { Dialogs::Layout::clearUnreadBadgesCache(); @@ -214,8 +227,8 @@ int DialogsInner::dialogsOffset() const { int DialogsInner::proxyPromotedCount() const { auto result = 0; - for_const (auto row, *shownDialogs()) { - if (row->entry()->useProxyPromotion()) { + for (const auto row : *shownDialogs()) { + if (row->entry()->fixedOnTopIndex()) { ++result; } else { break; @@ -902,8 +915,8 @@ void DialogsInner::checkReorderPinnedStart(QPoint localPosition) { int DialogsInner::shownPinnedCount() const { auto result = 0; - for_const (auto row, *shownDialogs()) { - if (row->entry()->useProxyPromotion()) { + for (const auto row : *shownDialogs()) { + if (row->entry()->fixedOnTopIndex()) { continue; } else if (!row->entry()->isPinnedDialog()) { break; @@ -918,8 +931,8 @@ int DialogsInner::countPinnedIndex(Dialogs::Row *ofRow) { return -1; } auto result = 0; - for_const (auto row, *shownDialogs()) { - if (row->entry()->useProxyPromotion()) { + for (const auto row : *shownDialogs()) { + if (row->entry()->fixedOnTopIndex()) { continue; } else if (!row->entry()->isPinnedDialog()) { break; @@ -1342,7 +1355,7 @@ void DialogsInner::updateSearchResult(not_null peer) { if (_state == State::Filtered) { if (!_peerSearchResults.empty()) { auto index = 0, add = peerSearchOffset(); - for_const (auto &result, _peerSearchResults) { + for (const auto &result : _peerSearchResults) { if (result->peer == peer) { rtlupdate(0, add + index * st::dialogsRowHeight, width(), st::dialogsRowHeight); break; diff --git a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp index e7f732271..30a4de262 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp @@ -251,7 +251,7 @@ void paintRow( namewidth, st::msgNameFont->height); - const auto promoted = chat.entry()->useProxyPromotion() + const auto promoted = (history && history->useProxyPromotion()) && !(flags & (Flag::SearchResult/* | Flag::FeedSearchResult*/)); // #feed if (promoted) { const auto text = lang(lng_proxy_sponsor); @@ -278,7 +278,7 @@ void paintRow( } auto availableWidth = namewidth; - if (entry->isPinnedDialog()) { + if (entry->isPinnedDialog() && !entry->fixedOnTopIndex()) { auto &icon = (active ? st::dialogsPinnedIconActive : (selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon)); icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth); availableWidth -= icon.width() + st::dialogsUnreadPadding; @@ -305,7 +305,7 @@ void paintRow( } } else if (!item) { auto availableWidth = namewidth; - if (entry->isPinnedDialog()) { + if (entry->isPinnedDialog() && !entry->fixedOnTopIndex()) { auto &icon = (active ? st::dialogsPinnedIconActive : (selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon)); icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth); availableWidth -= icon.width() + st::dialogsUnreadPadding; @@ -322,7 +322,7 @@ void paintRow( } paintItemCallback(nameleft, namewidth); - } else if (entry->isPinnedDialog()) { + } else if (entry->isPinnedDialog() && !entry->fixedOnTopIndex()) { auto availableWidth = namewidth; auto &icon = (active ? st::dialogsPinnedIconActive : (selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon)); icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth); @@ -590,7 +590,8 @@ void RowPainter::paint( const auto displayPinnedIcon = !displayUnreadCounter && !displayMentionBadge && !displayUnreadMark - && entry->isPinnedDialog(); + && entry->isPinnedDialog() + && !entry->fixedOnTopIndex(); const auto from = history ? (history->peer->migrateTo() diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 4a3d4173a..1a6c9fa50 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -184,13 +184,14 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null cont }); connect(_scroll, SIGNAL(geometryChanged()), _inner, SLOT(onParentGeometryChanged())); connect(_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll())); + session().data().chatsListChanges( ) | rpl::filter([=](Data::Folder *folder) { return (folder == _inner->shownFolder()); }) | rpl::start_with_next([=] { - _inner->refresh(); - onListScroll(); + Ui::PostponeCall(this, [=] { onListScroll(); }); }, lifetime()); + connect(_filter, &Ui::FlatInput::cancelled, [=] { onCancel(); }); diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index fff5485a7..84ccec5cb 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -2425,6 +2425,10 @@ bool History::useProxyPromotion() const { return false; } +int History::fixedOnTopIndex() const { + return isProxyPromoted() ? kProxyPromotionFixOnTopIndex : 0; +} + bool History::shouldBeInChatList() const { if (peer->migrateTo() || !folderKnown()) { return false; diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index b95f01a66..9d4955ad6 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -290,7 +290,8 @@ public: void setForwardDraft(MessageIdsList &&items); History *migrateSibling() const; - bool useProxyPromotion() const override; + bool useProxyPromotion() const; + int fixedOnTopIndex() const override; void updateChatListExistence() override; bool shouldBeInChatList() const override; bool toImportant() const override; diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 00810d119..e0cb15598 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -472,7 +472,7 @@ void Filler::addChannelActions(not_null channel) { void Filler::fill() { if (_source == PeerMenuSource::ChatsList) { if (const auto history = _peer->owner().historyLoaded(_peer)) { - if (!history->useProxyPromotion()) { + if (!history->fixedOnTopIndex()) { addPinToggle(); } }