Implement complex filter delete from context menu.

This commit is contained in:
John Preston 2023-04-05 15:06:41 +04:00
parent 6f4eef035d
commit 1a1fa5db3e
5 changed files with 112 additions and 24 deletions

View File

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat_filters.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "history/history.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "settings/settings_common.h"
@ -828,4 +829,15 @@ void ProcessFilterRemove(
Box<PeerListBox>(std::move(controller), std::move(initBox)));
}
[[nodiscard]] std::vector<not_null<PeerData*>> ExtractSuggestRemoving(
const Data::ChatFilter &filter) {
if (!filter.chatlist()) {
return {};
}
return filter.always() | ranges::views::filter([](
not_null<History*> history) {
return history->peer->isChannel();
}) | ranges::views::transform(&History::peer) | ranges::to_vector;
}
} // namespace Api

View File

@ -15,6 +15,10 @@ namespace Window {
class SessionController;
} // namespace Window
namespace Data {
class ChatFilter;
} // namespace Data
namespace Api {
void SaveNewFilterPinned(
@ -38,4 +42,7 @@ void ProcessFilterRemove(
std::vector<not_null<PeerData*>> suggest,
Fn<void(std::vector<not_null<PeerData*>>)> done);
[[nodiscard]] std::vector<not_null<PeerData*>> ExtractSuggestRemoving(
const Data::ChatFilter &filter);
} // namespace Api

View File

@ -165,14 +165,6 @@ struct FilterRow {
: result;
}
[[nodiscard]] std::vector<not_null<PeerData*>> ExtractSuggestRemoving(
const base::flat_set<not_null<History*>> &histories) {
return histories | ranges::views::filter([](
not_null<History*> history) {
return history->peer->isChannel();
}) | ranges::views::transform(&History::peer) | ranges::to_vector;
}
FilterRowButton::FilterRowButton(
not_null<QWidget*> parent,
not_null<Main::Session*> session,
@ -378,9 +370,7 @@ void FilterRowButton::paintEvent(QPaintEvent *e) {
};
const auto markForRemovalSure = [=](not_null<FilterRowButton*> button) {
const auto row = find(button);
auto suggestRemoving = row->filter.chatlist()
? ExtractSuggestRemoving(row->filter.always())
: std::vector<not_null<PeerData*>>();
auto suggestRemoving = Api::ExtractSuggestRemoving(row->filter);
if (row->removed || row->removePeersRequestId > 0) {
return;
} else if (!suggestRemoving.empty()) {

View File

@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "styles/style_widgets.h"
#include "styles/style_window.h"
#include "styles/style_layers.h" // attentionBoxButton
#include "styles/style_menu_icons.h"
namespace Window {
@ -406,23 +407,98 @@ void FiltersMenu::showEditBox(FilterId id) {
}
void FiltersMenu::showRemoveBox(FilterId id) {
_session->window().show(Ui::MakeConfirmBox({
.text = tr::lng_filters_remove_sure(),
.confirmed = [=](Fn<void()> &&close) { close(); remove(id); },
.confirmText = tr::lng_filters_remove_yes(),
}));
const auto session = &_session->session();
const auto &list = session->data().chatsFilters().list();
const auto i = ranges::find(list, id, &Data::ChatFilter::id);
const auto filter = (i != end(list)) ? *i : Data::ChatFilter();
const auto has = filter.hasMyLinks();
const auto confirm = [=](Fn<void()> action, bool onlyWhenHas = false) {
if (!has && onlyWhenHas) {
action();
return;
}
_session->window().show(Ui::MakeConfirmBox({
.text = (has
? tr::lng_filters_delete_sure()
: tr::lng_filters_remove_sure()),
.confirmed = [=](Fn<void()> &&close) { close(); action(); },
.confirmText = (has
? tr::lng_box_delete()
: tr::lng_filters_remove_yes()),
.confirmStyle = &st::attentionBoxButton,
}));
};
const auto simple = [=] {
confirm([=] { remove(id); });
};
const auto suggestRemoving = Api::ExtractSuggestRemoving(filter);
if (suggestRemoving.empty()) {
simple();
return;
} else if (_removingRequestId) {
if (_removingId == id) {
return;
}
session->api().request(_removingRequestId).cancel();
}
_removingId = id;
_removingRequestId = session->api().request(
MTPchatlists_GetLeaveChatlistSuggestions(
MTP_inputChatlistDialogFilter(
MTP_int(id)))
).done(crl::guard(&_outer, [=](const MTPVector<MTPPeer> &result) {
_removingRequestId = 0;
const auto suggestRemovePeers = ranges::views::all(
result.v
) | ranges::views::transform([=](const MTPPeer &peer) {
return session->data().peer(peerFromMTP(peer));
}) | ranges::to_vector;
const auto chosen = crl::guard(&_outer, [=](
std::vector<not_null<PeerData*>> peers) {
remove(id, std::move(peers));
});
confirm(crl::guard(&_outer, [=] {
Api::ProcessFilterRemove(
_session,
filter.title(),
filter.iconEmoji(),
suggestRemoving,
suggestRemovePeers,
chosen);
}), true);
})).fail(crl::guard(&_outer, [=] {
_removingRequestId = 0;
simple();
})).send();
}
void FiltersMenu::remove(FilterId id) {
_session->session().data().chatsFilters().apply(MTP_updateDialogFilter(
void FiltersMenu::remove(
FilterId id,
std::vector<not_null<PeerData*>> leave) {
const auto session = &_session->session();
const auto api = &session->api();
session->data().chatsFilters().apply(MTP_updateDialogFilter(
MTP_flags(MTPDupdateDialogFilter::Flag(0)),
MTP_int(id),
MTPDialogFilter()));
_session->session().api().request(MTPmessages_UpdateDialogFilter(
MTP_flags(MTPmessages_UpdateDialogFilter::Flag(0)),
MTP_int(id),
MTPDialogFilter()
)).send();
if (leave.empty()) {
api->request(MTPmessages_UpdateDialogFilter(
MTP_flags(MTPmessages_UpdateDialogFilter::Flag(0)),
MTP_int(id),
MTPDialogFilter()
)).send();
} else {
api->request(MTPchatlists_LeaveChatlist(
MTP_inputChatlistDialogFilter(MTP_int(id)),
MTP_vector<MTPInputPeer>(ranges::views::all(
leave
) | ranges::views::transform([](not_null<PeerData*> peer) {
return MTPInputPeer(peer->input);
}) | ranges::to<QVector>())
)).done([=](const MTPUpdates &result) {
api->applyUpdates(result);
}).send();
}
}
void FiltersMenu::applyReorder(

View File

@ -50,7 +50,7 @@ private:
void showMenu(QPoint position, FilterId id);
void showEditBox(FilterId id);
void showRemoveBox(FilterId id);
void remove(FilterId id);
void remove(FilterId id, std::vector<not_null<PeerData*>> leave = {});
void scrollToButton(not_null<Ui::RpWidget*> widget);
const not_null<SessionController*> _session;
@ -68,6 +68,9 @@ private:
bool _ignoreRefresh = false;
bool _waitingSuggested = false;
FilterId _removingId = 0;
mtpRequestId _removingRequestId = 0;
base::unique_qptr<Ui::PopupMenu> _popupMenu;
struct {
base::Timer timer;