Store server dialog filters separately.
GitOrigin-RevId: 30c0da52c254008ab17e3be0b6707cd0678a87ec
This commit is contained in:
parent
8bb76ff0e9
commit
d85dd48101
@ -5011,18 +5011,22 @@ void MessagesManager::DialogFilter::parse(ParserT &parser) {
|
|||||||
class MessagesManager::DialogFiltersLogEvent {
|
class MessagesManager::DialogFiltersLogEvent {
|
||||||
public:
|
public:
|
||||||
int32 updated_date = 0;
|
int32 updated_date = 0;
|
||||||
|
const vector<unique_ptr<DialogFilter>> *server_dialog_filters_in;
|
||||||
const vector<unique_ptr<DialogFilter>> *dialog_filters_in;
|
const vector<unique_ptr<DialogFilter>> *dialog_filters_in;
|
||||||
|
vector<unique_ptr<DialogFilter>> server_dialog_filters_out;
|
||||||
vector<unique_ptr<DialogFilter>> dialog_filters_out;
|
vector<unique_ptr<DialogFilter>> dialog_filters_out;
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
void store(StorerT &storer) const {
|
void store(StorerT &storer) const {
|
||||||
td::store(updated_date, storer);
|
td::store(updated_date, storer);
|
||||||
|
td::store(*server_dialog_filters_in, storer);
|
||||||
td::store(*dialog_filters_in, storer);
|
td::store(*dialog_filters_in, storer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
void parse(ParserT &parser) {
|
void parse(ParserT &parser) {
|
||||||
td::parse(updated_date, parser);
|
td::parse(updated_date, parser);
|
||||||
|
td::parse(server_dialog_filters_out, parser);
|
||||||
td::parse(dialog_filters_out, parser);
|
td::parse(dialog_filters_out, parser);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -10966,10 +10970,15 @@ void MessagesManager::init() {
|
|||||||
auto dialog_filters = G()->td_db()->get_binlog_pmc()->get("dialog_filters");
|
auto dialog_filters = G()->td_db()->get_binlog_pmc()->get("dialog_filters");
|
||||||
if (!dialog_filters.empty()) {
|
if (!dialog_filters.empty()) {
|
||||||
DialogFiltersLogEvent log_event;
|
DialogFiltersLogEvent log_event;
|
||||||
log_event_parse(log_event, dialog_filters).ensure();
|
if (log_event_parse(log_event, dialog_filters).is_ok()) {
|
||||||
|
dialog_filters_updated_date_ = log_event.updated_date;
|
||||||
dialog_filters_updated_date_ = log_event.updated_date;
|
server_dialog_filters_ = std::move(log_event.server_dialog_filters_out);
|
||||||
dialog_filters_ = std::move(log_event.dialog_filters_out);
|
for (auto &dialog_filter : log_event.dialog_filters_out) {
|
||||||
|
add_dialog_filter(std::move(dialog_filter), "binlog");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Failed to parse chat filters from binlog";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
send_update_chat_filters(true); // always send updateChatFilters
|
send_update_chat_filters(true); // always send updateChatFilters
|
||||||
|
|
||||||
@ -14240,22 +14249,77 @@ void MessagesManager::on_get_dialog_filters(Result<vector<tl_object_ptr<telegram
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto filters = r_filters.move_as_ok();
|
auto filters = r_filters.move_as_ok();
|
||||||
vector<unique_ptr<DialogFilter>> dialog_filters;
|
vector<unique_ptr<DialogFilter>> new_server_dialog_filters;
|
||||||
LOG(INFO) << "Receive " << filters.size() << " chat filters";
|
LOG(INFO) << "Receive " << filters.size() << " chat filters";
|
||||||
|
std::unordered_set<DialogFilterId, DialogFilterIdHash> new_dialog_filter_ids;
|
||||||
for (auto &filter : filters) {
|
for (auto &filter : filters) {
|
||||||
auto dialog_filter = DialogFilter::get_dialog_filter(std::move(filter), true);
|
auto dialog_filter = DialogFilter::get_dialog_filter(std::move(filter), true);
|
||||||
if (dialog_filter == nullptr) {
|
if (dialog_filter == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!new_dialog_filter_ids.insert(dialog_filter->dialog_filter_id).second) {
|
||||||
|
LOG(ERROR) << "Receive duplicate " << dialog_filter->dialog_filter_id;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO add secret chats to the filter
|
new_server_dialog_filters.push_back(std::move(dialog_filter));
|
||||||
dialog_filters.push_back(std::move(dialog_filter));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog_filters_updated_date_ = G()->unix_time();
|
dialog_filters_updated_date_ = G()->unix_time();
|
||||||
if (dialog_filters_ != dialog_filters) {
|
if (server_dialog_filters_ != new_server_dialog_filters) {
|
||||||
// TODO update all changed chat lists and their unread counts
|
std::unordered_map<DialogFilterId, const DialogFilter *, DialogFilterIdHash> old_server_dialog_filters;
|
||||||
dialog_filters_ = std::move(dialog_filters);
|
for (auto &filter : server_dialog_filters_) {
|
||||||
|
old_server_dialog_filters.emplace(filter->dialog_filter_id, filter.get());
|
||||||
|
}
|
||||||
|
for (auto &new_server_filter : new_server_dialog_filters) {
|
||||||
|
auto dialog_filter_id = new_server_filter->dialog_filter_id;
|
||||||
|
auto old_filter = get_dialog_filter(dialog_filter_id);
|
||||||
|
auto it = old_server_dialog_filters.find(dialog_filter_id);
|
||||||
|
if (it != old_server_dialog_filters.end()) {
|
||||||
|
auto old_server_filter = it->second;
|
||||||
|
if (*new_server_filter != *old_server_filter) {
|
||||||
|
if (old_filter == nullptr) {
|
||||||
|
// the filter was deleted, don't need to edit it
|
||||||
|
} else if (*old_filter == *new_server_filter) {
|
||||||
|
// the filter was edited from this client, nothing to do
|
||||||
|
} else if (*old_filter == *old_server_filter) {
|
||||||
|
// the filter was edited only from another client
|
||||||
|
edit_dialog_filter(make_unique<DialogFilter>(*new_server_filter), "on_get_dialog_filters 1");
|
||||||
|
} else {
|
||||||
|
// the filter was edited both locally and remotely
|
||||||
|
// TODO merge local and remote changes
|
||||||
|
edit_dialog_filter(make_unique<DialogFilter>(*new_server_filter), "on_get_dialog_filters 2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
old_server_dialog_filters.erase(it);
|
||||||
|
} else {
|
||||||
|
if (old_filter == nullptr) {
|
||||||
|
// the filter was added from another client
|
||||||
|
add_dialog_filter(make_unique<DialogFilter>(*new_server_filter), "on_get_dialog_filters");
|
||||||
|
} else if (*old_filter == *new_server_filter) {
|
||||||
|
// the filter was added from that client, nothing to do
|
||||||
|
} else {
|
||||||
|
// the filter was added from two different client simultaneously,
|
||||||
|
// or it was added and edited from that client
|
||||||
|
// prefer local value, so do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto &old_server_filter : old_server_dialog_filters) {
|
||||||
|
auto dialog_filter_id = old_server_filter.first;
|
||||||
|
// deleted filter
|
||||||
|
auto old_filter = get_dialog_filter(dialog_filter_id);
|
||||||
|
if (old_filter == nullptr) {
|
||||||
|
// the filter was deleted from this client, nothing to do
|
||||||
|
} else {
|
||||||
|
// the filter was deleted from another client
|
||||||
|
// ignore edits done from the current client and just delete the filter
|
||||||
|
delete_dialog_filter(dialog_filter_id, "on_get_dialog_filters");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO update dialog filter order
|
||||||
|
server_dialog_filters_ = std::move(new_server_dialog_filters);
|
||||||
send_update_chat_filters(false);
|
send_update_chat_filters(false);
|
||||||
}
|
}
|
||||||
schedule_dialog_filters_reload(DIALOG_FILTERS_CACHE_TIME * 0.0001 * Random::fast(9000, 11000));
|
schedule_dialog_filters_reload(DIALOG_FILTERS_CACHE_TIME * 0.0001 * Random::fast(9000, 11000));
|
||||||
@ -15262,7 +15326,7 @@ void MessagesManager::create_dialog_filter(td_api::object_ptr<td_api::chatFilter
|
|||||||
auto min_id = static_cast<int>(DialogFilterId::min().get());
|
auto min_id = static_cast<int>(DialogFilterId::min().get());
|
||||||
auto max_id = static_cast<int>(DialogFilterId::max().get());
|
auto max_id = static_cast<int>(DialogFilterId::max().get());
|
||||||
dialog_filter_id = DialogFilterId(static_cast<int32>(Random::fast(min_id, max_id)));
|
dialog_filter_id = DialogFilterId(static_cast<int32>(Random::fast(min_id, max_id)));
|
||||||
} while (get_dialog_filter(dialog_filter_id) != nullptr);
|
} while (get_dialog_filter(dialog_filter_id) != nullptr || get_server_dialog_filter(dialog_filter_id) != nullptr);
|
||||||
|
|
||||||
auto r_dialog_filter = create_dialog_filter(dialog_filter_id, std::move(filter));
|
auto r_dialog_filter = create_dialog_filter(dialog_filter_id, std::move(filter));
|
||||||
if (r_dialog_filter.is_error()) {
|
if (r_dialog_filter.is_error()) {
|
||||||
@ -15272,8 +15336,9 @@ void MessagesManager::create_dialog_filter(td_api::object_ptr<td_api::chatFilter
|
|||||||
CHECK(dialog_filter != nullptr);
|
CHECK(dialog_filter != nullptr);
|
||||||
auto input_dialog_filter = dialog_filter->get_input_dialog_filter();
|
auto input_dialog_filter = dialog_filter->get_input_dialog_filter();
|
||||||
|
|
||||||
// TODO logevent
|
add_dialog_filter(make_unique<DialogFilter>(*dialog_filter), "create_dialog_filter");
|
||||||
// TODO add dialog filter locally
|
send_update_chat_filters(false);
|
||||||
|
|
||||||
// TODO SequenceDispatcher
|
// TODO SequenceDispatcher
|
||||||
auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_filter = std::move(dialog_filter),
|
auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_filter = std::move(dialog_filter),
|
||||||
promise = std::move(promise)](Result<Unit> result) mutable {
|
promise = std::move(promise)](Result<Unit> result) mutable {
|
||||||
@ -15305,8 +15370,9 @@ void MessagesManager::edit_dialog_filter(DialogFilterId dialog_filter_id, td_api
|
|||||||
|
|
||||||
auto input_dialog_filter = new_dialog_filter->get_input_dialog_filter();
|
auto input_dialog_filter = new_dialog_filter->get_input_dialog_filter();
|
||||||
|
|
||||||
// TODO logevent
|
edit_dialog_filter(make_unique<DialogFilter>(*new_dialog_filter), "edit_dialog_filter");
|
||||||
// TODO edit dialog filter locally
|
send_update_chat_filters(false);
|
||||||
|
|
||||||
// TODO SequenceDispatcher
|
// TODO SequenceDispatcher
|
||||||
auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_filter = std::move(new_dialog_filter),
|
auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_filter = std::move(new_dialog_filter),
|
||||||
promise = std::move(promise)](Result<Unit> result) mutable {
|
promise = std::move(promise)](Result<Unit> result) mutable {
|
||||||
@ -15320,11 +15386,11 @@ void MessagesManager::edit_dialog_filter(DialogFilterId dialog_filter_id, td_api
|
|||||||
void MessagesManager::on_update_dialog_filter(unique_ptr<DialogFilter> dialog_filter, Status result,
|
void MessagesManager::on_update_dialog_filter(unique_ptr<DialogFilter> dialog_filter, Status result,
|
||||||
Promise<Unit> &&promise) {
|
Promise<Unit> &&promise) {
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
|
// TODO rollback dialog_filters_ changes
|
||||||
return promise.set_error(result.move_as_error());
|
return promise.set_error(result.move_as_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO update all changed chat lists and their unread counts
|
for (auto &filter : server_dialog_filters_) {
|
||||||
for (auto &filter : dialog_filters_) {
|
|
||||||
if (filter->dialog_filter_id == dialog_filter->dialog_filter_id) {
|
if (filter->dialog_filter_id == dialog_filter->dialog_filter_id) {
|
||||||
if (*filter != *dialog_filter) {
|
if (*filter != *dialog_filter) {
|
||||||
filter = std::move(dialog_filter);
|
filter = std::move(dialog_filter);
|
||||||
@ -15335,7 +15401,7 @@ void MessagesManager::on_update_dialog_filter(unique_ptr<DialogFilter> dialog_fi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog_filters_.push_back(std::move(dialog_filter));
|
server_dialog_filters_.push_back(std::move(dialog_filter));
|
||||||
send_update_chat_filters(false);
|
send_update_chat_filters(false);
|
||||||
promise.set_value(Unit());
|
promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
@ -15347,8 +15413,9 @@ void MessagesManager::delete_dialog_filter(DialogFilterId dialog_filter_id, Prom
|
|||||||
return promise.set_value(Unit());
|
return promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO logevent
|
delete_dialog_filter(dialog_filter_id, "delete_dialog_filter");
|
||||||
// TODO delete dialog filter locally
|
send_update_chat_filters(false);
|
||||||
|
|
||||||
// TODO SequenceDispatcher
|
// TODO SequenceDispatcher
|
||||||
auto query_promise = PromiseCreator::lambda(
|
auto query_promise = PromiseCreator::lambda(
|
||||||
[actor_id = actor_id(this), dialog_filter_id, promise = std::move(promise)](Result<Unit> result) mutable {
|
[actor_id = actor_id(this), dialog_filter_id, promise = std::move(promise)](Result<Unit> result) mutable {
|
||||||
@ -15360,13 +15427,13 @@ void MessagesManager::delete_dialog_filter(DialogFilterId dialog_filter_id, Prom
|
|||||||
|
|
||||||
void MessagesManager::on_delete_dialog_filter(DialogFilterId dialog_filter_id, Status result, Promise<Unit> &&promise) {
|
void MessagesManager::on_delete_dialog_filter(DialogFilterId dialog_filter_id, Status result, Promise<Unit> &&promise) {
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
|
// TODO rollback dialog_filters_ changes
|
||||||
return promise.set_error(result.move_as_error());
|
return promise.set_error(result.move_as_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = dialog_filters_.begin(); it != dialog_filters_.end(); ++it) {
|
for (auto it = server_dialog_filters_.begin(); it != server_dialog_filters_.end(); ++it) {
|
||||||
if ((*it)->dialog_filter_id == dialog_filter_id) {
|
if ((*it)->dialog_filter_id == dialog_filter_id) {
|
||||||
// TODO delete chat list
|
server_dialog_filters_.erase(it);
|
||||||
dialog_filters_.erase(it);
|
|
||||||
send_update_chat_filters(false);
|
send_update_chat_filters(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -15422,12 +15489,42 @@ void MessagesManager::reorder_dialog_filters(vector<DialogFilterId> dialog_filte
|
|||||||
}
|
}
|
||||||
send_update_chat_filters(false);
|
send_update_chat_filters(false);
|
||||||
|
|
||||||
// TODO logevent
|
|
||||||
// TODO SequenceDispatcher
|
// TODO SequenceDispatcher
|
||||||
td_->create_handler<ReorderDialogFiltersQuery>(std::move(promise))->send(dialog_filter_ids);
|
td_->create_handler<ReorderDialogFiltersQuery>(std::move(promise))->send(dialog_filter_ids);
|
||||||
return promise.set_value(Unit());
|
return promise.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessagesManager::add_dialog_filter(unique_ptr<DialogFilter> dialog_filter, const char *source) {
|
||||||
|
CHECK(dialog_filter != nullptr);
|
||||||
|
LOG(INFO) << "Add " << dialog_filter->dialog_filter_id << " from " << source;
|
||||||
|
CHECK(get_dialog_filter(dialog_filter->dialog_filter_id) == nullptr);
|
||||||
|
dialog_filters_.push_back(std::move(dialog_filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagesManager::edit_dialog_filter(unique_ptr<DialogFilter> dialog_filter, const char *source) {
|
||||||
|
CHECK(dialog_filter != nullptr);
|
||||||
|
LOG(INFO) << "Edit " << dialog_filter->dialog_filter_id << " from " << source;
|
||||||
|
for (auto &filter : dialog_filters_) {
|
||||||
|
if (filter->dialog_filter_id == dialog_filter->dialog_filter_id) {
|
||||||
|
CHECK(*filter != *dialog_filter);
|
||||||
|
filter = std::move(dialog_filter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessagesManager::delete_dialog_filter(DialogFilterId dialog_filter_id, const char *source) {
|
||||||
|
LOG(INFO) << "Delete " << dialog_filter_id << " from " << source;
|
||||||
|
for (auto it = dialog_filters_.begin(); it != server_dialog_filters_.end(); ++it) {
|
||||||
|
if ((*it)->dialog_filter_id == dialog_filter_id) {
|
||||||
|
dialog_filters_.erase(it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
Status MessagesManager::delete_dialog_reply_markup(DialogId dialog_id, MessageId message_id) {
|
Status MessagesManager::delete_dialog_reply_markup(DialogId dialog_id, MessageId message_id) {
|
||||||
if (td_->auth_manager_->is_bot()) {
|
if (td_->auth_manager_->is_bot()) {
|
||||||
return Status::Error(6, "Bots can't delete chat reply markup");
|
return Status::Error(6, "Bots can't delete chat reply markup");
|
||||||
@ -24075,6 +24172,7 @@ void MessagesManager::send_update_chat_filters(bool from_database) {
|
|||||||
if (!from_database) {
|
if (!from_database) {
|
||||||
DialogFiltersLogEvent log_event;
|
DialogFiltersLogEvent log_event;
|
||||||
log_event.updated_date = dialog_filters_updated_date_;
|
log_event.updated_date = dialog_filters_updated_date_;
|
||||||
|
log_event.server_dialog_filters_in = &server_dialog_filters_;
|
||||||
log_event.dialog_filters_in = &dialog_filters_;
|
log_event.dialog_filters_in = &dialog_filters_;
|
||||||
|
|
||||||
G()->td_db()->get_binlog_pmc()->set("dialog_filters", log_event_store(log_event).as_slice().str());
|
G()->td_db()->get_binlog_pmc()->set("dialog_filters", log_event_store(log_event).as_slice().str());
|
||||||
@ -30161,6 +30259,15 @@ MessagesManager::Dialog *MessagesManager::on_load_dialog_from_database(DialogId
|
|||||||
return add_new_dialog(parse_dialog(dialog_id, value), true);
|
return add_new_dialog(parse_dialog(dialog_id, value), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MessagesManager::DialogFilter *MessagesManager::get_server_dialog_filter(DialogFilterId dialog_filter_id) const {
|
||||||
|
for (auto &filter : server_dialog_filters_) {
|
||||||
|
if (filter->dialog_filter_id == dialog_filter_id) {
|
||||||
|
return filter.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
MessagesManager::DialogFilter *MessagesManager::get_dialog_filter(DialogFilterId dialog_filter_id) {
|
MessagesManager::DialogFilter *MessagesManager::get_dialog_filter(DialogFilterId dialog_filter_id) {
|
||||||
for (auto &filter : dialog_filters_) {
|
for (auto &filter : dialog_filters_) {
|
||||||
if (filter->dialog_filter_id == dialog_filter_id) {
|
if (filter->dialog_filter_id == dialog_filter_id) {
|
||||||
|
@ -2253,6 +2253,14 @@ class MessagesManager : public Actor {
|
|||||||
|
|
||||||
void on_delete_dialog_filter(DialogFilterId dialog_filter_id, Status result, Promise<Unit> &&promise);
|
void on_delete_dialog_filter(DialogFilterId dialog_filter_id, Status result, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void add_dialog_filter(unique_ptr<DialogFilter> dialog_filter, const char *source);
|
||||||
|
|
||||||
|
void edit_dialog_filter(unique_ptr<DialogFilter> dialog_filter, const char *source);
|
||||||
|
|
||||||
|
void delete_dialog_filter(DialogFilterId dialog_filter_id, const char *source);
|
||||||
|
|
||||||
|
const DialogFilter *get_server_dialog_filter(DialogFilterId dialog_filter_id) const;
|
||||||
|
|
||||||
DialogFilter *get_dialog_filter(DialogFilterId dialog_filter_id);
|
DialogFilter *get_dialog_filter(DialogFilterId dialog_filter_id);
|
||||||
const DialogFilter *get_dialog_filter(DialogFilterId dialog_filter_id) const;
|
const DialogFilter *get_dialog_filter(DialogFilterId dialog_filter_id) const;
|
||||||
|
|
||||||
@ -2854,6 +2862,7 @@ class MessagesManager : public Actor {
|
|||||||
std::unordered_map<FolderId, DialogFolder, FolderIdHash> dialog_folders_;
|
std::unordered_map<FolderId, DialogFolder, FolderIdHash> dialog_folders_;
|
||||||
|
|
||||||
int32 dialog_filters_updated_date_ = 0;
|
int32 dialog_filters_updated_date_ = 0;
|
||||||
|
vector<unique_ptr<DialogFilter>> server_dialog_filters_;
|
||||||
vector<unique_ptr<DialogFilter>> dialog_filters_;
|
vector<unique_ptr<DialogFilter>> dialog_filters_;
|
||||||
|
|
||||||
std::unordered_map<DialogId, string, DialogIdHash> active_get_channel_differencies_;
|
std::unordered_map<DialogId, string, DialogIdHash> active_get_channel_differencies_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user