mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-07-27 07:52:57 +02:00
Added suggestion for annual premium to top bar in dialogs.
This commit is contained in:
parent
98d9357208
commit
640db8af7d
9 changed files with 118 additions and 20 deletions
|
@ -3865,6 +3865,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
"lng_dialogs_top_bar_suggestions_birthday_title" = "Add your birthday! 🎂";
|
"lng_dialogs_top_bar_suggestions_birthday_title" = "Add your birthday! 🎂";
|
||||||
"lng_dialogs_top_bar_suggestions_birthday_about" = "Let your contacts know when you’re celebrating.";
|
"lng_dialogs_top_bar_suggestions_birthday_about" = "Let your contacts know when you’re celebrating.";
|
||||||
|
"lng_dialogs_top_bar_suggestions_premium_annual_title" = "Telegram Premium with a {text} discount";
|
||||||
|
"lng_dialogs_top_bar_suggestions_premium_annual_about" = "Sign up for the annual payment plan for Telegram Premium now to get the discount.";
|
||||||
|
|
||||||
"lng_about_random" = "Send a {emoji} emoji to any chat to try your luck.";
|
"lng_about_random" = "Send a {emoji} emoji to any chat to try your luck.";
|
||||||
"lng_about_random_send" = "Send";
|
"lng_about_random_send" = "Send";
|
||||||
|
|
|
@ -25,6 +25,7 @@ Data::PremiumSubscriptionOption CreateSubscriptionOption(
|
||||||
* kDiscountDivider;
|
* kDiscountDivider;
|
||||||
}();
|
}();
|
||||||
return {
|
return {
|
||||||
|
.months = months,
|
||||||
.duration = Ui::FormatTTL(months * 86400 * 31),
|
.duration = Ui::FormatTTL(months * 86400 * 31),
|
||||||
.discount = (discount > 0)
|
.discount = (discount > 0)
|
||||||
? QString::fromUtf8("\xe2\x88\x92%1%").arg(discount)
|
? QString::fromUtf8("\xe2\x88\x92%1%").arg(discount)
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
struct PremiumSubscriptionOption {
|
struct PremiumSubscriptionOption {
|
||||||
|
int months = 0;
|
||||||
QString duration;
|
QString duration;
|
||||||
QString discount;
|
QString discount;
|
||||||
QString costPerMonth;
|
QString costPerMonth;
|
||||||
|
|
|
@ -813,3 +813,10 @@ dialogsSponsoredButton: DialogRightButton(dialogRowOpenBot) {
|
||||||
}
|
}
|
||||||
margin: margins(0px, 9px, 10px, 0px);
|
margin: margins(0px, 9px, 10px, 0px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialogsTopBarSuggestionTitleStyle: TextStyle(defaultTextStyle) {
|
||||||
|
font: font(semibold 12px);
|
||||||
|
}
|
||||||
|
dialogsTopBarSuggestionAboutStyle: TextStyle(defaultTextStyle) {
|
||||||
|
font: font(11px);
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "dialogs/dialogs_top_bar_suggestion.h"
|
#include "dialogs/dialogs_top_bar_suggestion.h"
|
||||||
|
|
||||||
|
#include "api/api_premium.h"
|
||||||
|
#include "apiwrap.h"
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
|
@ -17,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_app_config.h"
|
#include "main/main_app_config.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
#include "settings/settings_premium.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/wrap/slide_wrap.h"
|
#include "ui/wrap/slide_wrap.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
|
@ -32,6 +35,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr auto kSugSetBirthday = "BIRTHDAY_SETUP"_cs;
|
constexpr auto kSugSetBirthday = "BIRTHDAY_SETUP"_cs;
|
||||||
|
constexpr auto kSugPremiumAnnual = "PREMIUM_ANNUAL"_cs;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -46,12 +50,14 @@ object_ptr<Ui::SlideWrap<Ui::RpWidget>> CreateTopBarSuggestion(
|
||||||
wrap->toggle(false, anim::type::instant);
|
wrap->toggle(false, anim::type::instant);
|
||||||
struct State {
|
struct State {
|
||||||
rpl::lifetime birthdayLifetime;
|
rpl::lifetime birthdayLifetime;
|
||||||
|
rpl::lifetime premiumLifetime;
|
||||||
};
|
};
|
||||||
const auto state = content->lifetime().make_state<State>();
|
const auto state = content->lifetime().make_state<State>();
|
||||||
|
|
||||||
const auto processCurrentSuggestion = [=](auto repeat) -> void {
|
const auto processCurrentSuggestion = [=](auto repeat) -> void {
|
||||||
if (session->appConfig().suggestionCurrent(kSugSetBirthday.utf8())
|
if (session->appConfig().suggestionCurrent(kSugSetBirthday.utf8())
|
||||||
&& !Data::IsBirthdayToday(session->user()->birthday())) {
|
&& !Data::IsBirthdayToday(session->user()->birthday())) {
|
||||||
|
content->setRightIcon(TopBarSuggestionContent::RightIcon::Close);
|
||||||
content->setClickedCallback([=] {
|
content->setClickedCallback([=] {
|
||||||
const auto controller = FindSessionController(parent);
|
const auto controller = FindSessionController(parent);
|
||||||
if (!controller) {
|
if (!controller) {
|
||||||
|
@ -86,6 +92,46 @@ object_ptr<Ui::SlideWrap<Ui::RpWidget>> CreateTopBarSuggestion(
|
||||||
tr::now,
|
tr::now,
|
||||||
TextWithEntities::Simple));
|
TextWithEntities::Simple));
|
||||||
wrap->toggle(true, anim::type::normal);
|
wrap->toggle(true, anim::type::normal);
|
||||||
|
} else if (session->premiumPossible()
|
||||||
|
&& !session->premium()
|
||||||
|
&& session->appConfig().suggestionCurrent(
|
||||||
|
kSugPremiumAnnual.utf8())) {
|
||||||
|
content->setRightIcon(TopBarSuggestionContent::RightIcon::Arrow);
|
||||||
|
const auto api = &session->api().premium();
|
||||||
|
const auto set = [=](QString discount) {
|
||||||
|
constexpr auto kMinus = QChar(0x2212);
|
||||||
|
content->setContent(
|
||||||
|
tr::lng_dialogs_top_bar_suggestions_premium_annual_title(
|
||||||
|
tr::now,
|
||||||
|
lt_text,
|
||||||
|
{ discount.replace(kMinus, QChar()) },
|
||||||
|
Ui::Text::Bold),
|
||||||
|
tr::lng_dialogs_top_bar_suggestions_premium_annual_about(
|
||||||
|
tr::now,
|
||||||
|
TextWithEntities::Simple));
|
||||||
|
content->setClickedCallback([=] {
|
||||||
|
const auto controller = FindSessionController(parent);
|
||||||
|
if (!controller) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Settings::ShowPremium(controller, "dialogs_hint");
|
||||||
|
session->appConfig().dismissSuggestion(
|
||||||
|
kSugPremiumAnnual.utf8());
|
||||||
|
repeat(repeat);
|
||||||
|
});
|
||||||
|
wrap->toggle(true, anim::type::normal);
|
||||||
|
};
|
||||||
|
api->statusTextValue(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
for (const auto &option : api->subscriptionOptions()) {
|
||||||
|
if (option.months == 12) {
|
||||||
|
set(option.discount);
|
||||||
|
state->premiumLifetime.destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, state->premiumLifetime);
|
||||||
|
api->reload();
|
||||||
} else {
|
} else {
|
||||||
wrap->toggle(false, anim::type::normal);
|
wrap->toggle(false, anim::type::normal);
|
||||||
base::call_delayed(st::slideWrapDuration * 2, wrap, [=] {
|
base::call_delayed(st::slideWrapDuration * 2, wrap, [=] {
|
||||||
|
|
|
@ -392,7 +392,9 @@ Widget::Widget(
|
||||||
) | rpl::start_with_next([=](int desiredHeight, float64 shown) {
|
) | rpl::start_with_next([=](int desiredHeight, float64 shown) {
|
||||||
const auto newHeight = desiredHeight * (1. - shown);
|
const auto newHeight = desiredHeight * (1. - shown);
|
||||||
_topBarSuggestion->entity()->setMaximumHeight(newHeight);
|
_topBarSuggestion->entity()->setMaximumHeight(newHeight);
|
||||||
_topBarSuggestion->entity()->setMinimumWidth(width());
|
_topBarSuggestion->entity()->setMinimumWidth((shown > 0)
|
||||||
|
? width()
|
||||||
|
: 0);
|
||||||
_topBarSuggestion->entity()->resize(width(), newHeight);
|
_topBarSuggestion->entity()->resize(width(), newHeight);
|
||||||
}, _topBarSuggestion->lifetime());
|
}, _topBarSuggestion->lifetime());
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,7 +301,7 @@ private:
|
||||||
base::Timer _chooseByDragTimer;
|
base::Timer _chooseByDragTimer;
|
||||||
|
|
||||||
const Layout _layout = Layout::Main;
|
const Layout _layout = Layout::Main;
|
||||||
int _narrowWidth = 0;
|
const int _narrowWidth = 0;
|
||||||
|
|
||||||
std::unique_ptr<Ui::AbstractButton> _frozenAccountBar;
|
std::unique_ptr<Ui::AbstractButton> _frozenAccountBar;
|
||||||
|
|
||||||
|
|
|
@ -6,27 +6,57 @@ For license and copyright information please follow this link:
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "dialogs/ui/dialogs_top_bar_suggestion_content.h"
|
#include "dialogs/ui/dialogs_top_bar_suggestion_content.h"
|
||||||
|
#include "ui/ui_rpl_filter.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_dialogs.h"
|
#include "styles/style_dialogs.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
|
|
||||||
namespace Dialogs {
|
namespace Dialogs {
|
||||||
namespace {
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
TopBarSuggestionContent::TopBarSuggestionContent(not_null<Ui::RpWidget*> p)
|
TopBarSuggestionContent::TopBarSuggestionContent(not_null<Ui::RpWidget*> p)
|
||||||
: Ui::RippleButton(p, st::defaultRippleAnimationBgOver)
|
: Ui::RippleButton(p, st::defaultRippleAnimationBgOver)
|
||||||
, _titleSt(st::semiboldTextStyle)
|
, _titleSt(st::semiboldTextStyle)
|
||||||
, _contentTitleSt(st::semiboldTextStyle)
|
, _contentTitleSt(st::dialogsTopBarSuggestionTitleStyle)
|
||||||
, _contentTextSt(st::defaultTextStyle)
|
, _contentTextSt(st::dialogsTopBarSuggestionAboutStyle) {
|
||||||
, _rightHide(
|
setRightIcon(RightIcon::Close);
|
||||||
base::make_unique_q<Ui::IconButton>(
|
}
|
||||||
this,
|
|
||||||
st::dialogsCancelSearchInPeer)) {
|
void TopBarSuggestionContent::setRightIcon(RightIcon icon) {
|
||||||
const auto rightHide = _rightHide.get();
|
if (icon == _rightIcon) {
|
||||||
sizeValue() | rpl::start_with_next([=](const QSize &s) {
|
return;
|
||||||
rightHide->moveToRight(st::buttonRadius, st::lineWidth);
|
}
|
||||||
}, rightHide->lifetime());
|
_rightHide = nullptr;
|
||||||
|
_rightArrow = nullptr;
|
||||||
|
_rightIcon = icon;
|
||||||
|
if (icon == RightIcon::Close) {
|
||||||
|
_rightHide = base::make_unique_q<Ui::IconButton>(
|
||||||
|
this,
|
||||||
|
st::dialogsCancelSearchInPeer);
|
||||||
|
const auto rightHide = _rightHide.get();
|
||||||
|
sizeValue() | rpl::filter_size(
|
||||||
|
) | rpl::start_with_next([=](const QSize &s) {
|
||||||
|
rightHide->moveToRight(st::buttonRadius, st::lineWidth);
|
||||||
|
}, rightHide->lifetime());
|
||||||
|
rightHide->show();
|
||||||
|
} else if (icon == RightIcon::Arrow) {
|
||||||
|
_rightArrow = base::make_unique_q<Ui::IconButton>(
|
||||||
|
this,
|
||||||
|
st::backButton);
|
||||||
|
const auto arrow = _rightArrow.get();
|
||||||
|
arrow->setIconOverride(
|
||||||
|
&st::settingsPremiumArrow,
|
||||||
|
&st::settingsPremiumArrowOver);
|
||||||
|
arrow->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
sizeValue() | rpl::filter_size(
|
||||||
|
) | rpl::start_with_next([=](const QSize &s) {
|
||||||
|
const auto &point = st::settingsPremiumArrowShift;
|
||||||
|
arrow->moveToLeft(
|
||||||
|
s.width() - arrow->width(),
|
||||||
|
point.y() + (s.height() - arrow->height()) / 2);
|
||||||
|
}, arrow->lifetime());
|
||||||
|
arrow->show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopBarSuggestionContent::draw(QPainter &p) {
|
void TopBarSuggestionContent::draw(QPainter &p) {
|
||||||
|
@ -41,28 +71,26 @@ void TopBarSuggestionContent::draw(QPainter &p) {
|
||||||
const auto rightPadding = st::msgReplyBarSkip;
|
const auto rightPadding = st::msgReplyBarSkip;
|
||||||
const auto topPadding = st::msgReplyPadding.top();
|
const auto topPadding = st::msgReplyPadding.top();
|
||||||
const auto availableWidthNoPhoto = r.width()
|
const auto availableWidthNoPhoto = r.width()
|
||||||
|
- (_rightArrow ? _rightArrow->width() / 2 : 0) // Takes full height.
|
||||||
- leftPadding
|
- leftPadding
|
||||||
- rightPadding;
|
- rightPadding;
|
||||||
const auto availableWidth = availableWidthNoPhoto
|
const auto availableWidth = availableWidthNoPhoto
|
||||||
- (_rightHide ? _rightHide->width() : 0);
|
- (_rightHide ? _rightHide->width() : 0);
|
||||||
const auto titleRight = leftPadding
|
const auto titleRight = leftPadding;
|
||||||
+ _titleSt.font->spacew * 2;
|
|
||||||
const auto hasSecondLineTitle = (titleRight
|
const auto hasSecondLineTitle = (titleRight
|
||||||
> (availableWidth - _contentTitle.maxWidth()));
|
> (availableWidth - _contentTitle.maxWidth()));
|
||||||
p.setPen(st::windowActiveTextFg);
|
p.setPen(st::windowActiveTextFg);
|
||||||
p.setPen(st::windowFg);
|
p.setPen(st::windowFg);
|
||||||
{
|
{
|
||||||
const auto left = leftPadding;
|
const auto left = leftPadding;
|
||||||
const auto top = hasSecondLineTitle
|
const auto top = topPadding;
|
||||||
? (topPadding + _titleSt.font->height)
|
|
||||||
: topPadding;
|
|
||||||
_contentTitle.draw(p, {
|
_contentTitle.draw(p, {
|
||||||
.position = QPoint(left, top),
|
.position = QPoint(left, top),
|
||||||
.outerWidth = hasSecondLineTitle
|
.outerWidth = hasSecondLineTitle
|
||||||
? availableWidth
|
? availableWidth
|
||||||
: (availableWidth - titleRight),
|
: (availableWidth - titleRight),
|
||||||
.availableWidth = availableWidth,
|
.availableWidth = availableWidth,
|
||||||
.elisionLines = 1,
|
.elisionLines = hasSecondLineTitle ? 2 : 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -94,6 +122,7 @@ void TopBarSuggestionContent::draw(QPainter &p) {
|
||||||
: availableWidth,
|
: availableWidth,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
p.setPen(st::windowSubTextFg);
|
||||||
_contentText.draw(p, {
|
_contentText.draw(p, {
|
||||||
.position = QPoint(left, top),
|
.position = QPoint(left, top),
|
||||||
.outerWidth = availableWidth,
|
.outerWidth = availableWidth,
|
||||||
|
|
|
@ -18,6 +18,12 @@ namespace Dialogs {
|
||||||
|
|
||||||
class TopBarSuggestionContent : public Ui::RippleButton {
|
class TopBarSuggestionContent : public Ui::RippleButton {
|
||||||
public:
|
public:
|
||||||
|
enum class RightIcon {
|
||||||
|
None,
|
||||||
|
Close,
|
||||||
|
Arrow,
|
||||||
|
};
|
||||||
|
|
||||||
TopBarSuggestionContent(not_null<Ui::RpWidget*>);
|
TopBarSuggestionContent(not_null<Ui::RpWidget*>);
|
||||||
|
|
||||||
void setContent(
|
void setContent(
|
||||||
|
@ -27,6 +33,7 @@ public:
|
||||||
[[nodiscard]] rpl::producer<int> desiredHeightValue() const override;
|
[[nodiscard]] rpl::producer<int> desiredHeightValue() const override;
|
||||||
|
|
||||||
void setHideCallback(Fn<void()>);
|
void setHideCallback(Fn<void()>);
|
||||||
|
void setRightIcon(RightIcon);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *) override;
|
void paintEvent(QPaintEvent *) override;
|
||||||
|
@ -44,8 +51,11 @@ private:
|
||||||
rpl::variable<int> _lastPaintedContentTop = 0;
|
rpl::variable<int> _lastPaintedContentTop = 0;
|
||||||
|
|
||||||
base::unique_qptr<Ui::IconButton> _rightHide;
|
base::unique_qptr<Ui::IconButton> _rightHide;
|
||||||
|
base::unique_qptr<Ui::IconButton> _rightArrow;
|
||||||
Fn<void()> _hideCallback;
|
Fn<void()> _hideCallback;
|
||||||
|
|
||||||
|
RightIcon _rightIcon = RightIcon::None;
|
||||||
|
|
||||||
std::shared_ptr<Ui::DynamicImage> _rightPhoto;
|
std::shared_ptr<Ui::DynamicImage> _rightPhoto;
|
||||||
QImage _rightPhotoImage;
|
QImage _rightPhotoImage;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue