Added preview box for premium doubled limits.

This commit is contained in:
23rd 2022-06-13 14:27:20 +03:00
parent 17274e17ed
commit acf7a82507
8 changed files with 393 additions and 11 deletions

View File

@ -1703,6 +1703,46 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_premium_success" = "You've successfully subscribed to Telegram Premium!";
"lng_premium_unavailable" = "This feature requires subscription to **Telegram Premium**.\n\nUnfortunately, **Telegram Premium** is not available in your region.";
// Doubled Limits.
"lng_premium_double_limits_subtitle_channels" = "Groups and Channels";
"lng_premium_double_limits_about_channels#one" = "Join up to {count} channels and large groups";
"lng_premium_double_limits_about_channels#other" = "Join up to {count} channels and large groups";
"lng_premium_double_limits_subtitle_pins" = "Pinned Chats";
"lng_premium_double_limits_about_pins#one" = "Pin up to {count} chats in your main chat list";
"lng_premium_double_limits_about_pins#other" = "Pin up to {count} chats in your main chat list";
"lng_premium_double_limits_subtitle_links" = "Public Links";
"lng_premium_double_limits_about_links#one" = "Reserve up to {count} t.me/name links";
"lng_premium_double_limits_about_links#other" = "Reserve up to {count} t.me/name links";
"lng_premium_double_limits_subtitle_gifs" = "Saved GIFs";
"lng_premium_double_limits_about_gifs#one" = "Save up to {count} GIFs in your Favorite GIFs";
"lng_premium_double_limits_about_gifs#other" = "Save up to {count} GIFs in your Favorite GIFs";
"lng_premium_double_limits_subtitle_stickers" = "Favorite Stickers";
"lng_premium_double_limits_about_stickers#one" = "Save up to {count} stickers in your Favorite stickers";
"lng_premium_double_limits_about_stickers#other" = "Save up to {count} stickers in your Favorite stickers";
"lng_premium_double_limits_subtitle_bio" = "Bio";
"lng_premium_double_limits_about_bio" = "Add more symbols and use links in your bio";
"lng_premium_double_limits_subtitle_captions" = "Captions";
"lng_premium_double_limits_about_captions" = "Use longer description for your photos and videos";
"lng_premium_double_limits_subtitle_folders" = "Folders";
"lng_premium_double_limits_about_folders#one" = "Organize your chats into {count} folders";
"lng_premium_double_limits_about_folders#other" = "Organize your chats into {count} folders";
"lng_premium_double_limits_subtitle_folder_chats" = "Chats per Folder";
"lng_premium_double_limits_about_folder_chats#one" = "Add up to {count} chats into each of your folders";
"lng_premium_double_limits_about_folder_chats#other" = "Add up to {count} chats into each of your folders";
"lng_premium_double_limits_subtitle_accounts" = "Connected Accounts";
"lng_premium_double_limits_about_accounts#one" = "Connect {count} accounts with different mobile numbers";
"lng_premium_double_limits_about_accounts#other" = "Connect {count} accounts with different mobile numbers";
//
"lng_accounts_limit_title" = "Limit Reached";
"lng_accounts_limit1#one" = "You have reached the limit of **{count}** connected accounts.";
"lng_accounts_limit1#other" = "You have reached the limit of **{count}** connected accounts.";

View File

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_streaming.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "main/main_domain.h" // kMaxAccounts
#include "ui/chat/chat_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/layers/generic_box.h"
@ -29,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/gradient_round_button.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/boxes/confirm_box.h"
#include "boxes/premium_limits_box.h" // AppConfigLimit
#include "settings/settings_premium.h"
#include "lottie/lottie_single_player.h"
#include "history/view/media/history_view_sticker.h"
@ -1293,3 +1295,178 @@ void PremiumUnavailableBox(not_null<Ui::GenericBox*> box) {
.inform = true,
});
}
void DoubledLimitsPreviewBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session) {
auto entries = std::vector<Ui::Premium::ListEntry>();
{
const auto premium = AppConfigLimit(
session,
"channels_limit_premium",
500 * 2);
entries.push_back(Ui::Premium::ListEntry{
tr::lng_premium_double_limits_subtitle_channels(),
tr::lng_premium_double_limits_about_channels(
lt_count,
rpl::single(float64(premium)),
Ui::Text::RichLangValue),
AppConfigLimit(
session,
"channels_limit_default",
500),
premium,
});
}
{
const auto premium = AppConfigLimit(
session,
"dialogs_folder_pinned_limit_premium",
5 * 2);
entries.push_back(Ui::Premium::ListEntry{
tr::lng_premium_double_limits_subtitle_pins(),
tr::lng_premium_double_limits_about_pins(
lt_count,
rpl::single(float64(premium)),
Ui::Text::RichLangValue),
AppConfigLimit(
session,
"dialogs_folder_pinned_limit_default",
5),
premium,
});
}
{
const auto premium = AppConfigLimit(
session,
"channels_public_limit_premium",
10 * 2);
entries.push_back(Ui::Premium::ListEntry{
tr::lng_premium_double_limits_subtitle_links(),
tr::lng_premium_double_limits_about_links(
lt_count,
rpl::single(float64(premium)),
Ui::Text::RichLangValue),
AppConfigLimit(
session,
"channels_public_limit_default",
10),
premium,
});
}
{
const auto premium = AppConfigLimit(
session,
"saved_gifs_limit_premium",
200 * 2);
entries.push_back(Ui::Premium::ListEntry{
tr::lng_premium_double_limits_subtitle_gifs(),
tr::lng_premium_double_limits_about_gifs(
lt_count,
rpl::single(float64(premium)),
Ui::Text::RichLangValue),
AppConfigLimit(
session,
"saved_gifs_limit_default",
200),
premium,
});
}
{
const auto premium = AppConfigLimit(
session,
"stickers_faved_limit_premium",
5 * 2);
entries.push_back(Ui::Premium::ListEntry{
tr::lng_premium_double_limits_subtitle_stickers(),
tr::lng_premium_double_limits_about_stickers(
lt_count,
rpl::single(float64(premium)),
Ui::Text::RichLangValue),
AppConfigLimit(
session,
"stickers_faved_limit_default",
5),
premium,
});
}
{
const auto premium = AppConfigLimit(
session,
"about_length_limit_premium",
70 * 2);
entries.push_back(Ui::Premium::ListEntry{
tr::lng_premium_double_limits_subtitle_bio(),
tr::lng_premium_double_limits_about_bio(
Ui::Text::RichLangValue),
AppConfigLimit(
session,
"about_length_limit_default",
70),
premium,
});
}
{
const auto premium = AppConfigLimit(
session,
"caption_length_limit_premium",
1024 * 2);
entries.push_back(Ui::Premium::ListEntry{
tr::lng_premium_double_limits_subtitle_captions(),
tr::lng_premium_double_limits_about_captions(
Ui::Text::RichLangValue),
AppConfigLimit(
session,
"caption_length_limit_default",
1024),
premium,
});
}
{
const auto premium = AppConfigLimit(
session,
"dialog_filters_limit_premium",
10 * 2);
entries.push_back(Ui::Premium::ListEntry{
tr::lng_premium_double_limits_subtitle_folders(),
tr::lng_premium_double_limits_about_folders(
lt_count,
rpl::single(float64(premium)),
Ui::Text::RichLangValue),
AppConfigLimit(
session,
"dialog_filters_limit_default",
10),
premium,
});
}
{
const auto premium = AppConfigLimit(
session,
"dialog_filters_chats_limit_premium",
100 * 2);
entries.push_back(Ui::Premium::ListEntry{
tr::lng_premium_double_limits_subtitle_folder_chats(),
tr::lng_premium_double_limits_about_folder_chats(
lt_count,
rpl::single(float64(premium)),
Ui::Text::RichLangValue),
AppConfigLimit(
session,
"dialog_filters_chats_limit_default",
100),
premium,
});
}
entries.push_back(Ui::Premium::ListEntry{
tr::lng_premium_double_limits_subtitle_accounts(),
tr::lng_premium_double_limits_about_accounts(
lt_count,
rpl::single(float64(Main::Domain::kMaxAccounts)),
Ui::Text::RichLangValue),
Main::Domain::kMaxAccounts,
Main::Domain::kPremiumMaxAccounts,
QString::number(Main::Domain::kMaxAccounts + 1) + QChar('+'),
});
Ui::Premium::ShowListBox(box, std::move(entries));
}

View File

@ -17,10 +17,18 @@ namespace Window {
class SessionController;
} // namespace Window
namespace Main {
class Session;
} // namespace Main
void ShowStickerPreviewBox(
not_null<Window::SessionController*> controller,
not_null<DocumentData*> document);
void DoubledLimitsPreviewBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session);
enum class PremiumPreview {
MoreUpload,
FasterDownload,

View File

@ -288,6 +288,9 @@ premiumPreviewBox: Box(defaultBox) {
font: font(13px semibold);
}
}
premiumPreviewDoubledLimitsBox: Box(premiumPreviewBox) {
buttonPadding: margins(12px, 12px, 12px, 12px);
}
premiumPreviewAboutTitlePadding: margins(18px, 19px, 18px, 0px);
premiumPreviewAboutTitle: FlatLabel(defaultFlatLabel) {
minWidth: 240px;

View File

@ -449,6 +449,9 @@ settingsPremiumTopBarClose: IconButton(infoTopBarClose) {
}
settingsPremiumRowTitlePadding: margins(60px, 5px, 46px, 3px);
settingsPremiumRowAboutPadding: margins(60px, 0px, 46px, 6px);
settingsPremiumPreviewTitlePadding: margins(24px, 13px, 24px, 3px);
settingsPremiumPreviewAboutPadding: margins(24px, 0px, 24px, 11px);
settingsPremiumPreviewLinePadding: margins(18px, 0px, 18px, 8px);
settingsPremiumTitlePadding: margins(0px, 20px, 0px, 16px);
settingsPremiumAbout: FlatLabel(defaultFlatLabel) {

View File

@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "info/info_wrap_widget.h" // Info::Wrap.
#include "info/settings/info_settings_widget.h" // SectionCustomTopBarData.
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "boxes/premium_preview_box.h"
#include "settings/settings_common.h"
#include "settings/settings_premium.h"
@ -782,6 +781,33 @@ void Premium::setupContent() {
arrow->moveToRight(0, (s.height() - arrow->height()) / 2);
}, arrow->lifetime());
button->setClickedCallback([=, controller = _controller] {
controller->show(Box([=](not_null<Ui::GenericBox*> box) {
DoubledLimitsPreviewBox(box, &controller->session());
auto callback = [=] {
SendScreenAccept(controller);
StartPremiumPayment(controller, _ref);
};
const auto button = CreateSubscribeButton(
controller,
box,
std::move(callback));
box->setStyle(st::premiumPreviewDoubledLimitsBox);
box->widthValue(
) | rpl::start_with_next([=](int width) {
const auto &padding =
st::premiumPreviewDoubledLimitsBox.buttonPadding;
button->resizeToWidth(width
- padding.left()
- padding.right());
button->moveToLeft(padding.left(), padding.top());
}, button->lifetime());
box->addButton(
object_ptr<Ui::AbstractButton>::fromRaw(button));
}));
});
iconContainers.push_back(dummy);
};
@ -815,10 +841,7 @@ void Premium::setupContent() {
const auto from = iconContainers.front()->y();
const auto to = iconContainers.back()->y() + iconSize.height();
auto gradient = QLinearGradient(0, 0, 0, to - from);
gradient.setColorAt(0.0, st::premiumIconBg1->c);
gradient.setColorAt(.28, st::premiumIconBg2->c);
gradient.setColorAt(.55, st::premiumButtonBg2->c);
gradient.setColorAt(1.0, st::premiumButtonBg1->c);
gradient.setStops(Ui::Premium::FullHeightGradientStops());
for (auto i = 0; i < int(icons.size()); i++) {
const auto &iconContainer = iconContainers[i];

View File

@ -11,11 +11,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/animations.h"
#include "ui/effects/gradient.h"
#include "ui/effects/numbers_animation.h"
#include "ui/text/text_utilities.h"
#include "ui/layers/generic_box.h"
#include "ui/text/text_options.h"
#include "ui/widgets/checkbox.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/wrap/vertical_layout.h"
#include "styles/style_boxes.h"
#include "styles/style_settings.h"
#include "styles/style_layers.h"
#include "styles/style_widgets.h"
@ -452,6 +455,8 @@ public:
TextFactory textFactory,
int min);
void setColorOverride(QBrush brush);
protected:
void paintEvent(QPaintEvent *event) override;
@ -469,6 +474,8 @@ private:
Ui::Text::String _rightLabel;
Ui::Text::String _leftLabel;
std::optional<QBrush> _overrideBrush;
};
Line::Line(
@ -495,6 +502,14 @@ Line::Line(
}, lifetime());
}
void Line::setColorOverride(QBrush brush) {
if (brush.style() == Qt::NoBrush) {
_overrideBrush = std::nullopt;
} else {
_overrideBrush = brush;
}
}
void Line::paintEvent(QPaintEvent *event) {
Painter p(this);
@ -568,11 +583,15 @@ void Line::recache(const QSize &s) {
halfRect.setRight(r.center().x());
pathRect.addRect(halfRect);
auto gradient = ComputeGradient(
this,
(_leftPixmap.width() / style::DevicePixelRatio()) + r.x(),
r.width());
p.fillPath(pathRound + pathRect, QBrush(std::move(gradient)));
if (_overrideBrush) {
p.fillPath(pathRound + pathRect, *_overrideBrush);
} else {
auto gradient = ComputeGradient(
this,
(_leftPixmap.width() / style::DevicePixelRatio()) + r.x(),
r.width());
p.fillPath(pathRound + pathRect, QBrush(std::move(gradient)));
}
_rightPixmap = std::move(rightPixmap);
}
@ -612,7 +631,7 @@ void AddLimitRow(
int max,
std::optional<tr::phrase<lngtag_count>> phrase,
int min) {
const auto line = parent->add(
parent->add(
object_ptr<Line>(parent, max, ProcessTextFactory(phrase), min),
st::boxRowPadding);
}
@ -774,5 +793,101 @@ QGradientStops LockGradientStops() {
return ButtonGradientStops();
}
QGradientStops FullHeightGradientStops() {
return {
{ 0.0, st::premiumIconBg1->c },
{ .28, st::premiumIconBg2->c },
{ .55, st::premiumButtonBg2->c },
{ 1.0, st::premiumButtonBg1->c },
};
}
void ShowListBox(
not_null<Ui::GenericBox*> box,
std::vector<ListEntry> entries) {
const auto &stLabel = st::defaultFlatLabel;
const auto &titlePadding = st::settingsPremiumPreviewTitlePadding;
const auto &descriptionPadding = st::settingsPremiumPreviewAboutPadding;
auto lines = std::vector<Line*>();
lines.reserve(int(entries.size()));
const auto content = box->verticalLayout();
for (auto &entry : entries) {
const auto subtitle = content->add(
object_ptr<Ui::FlatLabel>(
content,
base::take(entry.subtitle) | rpl::map(Ui::Text::Bold),
stLabel),
titlePadding);
const auto description = content->add(
object_ptr<Ui::FlatLabel>(
content,
base::take(entry.description),
st::boxDividerLabel),
descriptionPadding);
const auto limitRow = content->add(
object_ptr<Line>(
content,
entry.rightNumber,
TextFactory([=, text = ProcessTextFactory(std::nullopt)](
int n) {
if (entry.customRightText && (n == entry.rightNumber)) {
return *entry.customRightText;
} else {
return text(n);
}
}),
entry.leftNumber),
st::settingsPremiumPreviewLinePadding);
lines.push_back(limitRow);
}
content->resizeToWidth(content->height());
// Color lines.
Assert(lines.size() > 2);
const auto from = lines.front()->y();
const auto to = lines.back()->y() + lines.back()->height();
auto gradient = QLinearGradient(0, 0, 0, to - from);
{
auto stops = Ui::Premium::FullHeightGradientStops();
for (auto &stop : stops) {
stop.first = std::abs(stop.first - 1.);
}
gradient.setStops(std::move(stops));
}
for (auto i = 0; i < int(lines.size()); i++) {
const auto &line = lines[i];
const auto pointTop = line->y() - from;
const auto pointBottom = pointTop + line->height();
const auto ratioTop = pointTop / float64(to - from);
const auto ratioBottom = pointBottom / float64(to - from);
auto resultGradient = QLinearGradient(
QPointF(),
QPointF(0, pointBottom - pointTop));
resultGradient.setColorAt(
.0,
anim::gradient_color_at(gradient, ratioTop));
resultGradient.setColorAt(
.1,
anim::gradient_color_at(gradient, ratioBottom));
const auto brush = QBrush(resultGradient);
line->setColorOverride(brush);
}
box->addSkip(st::settingsPremiumPreviewLinePadding.bottom());
box->setTitle(tr::lng_premium_summary_subtitle_double_limits());
box->setWidth(st::boxWideWidth);
}
} // namespace Premium
} // namespace Ui

View File

@ -23,6 +23,7 @@ struct TextStyle;
namespace Ui {
class GenericBox;
class RadiobuttonGroup;
class VerticalLayout;
@ -63,6 +64,18 @@ void AddAccountsRow(
[[nodiscard]] QGradientStops LimitGradientStops();
[[nodiscard]] QGradientStops ButtonGradientStops();
[[nodiscard]] QGradientStops LockGradientStops();
[[nodiscard]] QGradientStops FullHeightGradientStops();
struct ListEntry final {
rpl::producer<QString> subtitle;
rpl::producer<TextWithEntities> description;
int leftNumber = 0;
int rightNumber = 0;
std::optional<QString> customRightText;
};
void ShowListBox(
not_null<Ui::GenericBox*> box,
std::vector<ListEntry> entries);
} // namespace Premium
} // namespace Ui