mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-31 06:26:18 +00:00
Support pinned locally in filters.
This commit is contained in:
@@ -55,19 +55,34 @@ Main::Session &Entry::session() const {
|
||||
return _owner->session();
|
||||
}
|
||||
|
||||
void Entry::cachePinnedIndex(int index) {
|
||||
if (_pinnedIndex != index) {
|
||||
const auto wasPinned = isPinnedDialog();
|
||||
_pinnedIndex = index;
|
||||
if (session().supportMode()) {
|
||||
// Force reorder in support mode.
|
||||
_sortKeyInChatList = 0;
|
||||
}
|
||||
updateChatListSortPosition();
|
||||
updateChatListEntry();
|
||||
if (wasPinned != isPinnedDialog()) {
|
||||
changedChatListPinHook();
|
||||
void Entry::pinnedIndexChanged(int was, int now) {
|
||||
if (session().supportMode()) {
|
||||
// Force reorder in support mode.
|
||||
_sortKeyInChatList = 0;
|
||||
}
|
||||
updateChatListSortPosition();
|
||||
updateChatListEntry();
|
||||
if ((was != 0) != (now != 0)) {
|
||||
changedChatListPinHook();
|
||||
}
|
||||
}
|
||||
|
||||
void Entry::cachePinnedIndex(FilterId filterId, int index) {
|
||||
const auto i = _pinnedIndex.find(filterId);
|
||||
const auto was = (i != end(_pinnedIndex)) ? i->second : 0;
|
||||
if (index == was) {
|
||||
return;
|
||||
}
|
||||
if (!index) {
|
||||
_pinnedIndex.erase(i);
|
||||
pinnedIndexChanged(was, index);
|
||||
} else {
|
||||
if (!was) {
|
||||
_pinnedIndex.emplace(filterId, index);
|
||||
} else {
|
||||
i->second = index;
|
||||
}
|
||||
pinnedIndexChanged(was, index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,9 +112,7 @@ void Entry::updateChatListSortPosition() {
|
||||
const auto fixedIndex = fixedOnTopIndex();
|
||||
_sortKeyInChatList = fixedIndex
|
||||
? FixedOnTopDialogPos(fixedIndex)
|
||||
: isPinnedDialog()
|
||||
? PinnedDialogPos(_pinnedIndex)
|
||||
: _sortKeyByDate;
|
||||
: computeSortPosition(0);
|
||||
if (needUpdateInChatList()) {
|
||||
setChatListExistence(true);
|
||||
} else {
|
||||
@@ -107,6 +120,23 @@ void Entry::updateChatListSortPosition() {
|
||||
}
|
||||
}
|
||||
|
||||
int Entry::lookupPinnedIndex(FilterId filterId) const {
|
||||
if (filterId) {
|
||||
const auto i = _pinnedIndex.find(filterId);
|
||||
return (i != end(_pinnedIndex)) ? i->second : 0;
|
||||
} else if (!_pinnedIndex.empty()) {
|
||||
return _pinnedIndex.front().first
|
||||
? 0
|
||||
: _pinnedIndex.front().second;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 Entry::computeSortPosition(FilterId filterId) const {
|
||||
const auto index = lookupPinnedIndex(filterId);
|
||||
return index ? PinnedDialogPos(index) : _sortKeyByDate;
|
||||
}
|
||||
|
||||
void Entry::updateChatListExistence() {
|
||||
setChatListExistence(shouldBeInChatList());
|
||||
}
|
||||
@@ -205,6 +235,9 @@ void Entry::removeFromChatList(
|
||||
return;
|
||||
}
|
||||
_chatListLinks.erase(i);
|
||||
if (isPinnedDialog(filterId)) {
|
||||
owner().setChatPinned(_key, filterId, false);
|
||||
}
|
||||
list->removeEntry(_key);
|
||||
}
|
||||
|
||||
|
@@ -32,10 +32,9 @@ struct RowsByLetter {
|
||||
};
|
||||
|
||||
enum class SortMode {
|
||||
Complex = 0x00,
|
||||
Date = 0x01,
|
||||
Name = 0x02,
|
||||
Add = 0x04,
|
||||
Date = 0x00,
|
||||
Name = 0x01,
|
||||
Add = 0x02,
|
||||
};
|
||||
|
||||
struct PositionChange {
|
||||
@@ -117,19 +116,18 @@ public:
|
||||
QChar letter,
|
||||
not_null<Row*> row);
|
||||
void updateChatListEntry() const;
|
||||
bool isPinnedDialog() const {
|
||||
return _pinnedIndex > 0;
|
||||
[[nodiscard]] bool isPinnedDialog(FilterId filterId) const {
|
||||
return lookupPinnedIndex(filterId) != 0;
|
||||
}
|
||||
void cachePinnedIndex(int index);
|
||||
void cachePinnedIndex(FilterId filterId, int index);
|
||||
bool isProxyPromoted() const {
|
||||
return _isProxyPromoted;
|
||||
}
|
||||
void cacheProxyPromoted(bool promoted);
|
||||
uint64 sortKeyInChatList() const {
|
||||
return _sortKeyInChatList;
|
||||
}
|
||||
uint64 sortKeyByDate() const {
|
||||
return _sortKeyByDate;
|
||||
[[nodiscard]] uint64 sortKeyInChatList(FilterId filterId) const {
|
||||
return filterId
|
||||
? computeSortPosition(filterId)
|
||||
: _sortKeyInChatList;
|
||||
}
|
||||
void updateChatListSortPosition();
|
||||
void setChatListTimeId(TimeId date);
|
||||
@@ -194,8 +192,12 @@ protected:
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] int lookupPinnedIndex(FilterId filterId) const;
|
||||
|
||||
private:
|
||||
virtual void changedChatListPinHook();
|
||||
void pinnedIndexChanged(int was, int now);
|
||||
[[nodiscard]] uint64 computeSortPosition(FilterId filterId) const;
|
||||
|
||||
void setChatListExistence(bool exists);
|
||||
RowsByLetter *chatListLinks(FilterId filterId);
|
||||
@@ -208,7 +210,7 @@ private:
|
||||
base::flat_map<FilterId, RowsByLetter> _chatListLinks;
|
||||
uint64 _sortKeyInChatList = 0;
|
||||
uint64 _sortKeyByDate = 0;
|
||||
int _pinnedIndex = 0;
|
||||
base::flat_map<FilterId, int> _pinnedIndex;
|
||||
bool _isProxyPromoted = false;
|
||||
TimeId _timeId = 0;
|
||||
|
||||
|
@@ -13,10 +13,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
namespace Dialogs {
|
||||
|
||||
IndexedList::IndexedList(SortMode sortMode)
|
||||
IndexedList::IndexedList(SortMode sortMode, FilterId filterId)
|
||||
: _sortMode(sortMode)
|
||||
, _list(sortMode)
|
||||
, _empty(sortMode) {
|
||||
, _filterId(filterId)
|
||||
, _list(sortMode, filterId)
|
||||
, _empty(sortMode, filterId) {
|
||||
}
|
||||
|
||||
RowsByLetter IndexedList::addToEnd(Key key) {
|
||||
@@ -28,7 +29,7 @@ RowsByLetter IndexedList::addToEnd(Key key) {
|
||||
for (const auto ch : key.entry()->chatListFirstLetters()) {
|
||||
auto j = _index.find(ch);
|
||||
if (j == _index.cend()) {
|
||||
j = _index.emplace(ch, _sortMode).first;
|
||||
j = _index.emplace(ch, _sortMode, _filterId).first;
|
||||
}
|
||||
result.letters.emplace(ch, j->second.addToEnd(key));
|
||||
}
|
||||
@@ -44,7 +45,7 @@ Row *IndexedList::addByName(Key key) {
|
||||
for (const auto ch : key.entry()->chatListFirstLetters()) {
|
||||
auto j = _index.find(ch);
|
||||
if (j == _index.cend()) {
|
||||
j = _index.emplace(ch, _sortMode).first;
|
||||
j = _index.emplace(ch, _sortMode, _filterId).first;
|
||||
}
|
||||
j->second.addByName(key);
|
||||
}
|
||||
@@ -79,7 +80,8 @@ void IndexedList::movePinned(Row *row, int deltaSign) {
|
||||
Assert(swapPinnedIndexWith != cbegin());
|
||||
--swapPinnedIndexWith;
|
||||
}
|
||||
Auth().data().reorderTwoPinnedChats(
|
||||
row->key().entry()->owner().reorderTwoPinnedChats(
|
||||
_filterId,
|
||||
row->key(),
|
||||
(*swapPinnedIndexWith)->key());
|
||||
}
|
||||
@@ -87,7 +89,7 @@ void IndexedList::movePinned(Row *row, int deltaSign) {
|
||||
void IndexedList::peerNameChanged(
|
||||
not_null<PeerData*> peer,
|
||||
const base::flat_set<QChar> &oldLetters) {
|
||||
Expects(_sortMode != SortMode::Date && _sortMode != SortMode::Complex);
|
||||
Expects(_sortMode != SortMode::Date);
|
||||
|
||||
if (const auto history = peer->owner().historyLoaded(peer)) {
|
||||
if (_sortMode == SortMode::Name) {
|
||||
@@ -102,7 +104,7 @@ void IndexedList::peerNameChanged(
|
||||
FilterId filterId,
|
||||
not_null<PeerData*> peer,
|
||||
const base::flat_set<QChar> &oldLetters) {
|
||||
Expects(_sortMode == SortMode::Date || _sortMode == SortMode::Complex);
|
||||
Expects(_sortMode == SortMode::Date);
|
||||
|
||||
if (const auto history = peer->owner().historyLoaded(peer)) {
|
||||
adjustNames(filterId, history, oldLetters);
|
||||
@@ -139,7 +141,7 @@ void IndexedList::adjustByName(
|
||||
for (auto ch : toAdd) {
|
||||
auto j = _index.find(ch);
|
||||
if (j == _index.cend()) {
|
||||
j = _index.emplace(ch, _sortMode).first;
|
||||
j = _index.emplace(ch, _sortMode, _filterId).first;
|
||||
}
|
||||
j->second.addByName(key);
|
||||
}
|
||||
@@ -165,7 +167,7 @@ void IndexedList::adjustNames(
|
||||
}
|
||||
}
|
||||
for (auto ch : toRemove) {
|
||||
if (_sortMode == SortMode::Date || _sortMode == SortMode::Complex) {
|
||||
if (_sortMode == SortMode::Date) {
|
||||
history->removeChatListEntryByLetter(filterId, ch);
|
||||
}
|
||||
if (auto it = _index.find(ch); it != _index.cend()) {
|
||||
@@ -175,10 +177,10 @@ void IndexedList::adjustNames(
|
||||
for (auto ch : toAdd) {
|
||||
auto j = _index.find(ch);
|
||||
if (j == _index.cend()) {
|
||||
j = _index.emplace(ch, _sortMode).first;
|
||||
j = _index.emplace(ch, _sortMode, _filterId).first;
|
||||
}
|
||||
auto row = j->second.addToEnd(key);
|
||||
if (_sortMode == SortMode::Date || _sortMode == SortMode::Complex) {
|
||||
if (_sortMode == SortMode::Date) {
|
||||
history->addChatListEntryByLetter(filterId, ch, row);
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ namespace Dialogs {
|
||||
|
||||
class IndexedList {
|
||||
public:
|
||||
IndexedList(SortMode sortMode);
|
||||
IndexedList(SortMode sortMode, FilterId filterId = 0);
|
||||
|
||||
RowsByLetter addToEnd(Key key);
|
||||
Row *addByName(Key key);
|
||||
@@ -81,6 +81,7 @@ private:
|
||||
const base::flat_set<QChar> &oldChars);
|
||||
|
||||
SortMode _sortMode = SortMode();
|
||||
FilterId _filterId = 0;
|
||||
List _list, _empty;
|
||||
base::flat_map<QChar, List> _index;
|
||||
|
||||
|
@@ -66,12 +66,14 @@ int FixedOnTopDialogsCount(not_null<Dialogs::IndexedList*> list) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int PinnedDialogsCount(not_null<Dialogs::IndexedList*> list) {
|
||||
int PinnedDialogsCount(
|
||||
FilterId filterId,
|
||||
not_null<Dialogs::IndexedList*> list) {
|
||||
auto result = 0;
|
||||
for (const auto row : *list) {
|
||||
if (row->entry()->fixedOnTopIndex()) {
|
||||
continue;
|
||||
} else if (!row->entry()->isPinnedDialog()) {
|
||||
} else if (!row->entry()->isPinnedDialog(filterId)) {
|
||||
break;
|
||||
}
|
||||
++result;
|
||||
@@ -1075,7 +1077,7 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
|
||||
});
|
||||
}
|
||||
if (anim::Disabled()
|
||||
&& (!_pressed || !_pressed->entry()->isPinnedDialog())) {
|
||||
&& (!_pressed || !_pressed->entry()->isPinnedDialog(_filterId))) {
|
||||
mousePressReleased(e->globalPos(), e->button());
|
||||
}
|
||||
}
|
||||
@@ -1091,7 +1093,9 @@ void InnerWidget::checkReorderPinnedStart(QPoint localPosition) {
|
||||
if (updateReorderIndexGetCount() < 2) {
|
||||
_dragging = nullptr;
|
||||
} else {
|
||||
const auto &order = session().data().pinnedChatsOrder(_openedFolder);
|
||||
const auto &order = session().data().pinnedChatsOrder(
|
||||
_openedFolder,
|
||||
_filterId);
|
||||
_pinnedOnDragStart = base::flat_set<Key>{
|
||||
order.begin(),
|
||||
order.end()
|
||||
@@ -1103,14 +1107,14 @@ void InnerWidget::checkReorderPinnedStart(QPoint localPosition) {
|
||||
}
|
||||
|
||||
int InnerWidget::countPinnedIndex(Row *ofRow) {
|
||||
if (!ofRow || !ofRow->entry()->isPinnedDialog()) {
|
||||
if (!ofRow || !ofRow->entry()->isPinnedDialog(_filterId)) {
|
||||
return -1;
|
||||
}
|
||||
auto result = 0;
|
||||
for (const auto row : *shownDialogs()) {
|
||||
if (row->entry()->fixedOnTopIndex()) {
|
||||
continue;
|
||||
} else if (!row->entry()->isPinnedDialog()) {
|
||||
} else if (!row->entry()->isPinnedDialog(_filterId)) {
|
||||
break;
|
||||
} else if (row == ofRow) {
|
||||
return result;
|
||||
@@ -1121,7 +1125,9 @@ int InnerWidget::countPinnedIndex(Row *ofRow) {
|
||||
}
|
||||
|
||||
void InnerWidget::savePinnedOrder() {
|
||||
const auto &newOrder = session().data().pinnedChatsOrder(_openedFolder);
|
||||
const auto &newOrder = session().data().pinnedChatsOrder(
|
||||
_openedFolder,
|
||||
_filterId);
|
||||
if (newOrder.size() != _pinnedOnDragStart.size()) {
|
||||
return; // Something has changed in the set of pinned chats.
|
||||
}
|
||||
@@ -1130,7 +1136,11 @@ void InnerWidget::savePinnedOrder() {
|
||||
return; // Something has changed in the set of pinned chats.
|
||||
}
|
||||
}
|
||||
session().api().savePinnedOrder(_openedFolder);
|
||||
if (_filterId) {
|
||||
// #TODO pinned reorder data and to server
|
||||
} else {
|
||||
session().api().savePinnedOrder(_openedFolder);
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::finishReorderPinned() {
|
||||
@@ -1162,7 +1172,7 @@ int InnerWidget::updateReorderIndexGetCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto count = Dialogs::PinnedDialogsCount(shownDialogs());
|
||||
const auto count = Dialogs::PinnedDialogsCount(_filterId, shownDialogs());
|
||||
Assert(index < count);
|
||||
if (count < 2) {
|
||||
stopReorderPinned();
|
||||
@@ -1789,6 +1799,7 @@ void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
|
||||
Window::FillPeerMenu(
|
||||
_controller,
|
||||
history->peer,
|
||||
_filterId,
|
||||
[&](const QString &text, Fn<void()> callback) {
|
||||
return _menu->addAction(text, std::move(callback));
|
||||
},
|
||||
@@ -2541,6 +2552,7 @@ void InnerWidget::switchToFilter(FilterId filterId) {
|
||||
&Data::ChatFilter::id)) {
|
||||
filterId = 0;
|
||||
}
|
||||
stopReorderPinned();
|
||||
_filterId = filterId;
|
||||
refreshWithCollapsedRows(true);
|
||||
_collapsedSelected = 0;
|
||||
@@ -2983,7 +2995,7 @@ void InnerWidget::setupShortcuts() {
|
||||
for (const auto [command, index] : pinned) {
|
||||
request->check(command) && request->handle([=, index = index] {
|
||||
const auto list = session().data().chatsList()->indexed();
|
||||
const auto count = Dialogs::PinnedDialogsCount(list);
|
||||
const auto count = Dialogs::PinnedDialogsCount(_filterId, list);
|
||||
if (index >= count) {
|
||||
return false;
|
||||
}
|
||||
|
@@ -218,6 +218,7 @@ void paintRow(
|
||||
not_null<const BasicRow*> row,
|
||||
not_null<Entry*> entry,
|
||||
Dialogs::Key chat,
|
||||
FilterId filterId,
|
||||
PeerData *from,
|
||||
const HiddenSenderInfo *hiddenSenderInfo,
|
||||
HistoryItem *item,
|
||||
@@ -322,7 +323,7 @@ void paintRow(
|
||||
}
|
||||
|
||||
auto availableWidth = namewidth;
|
||||
if (entry->isPinnedDialog() && !entry->fixedOnTopIndex()) {
|
||||
if (entry->isPinnedDialog(filterId) && (filterId || !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;
|
||||
@@ -349,7 +350,7 @@ void paintRow(
|
||||
}
|
||||
} else if (!item) {
|
||||
auto availableWidth = namewidth;
|
||||
if (entry->isPinnedDialog() && !entry->fixedOnTopIndex()) {
|
||||
if (entry->isPinnedDialog(filterId) && (filterId || !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;
|
||||
@@ -366,7 +367,7 @@ void paintRow(
|
||||
}
|
||||
|
||||
paintItemCallback(nameleft, namewidth);
|
||||
} else if (entry->isPinnedDialog() && !entry->fixedOnTopIndex()) {
|
||||
} else if (entry->isPinnedDialog(filterId) && (filterId || !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);
|
||||
@@ -613,7 +614,7 @@ void paintUnreadCount(
|
||||
void RowPainter::paint(
|
||||
Painter &p,
|
||||
not_null<const Row*> row,
|
||||
int filterId,
|
||||
FilterId filterId,
|
||||
int fullWidth,
|
||||
bool active,
|
||||
bool selected,
|
||||
@@ -669,9 +670,8 @@ void RowPainter::paint(
|
||||
const auto displayPinnedIcon = !displayUnreadCounter
|
||||
&& !displayMentionBadge
|
||||
&& !displayUnreadMark
|
||||
&& !filterId
|
||||
&& entry->isPinnedDialog()
|
||||
&& !entry->fixedOnTopIndex();
|
||||
&& entry->isPinnedDialog(filterId)
|
||||
&& (filterId || !entry->fixedOnTopIndex());
|
||||
|
||||
const auto from = history
|
||||
? (history->peer->migrateTo()
|
||||
@@ -749,6 +749,7 @@ void RowPainter::paint(
|
||||
row,
|
||||
entry,
|
||||
row->key(),
|
||||
filterId,
|
||||
from,
|
||||
nullptr,
|
||||
item,
|
||||
@@ -872,6 +873,7 @@ void RowPainter::paint(
|
||||
row,
|
||||
history,
|
||||
history,
|
||||
FilterId(),
|
||||
from,
|
||||
hiddenSenderInfo,
|
||||
item,
|
||||
|
@@ -29,7 +29,7 @@ public:
|
||||
static void paint(
|
||||
Painter &p,
|
||||
not_null<const Row*> row,
|
||||
int filterId,
|
||||
FilterId filterId,
|
||||
int fullWidth,
|
||||
bool active,
|
||||
bool selected,
|
||||
|
@@ -14,7 +14,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
namespace Dialogs {
|
||||
|
||||
List::List(SortMode sortMode) : _sortMode(sortMode) {
|
||||
List::List(SortMode sortMode, FilterId filterId)
|
||||
: _sortMode(sortMode)
|
||||
, _filterId(filterId) {
|
||||
}
|
||||
|
||||
List::const_iterator List::cfind(Row *value) const {
|
||||
@@ -32,7 +34,7 @@ not_null<Row*> List::addToEnd(Key key) {
|
||||
std::make_unique<Row>(key, _rows.size())
|
||||
).first->second.get();
|
||||
_rows.emplace_back(result);
|
||||
if (_sortMode == SortMode::Date || _sortMode == SortMode::Complex) {
|
||||
if (_sortMode == SortMode::Date) {
|
||||
adjustByDate(result);
|
||||
}
|
||||
return result;
|
||||
@@ -82,20 +84,20 @@ void List::adjustByName(not_null<Row*> row) {
|
||||
}
|
||||
|
||||
void List::adjustByDate(not_null<Row*> row) {
|
||||
Expects(_sortMode == SortMode::Date || _sortMode == SortMode::Complex);
|
||||
Expects(_sortMode == SortMode::Date);
|
||||
|
||||
const auto key = row->sortKey(_sortMode);
|
||||
const auto key = row->sortKey(_filterId);
|
||||
const auto index = row->pos();
|
||||
const auto i = _rows.begin() + index;
|
||||
const auto before = std::find_if(i + 1, _rows.end(), [&](Row *row) {
|
||||
return (row->sortKey(_sortMode) <= key);
|
||||
return (row->sortKey(_filterId) <= key);
|
||||
});
|
||||
if (before != i + 1) {
|
||||
rotate(i, i + 1, before);
|
||||
} else {
|
||||
const auto from = std::make_reverse_iterator(i);
|
||||
const auto after = std::find_if(from, _rows.rend(), [&](Row *row) {
|
||||
return (row->sortKey(_sortMode) >= key);
|
||||
return (row->sortKey(_filterId) >= key);
|
||||
}).base();
|
||||
if (after != i) {
|
||||
rotate(after, i, i + 1);
|
||||
|
@@ -16,7 +16,7 @@ enum class SortMode;
|
||||
|
||||
class List final {
|
||||
public:
|
||||
List(SortMode sortMode);
|
||||
List(SortMode sortMode, FilterId filterId = 0);
|
||||
List(const List &other) = delete;
|
||||
List &operator=(const List &other) = delete;
|
||||
List(List &&other) = default;
|
||||
@@ -78,6 +78,7 @@ private:
|
||||
std::vector<not_null<Row*>>::iterator last);
|
||||
|
||||
SortMode _sortMode = SortMode();
|
||||
FilterId _filterId = 0;
|
||||
std::vector<not_null<Row*>> _rows;
|
||||
std::map<Key, std::unique_ptr<Row>> _rowByKey;
|
||||
|
||||
|
@@ -14,8 +14,8 @@ namespace Dialogs {
|
||||
|
||||
MainList::MainList(FilterId filterId, rpl::producer<int> pinnedLimit)
|
||||
: _filterId(filterId)
|
||||
, _all(filterId ? SortMode::Date : SortMode::Complex)
|
||||
, _pinned(1) {
|
||||
, _all(SortMode::Date, filterId)
|
||||
, _pinned(filterId, 1) {
|
||||
_unreadState.known = true;
|
||||
|
||||
std::move(
|
||||
|
@@ -9,11 +9,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "dialogs/dialogs_key.h"
|
||||
#include "dialogs/dialogs_entry.h"
|
||||
#include "history/history.h"
|
||||
#include "data/data_session.h"
|
||||
|
||||
namespace Dialogs {
|
||||
|
||||
PinnedList::PinnedList(int limit) : _limit(limit) {
|
||||
PinnedList::PinnedList(FilterId filterId, int limit)
|
||||
: _filterId(filterId)
|
||||
, _limit(limit) {
|
||||
Expects(limit > 0);
|
||||
}
|
||||
|
||||
@@ -41,7 +44,7 @@ int PinnedList::addPinnedGetPosition(const Key &key) {
|
||||
applyLimit(_limit - 1);
|
||||
const auto position = int(_data.size());
|
||||
_data.push_back(key);
|
||||
key.entry()->cachePinnedIndex(position + 1);
|
||||
key.entry()->cachePinnedIndex(_filterId, position + 1);
|
||||
return position;
|
||||
}
|
||||
|
||||
@@ -54,19 +57,34 @@ void PinnedList::setPinned(const Key &key, bool pinned) {
|
||||
const auto begin = _data.begin();
|
||||
std::rotate(begin, begin + position, begin + position + 1);
|
||||
for (auto i = 0; i != position + 1; ++i) {
|
||||
_data[i].entry()->cachePinnedIndex(i + 1);
|
||||
_data[i].entry()->cachePinnedIndex(_filterId, i + 1);
|
||||
}
|
||||
}
|
||||
} else if (const auto it = ranges::find(_data, key); it != end(_data)) {
|
||||
const auto index = int(it - begin(_data));
|
||||
_data.erase(it);
|
||||
key.entry()->cachePinnedIndex(0);
|
||||
key.entry()->cachePinnedIndex(_filterId, 0);
|
||||
for (auto i = index, count = int(size(_data)); i != count; ++i) {
|
||||
_data[i].entry()->cachePinnedIndex(i + 1);
|
||||
_data[i].entry()->cachePinnedIndex(_filterId, i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PinnedList::applyFilterPinned(
|
||||
FilterId filterId,
|
||||
not_null<History*> history,
|
||||
int index) {
|
||||
Expects(index > 0);
|
||||
|
||||
history->cachePinnedIndex(filterId, index);
|
||||
|
||||
const auto key = Key{ history };
|
||||
if (ranges::find(_data, key) == end(_data)) {
|
||||
_data.push_back(key);
|
||||
// #TODO pinned
|
||||
}
|
||||
}
|
||||
|
||||
void PinnedList::applyLimit(int limit) {
|
||||
Expects(limit >= 0);
|
||||
|
||||
@@ -83,18 +101,32 @@ void PinnedList::applyList(
|
||||
not_null<Data::Session*> owner,
|
||||
const QVector<MTPDialogPeer> &list) {
|
||||
clear();
|
||||
for (const auto &peer : ranges::view::reverse(list)) {
|
||||
for (const auto &peer : list) {
|
||||
peer.match([&](const MTPDdialogPeer &data) {
|
||||
if (const auto peerId = peerFromMTP(data.vpeer())) {
|
||||
setPinned(owner->history(peerId), true);
|
||||
addPinned(owner->history(peerId));
|
||||
}
|
||||
}, [&](const MTPDdialogPeerFolder &data) {
|
||||
const auto folderId = data.vfolder_id().v;
|
||||
setPinned(owner->folder(folderId), true);
|
||||
addPinned(owner->folder(data.vfolder_id().v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void PinnedList::applyList(const std::vector<not_null<History*>> &list) {
|
||||
Expects(_filterId != 0);
|
||||
|
||||
clear();
|
||||
const auto count = int(list.size());
|
||||
_data.reserve(count);
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
const auto history = list[i];
|
||||
if (history->inChatList()) {
|
||||
_data.emplace_back(history);
|
||||
history->cachePinnedIndex(_filterId, i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PinnedList::reorder(const Key &key1, const Key &key2) {
|
||||
const auto index1 = ranges::find(_data, key1) - begin(_data);
|
||||
const auto index2 = ranges::find(_data, key2) - begin(_data);
|
||||
@@ -102,8 +134,8 @@ void PinnedList::reorder(const Key &key1, const Key &key2) {
|
||||
Assert(index2 >= 0 && index2 < _data.size());
|
||||
Assert(index1 != index2);
|
||||
std::swap(_data[index1], _data[index2]);
|
||||
key1.entry()->cachePinnedIndex(index2 + 1);
|
||||
key2.entry()->cachePinnedIndex(index1 + 1);
|
||||
key1.entry()->cachePinnedIndex(_filterId, index2 + 1);
|
||||
key2.entry()->cachePinnedIndex(_filterId, index1 + 1);
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
||||
|
@@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class History;
|
||||
|
||||
namespace Data {
|
||||
class Session;
|
||||
} // namespace Data
|
||||
@@ -17,7 +19,7 @@ class Key;
|
||||
|
||||
class PinnedList final {
|
||||
public:
|
||||
explicit PinnedList(int limit);
|
||||
PinnedList(FilterId filterId, int limit);
|
||||
|
||||
void setLimit(int limit);
|
||||
|
||||
@@ -28,11 +30,17 @@ public:
|
||||
// if (pinned) places on the first place in the list.
|
||||
void setPinned(const Key &key, bool pinned);
|
||||
|
||||
void applyFilterPinned(
|
||||
FilterId filterId,
|
||||
not_null<History*> history,
|
||||
int index);
|
||||
|
||||
void clear();
|
||||
|
||||
void applyList(
|
||||
not_null<Data::Session*> owner,
|
||||
const QVector<MTPDialogPeer> &list);
|
||||
void applyList(const std::vector<not_null<History*>> &list);
|
||||
void reorder(const Key &key1, const Key &key2);
|
||||
|
||||
const std::vector<Key> &order() const {
|
||||
@@ -43,6 +51,7 @@ private:
|
||||
int addPinnedGetPosition(const Key &key);
|
||||
void applyLimit(int limit);
|
||||
|
||||
FilterId _filterId = 0;
|
||||
int _limit = 0;
|
||||
std::vector<Key> _data;
|
||||
|
||||
|
@@ -220,10 +220,8 @@ Row::Row(Key key, int pos) : _id(key), _pos(pos) {
|
||||
}
|
||||
}
|
||||
|
||||
uint64 Row::sortKey(SortMode mode) const {
|
||||
return (mode == SortMode::Complex)
|
||||
? _id.entry()->sortKeyInChatList()
|
||||
: _id.entry()->sortKeyByDate();
|
||||
uint64 Row::sortKey(FilterId filterId) const {
|
||||
return _id.entry()->sortKeyInChatList(filterId);
|
||||
}
|
||||
|
||||
void Row::validateListEntryCache() const {
|
||||
|
@@ -90,7 +90,7 @@ public:
|
||||
int pos() const {
|
||||
return _pos;
|
||||
}
|
||||
uint64 sortKey(SortMode mode) const;
|
||||
uint64 sortKey(FilterId filterId) const;
|
||||
|
||||
void validateListEntryCache() const;
|
||||
const Ui::Text::String &listEntryCache() const {
|
||||
|
Reference in New Issue
Block a user