init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
164
Telegram/SourceFiles/dialogs/dialogs_pinned_list.cpp
Normal file
164
Telegram/SourceFiles/dialogs/dialogs_pinned_list.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
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
|
||||
Reference in New Issue
Block a user