Save pinned chats in filters to server.

This commit is contained in:
John Preston 2020-03-17 18:52:01 +04:00
parent e27a8fe058
commit 55900bbd3d
13 changed files with 112 additions and 79 deletions

View File

@ -134,6 +134,8 @@ nice_target_sources(Telegram ${src_loc}
PRIVATE PRIVATE
${style_files} ${style_files}
api/api_chat_filters.cpp
api/api_chat_filters.h
api/api_common.h api/api_common.h
api/api_hash.h api/api_hash.h
api/api_self_destruct.cpp api/api_self_destruct.cpp

View File

@ -0,0 +1,35 @@
/*
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 "api/api_chat_filters.h"
#include "data/data_session.h"
#include "data/data_chat_filters.h"
#include "main/main_session.h"
#include "apiwrap.h"
namespace Api {
void SaveNewFilterPinned(
not_null<Main::Session*> session,
FilterId filterId) {
const auto &order = session->data().pinnedChatsOrder(
nullptr,
filterId);
auto &filters = session->data().chatsFilters();
const auto &filter = filters.applyUpdatedPinned(
filterId,
order);
session->api().request(MTPmessages_UpdateDialogFilter(
MTP_flags(MTPmessages_UpdateDialogFilter::Flag::f_filter),
MTP_int(filterId),
filter.tl()
)).send();
}
} // namespace Api

View File

@ -0,0 +1,18 @@
/*
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
*/
#pragma once
namespace Main {
class Session;
} // namespace Main
namespace Api {
void SaveNewFilterPinned(not_null<Main::Session*> session, FilterId filterId);
} // namespace Api

View File

@ -343,9 +343,6 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) {
const auto feedHistory = [&](not_null<History*> history) { const auto feedHistory = [&](not_null<History*> history) {
const auto now = updated.contains(history); const auto now = updated.contains(history);
const auto was = filter.contains(history); const auto was = filter.contains(history);
if (now) {
history->applyFilterPinnedIndex(id, updated);
}
if (now != was) { if (now != was) {
if (now) { if (now) {
history->addToChatList(id, filterList); history->addToChatList(id, filterList);
@ -365,7 +362,8 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) {
if (const auto folder = _owner->folderLoaded(Data::Folder::kId)) { if (const auto folder = _owner->folderLoaded(Data::Folder::kId)) {
feedList(folder->chatsList()); feedList(folder->chatsList());
} }
} else if (pinnedChanged) { }
if (pinnedChanged) {
const auto id = filter.id(); const auto id = filter.id();
const auto filterList = _owner->chatsFilters().chatsList(id); const auto filterList = _owner->chatsFilters().chatsList(id);
filterList->pinned()->applyList(updated.pinned()); filterList->pinned()->applyList(updated.pinned());
@ -412,6 +410,35 @@ bool ChatFilters::applyOrder(const QVector<MTPint> &order) {
return true; return true;
} }
const ChatFilter &ChatFilters::applyUpdatedPinned(
FilterId id,
const std::vector<Dialogs::Key> &dialogs) {
const auto i = ranges::find(_list, id, &ChatFilter::id);
Assert(i != end(_list));
auto always = i->always();
auto pinned = std::vector<not_null<History*>>();
pinned.reserve(dialogs.size());
for (const auto &row : dialogs) {
if (const auto history = row.history()) {
if (always.contains(history)) {
pinned.push_back(history);
} else if (always.size() < ChatFilter::kPinnedLimit) {
always.insert(history);
pinned.push_back(history);
}
}
}
set(ChatFilter(
id,
i->title(),
i->flags(),
std::move(always),
std::move(pinned),
i->never()));
return *i;
}
const std::vector<ChatFilter> &ChatFilters::list() const { const std::vector<ChatFilter> &ChatFilters::list() const {
return _list; return _list;
} }

View File

@ -13,6 +13,7 @@ class History;
namespace Dialogs { namespace Dialogs {
class MainList; class MainList;
class Key;
} // namespace Dialogs } // namespace Dialogs
namespace Data { namespace Data {
@ -34,7 +35,7 @@ public:
friend constexpr inline bool is_flag_type(Flag) { return true; }; friend constexpr inline bool is_flag_type(Flag) { return true; };
using Flags = base::flags<Flag>; using Flags = base::flags<Flag>;
static constexpr int kPinnedLimit = 100; static constexpr int kPinnedLimit = 10;
ChatFilter() = default; ChatFilter() = default;
ChatFilter( ChatFilter(
@ -98,6 +99,10 @@ public:
[[nodiscard]] not_null<Dialogs::MainList*> chatsList(FilterId filterId); [[nodiscard]] not_null<Dialogs::MainList*> chatsList(FilterId filterId);
const ChatFilter &applyUpdatedPinned(
FilterId id,
const std::vector<Dialogs::Key> &dialogs);
private: private:
void load(bool force); void load(bool force);
bool applyOrder(const QVector<MTPint> &order); bool applyOrder(const QVector<MTPint> &order);

View File

@ -1570,11 +1570,16 @@ int Session::pinnedChatsCount(
int Session::pinnedChatsLimit( int Session::pinnedChatsLimit(
Data::Folder *folder, Data::Folder *folder,
FilterId filterId) const { FilterId filterId) const {
return filterId if (!filterId) {
? Data::ChatFilter::kPinnedLimit return folder
: folder ? Global::PinnedDialogsInFolderMax()
? Global::PinnedDialogsInFolderMax() : Global::PinnedDialogsCountMax();
: Global::PinnedDialogsCountMax(); }
const auto &list = chatsFilters().list();
const auto i = ranges::find(list, filterId, &Data::ChatFilter::id);
const auto pinned = (i != end(list)) ? i->pinned().size() : 0;
const auto already = (i != end(list)) ? i->always().size() : 0;
return Data::ChatFilter::kPinnedLimit + pinned - already;
} }
const std::vector<Dialogs::Key> &Session::pinnedChatsOrder( const std::vector<Dialogs::Key> &Session::pinnedChatsOrder(
@ -3375,7 +3380,6 @@ auto Session::refreshChatListEntry(
const auto filterList = chatsFilters().chatsList(id); const auto filterList = chatsFilters().chatsList(id);
auto filterResult = RefreshChatListEntryResult(); auto filterResult = RefreshChatListEntryResult();
if (filter.contains(history)) { if (filter.contains(history)) {
history->applyFilterPinnedIndex(id, filter);
filterResult.changed = !entry->inChatList(id); filterResult.changed = !entry->inChatList(id);
if (filterResult.changed) { if (filterResult.changed) {
entry->addToChatList(id, filterList); entry->addToChatList(id, filterList);

View File

@ -235,9 +235,6 @@ void Entry::removeFromChatList(
return; return;
} }
_chatListLinks.erase(i); _chatListLinks.erase(i);
if (isPinnedDialog(filterId)) {
owner().setChatPinned(_key, filterId, false);
}
list->removeEntry(_key); list->removeEntry(_key);
} }

View File

@ -44,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/multi_select.h" #include "ui/widgets/multi_select.h"
#include "ui/empty_userpic.h" #include "ui/empty_userpic.h"
#include "ui/unread_badge.h" #include "ui/unread_badge.h"
#include "api/api_chat_filters.h"
#include "facades.h" #include "facades.h"
#include "styles/style_dialogs.h" #include "styles/style_dialogs.h"
#include "styles/style_chat_helpers.h" #include "styles/style_chat_helpers.h"
@ -1137,7 +1138,7 @@ void InnerWidget::savePinnedOrder() {
} }
} }
if (_filterId) { if (_filterId) {
// #TODO pinned reorder data and to server Api::SaveNewFilterPinned(&session(), _filterId);
} else { } else {
session().api().savePinnedOrder(_openedFolder); session().api().savePinnedOrder(_openedFolder);
} }

View File

@ -70,21 +70,6 @@ void PinnedList::setPinned(const Key &key, bool pinned) {
} }
} }
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) { void PinnedList::applyLimit(int limit) {
Expects(limit >= 0); Expects(limit >= 0);
@ -120,10 +105,8 @@ void PinnedList::applyList(const std::vector<not_null<History*>> &list) {
_data.reserve(count); _data.reserve(count);
for (auto i = 0; i != count; ++i) { for (auto i = 0; i != count; ++i) {
const auto history = list[i]; const auto history = list[i];
if (history->inChatList()) { _data.emplace_back(history);
_data.emplace_back(history); history->cachePinnedIndex(_filterId, i + 1);
history->cachePinnedIndex(_filterId, i + 1);
}
} }
} }

View File

@ -30,11 +30,6 @@ public:
// if (pinned) places on the first place in the list. // if (pinned) places on the first place in the list.
void setPinned(const Key &key, bool pinned); void setPinned(const Key &key, bool pinned);
void applyFilterPinned(
FilterId filterId,
not_null<History*> history,
int index);
void clear(); void clear();
void applyList( void applyList(

View File

@ -1921,6 +1921,9 @@ void History::setFolderPointer(Data::Folder *folder) {
if (_folder == folder) { if (_folder == folder) {
return; return;
} }
if (isPinnedDialog(FilterId())) {
owner().setChatPinned(this, FilterId(), false);
}
auto &filters = owner().chatsFilters(); auto &filters = owner().chatsFilters();
const auto wasKnown = folderKnown(); const auto wasKnown = folderKnown();
const auto wasInList = inChatList(); const auto wasInList = inChatList();
@ -1943,7 +1946,6 @@ void History::setFolderPointer(Data::Folder *folder) {
for (const auto &filter : filters.list()) { for (const auto &filter : filters.list()) {
if (filter.contains(this)) { if (filter.contains(this)) {
const auto id = filter.id(); const auto id = filter.id();
applyFilterPinnedIndex(id, filter);
addToChatList(id, filters.chatsList(id)); addToChatList(id, filters.chatsList(id));
} }
} }
@ -1957,24 +1959,6 @@ void History::setFolderPointer(Data::Folder *folder) {
} }
} }
void History::applyFilterPinnedIndex(
FilterId filterId,
const Data::ChatFilter &filter) {
const auto &pinned = filter.pinned();
const auto i = ranges::find(pinned, this);
if (i == end(pinned)) {
return;
}
const auto index = (i - begin(pinned)) + 1;
if (index == lookupPinnedIndex(filterId)) {
return;
}
owner().chatsFilters().chatsList(filterId)->pinned()->applyFilterPinned(
filterId,
this,
index);
}
void History::applyPinnedUpdate(const MTPDupdateDialogPinned &data) { void History::applyPinnedUpdate(const MTPDupdateDialogPinned &data) {
const auto folderId = data.vfolder_id().value_or_empty(); const auto folderId = data.vfolder_id().value_or_empty();
if (!folderKnown()) { if (!folderKnown()) {

View File

@ -369,10 +369,6 @@ public:
HistoryItem *folderDialogItem = nullptr); HistoryItem *folderDialogItem = nullptr);
void clearFolder(); void clearFolder();
void applyFilterPinnedIndex(
FilterId filterId,
const Data::ChatFilter &filter);
// Interface for Data::Histories. // Interface for Data::Histories.
void setInboxReadTill(MsgId upTo); void setInboxReadTill(MsgId upTo);
std::optional<int> countStillUnreadLocal(MsgId readTillId) const; std::optional<int> countStillUnreadLocal(MsgId readTillId) const;

View File

@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwindow.h" #include "mainwindow.h"
#include "observer_peer.h" #include "observer_peer.h"
#include "api/api_common.h" #include "api/api_common.h"
#include "api/api_chat_filters.h"
#include "history/history.h" #include "history/history.h"
#include "history/history_item.h" #include "history/history_item.h"
#include "history/history_message.h" // GetErrorTextForSending. #include "history/history_message.h" // GetErrorTextForSending.
@ -45,6 +46,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_scheduled_messages.h" #include "data/data_scheduled_messages.h"
#include "data/data_histories.h" #include "data/data_histories.h"
#include "data/data_chat_filters.h"
#include "dialogs/dialogs_key.h" #include "dialogs/dialogs_key.h"
#include "boxes/peers/edit_peer_info_box.h" #include "boxes/peers/edit_peer_info_box.h"
#include "facades.h" #include "facades.h"
@ -208,23 +210,7 @@ void TogglePinnedDialog(Dialogs::Key key, FilterId filterId) {
} }
owner->setChatPinned(key, filterId, isPinned); owner->setChatPinned(key, filterId, isPinned);
// #TODO pinned save data and to server Api::SaveNewFilterPinned(&owner->session(), filterId);
//const auto flags = isPinned
// ? MTPmessages_ToggleDialogPin::Flag::f_pinned
// : MTPmessages_ToggleDialogPin::Flag(0);
//if (const auto history = key.history()) {
// history->session().api().request(MTPmessages_ToggleDialogPin(
// MTP_flags(flags),
// MTP_inputDialogPeer(key.history()->peer->input)
// )).done([=](const MTPBool &result) {
// owner->notifyPinnedDialogsOrderUpdated();
// }).send();
//} else if (const auto folder = key.folder()) {
// folder->session().api().request(MTPmessages_ToggleDialogPin(
// MTP_flags(flags),
// MTP_inputDialogPeerFolder(MTP_int(folder->id()))
// )).send();
//}
if (isPinned) { if (isPinned) {
if (const auto main = App::main()) { if (const auto main = App::main()) {
main->dialogsToUp(); main->dialogsToUp();