Fix handling of left dialogs, which are still pinned in filters.

This commit is contained in:
levlam 2021-05-09 00:31:43 +03:00
parent 9c49e6a625
commit 6baf923f07
2 changed files with 45 additions and 16 deletions

View File

@ -9279,9 +9279,11 @@ void MessagesManager::after_get_difference() {
auto *list = get_dialog_list(dialog_list_id);
CHECK(list != nullptr);
if (!list->is_dialog_unread_count_inited_) {
get_dialogs(dialog_list_id, MIN_DIALOG_DATE, static_cast<int32>(list->pinned_dialogs_.size() + 2), false,
PromiseCreator::lambda([dialog_list_id](Unit) {
if (!G()->close_flag()) {
int32 limit = list->are_pinned_dialogs_inited_ ? static_cast<int32>(list->pinned_dialogs_.size())
: get_pinned_dialogs_limit(dialog_list_id);
get_dialogs(dialog_list_id, MIN_DIALOG_DATE, limit + 2, false,
PromiseCreator::lambda([dialog_list_id](Result<Unit> result) {
if (!G()->close_flag() && result.is_ok()) {
LOG(INFO) << "Inited total chat count in " << dialog_list_id;
}
}));
@ -14026,12 +14028,29 @@ void MessagesManager::set_dialog_is_empty(Dialog *d, const char *source) {
update_dialog_pos(d, source);
}
bool MessagesManager::is_dialog_pinned(DialogListId dialog_list_id, DialogId dialog_id) const {
if (get_dialog_pinned_order(dialog_list_id, dialog_id) != DEFAULT_ORDER) {
return true;
}
if (dialog_list_id.is_filter()) {
const auto *filter = get_dialog_filter(dialog_list_id.get_filter_id());
if (filter != nullptr) {
for (const auto &input_dialog_id : filter->pinned_dialog_ids) {
if (input_dialog_id.get_dialog_id() == dialog_id) {
return true;
}
}
}
}
return false;
}
int64 MessagesManager::get_dialog_pinned_order(DialogListId dialog_list_id, DialogId dialog_id) const {
return get_dialog_pinned_order(get_dialog_list(dialog_list_id), dialog_id);
}
int64 MessagesManager::get_dialog_pinned_order(const DialogList *list, DialogId dialog_id) {
if (list != nullptr && !list->pinned_dialogs_.empty()) {
if (list != nullptr && !list->pinned_dialog_id_orders_.empty()) {
auto it = list->pinned_dialog_id_orders_.find(dialog_id);
if (it != list->pinned_dialog_id_orders_.end()) {
return it->second;
@ -14050,6 +14069,7 @@ bool MessagesManager::set_dialog_is_pinned(DialogId dialog_id, bool is_pinned) {
return set_dialog_is_pinned(DialogListId(d->folder_id), d, is_pinned);
}
// only removes the Dialog from the dialog list, but changes nothing in the corresponding DialogFilter
bool MessagesManager::set_dialog_is_pinned(DialogListId dialog_list_id, Dialog *d, bool is_pinned,
bool need_update_dialog_lists) {
if (td_->auth_manager_->is_bot()) {
@ -14558,7 +14578,7 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<te
if (!td_->auth_manager_->is_bot() && !from_pinned_dialog_list) {
// set is_pinned only after updating dialog pos to ensure that order is initialized
bool is_pinned = (dialog->flags_ & DIALOG_FLAG_IS_PINNED) != 0;
bool was_pinned = get_dialog_pinned_order(DialogListId(d->folder_id), dialog_id) != DEFAULT_ORDER;
bool was_pinned = is_dialog_pinned(DialogListId(d->folder_id), dialog_id);
if (is_pinned != was_pinned) {
set_dialog_is_pinned(DialogListId(d->folder_id), d, is_pinned);
}
@ -15641,7 +15661,7 @@ std::pair<int32, vector<DialogId>> MessagesManager::get_dialogs(DialogListId dia
auto *filter = get_dialog_filter(dialog_list_id.get_filter_id());
CHECK(filter != nullptr);
vector<InputDialogId> input_dialog_ids;
for (auto &input_dialog_id : filter->pinned_dialog_ids) {
for (const auto &input_dialog_id : filter->pinned_dialog_ids) {
auto dialog_id = input_dialog_id.get_dialog_id();
if (!have_dialog_force(dialog_id, "get_dialogs")) {
if (dialog_id.get_type() == DialogType::SecretChat) {
@ -15955,6 +15975,14 @@ void MessagesManager::preload_folder_dialog_list(FolderId folder_id) {
vector<DialogId> MessagesManager::get_pinned_dialog_ids(DialogListId dialog_list_id) const {
CHECK(!td_->auth_manager_->is_bot());
if (dialog_list_id.is_filter()) {
const auto *filter = get_dialog_filter(dialog_list_id.get_filter_id());
if (filter == nullptr) {
return {};
}
return transform(filter->pinned_dialog_ids, [](auto &input_dialog) { return input_dialog.get_dialog_id(); });
}
auto *list = get_dialog_list(dialog_list_id);
if (list == nullptr || !list->are_pinned_dialogs_inited_) {
return {};
@ -17834,9 +17862,7 @@ void MessagesManager::sort_dialog_filter_input_dialog_ids(DialogFilter *dialog_f
{&dialog_filter->pinned_dialog_ids, &dialog_filter->excluded_dialog_ids, &dialog_filter->included_dialog_ids}) {
for (auto input_dialog_id : *input_dialog_ids) {
LOG_CHECK(all_dialog_ids.insert(input_dialog_id.get_dialog_id()).second)
<< source << ' ' << td::contains(dialog_filter->pinned_dialog_ids, input_dialog_id) << ' '
<< td::contains(dialog_filter->excluded_dialog_ids, input_dialog_id) << ' '
<< td::contains(dialog_filter->included_dialog_ids, input_dialog_id);
<< source << ' ' << input_dialog_id.get_dialog_id() << ' ' << dialog_filter;
}
}
}
@ -18185,7 +18211,7 @@ void MessagesManager::add_dialog_filter(unique_ptr<DialogFilter> dialog_filter,
}
}
for (auto &input_dialog_id : reversed(dialog_filters_.back()->pinned_dialog_ids)) {
for (const auto &input_dialog_id : reversed(dialog_filters_.back()->pinned_dialog_ids)) {
auto dialog_id = input_dialog_id.get_dialog_id();
auto order = get_next_pinned_dialog_order();
list.pinned_dialogs_.emplace_back(order, dialog_id);
@ -18229,7 +18255,7 @@ void MessagesManager::edit_dialog_filter(unique_ptr<DialogFilter> new_dialog_fil
new_list.dialog_list_id = dialog_list_id;
auto old_it = old_list.pinned_dialogs_.rbegin();
for (auto &input_dialog_id : reversed(new_dialog_filter->pinned_dialog_ids)) {
for (const auto &input_dialog_id : reversed(new_dialog_filter->pinned_dialog_ids)) {
auto dialog_id = input_dialog_id.get_dialog_id();
while (old_it < old_list.pinned_dialogs_.rend()) {
if (old_it->get_dialog_id() == dialog_id) {
@ -18689,7 +18715,7 @@ Status MessagesManager::toggle_dialog_is_pinned(DialogListId dialog_list_id, Dia
return Status::Error(6, "Pinned chats must be loaded first");
}
bool was_pinned = get_dialog_pinned_order(dialog_list_id, dialog_id) != DEFAULT_ORDER;
bool was_pinned = is_dialog_pinned(dialog_list_id, dialog_id);
if (is_pinned == was_pinned) {
return Status::OK();
}
@ -18709,7 +18735,8 @@ Status MessagesManager::toggle_dialog_is_pinned(DialogListId dialog_list_id, Dia
td::remove_if(new_dialog_filter->included_dialog_ids, is_changed_dialog);
td::remove_if(new_dialog_filter->excluded_dialog_ids, is_changed_dialog);
} else {
td::remove_if(new_dialog_filter->pinned_dialog_ids, is_changed_dialog);
bool is_removed = td::remove_if(new_dialog_filter->pinned_dialog_ids, is_changed_dialog);
CHECK(is_removed);
new_dialog_filter->included_dialog_ids.push_back(get_input_dialog_id(dialog_id));
}
@ -34472,7 +34499,7 @@ bool MessagesManager::set_dialog_order(Dialog *d, int64 new_order, bool need_sen
if (new_order == DEFAULT_ORDER) {
// first addition of a new left dialog
if (folder.ordered_dialogs_.insert(new_date).second) {
for (auto &dialog_list : dialog_lists_) {
for (const auto &dialog_list : dialog_lists_) {
if (get_dialog_pinned_order(&dialog_list.second, d->dialog_id) != DEFAULT_ORDER) {
set_dialog_is_pinned(dialog_list.first, d, false);
}
@ -35129,7 +35156,7 @@ MessagesManager::get_dialog_positions(const Dialog *d) const {
CHECK(d != nullptr);
std::unordered_map<DialogListId, MessagesManager::DialogPositionInList, DialogListIdHash> positions;
if (!td_->auth_manager_->is_bot()) {
for (auto &dialog_list : dialog_lists_) {
for (const auto &dialog_list : dialog_lists_) {
positions.emplace(dialog_list.first, get_dialog_position_in_list(&dialog_list.second, d));
}
}
@ -35752,7 +35779,7 @@ void MessagesManager::on_get_channel_difference(
if (!td_->auth_manager_->is_bot()) {
// set is_pinned only after updating dialog pos to ensure that order is initialized
bool is_pinned = (dialog->flags_ & DIALOG_FLAG_IS_PINNED) != 0;
bool was_pinned = get_dialog_pinned_order(DialogListId(d->folder_id), dialog_id) != DEFAULT_ORDER;
bool was_pinned = is_dialog_pinned(DialogListId(d->folder_id), dialog_id);
if (is_pinned != was_pinned) {
set_dialog_is_pinned(DialogListId(d->folder_id), d, is_pinned);
}

View File

@ -1714,6 +1714,8 @@ class MessagesManager : public Actor {
bool is_dialog_mention_notifications_disabled(const Dialog *d) const;
bool is_dialog_pinned(DialogListId dialog_list_id, DialogId dialog_id) const;
int64 get_dialog_pinned_order(DialogListId dialog_list_id, DialogId dialog_id) const;
static int64 get_dialog_pinned_order(const DialogList *list, DialogId dialog_id);