Support new limit boxes for shareable folders.

This commit is contained in:
John Preston 2023-04-03 17:42:01 +04:00
parent 77939ae9bd
commit 9b1c5b1050
10 changed files with 160 additions and 16 deletions

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "boxes/peer_list_box.h"
#include "boxes/premium_limits_box.h"
#include "boxes/filters/edit_filter_links.h" // FilterChatStatusText
#include "core/application.h"
#include "data/data_chat_filters.h"
@ -362,6 +363,30 @@ void ToggleChatsController::setAddedTopHeight(int addedTopHeight) {
_addedTopWidget->resize(_addedTopWidget->width(), addedTopHeight);
}
void ShowImportError(
not_null<Window::SessionController*> window,
FilterId id,
int added,
const QString &error) {
const auto session = &window->session();
const auto &list = session->data().chatsFilters().list();
const auto i = ranges::find(list, id, &Data::ChatFilter::id);
const auto count = added
+ ((i != end(list)) ? int(i->always().size()) : 0);
if (error == u"USER_CHANNELS_TOO_MUCH"_q) {
window->show(Box(ChannelsLimitBox, session));
} else if (error == u"FILTER_INCLUDE_TOO_MUCH"_q) {
window->show(Box(FilterChatsLimitBox, session, count));
} else if (error == u"CHATLISTS_TOO_MUCH"_q) {
window->show(Box(ShareableFiltersLimitBox, session));
} else {
Ui::ShowMultilineToast({
.parentOverride = Window::Show(window).toastParent(),
.text = { error },
});
}
}
void ShowImportToast(
base::weak_ptr<Window::SessionController> weak,
const QString &title,
@ -462,20 +487,15 @@ void ProcessFilterInvite(
button->setClickedCallback([=] {
if (peers.empty()) {
box->closeBox();
//} else if (count + alreadyInFilter() >= ...) {
// #TODO filters
} else if (!state->importing) {
state->importing = true;
const auto added = int(peers.size());
ImportInvite(slug, filterId, peers, crl::guard(box, [=] {
ShowImportToast(weak, title, type, peers.size());
box->closeBox();
}), crl::guard(box, [=](QString text) {
if (const auto strong = weak.get()) {
Ui::ShowMultilineToast({
.parentOverride = Window::Show(
strong).toastParent(),
.text = { text },
});
ShowImportError(strong, filterId, added, text);
}
state->importing = false;
}));

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/filters/edit_filter_chats_list.h"
#include "boxes/filters/edit_filter_links.h"
#include "boxes/premium_limits_box.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "ui/layers/generic_box.h"
#include "ui/text/text_utilities.h"
@ -769,8 +770,12 @@ void EditFilterBox(
window->show(ShowLinkBox(window, updated, link));
}, [=](QString error) {
if (error == "CHATLISTS_TOO_MUCH") {
// #TODO filters
if (error == u"CHATLISTS_TOO_MUCH"_q) {
const auto session = &window->session();
window->show(Box(ShareableFiltersLimitBox, session));
} else if (error == u"INVITES_TOO_MUCH"_q) {
const auto session = &window->session();
window->show(Box(FilterLinksLimitBox, session));
} else {
window->show(ShowLinkBox(window, updated, { .id = id }));
}

View File

@ -1047,7 +1047,8 @@ bool GoodForExportFilterLink(
not_null<Window::SessionController*> window,
const Data::ChatFilter &filter) {
using Flag = Data::ChatFilter::Flag;
if (!filter.never().empty() || (filter.flags() & ~Flag::Chatlist)) {
const auto listflags = Flag::Chatlist | Flag::HasMyLinks;
if (!filter.never().empty() || (filter.flags() & ~listflags)) {
Ui::ShowMultilineToast({
.parentOverride = Window::Show(window).toastParent(),
.text = { tr::lng_filters_link_cant(tr::now) },

View File

@ -723,6 +723,44 @@ void FilterChatsLimitBox(
{ defaultLimit, current, premiumLimit, &st::premiumIconChats });
}
void FilterLinksLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session) {
const auto premium = session->premium();
const auto premiumPossible = session->premiumPossible();
const auto limits = Data::PremiumLimits(session);
const auto defaultLimit = float64(limits.dialogFiltersLinksDefault());
const auto premiumLimit = float64(limits.dialogFiltersLinksPremium());
const auto current = (premium ? premiumLimit : defaultLimit);
auto text = rpl::combine(
tr::lng_filter_links_limit1(
lt_count,
rpl::single(premium ? premiumLimit : defaultLimit),
Ui::Text::RichLangValue),
((premium || !premiumPossible)
? rpl::single(TextWithEntities())
: tr::lng_filter_links_limit2(
lt_count,
rpl::single(premiumLimit),
Ui::Text::RichLangValue))
) | rpl::map([](TextWithEntities &&a, TextWithEntities &&b) {
return b.text.isEmpty()
? a
: a.append(QChar(' ')).append(std::move(b));
});
SimpleLimitBox(
box,
session,
tr::lng_filter_links_limit_title(),
std::move(text),
"chatlist_invites",
{ defaultLimit, current, premiumLimit, &st::premiumIconChats });
}
void FiltersLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session) {
@ -761,6 +799,44 @@ void FiltersLimitBox(
{ defaultLimit, current, premiumLimit, &st::premiumIconFolders });
}
void ShareableFiltersLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session) {
const auto premium = session->premium();
const auto premiumPossible = session->premiumPossible();
const auto limits = Data::PremiumLimits(session);
const auto defaultLimit = float64(limits.dialogShareableFiltersDefault());
const auto premiumLimit = float64(limits.dialogShareableFiltersPremium());
const auto current = float64(ranges::count_if(
session->data().chatsFilters().list(),
[](const Data::ChatFilter &f) { return f.chatlist(); }));
auto text = rpl::combine(
tr::lng_filter_shared_limit1(
lt_count,
rpl::single(premium ? premiumLimit : defaultLimit),
Ui::Text::RichLangValue),
((premium || !premiumPossible)
? rpl::single(TextWithEntities())
: tr::lng_filter_shared_limit2(
lt_count,
rpl::single(premiumLimit),
Ui::Text::RichLangValue))
) | rpl::map([](TextWithEntities &&a, TextWithEntities &&b) {
return b.text.isEmpty()
? a
: a.append(QChar(' ')).append(std::move(b));
});
SimpleLimitBox(
box,
session,
tr::lng_filter_shared_limit_title(),
std::move(text),
"chatlists_joined",
{ defaultLimit, current, premiumLimit, &st::premiumIconFolders });
}
void FilterPinsLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session,

View File

@ -32,9 +32,15 @@ void FilterChatsLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session,
int currentCount);
void FilterLinksLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session);
void FiltersLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session);
void ShareableFiltersLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session);
void FilterPinsLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session,

View File

@ -155,7 +155,8 @@ ChatFilter ChatFilter::FromTL(
data.vid().v,
qs(data.vtitle()),
qs(data.vemoticon().value_or_empty()),
Flag::Chatlist,
(Flag::Chatlist
| (data.is_has_my_invites() ? Flag::HasMyLinks : Flag())),
std::move(list),
std::move(pinned),
{});
@ -239,6 +240,10 @@ bool ChatFilter::chatlist() const {
return _flags & Flag::Chatlist;
}
bool ChatFilter::hasMyLinks() const {
return _flags & Flag::HasMyLinks;
}
const base::flat_set<not_null<History*>> &ChatFilter::always() const {
return _always;
}

View File

@ -37,7 +37,8 @@ public:
NoRead = (1 << 6),
NoArchived = (1 << 7),
Chatlist = (1 << 8),
Chatlist = (1 << 8),
HasMyLinks = (1 << 9),
};
friend constexpr inline bool is_flag_type(Flag) { return true; };
using Flags = base::flags<Flag>;
@ -64,6 +65,7 @@ public:
[[nodiscard]] QString iconEmoji() const;
[[nodiscard]] Flags flags() const;
[[nodiscard]] bool chatlist() const;
[[nodiscard]] bool hasMyLinks() const;
[[nodiscard]] const base::flat_set<not_null<History*>> &always() const;
[[nodiscard]] const std::vector<not_null<History*>> &pinned() const;
[[nodiscard]] const base::flat_set<not_null<History*>> &never() const;

View File

@ -65,6 +65,18 @@ int PremiumLimits::dialogFiltersCurrent() const {
: dialogFiltersDefault();
}
int PremiumLimits::dialogShareableFiltersDefault() const {
return appConfigLimit("chatlists_joined_limit_default", 2);
}
int PremiumLimits::dialogShareableFiltersPremium() const {
return appConfigLimit("chatlists_joined_limit_premium", 20);
}
int PremiumLimits::dialogShareableFiltersCurrent() const {
return isPremium()
? dialogShareableFiltersPremium()
: dialogShareableFiltersDefault();
}
int PremiumLimits::dialogFiltersChatsDefault() const {
return appConfigLimit("dialog_filters_chats_limit_default", 100);
}
@ -77,6 +89,18 @@ int PremiumLimits::dialogFiltersChatsCurrent() const {
: dialogFiltersChatsDefault();
}
int PremiumLimits::dialogFiltersLinksDefault() const {
return appConfigLimit("chatlist_invites_limit_default", 3);
}
int PremiumLimits::dialogFiltersLinksPremium() const {
return appConfigLimit("chatlist_invites_limit_premium", 20);
}
int PremiumLimits::dialogFiltersLinksCurrent() const {
return isPremium()
? dialogFiltersLinksPremium()
: dialogFiltersLinksDefault();
}
int PremiumLimits::dialogsPinnedDefault() const {
return appConfigLimit("dialogs_pinned_limit_default", 5);
}

View File

@ -33,10 +33,18 @@ public:
[[nodiscard]] int dialogFiltersPremium() const;
[[nodiscard]] int dialogFiltersCurrent() const;
[[nodiscard]] int dialogShareableFiltersDefault() const;
[[nodiscard]] int dialogShareableFiltersPremium() const;
[[nodiscard]] int dialogShareableFiltersCurrent() const;
[[nodiscard]] int dialogFiltersChatsDefault() const;
[[nodiscard]] int dialogFiltersChatsPremium() const;
[[nodiscard]] int dialogFiltersChatsCurrent() const;
[[nodiscard]] int dialogFiltersLinksDefault() const;
[[nodiscard]] int dialogFiltersLinksPremium() const;
[[nodiscard]] int dialogFiltersLinksCurrent() const;
[[nodiscard]] int dialogsPinnedDefault() const;
[[nodiscard]] int dialogsPinnedPremium() const;
[[nodiscard]] int dialogsPinnedCurrent() const;

View File

@ -104,7 +104,6 @@ struct FilterRow {
not_null<FilterRowButton*> button;
Data::ChatFilter filter;
bool removed = false;
bool removeHasLinks = false;
mtpRequestId removePeersRequestId = 0;
std::vector<not_null<PeerData*>> suggestRemovePeers;
std::vector<not_null<PeerData*>> removePeers;
@ -399,7 +398,7 @@ void FilterRowButton::paintEvent(QPaintEvent *e) {
const auto row = find(button);
if (row->removed || row->removePeersRequestId > 0) {
return;
} else if (row->filter.chatlist() && row->removeHasLinks) {
} else if (row->filter.hasMyLinks()) {
controller->show(Ui::MakeConfirmBox({
.text = { tr::lng_filters_delete_sure(tr::now) },
.confirmed = crl::guard(button, [=](Fn<void()> close) {
@ -430,12 +429,10 @@ void FilterRowButton::paintEvent(QPaintEvent *e) {
) | 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 {