| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #include "dialogs/dialogs_pinned_list.h"
- #include "data/data_saved_messages.h"
- #include "dialogs/dialogs_key.h"
- #include "dialogs/dialogs_entry.h"
- #include "history/history.h"
- #include "data/data_session.h"
- #include "data/data_forum.h"
- namespace Dialogs {
- PinnedList::PinnedList(FilterId filterId, int limit)
- : _filterId(filterId)
- , _limit(limit) {
- Expects(limit > 0);
- }
- void PinnedList::setLimit(int limit) {
- Expects(limit > 0);
- if (_limit == limit) {
- return;
- }
- _limit = limit;
- applyLimit(_limit);
- }
- void PinnedList::addPinned(Key key) {
- Expects(key.entry()->folderKnown());
- addPinnedGetPosition(key);
- }
- int PinnedList::addPinnedGetPosition(Key key) {
- const auto already = ranges::find(_data, key);
- if (already != end(_data)) {
- return already - begin(_data);
- }
- applyLimit(_limit - 1);
- const auto position = int(_data.size());
- _data.push_back(key);
- key.entry()->cachePinnedIndex(_filterId, position + 1);
- return position;
- }
- void PinnedList::setPinned(Key key, bool pinned) {
- Expects(key.entry()->folderKnown() || _filterId != 0);
- if (pinned) {
- const int position = addPinnedGetPosition(key);
- if (position) {
- 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(_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(_filterId, 0);
- for (auto i = index, count = int(size(_data)); i != count; ++i) {
- _data[i].entry()->cachePinnedIndex(_filterId, i + 1);
- }
- }
- }
- void PinnedList::applyLimit(int limit) {
- Expects(limit >= 0);
- while (_data.size() > limit) {
- setPinned(_data.back(), false);
- }
- }
- void PinnedList::clear() {
- applyLimit(0);
- }
- void PinnedList::applyList(
- not_null<Data::Session*> owner,
- const QVector<MTPDialogPeer> &list) {
- Expects(this != owner->savedMessages().chatsList()->pinned());
- clear();
- for (const auto &peer : list) {
- peer.match([&](const MTPDdialogPeer &data) {
- if (const auto peerId = peerFromMTP(data.vpeer())) {
- addPinned(owner->history(peerId));
- }
- }, [&](const MTPDdialogPeerFolder &data) {
- addPinned(owner->folder(data.vfolder_id().v));
- });
- }
- }
- void PinnedList::applyList(
- not_null<Data::SavedMessages*> sublistsOwner,
- const QVector<MTPDialogPeer> &list) {
- Expects(this == sublistsOwner->chatsList()->pinned());
- clear();
- for (const auto &peer : list) {
- peer.match([&](const MTPDdialogPeer &data) {
- if (const auto peerId = peerFromMTP(data.vpeer())) {
- const auto peer = sublistsOwner->owner().peer(peerId);
- addPinned(sublistsOwner->sublist(peer));
- }
- }, [](const MTPDdialogPeerFolder &data) {
- });
- }
- }
- void PinnedList::applyList(
- not_null<Data::Forum*> forum,
- const QVector<MTPint> &list) {
- Expects(this == forum->topicsList()->pinned());
- clear();
- for (const auto &topicId : list) {
- addPinned(forum->topicFor(topicId.v));
- }
- }
- void PinnedList::applyList(const std::vector<not_null<History*>> &list) {
- Expects(_filterId != 0);
- const auto old = base::take(_data);
- const auto count = int(list.size());
- _data.reserve(count);
- for (auto i = 0; i != count; ++i) {
- const auto history = list[i];
- _data.emplace_back(history);
- history->cachePinnedIndex(_filterId, i + 1);
- }
- for (const auto &key : old) {
- const auto history = key.history();
- if (!history || !ranges::contains(_data, history, &Key::history)) {
- key.entry()->cachePinnedIndex(_filterId, 0);
- }
- }
- }
- void PinnedList::reorder(Key key1, Key key2) {
- const auto index1 = ranges::find(_data, key1) - begin(_data);
- const auto index2 = ranges::find(_data, key2) - begin(_data);
- Assert(index1 >= 0 && index1 < _data.size());
- Assert(index2 >= 0 && index2 < _data.size());
- Assert(index1 != index2);
- std::swap(_data[index1], _data[index2]);
- key1.entry()->cachePinnedIndex(_filterId, index2 + 1);
- key2.entry()->cachePinnedIndex(_filterId, index1 + 1);
- }
- } // namespace Dialogs
|