Improve premium section bottom.

This commit is contained in:
John Preston 2022-06-13 13:27:38 +04:00
parent 0bd65794d2
commit fc07954276
4 changed files with 73 additions and 81 deletions

View file

@ -1676,7 +1676,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_premium_summary_title" = "Telegram Premium"; "lng_premium_summary_title" = "Telegram Premium";
"lng_premium_summary_top_about" = "Go **beyond the limits**, get **exclusive features** and support us by subscribing to **Telegram Premium**."; "lng_premium_summary_top_about" = "Go **beyond the limits**, get **exclusive features** and support us by subscribing to **Telegram Premium**.";
"lng_premium_summary_title_subscribed" = "You are all set!"; "lng_premium_summary_title_subscribed" = "You are all set!";
"lng_premium_summary_top_about_subscribed" = "Thank you for subscribing to **Telegram Premium**.\nHere's what is now unlocked.";
"lng_premium_summary_subtitle_double_limits" = "Doubled Limits"; "lng_premium_summary_subtitle_double_limits" = "Doubled Limits";
"lng_premium_summary_about_double_limits" = "Up to 1000 channels, 20 folders, 10 pins, 20 public links, 4 accounts and more."; "lng_premium_summary_about_double_limits" = "Up to 1000 channels, 20 folders, 10 pins, 20 public links, 4 accounts and more.";
"lng_premium_summary_subtitle_more_upload" = "4Gb Upload Size"; "lng_premium_summary_subtitle_more_upload" = "4Gb Upload Size";

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/platform_integration.h" #include "platform/platform_integration.h"
#include "platform/platform_specific.h" #include "platform/platform_specific.h"
#include "core/application.h" #include "core/application.h"
#include "core/core_settings.h"
#include "core/sandbox.h" #include "core/sandbox.h"
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>

View file

@ -451,8 +451,18 @@ settingsPremiumRowTitlePadding: margins(60px, 5px, 46px, 3px);
settingsPremiumRowAboutPadding: margins(60px, 0px, 46px, 6px); settingsPremiumRowAboutPadding: margins(60px, 0px, 46px, 6px);
settingsPremiumTitlePadding: margins(0px, 20px, 0px, 16px); settingsPremiumTitlePadding: margins(0px, 20px, 0px, 16px);
settingsPremiumAboutTextStyle: TextStyle(defaultTextStyle) { settingsPremiumAbout: FlatLabel(defaultFlatLabel) {
font: font(12px); style: TextStyle(defaultTextStyle) {
lineHeight: 18px; font: font(12px);
linkFont: font(12px underline);
linkFontOver: font(12px underline);
lineHeight: 18px;
}
palette: TextPalette(defaultTextPalette) {
linkFg: premiumButtonFg;
}
align: align(top);
textFg: premiumButtonFg;
minWidth: 190px;
} }
settingsPremiumStatusPadding: margins(22px, 8px, 22px, 2px); settingsPremiumStatusPadding: margins(22px, 8px, 22px, 2px);

View file

@ -441,7 +441,11 @@ void MiniStars::createStar(crl::time now) {
class TopBar final : public Ui::RpWidget { class TopBar final : public Ui::RpWidget {
public: public:
TopBar(not_null<QWidget*> parent, rpl::producer<bool> premiumValue); TopBar(
not_null<QWidget*> parent,
not_null<Window::SessionController*> controller,
rpl::producer<QString> title,
rpl::producer<TextWithEntities> about);
void setRoundEdges(bool value); void setRoundEdges(bool value);
void setTextPosition(int x, int y); void setTextPosition(int x, int y);
@ -457,10 +461,9 @@ private:
const style::font &_titleFont; const style::font &_titleFont;
const style::margins &_titlePadding; const style::margins &_titlePadding;
const style::TextStyle &_aboutSt; object_ptr<Ui::FlatLabel> _about;
MiniStars _ministars; MiniStars _ministars;
QSvgRenderer _star; QSvgRenderer _star;
Ui::Text::String _about;
struct { struct {
float64 top = 0.; float64 top = 0.;
@ -478,32 +481,37 @@ private:
}; };
TopBar::TopBar(not_null<QWidget*> parent, rpl::producer<bool> premiumValue) TopBar::TopBar(
not_null<QWidget*> parent,
not_null<Window::SessionController*> controller,
rpl::producer<QString> title,
rpl::producer<TextWithEntities> about)
: Ui::RpWidget(parent) : Ui::RpWidget(parent)
, _titleFont(st::boxTitle.style.font) , _titleFont(st::boxTitle.style.font)
, _titlePadding(st::settingsPremiumTitlePadding) , _titlePadding(st::settingsPremiumTitlePadding)
, _aboutSt(st::settingsPremiumAboutTextStyle) , _about(this, std::move(about), st::settingsPremiumAbout)
, _ministars([=](const QRect &r) { update(r); }) , _ministars([=](const QRect &r) { update(r); })
, _star(u":/gui/icons/settings/star.svg"_q) { , _star(u":/gui/icons/settings/star.svg"_q) {
std::move( std::move(
premiumValue title
) | rpl::start_with_next([=](bool premium) { ) | rpl::start_with_next([=](QString text) {
_titlePath = QPainterPath(); _titlePath = QPainterPath();
_titlePath.addText( _titlePath.addText(0, _titleFont->ascent, _titleFont, text);
0,
_titleFont->ascent,
_titleFont,
(premium
? tr::lng_premium_summary_title_subscribed
: tr::lng_premium_summary_title)(tr::now));
const auto &about = premium
? tr::lng_premium_summary_top_about_subscribed
: tr::lng_premium_summary_top_about;
_about.setMarkedText(
_aboutSt,
about(tr::now, Ui::Text::RichLangValue));
update(); update();
}, lifetime()); }, lifetime());
_about->setClickHandlerFilter([=](
const ClickHandlerPtr &handler,
Qt::MouseButton button) {
ActivateClickHandler(_about, handler, {
button,
QVariant::fromValue(ClickHandlerContext{
.sessionWindow = base::make_weak(controller.get()),
.botStartAutoSubmit = true,
})
});
return false;
});
} }
void TopBar::setRoundEdges(bool value) { void TopBar::setRoundEdges(bool value) {
@ -539,6 +547,19 @@ void TopBar::resizeEvent(QResizeEvent *e) {
_ministarsRect = starRect(_progress.top, 1.); _ministarsRect = starRect(_progress.top, 1.);
_starRect = starRect(_progress.top, _progress.body); _starRect = starRect(_progress.top, _progress.body);
const auto &padding = st::boxRowPadding;
const auto availableWidth = width() - padding.left() - padding.right();
const auto titleTop = _starRect.top()
+ _starRect.height()
+ _titlePadding.top();
const auto titlePathRect = _titlePath.boundingRect();
const auto aboutTop = titleTop
+ titlePathRect.height()
+ _titlePadding.bottom();
_about->resizeToWidth(availableWidth);
_about->moveToLeft(padding.left(), aboutTop);
_about->setOpacity(_progress.body);
Ui::RpWidget::resizeEvent(e); Ui::RpWidget::resizeEvent(e);
} }
@ -584,18 +605,7 @@ void TopBar::paintEvent(QPaintEvent *e) {
p.setPen(st::premiumButtonFg); p.setPen(st::premiumButtonFg);
const auto &padding = st::boxRowPadding;
const auto availableWidth = width() - padding.left() - padding.right();
const auto titleTop = _starRect.top()
+ _starRect.height()
+ _titlePadding.top();
const auto titlePathRect = _titlePath.boundingRect(); const auto titlePathRect = _titlePath.boundingRect();
const auto aboutTop = titleTop
+ titlePathRect.height()
+ _titlePadding.bottom();
p.setFont(_aboutSt.font);
_about.draw(p, padding.left(), aboutTop, availableWidth, style::al_top);
// Title. // Title.
p.setOpacity(1.); p.setOpacity(1.);
@ -633,7 +643,6 @@ public:
void showFinished() override; void showFinished() override;
[[nodiscard]] bool hasFlexibleTopBar() const override; [[nodiscard]] bool hasFlexibleTopBar() const override;
[[nodiscard]] const Ui::RoundRect *bottomSkipRounding() const override;
void setStepDataReference(std::any &data) override; void setStepDataReference(std::any &data) override;
@ -649,7 +658,6 @@ private:
base::unique_qptr<Ui::IconButton> _close; base::unique_qptr<Ui::IconButton> _close;
rpl::variable<bool> _backToggles; rpl::variable<bool> _backToggles;
rpl::variable<Info::Wrap> _wrap; rpl::variable<Info::Wrap> _wrap;
std::optional<Ui::RoundRect> _bottomSkipRounding;
rpl::event_stream<> _showBack; rpl::event_stream<> _showBack;
rpl::event_stream<> _showFinished; rpl::event_stream<> _showFinished;
@ -674,10 +682,6 @@ bool Premium::hasFlexibleTopBar() const {
return true; return true;
} }
const Ui::RoundRect *Premium::bottomSkipRounding() const {
return _bottomSkipRounding ? &*_bottomSkipRounding : nullptr;
}
rpl::producer<> Premium::sectionShowBack() { rpl::producer<> Premium::sectionShowBack() {
return _showBack.events(); return _showBack.events();
} }
@ -829,9 +833,22 @@ void Premium::setupContent() {
QPointer<Ui::RpWidget> Premium::createPinnedToTop( QPointer<Ui::RpWidget> Premium::createPinnedToTop(
not_null<QWidget*> parent) { not_null<QWidget*> parent) {
auto title = _controller->session().premium()
? tr::lng_premium_summary_title()
: rpl::conditional(
Data::AmPremiumValue(&_controller->session()),
tr::lng_premium_summary_title_subscribed(),
tr::lng_premium_summary_title());
auto about = rpl::conditional(
Data::AmPremiumValue(&_controller->session()),
_controller->session().api().premium().statusTextValue(),
tr::lng_premium_summary_top_about(Ui::Text::RichLangValue));
const auto content = Ui::CreateChild<TopBar>( const auto content = Ui::CreateChild<TopBar>(
parent.get(), parent.get(),
Data::AmPremiumValue(&_controller->session())); _controller,
std::move(title),
std::move(about));
_wrap.value( _wrap.value(
) | rpl::start_with_next([=](Info::Wrap wrap) { ) | rpl::start_with_next([=](Info::Wrap wrap) {
@ -899,51 +916,25 @@ QPointer<Ui::RpWidget> Premium::createPinnedToBottom(
SendScreenAccept(_controller); SendScreenAccept(_controller);
StartPremiumPayment(_controller, _ref); StartPremiumPayment(_controller, _ref);
}); });
_showFinished.events( _showFinished.events(
) | rpl::take(1) | rpl::start_with_next([=] { ) | rpl::take(1) | rpl::start_with_next([=] {
button->startGlareAnimation(); button->startGlareAnimation();
}, button->lifetime()); }, button->lifetime());
auto text = _controller->session().api().premium().statusTextValue();
const auto status = Ui::CreateChild<Ui::DividerLabel>(
content,
object_ptr<Ui::FlatLabel>(
content,
rpl::duplicate(text),
st::boxDividerLabel),
st::settingsPremiumStatusPadding,
RectPart::Top);
content->widthValue( content->widthValue(
) | rpl::start_with_next([=](int width) { ) | rpl::start_with_next([=](int width) {
const auto padding = st::settingsPremiumButtonPadding; const auto padding = st::settingsPremiumButtonPadding;
status->resizeToWidth(width);
button->resizeToWidth(width - padding.left() - padding.right()); button->resizeToWidth(width - padding.left() - padding.right());
}, status->lifetime()); }, button->lifetime());
const auto controller = _controller;
status->entity()->setClickHandlerFilter([=](
const ClickHandlerPtr &handler,
Qt::MouseButton button) {
ActivateClickHandler(status, handler, {
button,
QVariant::fromValue(ClickHandlerContext{
.sessionWindow = base::make_weak(controller.get()),
.botStartAutoSubmit = true,
})
});
return false;
});
const auto session = &_controller->session(); const auto session = &_controller->session();
rpl::combine( rpl::combine(
button->heightValue(), button->heightValue(),
status->heightValue(),
std::move(text),
Data::AmPremiumValue(session), Data::AmPremiumValue(session),
session->premiumPossibleValue() session->premiumPossibleValue()
) | rpl::start_with_next([=]( ) | rpl::start_with_next([=](
int buttonHeight, int buttonHeight,
int statusHeight,
const TextWithEntities &text,
bool premium, bool premium,
bool premiumPossible) { bool premiumPossible) {
const auto padding = st::settingsPremiumButtonPadding; const auto padding = st::settingsPremiumButtonPadding;
@ -951,19 +942,10 @@ QPointer<Ui::RpWidget> Premium::createPinnedToBottom(
? 0 ? 0
: !premium : !premium
? (padding.top() + buttonHeight + padding.bottom()) ? (padding.top() + buttonHeight + padding.bottom())
: text.text.isEmpty() : 0;
? 0
: statusHeight;
content->resize(content->width(), finalHeight); content->resize(content->width(), finalHeight);
button->moveToLeft(padding.left(), padding.top()); button->moveToLeft(padding.left(), padding.top());
status->moveToLeft(0, 0);
button->setVisible(!premium && premiumPossible); button->setVisible(!premium && premiumPossible);
status->setVisible(premium && !text.text.isEmpty());
if (!premium || text.text.isEmpty()) {
_bottomSkipRounding.reset();
} else if (!_bottomSkipRounding) {
_bottomSkipRounding.emplace(st::boxRadius, st::boxDividerBg);
}
}, button->lifetime()); }, button->lifetime());
return Ui::MakeWeak(not_null<Ui::RpWidget*>{ content }); return Ui::MakeWeak(not_null<Ui::RpWidget*>{ content });