mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Support nice leaving of shareable folder.
This commit is contained in:
parent
4444844443
commit
6be2fb9790
8 changed files with 396 additions and 79 deletions
|
@ -3558,9 +3558,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_filters_toast_add" = "{chat} added to {folder} folder";
|
"lng_filters_toast_add" = "{chat} added to {folder} folder";
|
||||||
"lng_filters_toast_remove" = "{chat} removed from {folder} folder";
|
"lng_filters_toast_remove" = "{chat} removed from {folder} folder";
|
||||||
|
|
||||||
"lng_filters_link" = "Invite links";
|
"lng_filters_delete_sure" = "Are you sure you want to delete this folder? This will also deactivate all the invite links used to share this folder.";
|
||||||
|
"lng_filters_link" = "Share Folder";
|
||||||
|
"lng_filters_link_has" = "Invite links";
|
||||||
"lng_filters_link_badge" = "New";
|
"lng_filters_link_badge" = "New";
|
||||||
"lng_filters_link_create" = "Share Folder";
|
"lng_filters_link_create" = "Create an Invite Link";
|
||||||
"lng_filters_link_cant" = "No way to share folders with chat types or excluded chats.";
|
"lng_filters_link_cant" = "No way to share folders with chat types or excluded chats.";
|
||||||
"lng_filters_link_about" = "Share access to some of this folder's groups and channels with others.";
|
"lng_filters_link_about" = "Share access to some of this folder's groups and channels with others.";
|
||||||
"lng_filters_link_about_many" = "Create more links to set up different access levels for different people.";
|
"lng_filters_link_about_many" = "Create more links to set up different access levels for different people.";
|
||||||
|
@ -3577,6 +3579,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_filters_link_noadmin_status" = "you can't invite others here";
|
"lng_filters_link_noadmin_status" = "you can't invite others here";
|
||||||
"lng_filters_link_noadmin_group_error" = "You don't have the admin rights to share invite links to this group chat.";
|
"lng_filters_link_noadmin_group_error" = "You don't have the admin rights to share invite links to this group chat.";
|
||||||
"lng_filters_link_noadmin_channel_error" = "You don't have the admin rights to share invite links to this channel.";
|
"lng_filters_link_noadmin_channel_error" = "You don't have the admin rights to share invite links to this channel.";
|
||||||
|
"lng_filters_link_already_group" = "you are already a member";
|
||||||
|
"lng_filters_link_already_channel" = "you are already subscribed";
|
||||||
"lng_filters_link_chats_about" = "Select groups and channels that you want everyone who adds the folder via invite link to join.";
|
"lng_filters_link_chats_about" = "Select groups and channels that you want everyone who adds the folder via invite link to join.";
|
||||||
"lng_filters_link_no_about" = "There are no chats in this folder that you can share with others.";
|
"lng_filters_link_no_about" = "There are no chats in this folder that you can share with others.";
|
||||||
"lng_filters_link_chats_no" = "These chats cannot be shared";
|
"lng_filters_link_chats_no" = "These chats cannot be shared";
|
||||||
|
@ -3604,8 +3608,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_filters_by_link_quit#other" = "{count} chats to quit";
|
"lng_filters_by_link_quit#other" = "{count} chats to quit";
|
||||||
"lng_filters_by_link_select" = "Select All";
|
"lng_filters_by_link_select" = "Select All";
|
||||||
"lng_filters_by_link_deselect" = "Deselect All";
|
"lng_filters_by_link_deselect" = "Deselect All";
|
||||||
|
"lng_filters_by_link_about_quit" = "You can deselect the chats you don't want to quit.";
|
||||||
"lng_filters_by_link_remove_button" = "Remove Folder";
|
"lng_filters_by_link_remove_button" = "Remove Folder";
|
||||||
"lng_filters_by_link_quit_button" = "Remove Folder and Chats";
|
"lng_filters_by_link_quit_button" = "Remove Folder and Chats";
|
||||||
|
"lng_filters_added_title" = "Folder {folder} Added";
|
||||||
|
"lng_filters_added_also#one" = "You also joined {count} chat.";
|
||||||
|
"lng_filters_added_also#other" = "You also joined {count} chats.";
|
||||||
|
"lng_filters_updated_title" = "Folder {folder} Updated";
|
||||||
|
"lng_filters_updated_also#one" = "You have joined {count} new chat.";
|
||||||
|
"lng_filters_updated_also#other" = "You have joined {count} new chats.";
|
||||||
"lng_filters_bar_you_can#one" = "You can join {count} new chat";
|
"lng_filters_bar_you_can#one" = "You can join {count} new chat";
|
||||||
"lng_filters_bar_you_can#other" = "You can join {count} new chats";
|
"lng_filters_bar_you_can#other" = "You can join {count} new chats";
|
||||||
"lng_filters_bar_view" = "Click here to view them";
|
"lng_filters_bar_view" = "Click here to view them";
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "boxes/peer_list_box.h"
|
#include "boxes/peer_list_box.h"
|
||||||
|
#include "boxes/filters/edit_filter_links.h" // FilterChatStatusText
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "data/data_chat_filters.h"
|
#include "data/data_chat_filters.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
|
@ -21,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/toasts/common_toasts.h"
|
#include "ui/toasts/common_toasts.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/filter_icons.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "styles/style_filter_icons.h"
|
#include "styles/style_filter_icons.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
@ -41,10 +43,9 @@ public:
|
||||||
ToggleChatsController(
|
ToggleChatsController(
|
||||||
not_null<Window::SessionController*> window,
|
not_null<Window::SessionController*> window,
|
||||||
ToggleAction action,
|
ToggleAction action,
|
||||||
const QString &slug,
|
|
||||||
FilterId filterId,
|
|
||||||
const QString &title,
|
const QString &title,
|
||||||
std::vector<not_null<PeerData*>> chats);
|
std::vector<not_null<PeerData*>> chats,
|
||||||
|
std::vector<not_null<PeerData*>> additional);
|
||||||
|
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
|
@ -63,10 +64,9 @@ private:
|
||||||
Ui::RpWidget *_addedTopWidget = nullptr;
|
Ui::RpWidget *_addedTopWidget = nullptr;
|
||||||
|
|
||||||
ToggleAction _action = ToggleAction::Adding;
|
ToggleAction _action = ToggleAction::Adding;
|
||||||
QString _slug;
|
|
||||||
FilterId _filterId = 0;
|
|
||||||
QString _filterTitle;
|
QString _filterTitle;
|
||||||
std::vector<not_null<PeerData*>> _chats;
|
std::vector<not_null<PeerData*>> _chats;
|
||||||
|
std::vector<not_null<PeerData*>> _additional;
|
||||||
rpl::variable<base::flat_set<not_null<PeerData*>>> _selected;
|
rpl::variable<base::flat_set<not_null<PeerData*>>> _selected;
|
||||||
|
|
||||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||||
|
@ -128,13 +128,18 @@ void InitFilterLinkHeader(
|
||||||
Fn<void(int)> setAddedTopHeight,
|
Fn<void(int)> setAddedTopHeight,
|
||||||
Ui::FilterLinkHeaderType type,
|
Ui::FilterLinkHeaderType type,
|
||||||
const QString &title,
|
const QString &title,
|
||||||
|
const QString &iconEmoji,
|
||||||
rpl::producer<int> count) {
|
rpl::producer<int> count) {
|
||||||
|
const auto icon = Ui::LookupFilterIcon(
|
||||||
|
Ui::LookupFilterIconByEmoji(
|
||||||
|
iconEmoji
|
||||||
|
).value_or(Ui::FilterIcon::Custom)).active;
|
||||||
auto header = Ui::MakeFilterLinkHeader(box, {
|
auto header = Ui::MakeFilterLinkHeader(box, {
|
||||||
.type = type,
|
.type = type,
|
||||||
.title = TitleText(type)(tr::now),
|
.title = TitleText(type)(tr::now),
|
||||||
.about = AboutText(type, title),
|
.about = AboutText(type, title),
|
||||||
.folderTitle = title,
|
.folderTitle = title,
|
||||||
.folderIcon = &st::foldersCustomActive,
|
.folderIcon = icon,
|
||||||
.badge = (type == Ui::FilterLinkHeaderType::AddingChats
|
.badge = (type == Ui::FilterLinkHeaderType::AddingChats
|
||||||
? std::move(count)
|
? std::move(count)
|
||||||
: rpl::single(0)),
|
: rpl::single(0)),
|
||||||
|
@ -220,16 +225,14 @@ void ImportInvite(
|
||||||
ToggleChatsController::ToggleChatsController(
|
ToggleChatsController::ToggleChatsController(
|
||||||
not_null<Window::SessionController*> window,
|
not_null<Window::SessionController*> window,
|
||||||
ToggleAction action,
|
ToggleAction action,
|
||||||
const QString &slug,
|
|
||||||
FilterId filterId,
|
|
||||||
const QString &title,
|
const QString &title,
|
||||||
std::vector<not_null<PeerData*>> chats)
|
std::vector<not_null<PeerData*>> chats,
|
||||||
|
std::vector<not_null<PeerData*>> additional)
|
||||||
: _window(window)
|
: _window(window)
|
||||||
, _action(action)
|
, _action(action)
|
||||||
, _slug(slug)
|
|
||||||
, _filterId(filterId)
|
|
||||||
, _filterTitle(title)
|
, _filterTitle(title)
|
||||||
, _chats(std::move(chats)) {
|
, _chats(std::move(chats))
|
||||||
|
, _additional(std::move(additional)) {
|
||||||
setStyleOverrides(&st::filterLinkChatsList);
|
setStyleOverrides(&st::filterLinkChatsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,12 +240,34 @@ void ToggleChatsController::prepare() {
|
||||||
setupAboveWidget();
|
setupAboveWidget();
|
||||||
setupBelowWidget();
|
setupBelowWidget();
|
||||||
auto selected = base::flat_set<not_null<PeerData*>>();
|
auto selected = base::flat_set<not_null<PeerData*>>();
|
||||||
for (const auto &peer : _chats) {
|
const auto add = [&](not_null<PeerData*> peer, bool additional = false) {
|
||||||
auto row = std::make_unique<PeerListRow>(peer);
|
auto row = std::make_unique<PeerListRow>(peer);
|
||||||
|
if (delegate()->peerListFindRow(peer->id.value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto raw = row.get();
|
const auto raw = row.get();
|
||||||
delegate()->peerListAppendRow(std::move(row));
|
delegate()->peerListAppendRow(std::move(row));
|
||||||
delegate()->peerListSetRowChecked(raw, true);
|
if (!additional || _action == ToggleAction::Removing) {
|
||||||
selected.emplace(peer);
|
if (const auto status = FilterChatStatusText(peer)
|
||||||
|
; !status.isEmpty()) {
|
||||||
|
raw->setCustomStatus(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!additional) {
|
||||||
|
delegate()->peerListSetRowChecked(raw, true);
|
||||||
|
selected.emplace(peer);
|
||||||
|
} else if (_action == ToggleAction::Adding) {
|
||||||
|
raw->setDisabledState(PeerListRow::State::DisabledChecked);
|
||||||
|
raw->setCustomStatus(peer->isBroadcast()
|
||||||
|
? tr::lng_filters_link_already_channel(tr::now)
|
||||||
|
: tr::lng_filters_link_already_group(tr::now));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (const auto &peer : _chats) {
|
||||||
|
add(peer);
|
||||||
|
}
|
||||||
|
for (const auto &peer : _additional) {
|
||||||
|
add(peer, true);
|
||||||
}
|
}
|
||||||
delegate()->peerListRefreshRows();
|
delegate()->peerListRefreshRows();
|
||||||
_selected = std::move(selected);
|
_selected = std::move(selected);
|
||||||
|
@ -269,23 +294,51 @@ void ToggleChatsController::setupAboveWidget() {
|
||||||
|
|
||||||
_addedTopWidget = container->add(object_ptr<Ui::RpWidget>(container));
|
_addedTopWidget = container->add(object_ptr<Ui::RpWidget>(container));
|
||||||
AddDivider(container);
|
AddDivider(container);
|
||||||
|
const auto totalCount = [&] {
|
||||||
|
if (_chats.empty()) {
|
||||||
|
return _additional.size();
|
||||||
|
} else if (_additional.empty()) {
|
||||||
|
return _chats.size();
|
||||||
|
}
|
||||||
|
auto result = _chats.size();
|
||||||
|
for (const auto &peer : _additional) {
|
||||||
|
if (!ranges::contains(_chats, peer)) {
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
const auto count = (_action == ToggleAction::Removing)
|
||||||
|
? totalCount()
|
||||||
|
: _chats.empty()
|
||||||
|
? _additional.size()
|
||||||
|
: _chats.size();
|
||||||
AddSubsectionTitle(
|
AddSubsectionTitle(
|
||||||
container,
|
container,
|
||||||
tr::lng_filters_by_link_join(
|
(_action == ToggleAction::Removing
|
||||||
lt_count,
|
? tr::lng_filters_by_link_quit
|
||||||
rpl::single(float64(_chats.size()))),
|
: _chats.empty()
|
||||||
|
? tr::lng_filters_by_link_in
|
||||||
|
: tr::lng_filters_by_link_join)(
|
||||||
|
lt_count,
|
||||||
|
rpl::single(float64(count))),
|
||||||
st::filterLinkSubsectionTitlePadding);
|
st::filterLinkSubsectionTitlePadding);
|
||||||
|
|
||||||
delegate()->peerListSetAboveWidget(std::move(wrap));
|
delegate()->peerListSetAboveWidget(std::move(wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToggleChatsController::setupBelowWidget() {
|
void ToggleChatsController::setupBelowWidget() {
|
||||||
|
if (_chats.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
delegate()->peerListSetBelowWidget(
|
delegate()->peerListSetBelowWidget(
|
||||||
object_ptr<Ui::DividerLabel>(
|
object_ptr<Ui::DividerLabel>(
|
||||||
(QWidget*)nullptr,
|
(QWidget*)nullptr,
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
(QWidget*)nullptr,
|
(QWidget*)nullptr,
|
||||||
tr::lng_filters_by_link_about(tr::now),
|
(_action == ToggleAction::Removing
|
||||||
|
? tr::lng_filters_by_link_about_quit
|
||||||
|
: tr::lng_filters_by_link_about)(tr::now),
|
||||||
st::boxDividerLabel),
|
st::boxDividerLabel),
|
||||||
st::settingsDividerLabelPadding));
|
st::settingsDividerLabelPadding));
|
||||||
}
|
}
|
||||||
|
@ -305,12 +358,40 @@ void ToggleChatsController::setAddedTopHeight(int addedTopHeight) {
|
||||||
_addedTopWidget->resize(_addedTopWidget->width(), addedTopHeight);
|
_addedTopWidget->resize(_addedTopWidget->width(), addedTopHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShowImportToast(
|
||||||
|
base::weak_ptr<Window::SessionController> weak,
|
||||||
|
const QString &title,
|
||||||
|
Ui::FilterLinkHeaderType type,
|
||||||
|
int added) {
|
||||||
|
const auto strong = weak.get();
|
||||||
|
if (!strong) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto created = (type == Ui::FilterLinkHeaderType::AddingFilter);
|
||||||
|
const auto phrase = created
|
||||||
|
? tr::lng_filters_added_title
|
||||||
|
: tr::lng_filters_updated_title;
|
||||||
|
auto text = Ui::Text::Bold(phrase(tr::now, lt_folder, title));
|
||||||
|
if (added > 0) {
|
||||||
|
const auto phrase = created
|
||||||
|
? tr::lng_filters_added_also
|
||||||
|
: tr::lng_filters_updated_also;
|
||||||
|
text.append('\n').append(phrase(tr::now, lt_count, added));
|
||||||
|
}
|
||||||
|
Ui::ShowMultilineToast({
|
||||||
|
.parentOverride = Window::Show(strong).toastParent(),
|
||||||
|
.text = { std::move(text) },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ProcessFilterInvite(
|
void ProcessFilterInvite(
|
||||||
base::weak_ptr<Window::SessionController> weak,
|
base::weak_ptr<Window::SessionController> weak,
|
||||||
const QString &slug,
|
const QString &slug,
|
||||||
FilterId filterId,
|
FilterId filterId,
|
||||||
const QString &title,
|
const QString &title,
|
||||||
std::vector<not_null<PeerData*>> peers) {
|
const QString &iconEmoji,
|
||||||
|
std::vector<not_null<PeerData*>> peers,
|
||||||
|
std::vector<not_null<PeerData*>> already) {
|
||||||
const auto strong = weak.get();
|
const auto strong = weak.get();
|
||||||
if (!strong) {
|
if (!strong) {
|
||||||
return;
|
return;
|
||||||
|
@ -323,19 +404,21 @@ void ProcessFilterInvite(
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto fullyAdded = (peers.empty() && filterId);
|
||||||
auto controller = std::make_unique<ToggleChatsController>(
|
auto controller = std::make_unique<ToggleChatsController>(
|
||||||
strong,
|
strong,
|
||||||
ToggleAction::Adding,
|
ToggleAction::Adding,
|
||||||
slug,
|
|
||||||
filterId,
|
|
||||||
title,
|
title,
|
||||||
std::move(peers));
|
std::move(peers),
|
||||||
|
std::move(already));
|
||||||
const auto raw = controller.get();
|
const auto raw = controller.get();
|
||||||
auto initBox = [=](not_null<PeerListBox*> box) {
|
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||||
box->setStyle(st::filterInviteBox);
|
box->setStyle(st::filterInviteBox);
|
||||||
|
|
||||||
using Type = Ui::FilterLinkHeaderType;
|
using Type = Ui::FilterLinkHeaderType;
|
||||||
const auto type = !filterId
|
const auto type = fullyAdded
|
||||||
|
? Type::AllAdded
|
||||||
|
: !filterId
|
||||||
? Type::AddingFilter
|
? Type::AddingFilter
|
||||||
: Type::AddingChats;
|
: Type::AddingChats;
|
||||||
auto badge = raw->selectedValue(
|
auto badge = raw->selectedValue(
|
||||||
|
@ -344,7 +427,7 @@ void ProcessFilterInvite(
|
||||||
});
|
});
|
||||||
InitFilterLinkHeader(box, [=](int addedTopHeight) {
|
InitFilterLinkHeader(box, [=](int addedTopHeight) {
|
||||||
raw->setAddedTopHeight(addedTopHeight);
|
raw->setAddedTopHeight(addedTopHeight);
|
||||||
}, type, title, rpl::duplicate(badge));
|
}, type, title, iconEmoji, rpl::duplicate(badge));
|
||||||
|
|
||||||
auto owned = Ui::FilterLinkProcessButton(
|
auto owned = Ui::FilterLinkProcessButton(
|
||||||
box,
|
box,
|
||||||
|
@ -380,6 +463,7 @@ void ProcessFilterInvite(
|
||||||
} else if (!state->importing) {
|
} else if (!state->importing) {
|
||||||
state->importing = true;
|
state->importing = true;
|
||||||
ImportInvite(weak, slug, peers, crl::guard(box, [=] {
|
ImportInvite(weak, slug, peers, crl::guard(box, [=] {
|
||||||
|
ShowImportToast(weak, title, type, peers.size());
|
||||||
box->closeBox();
|
box->closeBox();
|
||||||
}), crl::guard(box, [=] {
|
}), crl::guard(box, [=] {
|
||||||
state->importing = false;
|
state->importing = false;
|
||||||
|
@ -396,7 +480,8 @@ void ProcessFilterInvite(
|
||||||
base::weak_ptr<Window::SessionController> weak,
|
base::weak_ptr<Window::SessionController> weak,
|
||||||
const QString &slug,
|
const QString &slug,
|
||||||
FilterId filterId,
|
FilterId filterId,
|
||||||
std::vector<not_null<PeerData*>> peers) {
|
std::vector<not_null<PeerData*>> peers,
|
||||||
|
std::vector<not_null<PeerData*>> already) {
|
||||||
const auto strong = weak.get();
|
const auto strong = weak.get();
|
||||||
if (!strong) {
|
if (!strong) {
|
||||||
return;
|
return;
|
||||||
|
@ -411,7 +496,14 @@ void ProcessFilterInvite(
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ProcessFilterInvite(weak, slug, filterId, it->title(), std::move(peers));
|
ProcessFilterInvite(
|
||||||
|
weak,
|
||||||
|
slug,
|
||||||
|
filterId,
|
||||||
|
it->title(),
|
||||||
|
it->iconEmoji(),
|
||||||
|
std::move(peers),
|
||||||
|
std::move(already));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -441,6 +533,7 @@ void CheckFilterInvite(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto title = QString();
|
auto title = QString();
|
||||||
|
auto iconEmoji = QString();
|
||||||
auto filterId = FilterId();
|
auto filterId = FilterId();
|
||||||
auto peers = std::vector<not_null<PeerData*>>();
|
auto peers = std::vector<not_null<PeerData*>>();
|
||||||
auto already = std::vector<not_null<PeerData*>>();
|
auto already = std::vector<not_null<PeerData*>>();
|
||||||
|
@ -459,6 +552,7 @@ void CheckFilterInvite(
|
||||||
};
|
};
|
||||||
result.match([&](const MTPDcommunities_communityInvite &data) {
|
result.match([&](const MTPDcommunities_communityInvite &data) {
|
||||||
title = qs(data.vtitle());
|
title = qs(data.vtitle());
|
||||||
|
iconEmoji = data.vemoticon().value_or_empty();
|
||||||
peers = parseList(data.vpeers());
|
peers = parseList(data.vpeers());
|
||||||
}, [&](const MTPDcommunities_communityInviteAlready &data) {
|
}, [&](const MTPDcommunities_communityInviteAlready &data) {
|
||||||
filterId = data.vfilter_id().v;
|
filterId = data.vfilter_id().v;
|
||||||
|
@ -477,20 +571,103 @@ void CheckFilterInvite(
|
||||||
owner.chatsFilters().changed(
|
owner.chatsFilters().changed(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
lifetime->destroy();
|
lifetime->destroy();
|
||||||
ProcessFilterInvite(weak, slug, filterId, std::move(peers));
|
ProcessFilterInvite(
|
||||||
|
weak,
|
||||||
|
slug,
|
||||||
|
filterId,
|
||||||
|
std::move(peers),
|
||||||
|
std::move(already));
|
||||||
}, *lifetime);
|
}, *lifetime);
|
||||||
owner.chatsFilters().reload();
|
owner.chatsFilters().reload();
|
||||||
} else if (filterId) {
|
} else if (filterId) {
|
||||||
ProcessFilterInvite(weak, slug, filterId, std::move(peers));
|
ProcessFilterInvite(
|
||||||
|
weak,
|
||||||
|
slug,
|
||||||
|
filterId,
|
||||||
|
std::move(peers),
|
||||||
|
std::move(already));
|
||||||
} else {
|
} else {
|
||||||
ProcessFilterInvite(weak, slug, filterId, title, std::move(peers));
|
ProcessFilterInvite(
|
||||||
|
weak,
|
||||||
|
slug,
|
||||||
|
filterId,
|
||||||
|
title,
|
||||||
|
iconEmoji,
|
||||||
|
std::move(peers),
|
||||||
|
std::move(already));
|
||||||
}
|
}
|
||||||
}, [=](const MTP::Error &error) {
|
}, [=](const MTP::Error &error) {
|
||||||
if (error.code() != 400) {
|
if (error.code() != 400) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ProcessFilterInvite(weak, slug, FilterId(), QString(), {});
|
ProcessFilterInvite(weak, slug, {}, {}, {}, {}, {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProcessFilterRemove(
|
||||||
|
base::weak_ptr<Window::SessionController> weak,
|
||||||
|
const QString &title,
|
||||||
|
const QString &iconEmoji,
|
||||||
|
std::vector<not_null<PeerData*>> all,
|
||||||
|
std::vector<not_null<PeerData*>> suggest,
|
||||||
|
Fn<void(std::vector<not_null<PeerData*>>)> done) {
|
||||||
|
const auto strong = weak.get();
|
||||||
|
if (!strong) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Core::App().hideMediaView();
|
||||||
|
if (all.empty() && suggest.empty()) {
|
||||||
|
done({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto controller = std::make_unique<ToggleChatsController>(
|
||||||
|
strong,
|
||||||
|
ToggleAction::Removing,
|
||||||
|
title,
|
||||||
|
std::move(suggest),
|
||||||
|
std::move(all));
|
||||||
|
const auto raw = controller.get();
|
||||||
|
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||||
|
box->setStyle(st::filterInviteBox);
|
||||||
|
|
||||||
|
const auto type = Ui::FilterLinkHeaderType::Removing;
|
||||||
|
auto badge = raw->selectedValue(
|
||||||
|
) | rpl::map([=](const base::flat_set<not_null<PeerData*>> &peers) {
|
||||||
|
return int(peers.size());
|
||||||
|
});
|
||||||
|
InitFilterLinkHeader(box, [=](int addedTopHeight) {
|
||||||
|
raw->setAddedTopHeight(addedTopHeight);
|
||||||
|
}, type, title, iconEmoji, rpl::single(0));
|
||||||
|
|
||||||
|
auto owned = Ui::FilterLinkProcessButton(
|
||||||
|
box,
|
||||||
|
type,
|
||||||
|
title,
|
||||||
|
std::move(badge));
|
||||||
|
|
||||||
|
const auto button = owned.data();
|
||||||
|
box->widthValue(
|
||||||
|
) | rpl::start_with_next([=](int width) {
|
||||||
|
const auto &padding = st::filterInviteBox.buttonPadding;
|
||||||
|
button->resizeToWidth(width
|
||||||
|
- padding.left()
|
||||||
|
- padding.right());
|
||||||
|
button->moveToLeft(padding.left(), padding.top());
|
||||||
|
}, button->lifetime());
|
||||||
|
|
||||||
|
box->addButton(std::move(owned));
|
||||||
|
|
||||||
|
raw->selectedValue(
|
||||||
|
) | rpl::start_with_next([=](
|
||||||
|
base::flat_set<not_null<PeerData*>> &&peers) {
|
||||||
|
button->setClickedCallback([=] {
|
||||||
|
done(peers | ranges::to_vector);
|
||||||
|
box->closeBox();
|
||||||
|
});
|
||||||
|
}, box->lifetime());
|
||||||
|
};
|
||||||
|
strong->show(
|
||||||
|
Box<PeerListBox>(std::move(controller), std::move(initBox)));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Api
|
} // namespace Api
|
||||||
|
|
|
@ -25,4 +25,12 @@ void CheckFilterInvite(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
const QString &slug);
|
const QString &slug);
|
||||||
|
|
||||||
|
void ProcessFilterRemove(
|
||||||
|
base::weak_ptr<Window::SessionController> weak,
|
||||||
|
const QString &title,
|
||||||
|
const QString &iconEmoji,
|
||||||
|
std::vector<not_null<PeerData*>> all,
|
||||||
|
std::vector<not_null<PeerData*>> suggest,
|
||||||
|
Fn<void(std::vector<not_null<PeerData*>>)> done);
|
||||||
|
|
||||||
} // namespace Api
|
} // namespace Api
|
||||||
|
|
|
@ -706,7 +706,16 @@ void EditFilterBox(
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
AddSubsectionTitle(content, tr::lng_filters_link());
|
AddSubsectionTitle(
|
||||||
|
content,
|
||||||
|
rpl::conditional(
|
||||||
|
state->hasLinks.value(),
|
||||||
|
tr::lng_filters_link_has(),
|
||||||
|
tr::lng_filters_link()));
|
||||||
|
|
||||||
|
state->hasLinks.changes() | rpl::start_with_next([=] {
|
||||||
|
content->resizeToWidth(content->widthNoMargins());
|
||||||
|
}, content->lifetime());
|
||||||
|
|
||||||
if (filter.community()) {
|
if (filter.community()) {
|
||||||
window->session().data().chatsFilters().reloadCommunityLinks(
|
window->session().data().chatsFilters().reloadCommunityLinks(
|
||||||
|
|
|
@ -679,26 +679,12 @@ void LinkController::prepare() {
|
||||||
|
|
||||||
setupAboveWidget();
|
setupAboveWidget();
|
||||||
setupBelowWidget();
|
setupBelowWidget();
|
||||||
const auto countStatus = [&](not_null<PeerData*> peer) {
|
|
||||||
if (const auto chat = peer->asChat()) {
|
|
||||||
if (const auto count = chat->count; count > 0) {
|
|
||||||
return tr::lng_chat_status_members(tr::now, lt_count, count);
|
|
||||||
}
|
|
||||||
} else if (const auto channel = peer->asChannel()) {
|
|
||||||
if (channel->membersCountKnown()) {
|
|
||||||
return (channel->isBroadcast()
|
|
||||||
? tr::lng_chat_status_subscribers
|
|
||||||
: tr::lng_chat_status_members)(
|
|
||||||
tr::now,
|
|
||||||
lt_count,
|
|
||||||
channel->membersCount());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
};
|
|
||||||
for (const auto &history : _data.chats) {
|
for (const auto &history : _data.chats) {
|
||||||
const auto peer = history->peer;
|
const auto peer = history->peer;
|
||||||
auto row = std::make_unique<ChatRow>(peer, countStatus(peer), false);
|
auto row = std::make_unique<ChatRow>(
|
||||||
|
peer,
|
||||||
|
FilterChatStatusText(peer),
|
||||||
|
false);
|
||||||
const auto raw = row.get();
|
const auto raw = row.get();
|
||||||
delegate()->peerListAppendRow(std::move(row));
|
delegate()->peerListAppendRow(std::move(row));
|
||||||
delegate()->peerListSetRowChecked(raw, true);
|
delegate()->peerListSetRowChecked(raw, true);
|
||||||
|
@ -712,7 +698,7 @@ void LinkController::prepare() {
|
||||||
const auto error = ErrorForSharing(history);
|
const auto error = ErrorForSharing(history);
|
||||||
auto row = std::make_unique<ChatRow>(
|
auto row = std::make_unique<ChatRow>(
|
||||||
peer,
|
peer,
|
||||||
error ? error->status : countStatus(peer),
|
error ? error->status : FilterChatStatusText(peer),
|
||||||
error.has_value());
|
error.has_value());
|
||||||
const auto raw = row.get();
|
const auto raw = row.get();
|
||||||
delegate()->peerListAppendRow(std::move(row));
|
delegate()->peerListAppendRow(std::move(row));
|
||||||
|
@ -1160,6 +1146,24 @@ object_ptr<Ui::BoxContent> ShowLinkBox(
|
||||||
return Box<PeerListBox>(std::move(controller), std::move(initBox));
|
return Box<PeerListBox>(std::move(controller), std::move(initBox));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString FilterChatStatusText(not_null<PeerData*> peer) {
|
||||||
|
if (const auto chat = peer->asChat()) {
|
||||||
|
if (const auto count = chat->count; count > 0) {
|
||||||
|
return tr::lng_chat_status_members(tr::now, lt_count, count);
|
||||||
|
}
|
||||||
|
} else if (const auto channel = peer->asChannel()) {
|
||||||
|
if (channel->membersCountKnown()) {
|
||||||
|
return (channel->isBroadcast()
|
||||||
|
? tr::lng_chat_status_subscribers
|
||||||
|
: tr::lng_chat_status_members)(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
channel->membersCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
void SetupFilterLinks(
|
void SetupFilterLinks(
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
not_null<Window::SessionController*> window,
|
not_null<Window::SessionController*> window,
|
||||||
|
|
|
@ -36,10 +36,11 @@ void ExportFilterLink(
|
||||||
Fn<void(Data::ChatFilterLink)> done,
|
Fn<void(Data::ChatFilterLink)> done,
|
||||||
Fn<void(QString)> fail);
|
Fn<void(QString)> fail);
|
||||||
|
|
||||||
object_ptr<Ui::BoxContent> ShowLinkBox(
|
[[nodiscard]] object_ptr<Ui::BoxContent> ShowLinkBox(
|
||||||
not_null<Window::SessionController*> window,
|
not_null<Window::SessionController*> window,
|
||||||
const Data::ChatFilter &filter,
|
const Data::ChatFilter &filter,
|
||||||
const Data::ChatFilterLink &link);
|
const Data::ChatFilterLink &link);
|
||||||
|
[[nodiscard]] QString FilterChatStatusText(not_null<PeerData*> peer);
|
||||||
|
|
||||||
void SetupFilterLinks(
|
void SetupFilterLinks(
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
|
|
@ -1354,6 +1354,9 @@ void Session::setupChannelLeavingViewer() {
|
||||||
history->removeJoinedMessage();
|
history->removeJoinedMessage();
|
||||||
history->updateChatListExistence();
|
history->updateChatListExistence();
|
||||||
history->updateChatListSortPosition();
|
history->updateChatListSortPosition();
|
||||||
|
if (!history->inChatList()) {
|
||||||
|
history->clearFolder();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "settings/settings_folders.h"
|
#include "settings/settings_folders.h"
|
||||||
|
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
#include "api/api_chat_filters.h" // ProcessFilterRemove.
|
||||||
#include "boxes/premium_limits_box.h"
|
#include "boxes/premium_limits_box.h"
|
||||||
#include "boxes/filters/edit_filter_box.h"
|
#include "boxes/filters/edit_filter_box.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
|
@ -22,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lottie/lottie_icon.h"
|
#include "lottie/lottie_icon.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "ui/filter_icons.h"
|
#include "ui/filter_icons.h"
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
|
@ -102,6 +104,10 @@ struct FilterRow {
|
||||||
not_null<FilterRowButton*> button;
|
not_null<FilterRowButton*> button;
|
||||||
Data::ChatFilter filter;
|
Data::ChatFilter filter;
|
||||||
bool removed = false;
|
bool removed = false;
|
||||||
|
bool removeHasLinks = false;
|
||||||
|
mtpRequestId removePeersRequestId = 0;
|
||||||
|
std::vector<not_null<PeerData*>> suggestRemovePeers;
|
||||||
|
std::vector<not_null<PeerData*>> removePeers;
|
||||||
bool added = false;
|
bool added = false;
|
||||||
bool postponedCountUpdate = false;
|
bool postponedCountUpdate = false;
|
||||||
};
|
};
|
||||||
|
@ -361,6 +367,81 @@ void FilterRowButton::paintEvent(QPaintEvent *e) {
|
||||||
controller->show(Box(FiltersLimitBox, session));
|
controller->show(Box(FiltersLimitBox, session));
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
const auto markForRemovalSure = [=](not_null<FilterRowButton*> button) {
|
||||||
|
const auto row = find(button);
|
||||||
|
if (row->removed || row->removePeersRequestId > 0) {
|
||||||
|
return;
|
||||||
|
} else if (row->filter.community()
|
||||||
|
&& !row->filter.always().empty()) {
|
||||||
|
const auto chosen = crl::guard(button, [=](
|
||||||
|
std::vector<not_null<PeerData*>> peers) {
|
||||||
|
const auto row = find(button);
|
||||||
|
row->removePeers = std::move(peers);
|
||||||
|
row->removed = true;
|
||||||
|
button->setRemoved(true);
|
||||||
|
});
|
||||||
|
Api::ProcessFilterRemove(
|
||||||
|
controller,
|
||||||
|
row->filter.title(),
|
||||||
|
row->filter.iconEmoji(),
|
||||||
|
row->filter.always() | ranges::views::transform(
|
||||||
|
&History::peer
|
||||||
|
) | ranges::to_vector,
|
||||||
|
row->suggestRemovePeers,
|
||||||
|
chosen);
|
||||||
|
} else {
|
||||||
|
row->removePeers = {};
|
||||||
|
row->removed = true;
|
||||||
|
button->setRemoved(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const auto markForRemoval = [=](not_null<FilterRowButton*> button) {
|
||||||
|
const auto row = find(button);
|
||||||
|
if (row->removed || row->removePeersRequestId > 0) {
|
||||||
|
return;
|
||||||
|
} else if (row->filter.community() && row->removeHasLinks) {
|
||||||
|
controller->show(Ui::MakeConfirmBox({
|
||||||
|
.text = { tr::lng_filters_delete_sure(tr::now) },
|
||||||
|
.confirmed = crl::guard(button, [=](Fn<void()> close) {
|
||||||
|
markForRemovalSure(button);
|
||||||
|
close();
|
||||||
|
}),
|
||||||
|
.confirmText = tr::lng_box_delete(),
|
||||||
|
.confirmStyle = &st::attentionBoxButton,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
markForRemovalSure(button);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const auto remove = [=](not_null<FilterRowButton*> button) {
|
||||||
|
const auto row = find(button);
|
||||||
|
if (row->removed || row->removePeersRequestId > 0) {
|
||||||
|
return;
|
||||||
|
} else if (row->filter.community() && !row->removePeersRequestId) {
|
||||||
|
row->removePeersRequestId = session->api().request(
|
||||||
|
MTPcommunities_GetLeaveCommunitySuggestions(
|
||||||
|
MTP_inputCommunityDialogFilter(
|
||||||
|
MTP_int(row->filter.id())))
|
||||||
|
).done(crl::guard(button, [=](const MTPVector<MTPPeer> &result) {
|
||||||
|
const auto row = find(button);
|
||||||
|
row->removePeersRequestId = -1;
|
||||||
|
row->suggestRemovePeers = ranges::views::all(
|
||||||
|
result.v
|
||||||
|
) | ranges::views::transform([=](const MTPPeer &peer) {
|
||||||
|
return session->data().peer(peerFromMTP(peer));
|
||||||
|
}) | ranges::to_vector;
|
||||||
|
row->removeHasLinks = true; // #TODO filters
|
||||||
|
markForRemoval(button);
|
||||||
|
})).fail(crl::guard(button, [=] {
|
||||||
|
const auto row = find(button);
|
||||||
|
row->removePeersRequestId = -1;
|
||||||
|
row->removeHasLinks = false;
|
||||||
|
markForRemoval(button);
|
||||||
|
})).send();
|
||||||
|
} else {
|
||||||
|
markForRemoval(button);
|
||||||
|
}
|
||||||
|
};
|
||||||
const auto wrap = container->add(object_ptr<Ui::VerticalLayout>(
|
const auto wrap = container->add(object_ptr<Ui::VerticalLayout>(
|
||||||
container));
|
container));
|
||||||
const auto addFilter = [=](const Data::ChatFilter &filter) {
|
const auto addFilter = [=](const Data::ChatFilter &filter) {
|
||||||
|
@ -368,8 +449,7 @@ void FilterRowButton::paintEvent(QPaintEvent *e) {
|
||||||
object_ptr<FilterRowButton>(wrap, session, filter));
|
object_ptr<FilterRowButton>(wrap, session, filter));
|
||||||
button->removeRequests(
|
button->removeRequests(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
button->setRemoved(true);
|
remove(button);
|
||||||
find(button)->removed = true;
|
|
||||||
}, button->lifetime());
|
}, button->lifetime());
|
||||||
button->restoreRequests(
|
button->restoreRequests(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
|
@ -562,6 +642,7 @@ void FilterRowButton::paintEvent(QPaintEvent *e) {
|
||||||
auto updates = std::vector<MTPUpdate>();
|
auto updates = std::vector<MTPUpdate>();
|
||||||
auto addRequests = std::vector<MTPmessages_UpdateDialogFilter>();
|
auto addRequests = std::vector<MTPmessages_UpdateDialogFilter>();
|
||||||
auto removeRequests = std::vector<MTPmessages_UpdateDialogFilter>();
|
auto removeRequests = std::vector<MTPmessages_UpdateDialogFilter>();
|
||||||
|
auto removeCommunityRequests = std::vector<MTPcommunities_LeaveCommunity>();
|
||||||
|
|
||||||
auto &realFilters = session->data().chatsFilters();
|
auto &realFilters = session->data().chatsFilters();
|
||||||
const auto &list = realFilters.list();
|
const auto &list = realFilters.list();
|
||||||
|
@ -590,17 +671,32 @@ void FilterRowButton::paintEvent(QPaintEvent *e) {
|
||||||
const auto tl = removed
|
const auto tl = removed
|
||||||
? MTPDialogFilter()
|
? MTPDialogFilter()
|
||||||
: row.filter.tl(newId);
|
: row.filter.tl(newId);
|
||||||
const auto request = MTPmessages_UpdateDialogFilter(
|
const auto removeCommunityWithChats = removed
|
||||||
MTP_flags(removed
|
&& row.filter.community()
|
||||||
? MTPmessages_UpdateDialogFilter::Flag(0)
|
&& !row.removePeers.empty();
|
||||||
: MTPmessages_UpdateDialogFilter::Flag::f_filter),
|
if (removeCommunityWithChats) {
|
||||||
MTP_int(newId),
|
auto inputs = ranges::views::all(
|
||||||
tl);
|
row.removePeers
|
||||||
if (removed) {
|
) | ranges::views::transform([](not_null<PeerData*> peer) {
|
||||||
removeRequests.push_back(request);
|
return MTPInputPeer(peer->input);
|
||||||
|
}) | ranges::to<QVector>();
|
||||||
|
removeCommunityRequests.push_back(
|
||||||
|
MTPcommunities_LeaveCommunity(
|
||||||
|
MTP_inputCommunityDialogFilter(MTP_int(newId)),
|
||||||
|
MTP_vector<MTPInputPeer>(std::move(inputs))));
|
||||||
} else {
|
} else {
|
||||||
addRequests.push_back(request);
|
const auto request = MTPmessages_UpdateDialogFilter(
|
||||||
order.push_back(newId);
|
MTP_flags(removed
|
||||||
|
? MTPmessages_UpdateDialogFilter::Flag(0)
|
||||||
|
: MTPmessages_UpdateDialogFilter::Flag::f_filter),
|
||||||
|
MTP_int(newId),
|
||||||
|
tl);
|
||||||
|
if (removed) {
|
||||||
|
removeRequests.push_back(request);
|
||||||
|
} else {
|
||||||
|
addRequests.push_back(request);
|
||||||
|
order.push_back(newId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updates.push_back(MTP_updateDialogFilter(
|
updates.push_back(MTP_updateDialogFilter(
|
||||||
MTP_flags(removed
|
MTP_flags(removed
|
||||||
|
@ -629,7 +725,8 @@ void FilterRowButton::paintEvent(QPaintEvent *e) {
|
||||||
order = std::move(order),
|
order = std::move(order),
|
||||||
updates = std::move(updates),
|
updates = std::move(updates),
|
||||||
addRequests = std::move(addRequests),
|
addRequests = std::move(addRequests),
|
||||||
removeRequests = std::move(removeRequests)
|
removeRequests = std::move(removeRequests),
|
||||||
|
removeCommunityRequests = std::move(removeCommunityRequests)
|
||||||
] {
|
] {
|
||||||
const auto api = &session->api();
|
const auto api = &session->api();
|
||||||
const auto filters = &session->data().chatsFilters();
|
const auto filters = &session->data().chatsFilters();
|
||||||
|
@ -646,18 +743,25 @@ void FilterRowButton::paintEvent(QPaintEvent *e) {
|
||||||
filters->apply(update);
|
filters->apply(update);
|
||||||
}
|
}
|
||||||
auto previousId = mtpRequestId(0);
|
auto previousId = mtpRequestId(0);
|
||||||
auto &&requests = ranges::views::concat(
|
const auto sendRequests = [&](const auto &requests) {
|
||||||
removeRequests,
|
for (auto &request : requests) {
|
||||||
addRequests);
|
previousId = api->request(
|
||||||
for (auto &request : requests) {
|
std::move(request)
|
||||||
previousId = api->request(
|
).done([=](const auto &result, mtpRequestId id) {
|
||||||
std::move(request)
|
if constexpr (std::is_same_v<
|
||||||
).done([=](const auto &, mtpRequestId id) {
|
std::decay_t<decltype(result)>,
|
||||||
ids->remove(id);
|
MTPUpdates>) {
|
||||||
checkFinished();
|
session->api().applyUpdates(result);
|
||||||
}).afterRequest(previousId).send();
|
}
|
||||||
ids->emplace(previousId);
|
ids->remove(id);
|
||||||
}
|
checkFinished();
|
||||||
|
}).afterRequest(previousId).send();
|
||||||
|
ids->emplace(previousId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
sendRequests(removeRequests);
|
||||||
|
sendRequests(removeCommunityRequests);
|
||||||
|
sendRequests(addRequests);
|
||||||
if (!order.empty() && !addRequests.empty()) {
|
if (!order.empty() && !addRequests.empty()) {
|
||||||
filters->saveOrder(order, previousId);
|
filters->saveOrder(order, previousId);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue