Add class RecentDialogList.
This commit is contained in:
parent
5379c66acb
commit
5bec536803
@ -388,6 +388,7 @@ set(TDLIB_SOURCE
|
||||
td/telegram/PhotoSizeSource.cpp
|
||||
td/telegram/PollManager.cpp
|
||||
td/telegram/QueryCombiner.cpp
|
||||
td/telegram/RecentDialogList.cpp
|
||||
td/telegram/ReplyMarkup.cpp
|
||||
td/telegram/ReportReason.cpp
|
||||
td/telegram/RestrictionReason.cpp
|
||||
@ -596,6 +597,7 @@ set(TDLIB_SOURCE
|
||||
td/telegram/PtsManager.h
|
||||
td/telegram/PublicDialogType.h
|
||||
td/telegram/QueryCombiner.h
|
||||
td/telegram/RecentDialogList.h
|
||||
td/telegram/ReplyMarkup.h
|
||||
td/telegram/ReportReason.h
|
||||
td/telegram/RequestActor.h
|
||||
|
@ -5694,7 +5694,8 @@ MessagesManager::Dialog::~Dialog() {
|
||||
}
|
||||
}
|
||||
|
||||
MessagesManager::MessagesManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
|
||||
MessagesManager::MessagesManager(Td *td, ActorShared<> parent)
|
||||
: recently_found_dialogs_{td, "recently_found", MAX_RECENTLY_FOUND_DIALOGS}, td_(td), parent_(std::move(parent)) {
|
||||
upload_media_callback_ = std::make_shared<UploadMediaCallback>();
|
||||
upload_thumbnail_callback_ = std::make_shared<UploadThumbnailCallback>();
|
||||
upload_dialog_photo_callback_ = std::make_shared<UploadDialogPhotoCallback>();
|
||||
@ -10917,9 +10918,7 @@ void MessagesManager::on_dialog_deleted(DialogId dialog_id, Promise<Unit> &&prom
|
||||
d->is_empty = false;
|
||||
d->need_restore_reply_markup = true;
|
||||
}
|
||||
if (remove_recently_found_dialog_internal(dialog_id)) {
|
||||
save_recently_found_dialogs();
|
||||
}
|
||||
recently_found_dialogs_.remove_dialog(dialog_id);
|
||||
if (dialog_id.get_type() == DialogType::Channel) {
|
||||
G()->td_db()->get_binlog_pmc()->erase(get_channel_pts_key(dialog_id));
|
||||
}
|
||||
@ -16249,17 +16248,13 @@ std::pair<int32, vector<DialogId>> MessagesManager::search_dialogs(const string
|
||||
return {};
|
||||
}
|
||||
if (query.empty()) {
|
||||
if (!load_recently_found_dialogs(promise)) {
|
||||
if (!recently_found_dialogs_.load_dialogs(promise)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
promise.set_value(Unit());
|
||||
|
||||
update_recently_found_dialogs();
|
||||
|
||||
size_t result_size = min(static_cast<size_t>(limit), recently_found_dialog_ids_.size());
|
||||
return {narrow_cast<int32>(recently_found_dialog_ids_.size()),
|
||||
vector<DialogId>(recently_found_dialog_ids_.begin(), recently_found_dialog_ids_.begin() + result_size)};
|
||||
return recently_found_dialogs_.get_dialogs(limit);
|
||||
}
|
||||
|
||||
auto result = dialogs_hints_.search(query, limit);
|
||||
@ -24743,6 +24738,10 @@ bool MessagesManager::is_broadcast_channel(DialogId dialog_id) const {
|
||||
ContactsManager::ChannelType::Broadcast;
|
||||
}
|
||||
|
||||
bool MessagesManager::is_deleted_secret_chat(DialogId dialog_id) const {
|
||||
return is_deleted_secret_chat(get_dialog(dialog_id));
|
||||
}
|
||||
|
||||
bool MessagesManager::is_deleted_secret_chat(const Dialog *d) const {
|
||||
if (d == nullptr) {
|
||||
return true;
|
||||
@ -37306,213 +37305,24 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
|
||||
}
|
||||
}
|
||||
|
||||
void MessagesManager::save_recently_found_dialogs() {
|
||||
if (recently_found_dialogs_loaded_ < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
string value;
|
||||
for (auto &dialog_id : recently_found_dialog_ids_) {
|
||||
if (!value.empty()) {
|
||||
value += ',';
|
||||
}
|
||||
if (!G()->parameters().use_message_db) {
|
||||
// if there is no dialog database, prefer to save dialogs by username
|
||||
auto username = get_dialog_username(dialog_id);
|
||||
if (dialog_id.get_type() != DialogType::SecretChat && !username.empty()) {
|
||||
value += '@';
|
||||
value += username;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
value += to_string(dialog_id.get());
|
||||
}
|
||||
LOG(DEBUG) << "Save recently found chats " << value;
|
||||
G()->td_db()->get_binlog_pmc()->set("recently_found_dialog_usernames_and_ids", value);
|
||||
}
|
||||
|
||||
bool MessagesManager::load_recently_found_dialogs(Promise<Unit> &promise) {
|
||||
CHECK(!td_->auth_manager_->is_bot());
|
||||
if (recently_found_dialogs_loaded_ >= 2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string found_dialogs_str = G()->td_db()->get_binlog_pmc()->get("recently_found_dialog_usernames_and_ids");
|
||||
if (found_dialogs_str.empty()) {
|
||||
recently_found_dialogs_loaded_ = 2;
|
||||
if (!recently_found_dialog_ids_.empty()) {
|
||||
save_recently_found_dialogs();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "Loaded recently found chats " << found_dialogs_str;
|
||||
auto found_dialogs = full_split(found_dialogs_str, ',');
|
||||
if (recently_found_dialogs_loaded_ == 1 && resolve_recently_found_dialogs_multipromise_.promise_count() == 0) {
|
||||
// queries was sent and have already been finished
|
||||
auto newly_found_dialogs = std::move(recently_found_dialog_ids_);
|
||||
recently_found_dialog_ids_.clear();
|
||||
|
||||
for (auto it = found_dialogs.rbegin(); it != found_dialogs.rend(); ++it) {
|
||||
if ((*it)[0] == '@') {
|
||||
auto dialog_id = resolve_dialog_username(it->substr(1));
|
||||
if (dialog_id.is_valid() && have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
force_create_dialog(dialog_id, "recently found resolved dialog");
|
||||
add_recently_found_dialog_internal(dialog_id);
|
||||
}
|
||||
} else {
|
||||
auto dialog_id = DialogId(to_integer<int64>(*it));
|
||||
CHECK(dialog_id.is_valid());
|
||||
if (have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
force_create_dialog(dialog_id, "recently found dialog");
|
||||
add_recently_found_dialog_internal(dialog_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto it = newly_found_dialogs.rbegin(); it != newly_found_dialogs.rend(); ++it) {
|
||||
add_recently_found_dialog_internal(*it);
|
||||
}
|
||||
recently_found_dialogs_loaded_ = 2;
|
||||
if (!newly_found_dialogs.empty()) {
|
||||
save_recently_found_dialogs();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
resolve_recently_found_dialogs_multipromise_.add_promise(std::move(promise));
|
||||
if (recently_found_dialogs_loaded_ == 0) {
|
||||
recently_found_dialogs_loaded_ = 1;
|
||||
|
||||
resolve_recently_found_dialogs_multipromise_.set_ignore_errors(true);
|
||||
auto lock = resolve_recently_found_dialogs_multipromise_.get_promise();
|
||||
|
||||
for (auto &found_dialog : found_dialogs) {
|
||||
if (found_dialog[0] == '@') {
|
||||
search_public_dialog(found_dialog, false, resolve_recently_found_dialogs_multipromise_.get_promise());
|
||||
}
|
||||
}
|
||||
if (G()->parameters().use_message_db) {
|
||||
for (auto &found_dialog : found_dialogs) {
|
||||
if (found_dialog[0] != '@') {
|
||||
auto dialog_id = DialogId(to_integer<int64>(found_dialog));
|
||||
CHECK(dialog_id.is_valid());
|
||||
// TODO use asynchronous load
|
||||
// get_dialog(dialog_id, resolve_recently_found_dialogs_multipromise_.get_promise());
|
||||
get_dialog_force(dialog_id, "load_recently_found_dialogs");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
get_dialogs_from_list(DialogListId(FolderId::main()), MAX_GET_DIALOGS + 2,
|
||||
PromiseCreator::lambda(
|
||||
[promise = resolve_recently_found_dialogs_multipromise_.get_promise()](
|
||||
td_api::object_ptr<td_api::chats> &&chats) mutable { promise.set_value(Unit()); }));
|
||||
td_->contacts_manager_->search_contacts("", 1, resolve_recently_found_dialogs_multipromise_.get_promise());
|
||||
}
|
||||
|
||||
lock.set_value(Unit());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Status MessagesManager::add_recently_found_dialog(DialogId dialog_id) {
|
||||
if (!have_dialog_force(dialog_id, "add_recently_found_dialog")) {
|
||||
return Status::Error(5, "Chat not found");
|
||||
return Status::Error(400, "Chat not found");
|
||||
}
|
||||
if (add_recently_found_dialog_internal(dialog_id)) {
|
||||
save_recently_found_dialogs();
|
||||
}
|
||||
|
||||
recently_found_dialogs_.add_dialog(dialog_id);
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status MessagesManager::remove_recently_found_dialog(DialogId dialog_id) {
|
||||
if (!have_dialog_force(dialog_id, "remove_recently_found_dialog")) {
|
||||
return Status::Error(5, "Chat not found");
|
||||
return Status::Error(400, "Chat not found");
|
||||
}
|
||||
if (remove_recently_found_dialog_internal(dialog_id)) {
|
||||
save_recently_found_dialogs();
|
||||
}
|
||||
|
||||
recently_found_dialogs_.remove_dialog(dialog_id);
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
void MessagesManager::clear_recently_found_dialogs() {
|
||||
recently_found_dialogs_loaded_ = 2;
|
||||
if (recently_found_dialog_ids_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
recently_found_dialog_ids_.clear();
|
||||
save_recently_found_dialogs();
|
||||
}
|
||||
|
||||
bool MessagesManager::add_recently_found_dialog_internal(DialogId dialog_id) {
|
||||
CHECK(have_dialog(dialog_id));
|
||||
|
||||
if (!recently_found_dialog_ids_.empty() && recently_found_dialog_ids_[0] == dialog_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO create function
|
||||
auto it = std::find(recently_found_dialog_ids_.begin(), recently_found_dialog_ids_.end(), dialog_id);
|
||||
if (it == recently_found_dialog_ids_.end()) {
|
||||
if (narrow_cast<int32>(recently_found_dialog_ids_.size()) == MAX_RECENTLY_FOUND_DIALOGS) {
|
||||
CHECK(!recently_found_dialog_ids_.empty());
|
||||
recently_found_dialog_ids_.back() = dialog_id;
|
||||
} else {
|
||||
recently_found_dialog_ids_.push_back(dialog_id);
|
||||
}
|
||||
it = recently_found_dialog_ids_.end() - 1;
|
||||
}
|
||||
std::rotate(recently_found_dialog_ids_.begin(), it, it + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MessagesManager::remove_recently_found_dialog_internal(DialogId dialog_id) {
|
||||
CHECK(have_dialog(dialog_id));
|
||||
return td::remove(recently_found_dialog_ids_, dialog_id);
|
||||
}
|
||||
|
||||
void MessagesManager::update_recently_found_dialogs() {
|
||||
vector<DialogId> dialog_ids;
|
||||
for (auto dialog_id : recently_found_dialog_ids_) {
|
||||
const Dialog *d = get_dialog(dialog_id);
|
||||
if (d == nullptr) {
|
||||
continue;
|
||||
}
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::User:
|
||||
// always keep
|
||||
break;
|
||||
case DialogType::Chat: {
|
||||
auto channel_id = td_->contacts_manager_->get_chat_migrated_to_channel_id(dialog_id.get_chat_id());
|
||||
if (channel_id.is_valid() && get_dialog(DialogId(channel_id)) != nullptr) {
|
||||
dialog_id = DialogId(channel_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DialogType::Channel:
|
||||
// always keep
|
||||
break;
|
||||
case DialogType::SecretChat:
|
||||
if (is_deleted_secret_chat(d)) {
|
||||
dialog_id = DialogId();
|
||||
}
|
||||
break;
|
||||
case DialogType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
if (dialog_id.is_valid()) {
|
||||
dialog_ids.push_back(dialog_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (dialog_ids != recently_found_dialog_ids_) {
|
||||
recently_found_dialog_ids_ = std::move(dialog_ids);
|
||||
save_recently_found_dialogs();
|
||||
}
|
||||
recently_found_dialogs_.clear_dialogs();
|
||||
}
|
||||
|
||||
void MessagesManager::suffix_load_loop(Dialog *d) {
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "td/telegram/NotificationGroupType.h"
|
||||
#include "td/telegram/NotificationId.h"
|
||||
#include "td/telegram/NotificationSettings.h"
|
||||
#include "td/telegram/RecentDialogList.h"
|
||||
#include "td/telegram/ReplyMarkup.h"
|
||||
#include "td/telegram/ReportReason.h"
|
||||
#include "td/telegram/RestrictionReason.h"
|
||||
@ -575,6 +576,8 @@ class MessagesManager final : public Actor {
|
||||
|
||||
bool is_message_edited_recently(FullMessageId full_message_id, int32 seconds);
|
||||
|
||||
bool is_deleted_secret_chat(DialogId dialog_id) const;
|
||||
|
||||
Result<std::pair<string, bool>> get_message_link(FullMessageId full_message_id, int32 media_timestamp, bool for_group,
|
||||
bool for_comment);
|
||||
|
||||
@ -2959,16 +2962,6 @@ class MessagesManager final : public Actor {
|
||||
|
||||
static MessageId get_next_yet_unsent_scheduled_message_id(Dialog *d, int32 date);
|
||||
|
||||
bool add_recently_found_dialog_internal(DialogId dialog_id);
|
||||
|
||||
bool remove_recently_found_dialog_internal(DialogId dialog_id);
|
||||
|
||||
void update_recently_found_dialogs();
|
||||
|
||||
void save_recently_found_dialogs();
|
||||
|
||||
bool load_recently_found_dialogs(Promise<Unit> &promise);
|
||||
|
||||
void reget_message_from_server_if_needed(DialogId dialog_id, const Message *m);
|
||||
|
||||
void speculatively_update_active_group_call_id(Dialog *d, const Message *m);
|
||||
@ -3063,10 +3056,7 @@ class MessagesManager final : public Actor {
|
||||
|
||||
static DialogId get_message_original_sender(const Message *m);
|
||||
|
||||
int32 recently_found_dialogs_loaded_ = 0; // 0 - not loaded, 1 - load request was sent, 2 - loaded
|
||||
MultiPromiseActor resolve_recently_found_dialogs_multipromise_{"ResolveRecentlyFoundDialogsMultiPromiseActor"};
|
||||
|
||||
vector<DialogId> recently_found_dialog_ids_;
|
||||
RecentDialogList recently_found_dialogs_;
|
||||
|
||||
class UploadMediaCallback;
|
||||
class UploadThumbnailCallback;
|
||||
|
243
td/telegram/RecentDialogList.cpp
Normal file
243
td/telegram/RecentDialogList.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#include "td/telegram/RecentDialogList.h"
|
||||
|
||||
#include "td/telegram/ContactsManager.h"
|
||||
#include "td/telegram/Global.h"
|
||||
#include "td/telegram/MessagesManager.h"
|
||||
#include "td/telegram/Td.h"
|
||||
#include "td/telegram/TdDb.h"
|
||||
#include "td/telegram/TdParameters.h"
|
||||
|
||||
#include "td/utils/algorithm.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/SliceBuilder.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
RecentDialogList::RecentDialogList(Td *td, const char *name, size_t max_size)
|
||||
: td_(td), name_(name), max_size_(max_size) {
|
||||
}
|
||||
|
||||
string RecentDialogList::get_binlog_key() const {
|
||||
return PSTRING() << name_ << "_dialog_usernames_and_ids";
|
||||
}
|
||||
|
||||
void RecentDialogList::save_dialogs() {
|
||||
if (dialogs_loaded_ < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
string value;
|
||||
for (auto &dialog_id : dialog_ids_) {
|
||||
if (!value.empty()) {
|
||||
value += ',';
|
||||
}
|
||||
if (!G()->parameters().use_message_db) {
|
||||
// if there is no dialog database, prefer to save dialogs by username
|
||||
string username;
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::User:
|
||||
username = td_->contacts_manager_->get_user_username(dialog_id.get_user_id());
|
||||
break;
|
||||
case DialogType::Chat:
|
||||
break;
|
||||
case DialogType::Channel:
|
||||
username = td_->contacts_manager_->get_channel_username(dialog_id.get_channel_id());
|
||||
break;
|
||||
case DialogType::SecretChat:
|
||||
break;
|
||||
case DialogType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (!username.empty()) {
|
||||
value += '@';
|
||||
value += username;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
value += to_string(dialog_id.get());
|
||||
}
|
||||
G()->td_db()->get_binlog_pmc()->set(get_binlog_key(), value);
|
||||
}
|
||||
|
||||
bool RecentDialogList::load_dialogs(Promise<Unit> &promise) {
|
||||
if (dialogs_loaded_ >= 2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string found_dialogs_str = G()->td_db()->get_binlog_pmc()->get(get_binlog_key());
|
||||
if (found_dialogs_str.empty()) {
|
||||
dialogs_loaded_ = 2;
|
||||
if (!dialog_ids_.empty()) {
|
||||
save_dialogs();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
auto found_dialogs = full_split(found_dialogs_str, ',');
|
||||
if (dialogs_loaded_ == 1 && resolve_dialogs_multipromise_.promise_count() == 0) {
|
||||
// queries was sent and have already been finished
|
||||
auto newly_found_dialogs = std::move(dialog_ids_);
|
||||
dialog_ids_.clear();
|
||||
|
||||
for (auto it = found_dialogs.rbegin(); it != found_dialogs.rend(); ++it) {
|
||||
if ((*it)[0] == '@') {
|
||||
auto dialog_id = td_->messages_manager_->resolve_dialog_username(it->substr(1));
|
||||
if (dialog_id.is_valid() && td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
td_->messages_manager_->force_create_dialog(dialog_id, "resolved recent dialog");
|
||||
do_add_dialog(dialog_id);
|
||||
}
|
||||
} else {
|
||||
auto dialog_id = DialogId(to_integer<int64>(*it));
|
||||
CHECK(dialog_id.is_valid());
|
||||
if (td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) {
|
||||
td_->messages_manager_->force_create_dialog(dialog_id, "recent dialog");
|
||||
do_add_dialog(dialog_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto it = newly_found_dialogs.rbegin(); it != newly_found_dialogs.rend(); ++it) {
|
||||
do_add_dialog(*it);
|
||||
}
|
||||
dialogs_loaded_ = 2;
|
||||
if (!newly_found_dialogs.empty()) {
|
||||
save_dialogs();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
resolve_dialogs_multipromise_.add_promise(std::move(promise));
|
||||
if (dialogs_loaded_ == 0) {
|
||||
dialogs_loaded_ = 1;
|
||||
|
||||
resolve_dialogs_multipromise_.set_ignore_errors(true);
|
||||
auto lock = resolve_dialogs_multipromise_.get_promise();
|
||||
|
||||
for (auto &found_dialog : found_dialogs) {
|
||||
if (found_dialog[0] == '@') {
|
||||
td_->messages_manager_->search_public_dialog(found_dialog, false, resolve_dialogs_multipromise_.get_promise());
|
||||
}
|
||||
}
|
||||
if (G()->parameters().use_message_db) {
|
||||
for (auto &found_dialog : found_dialogs) {
|
||||
if (found_dialog[0] != '@') {
|
||||
auto dialog_id = DialogId(to_integer<int64>(found_dialog));
|
||||
CHECK(dialog_id.is_valid());
|
||||
// TODO use asynchronous load
|
||||
// get_dialog(dialog_id, resolve_dialogs_multipromise_.get_promise());
|
||||
td_->messages_manager_->have_dialog_force(dialog_id, "RecentDialogList::load_dialogs");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
td_->messages_manager_->get_dialogs_from_list(
|
||||
DialogListId(FolderId::main()), 102,
|
||||
PromiseCreator::lambda(
|
||||
[promise = resolve_dialogs_multipromise_.get_promise()](
|
||||
td_api::object_ptr<td_api::chats> &&chats) mutable { promise.set_value(Unit()); }));
|
||||
td_->contacts_manager_->search_contacts("", 1, resolve_dialogs_multipromise_.get_promise());
|
||||
}
|
||||
|
||||
lock.set_value(Unit());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RecentDialogList::add_dialog(DialogId dialog_id) {
|
||||
if (do_add_dialog(dialog_id)) {
|
||||
save_dialogs();
|
||||
}
|
||||
}
|
||||
|
||||
bool RecentDialogList::do_add_dialog(DialogId dialog_id) {
|
||||
if (!dialog_ids_.empty() && dialog_ids_[0] == dialog_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO create function
|
||||
auto it = std::find(dialog_ids_.begin(), dialog_ids_.end(), dialog_id);
|
||||
if (it == dialog_ids_.end()) {
|
||||
if (dialog_ids_.size() == max_size_) {
|
||||
CHECK(!dialog_ids_.empty());
|
||||
dialog_ids_.back() = dialog_id;
|
||||
} else {
|
||||
dialog_ids_.push_back(dialog_id);
|
||||
}
|
||||
it = dialog_ids_.end() - 1;
|
||||
}
|
||||
std::rotate(dialog_ids_.begin(), it, it + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RecentDialogList::remove_dialog(DialogId dialog_id) {
|
||||
if (td::remove(dialog_ids_, dialog_id)) {
|
||||
save_dialogs();
|
||||
}
|
||||
}
|
||||
|
||||
void RecentDialogList::update_dialogs() {
|
||||
vector<DialogId> dialog_ids;
|
||||
for (auto dialog_id : dialog_ids_) {
|
||||
if (!td_->messages_manager_->have_dialog(dialog_id)) {
|
||||
continue;
|
||||
}
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::User:
|
||||
// always keep
|
||||
break;
|
||||
case DialogType::Chat: {
|
||||
auto channel_id = td_->contacts_manager_->get_chat_migrated_to_channel_id(dialog_id.get_chat_id());
|
||||
if (channel_id.is_valid() && td_->messages_manager_->have_dialog(DialogId(channel_id))) {
|
||||
dialog_id = DialogId(channel_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DialogType::Channel:
|
||||
// always keep
|
||||
break;
|
||||
case DialogType::SecretChat:
|
||||
if (td_->messages_manager_->is_deleted_secret_chat(dialog_id)) {
|
||||
dialog_id = DialogId();
|
||||
}
|
||||
break;
|
||||
case DialogType::None:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
if (dialog_id.is_valid()) {
|
||||
dialog_ids.push_back(dialog_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (dialog_ids != dialog_ids_) {
|
||||
dialog_ids_ = std::move(dialog_ids);
|
||||
save_dialogs();
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<int32, vector<DialogId>> RecentDialogList::get_dialogs(int32 limit) {
|
||||
CHECK(dialogs_loaded_ == 2);
|
||||
update_dialogs();
|
||||
|
||||
size_t result_size = min(static_cast<size_t>(limit), dialog_ids_.size());
|
||||
return {narrow_cast<int32>(dialog_ids_.size()),
|
||||
vector<DialogId>(dialog_ids_.begin(), dialog_ids_.begin() + result_size)};
|
||||
}
|
||||
|
||||
void RecentDialogList::clear_dialogs() {
|
||||
if (dialog_ids_.empty() && dialogs_loaded_ == 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
dialogs_loaded_ = 2;
|
||||
dialog_ids_.clear();
|
||||
save_dialogs();
|
||||
}
|
||||
|
||||
} // namespace td
|
54
td/telegram/RecentDialogList.h
Normal file
54
td/telegram/RecentDialogList.h
Normal file
@ -0,0 +1,54 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/telegram/DialogId.h"
|
||||
|
||||
#include "td/actor/MultiPromise.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace td {
|
||||
|
||||
class Td;
|
||||
|
||||
// stores list of Dialog identifiers of a limited size
|
||||
class RecentDialogList : public Actor {
|
||||
public:
|
||||
RecentDialogList(Td *td, const char *name, size_t max_size);
|
||||
|
||||
void add_dialog(DialogId dialog_id);
|
||||
|
||||
void remove_dialog(DialogId dialog_id);
|
||||
|
||||
bool load_dialogs(Promise<Unit> &promise);
|
||||
|
||||
std::pair<int32, vector<DialogId>> get_dialogs(int32 limit);
|
||||
|
||||
void clear_dialogs();
|
||||
|
||||
private:
|
||||
Td *td_;
|
||||
const char *name_;
|
||||
size_t max_size_;
|
||||
vector<DialogId> dialog_ids_;
|
||||
|
||||
int32 dialogs_loaded_ = 0; // 0 - not loaded, 1 - load request was sent, 2 - loaded
|
||||
MultiPromiseActor resolve_dialogs_multipromise_{"ResolveDialogsMultiPromiseActor"};
|
||||
|
||||
bool do_add_dialog(DialogId dialog_id);
|
||||
|
||||
string get_binlog_key() const;
|
||||
|
||||
void update_dialogs();
|
||||
|
||||
void save_dialogs();
|
||||
};
|
||||
|
||||
} // namespace td
|
Loading…
Reference in New Issue
Block a user