Dialog list fixes.

GitOrigin-RevId: 7591555e389fe55d33d5d7982a441491039d23ed
This commit is contained in:
levlam 2020-05-28 21:24:50 +03:00
parent 7ec366b7f7
commit 8ac003dc9d
3 changed files with 60 additions and 32 deletions

View File

@ -67,7 +67,7 @@ struct DialogFilterIdHash {
}; };
inline StringBuilder &operator<<(StringBuilder &string_builder, DialogFilterId dialog_filter_id) { inline StringBuilder &operator<<(StringBuilder &string_builder, DialogFilterId dialog_filter_id) {
return string_builder << "chat filter " << dialog_filter_id.get(); return string_builder << "filter " << dialog_filter_id.get();
} }
} // namespace td } // namespace td

View File

@ -125,6 +125,8 @@ bool InputDialogId::are_equivalent(const vector<InputDialogId> &lhs, const vecto
if (lhs_it->get_dialog_id() != rhs_it->get_dialog_id()) { if (lhs_it->get_dialog_id() != rhs_it->get_dialog_id()) {
return false; return false;
} }
++lhs_it;
++rhs_it;
} }
return lhs_it == lhs.end() && rhs_it == rhs.end(); return lhs_it == lhs.end() && rhs_it == rhs.end();
} }

View File

@ -4894,7 +4894,7 @@ struct MessagesManager::DialogFilter {
} }
bool is_empty(bool for_server) const { bool is_empty(bool for_server) const {
if (include_contacts || include_non_contacts || include_bots || include_groups || include_channels) { if (!include_contacts && !include_non_contacts && !include_bots && !include_groups && !include_channels) {
return false; return false;
} }
@ -10326,9 +10326,17 @@ void MessagesManager::recalc_unread_count(DialogListId dialog_list_id) {
for (auto folder_id : get_dialog_list_folder_ids(list)) { for (auto folder_id : get_dialog_list_folder_ids(list)) {
const auto &folder = *get_dialog_folder(folder_id); const auto &folder = *get_dialog_folder(folder_id);
for (const auto &dialog_date : folder.ordered_dialogs_) { for (const auto &dialog_date : folder.ordered_dialogs_) {
if (dialog_date.get_order() == DEFAULT_ORDER) {
break;
}
auto dialog_id = dialog_date.get_dialog_id(); auto dialog_id = dialog_date.get_dialog_id();
Dialog *d = get_dialog(dialog_id); Dialog *d = get_dialog(dialog_id);
CHECK(d != nullptr); CHECK(d != nullptr);
if (!is_dialog_in_list(d, dialog_list_id)) {
continue;
}
int unread_count = d->server_unread_count + d->local_unread_count; int unread_count = d->server_unread_count + d->local_unread_count;
if (need_unread_counter(d->order) && (unread_count > 0 || d->is_marked_as_unread)) { if (need_unread_counter(d->order) && (unread_count > 0 || d->is_marked_as_unread)) {
message_total_count += unread_count; message_total_count += unread_count;
@ -13952,8 +13960,8 @@ vector<DialogId> MessagesManager::get_dialogs(DialogListId dialog_list_id, Dialo
return result; return result;
} }
if (limit > MAX_GET_DIALOGS) { if (limit > MAX_GET_DIALOGS + 2) {
limit = MAX_GET_DIALOGS; limit = MAX_GET_DIALOGS + 2;
} }
if (dialog_list_id == DialogListId(FolderId::main()) && sponsored_dialog_id_.is_valid()) { if (dialog_list_id == DialogListId(FolderId::main()) && sponsored_dialog_id_.is_valid()) {
@ -14005,7 +14013,8 @@ vector<DialogId> MessagesManager::get_dialogs(DialogListId dialog_list_id, Dialo
for (size_t i = 0; i < folders.size(); i++) { for (size_t i = 0; i < folders.size(); i++) {
while (folder_iterators[i] != folders[i]->ordered_dialogs_.end() && while (folder_iterators[i] != folders[i]->ordered_dialogs_.end() &&
*folder_iterators[i] <= list.list_last_dialog_date_ && *folder_iterators[i] <= list.list_last_dialog_date_ &&
get_dialog_pinned_order(&list, folder_iterators[i]->get_dialog_id()) != DEFAULT_ORDER) { (!is_dialog_in_list(get_dialog(folder_iterators[i]->get_dialog_id()), dialog_list_id) ||
get_dialog_pinned_order(&list, folder_iterators[i]->get_dialog_id()) != DEFAULT_ORDER)) {
++folder_iterators[i]; ++folder_iterators[i];
} }
if (folder_iterators[i] != folders[i]->ordered_dialogs_.end() && if (folder_iterators[i] != folders[i]->ordered_dialogs_.end() &&
@ -14255,7 +14264,7 @@ void MessagesManager::schedule_dialog_filters_reload(double timeout) {
if (timeout < 0) { if (timeout < 0) {
timeout = 0.0; timeout = 0.0;
} }
LOG(INFO) << "Schedule reload of dialog filters in " << timeout; LOG(INFO) << "Schedule reload of chat filters in " << timeout;
reload_dialog_filters_timeout_.set_callback(std::move(MessagesManager::on_reload_dialog_filters_timeout)); reload_dialog_filters_timeout_.set_callback(std::move(MessagesManager::on_reload_dialog_filters_timeout));
reload_dialog_filters_timeout_.set_callback_data(static_cast<void *>(this)); reload_dialog_filters_timeout_.set_callback_data(static_cast<void *>(this));
reload_dialog_filters_timeout_.set_timeout_in(timeout); reload_dialog_filters_timeout_.set_timeout_in(timeout);
@ -14270,10 +14279,14 @@ void MessagesManager::on_reload_dialog_filters_timeout(void *messages_manager_pt
} }
void MessagesManager::reload_dialog_filters() { void MessagesManager::reload_dialog_filters() {
if (G()->close_flag()) {
return;
}
if (are_dialog_filters_being_synchronized_ || are_dialog_filters_being_reloaded_) { if (are_dialog_filters_being_synchronized_ || are_dialog_filters_being_reloaded_) {
need_dialog_filters_reload_ = true; need_dialog_filters_reload_ = true;
return; return;
} }
LOG(INFO) << "Reload chat filters from server";
are_dialog_filters_being_reloaded_ = true; are_dialog_filters_being_reloaded_ = true;
need_dialog_filters_reload_ = false; need_dialog_filters_reload_ = false;
auto promise = PromiseCreator::lambda( auto promise = PromiseCreator::lambda(
@ -14298,7 +14311,7 @@ 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>> new_server_dialog_filters; vector<unique_ptr<DialogFilter>> new_server_dialog_filters;
LOG(INFO) << "Receive " << filters.size() << " chat filters"; LOG(INFO) << "Receive " << filters.size() << " chat filters from server";
std::unordered_set<DialogFilterId, DialogFilterIdHash> new_dialog_filter_ids; 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);
@ -14401,7 +14414,7 @@ void MessagesManager::on_get_dialog_filters(Result<vector<tl_object_ptr<telegram
bool MessagesManager::need_synchronize_dialog_filters() const { bool MessagesManager::need_synchronize_dialog_filters() const {
size_t server_dialog_filter_count = 0; size_t server_dialog_filter_count = 0;
vector<DialogFilterId> dialog_filter_ids; vector<DialogFilterId> dialog_filter_ids;
for (auto &dialog_filter : dialog_filters_) { for (const auto &dialog_filter : dialog_filters_) {
if (dialog_filter->is_empty(true)) { if (dialog_filter->is_empty(true)) {
continue; continue;
} }
@ -14426,6 +14439,9 @@ bool MessagesManager::need_synchronize_dialog_filters() const {
} }
void MessagesManager::synchronize_dialog_filters() { void MessagesManager::synchronize_dialog_filters() {
if (G()->close_flag()) {
return;
}
if (are_dialog_filters_being_synchronized_ || are_dialog_filters_being_reloaded_) { if (are_dialog_filters_being_synchronized_ || are_dialog_filters_being_reloaded_) {
return; return;
} }
@ -14436,6 +14452,7 @@ void MessagesManager::synchronize_dialog_filters() {
return; return;
} }
LOG(INFO) << "Synchronize chat filter changes with server";
for (auto &server_dialog_filter : server_dialog_filters_) { for (auto &server_dialog_filter : server_dialog_filters_) {
if (get_dialog_filter(server_dialog_filter->dialog_filter_id) == nullptr) { if (get_dialog_filter(server_dialog_filter->dialog_filter_id) == nullptr) {
return delete_dialog_filter_on_server(server_dialog_filter->dialog_filter_id); return delete_dialog_filter_on_server(server_dialog_filter->dialog_filter_id);
@ -14443,7 +14460,7 @@ void MessagesManager::synchronize_dialog_filters() {
} }
vector<DialogFilterId> dialog_filter_ids; vector<DialogFilterId> dialog_filter_ids;
for (auto &dialog_filter : dialog_filters_) { for (const auto &dialog_filter : dialog_filters_) {
if (dialog_filter->is_empty(true)) { if (dialog_filter->is_empty(true)) {
continue; continue;
} }
@ -15510,7 +15527,7 @@ Result<unique_ptr<MessagesManager::DialogFilter>> MessagesManager::create_dialog
dialog_filter->title = clean_name(std::move(filter->title_), MAX_DIALOG_FILTER_TITLE_LENGTH); dialog_filter->title = clean_name(std::move(filter->title_), MAX_DIALOG_FILTER_TITLE_LENGTH);
if (dialog_filter->title.empty()) { if (dialog_filter->title.empty()) {
return Status::Error(400, "Title must not be empty"); return Status::Error(400, "Title must be non-empty");
} }
dialog_filter->emoji = std::move(filter->emoji_); dialog_filter->emoji = std::move(filter->emoji_);
dialog_filter->exclude_muted = filter->exclude_muted_; dialog_filter->exclude_muted = filter->exclude_muted_;
@ -15782,7 +15799,7 @@ void MessagesManager::add_dialog_filter(unique_ptr<DialogFilter> dialog_filter,
} }
} }
for (auto &input_dialog_id : reversed(dialog_filter->pinned_dialog_ids)) { for (auto &input_dialog_id : reversed(dialog_filters_.back()->pinned_dialog_ids)) {
auto dialog_id = input_dialog_id.get_dialog_id(); auto dialog_id = input_dialog_id.get_dialog_id();
auto order = get_next_pinned_dialog_order(); auto order = get_next_pinned_dialog_order();
list.pinned_dialogs_.emplace_back(order, dialog_id); list.pinned_dialogs_.emplace_back(order, dialog_id);
@ -15819,6 +15836,7 @@ void MessagesManager::edit_dialog_filter(unique_ptr<DialogFilter> new_dialog_fil
} }
DialogList new_list; DialogList new_list;
new_list.dialog_list_id = dialog_list_id;
auto old_it = old_list.pinned_dialogs_.rbegin(); auto old_it = old_list.pinned_dialogs_.rbegin();
for (auto &input_dialog_id : reversed(new_dialog_filter->pinned_dialog_ids)) { for (auto &input_dialog_id : reversed(new_dialog_filter->pinned_dialog_ids)) {
@ -15847,7 +15865,7 @@ void MessagesManager::edit_dialog_filter(unique_ptr<DialogFilter> new_dialog_fil
new_list.server_dialog_total_count_ = 0; new_list.server_dialog_total_count_ = 0;
new_list.secret_chat_total_count_ = 0; new_list.secret_chat_total_count_ = 0;
vector<const Dialog *> updated_position_dialogs; std::map<DialogDate, const Dialog *> updated_position_dialogs;
for (auto folder_id : folder_ids) { for (auto folder_id : folder_ids) {
auto *folder = get_dialog_folder(folder_id); auto *folder = get_dialog_folder(folder_id);
CHECK(folder != nullptr); CHECK(folder != nullptr);
@ -15875,7 +15893,7 @@ void MessagesManager::edit_dialog_filter(unique_ptr<DialogFilter> new_dialog_fil
if (old_order.public_order != new_order.public_order || old_order.is_pinned != new_order.is_pinned || if (old_order.public_order != new_order.public_order || old_order.is_pinned != new_order.is_pinned ||
old_order.is_sponsored != new_order.is_sponsored) { old_order.is_sponsored != new_order.is_sponsored) {
updated_position_dialogs.push_back(d); updated_position_dialogs.emplace(DialogDate(new_order.public_order, dialog_id), d);
} }
bool was_in_list = old_order.private_order != 0; bool was_in_list = old_order.private_order != 0;
@ -15935,16 +15953,18 @@ void MessagesManager::edit_dialog_filter(unique_ptr<DialogFilter> new_dialog_fil
} }
bool need_update_unread_message_count = bool need_update_unread_message_count =
old_list.unread_message_total_count_ != new_list.unread_message_total_count_ || new_list.is_message_unread_count_inited_ &&
old_list.unread_message_muted_count_ != new_list.unread_message_muted_count_ || (old_list.unread_message_total_count_ != new_list.unread_message_total_count_ ||
(new_list.is_message_unread_count_inited_ && !old_list.is_message_unread_count_inited_); old_list.unread_message_muted_count_ != new_list.unread_message_muted_count_ ||
!old_list.is_message_unread_count_inited_);
bool need_update_unread_chat_count = bool need_update_unread_chat_count =
old_list.unread_dialog_total_count_ != new_list.unread_dialog_total_count_ || new_list.is_dialog_unread_count_inited_ &&
old_list.unread_dialog_muted_count_ != new_list.unread_dialog_muted_count_ || (old_list.unread_dialog_total_count_ != new_list.unread_dialog_total_count_ ||
old_list.unread_dialog_marked_count_ != new_list.unread_dialog_marked_count_ || old_list.unread_dialog_muted_count_ != new_list.unread_dialog_muted_count_ ||
old_list.unread_dialog_muted_marked_count_ != new_list.unread_dialog_muted_marked_count_ || old_list.unread_dialog_marked_count_ != new_list.unread_dialog_marked_count_ ||
get_dialog_total_count(old_list) != get_dialog_total_count(new_list) || old_list.unread_dialog_muted_marked_count_ != new_list.unread_dialog_muted_marked_count_ ||
(new_list.is_dialog_unread_count_inited_ && !old_list.is_dialog_unread_count_inited_); get_dialog_total_count(old_list) != get_dialog_total_count(new_list) ||
!old_list.is_dialog_unread_count_inited_);
auto load_list_promises = std::move(old_list.load_list_queries_); auto load_list_promises = std::move(old_list.load_list_queries_);
@ -15958,14 +15978,19 @@ void MessagesManager::edit_dialog_filter(unique_ptr<DialogFilter> new_dialog_fil
send_update_unread_chat_count(old_list, DialogId(), true, "edit_dialog_filter"); send_update_unread_chat_count(old_list, DialogId(), true, "edit_dialog_filter");
} }
for (auto d : updated_position_dialogs) { for (auto it : updated_position_dialogs) {
send_update_chat_position(dialog_list_id, d); send_update_chat_position(dialog_list_id, it.second);
}
if (old_list.need_unread_count_recalc_) {
// repair unread count
get_dialogs(dialog_list_id, MIN_DIALOG_DATE, static_cast<int32>(old_list.pinned_dialogs_.size() + 2), false,
Promise<Unit>());
} }
for (auto &promise : load_list_promises) { for (auto &promise : load_list_promises) {
promise.set_value(Unit()); // try again promise.set_value(Unit()); // try again
} }
return; return;
} }
} }
@ -30552,8 +30577,6 @@ void MessagesManager::update_dialog_lists(
send_update_chat_position(dialog_list_id, d); send_update_chat_position(dialog_list_id, d);
} }
bool need_update_unread_chat_count = list.is_dialog_unread_count_inited_ && !is_loaded_from_database &&
old_order.total_dialog_count != new_order.total_dialog_count;
if (was_in_list != is_in_list) { if (was_in_list != is_in_list) {
const int32 delta = was_in_list ? -1 : 1; const int32 delta = was_in_list ? -1 : 1;
list.in_memory_dialog_total_count_ += delta; list.in_memory_dialog_total_count_ += delta;
@ -30570,6 +30593,8 @@ void MessagesManager::update_dialog_lists(
} }
if (!is_loaded_from_database) { if (!is_loaded_from_database) {
bool need_update_unread_chat_count =
list.is_dialog_unread_count_inited_ && old_order.total_dialog_count != get_dialog_total_count(list);
auto unread_count = d->server_unread_count + d->local_unread_count; auto unread_count = d->server_unread_count + d->local_unread_count;
const char *change_source = was_in_list ? "on_dialog_leave" : "on_dialog_join"; const char *change_source = was_in_list ? "on_dialog_leave" : "on_dialog_join";
if (unread_count != 0 && list.is_message_unread_count_inited_) { if (unread_count != 0 && list.is_message_unread_count_inited_) {
@ -30592,7 +30617,9 @@ void MessagesManager::update_dialog_lists(
list.unread_dialog_muted_marked_count_ += delta; list.unread_dialog_muted_marked_count_ += delta;
} }
} }
need_update_unread_chat_count = false; need_update_unread_chat_count = true;
}
if (need_update_unread_chat_count) {
send_update_unread_chat_count(list, dialog_id, true, change_source); send_update_unread_chat_count(list, dialog_id, true, change_source);
} }
} }
@ -30618,10 +30645,6 @@ void MessagesManager::update_dialog_lists(
} }
} }
if (need_update_unread_chat_count) {
send_update_unread_chat_count(list, dialog_id, true, "changed chat_count");
}
if (!is_loaded_from_database && !old_order.is_sponsored && new_order.is_sponsored) { if (!is_loaded_from_database && !old_order.is_sponsored && new_order.is_sponsored) {
// a chat is sponsored only if user isn't a chat member // a chat is sponsored only if user isn't a chat member
remove_all_dialog_notifications(d, false, "update_dialog_lists 3"); remove_all_dialog_notifications(d, false, "update_dialog_lists 3");
@ -30644,6 +30667,7 @@ void MessagesManager::update_last_dialog_date(FolderId folder_id) {
if (old_last_dialog_date != folder->folder_last_dialog_date_) { if (old_last_dialog_date != folder->folder_last_dialog_date_) {
for (auto &dialog_list : dialog_lists_) { for (auto &dialog_list : dialog_lists_) {
update_list_last_pinned_dialog_date(dialog_list.second);
update_list_last_dialog_date(dialog_list.second); update_list_last_dialog_date(dialog_list.second);
} }
} }
@ -30937,11 +30961,13 @@ bool MessagesManager::is_dialog_in_list(const Dialog *d, DialogListId dialog_lis
} }
void MessagesManager::add_dialog_to_list(Dialog *d, DialogListId dialog_list_id) const { void MessagesManager::add_dialog_to_list(Dialog *d, DialogListId dialog_list_id) const {
LOG(INFO) << "Add " << d->dialog_id << " to " << dialog_list_id;
CHECK(!is_dialog_in_list(d, dialog_list_id)); CHECK(!is_dialog_in_list(d, dialog_list_id));
d->dialog_list_ids.push_back(dialog_list_id); d->dialog_list_ids.push_back(dialog_list_id);
} }
void MessagesManager::remove_dialog_from_list(Dialog *d, DialogListId dialog_list_id) const { void MessagesManager::remove_dialog_from_list(Dialog *d, DialogListId dialog_list_id) const {
LOG(INFO) << "Remove " << d->dialog_id << " from " << dialog_list_id;
bool is_removed = td::remove(d->dialog_list_ids, dialog_list_id); bool is_removed = td::remove(d->dialog_list_ids, dialog_list_id);
CHECK(is_removed); CHECK(is_removed);
} }