mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added initial implementation of TopBar in Premium Settings for user.
This commit is contained in:
parent
b519b6bf4c
commit
01b50a8460
4 changed files with 509 additions and 30 deletions
|
@ -1702,6 +1702,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_premium_unlock_stickers" = "Unlock Premium Stickers";
|
"lng_premium_unlock_stickers" = "Unlock Premium Stickers";
|
||||||
"lng_premium_unlock_emoji" = "Unlock Animated Emoji";
|
"lng_premium_unlock_emoji" = "Unlock Animated Emoji";
|
||||||
|
|
||||||
|
"lng_premium_emoji_status_title" = "{user} set this emoji from {link} as their current status.";
|
||||||
|
"lng_premium_emoji_status_about" = "Emoji status is a premium feature. Other features included in **Telegram Premium**:";
|
||||||
|
"lng_premium_emoji_status_button" = "Unlock Emoji Status";
|
||||||
|
|
||||||
|
"lng_premium_summary_user_title" = "{user} is a subscriber of Telegram Premium.";
|
||||||
|
"lng_premium_summary_user_about" = "Owners of Telegram Premium accounts have exclusive access to multiple additional features.";
|
||||||
|
"lng_premium_summary_user_button" = "Learn More";
|
||||||
|
|
||||||
"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!";
|
||||||
|
|
|
@ -142,8 +142,10 @@ Widget::Widget(
|
||||||
- _pinnedToTop->minimumHeight();
|
- _pinnedToTop->minimumHeight();
|
||||||
};
|
};
|
||||||
|
|
||||||
_inner->heightValue(
|
rpl::combine(
|
||||||
) | rpl::start_with_next([=](int h) {
|
_pinnedToTop->heightValue(),
|
||||||
|
_inner->heightValue()
|
||||||
|
) | rpl::start_with_next([=](int, int h) {
|
||||||
_flexibleScroll.contentHeightValue.fire(h + heightDiff());
|
_flexibleScroll.contentHeightValue.fire(h + heightDiff());
|
||||||
}, _pinnedToTop->lifetime());
|
}, _pinnedToTop->lifetime());
|
||||||
|
|
||||||
|
|
|
@ -428,8 +428,8 @@ notifyPreviewBottomSkip: 9px;
|
||||||
settingsPremiumButtonPadding: margins(11px, 11px, 11px, 3px);
|
settingsPremiumButtonPadding: margins(11px, 11px, 11px, 3px);
|
||||||
settingsPremiumTopBarBackIcon: icon {{ "info/info_back", premiumButtonFg }};
|
settingsPremiumTopBarBackIcon: icon {{ "info/info_back", premiumButtonFg }};
|
||||||
settingsPremiumTopBarBackIconOver: icon {{ "info/info_back", premiumButtonFg }};
|
settingsPremiumTopBarBackIconOver: icon {{ "info/info_back", premiumButtonFg }};
|
||||||
settingsPremiumStarSize: size(77px, 73px);
|
settingsPremiumStarSize: size(84px, 81px);
|
||||||
settingsPremiumStarTopSkip: 42px;
|
settingsPremiumStarTopSkip: 37px;
|
||||||
settingsPremiumTopBarBack: IconButton(infoTopBarBack) {
|
settingsPremiumTopBarBack: IconButton(infoTopBarBack) {
|
||||||
icon: settingsPremiumTopBarBackIcon;
|
icon: settingsPremiumTopBarBackIcon;
|
||||||
iconOver: settingsPremiumTopBarBackIconOver;
|
iconOver: settingsPremiumTopBarBackIconOver;
|
||||||
|
@ -469,13 +469,14 @@ settingsPremiumPreviewAboutPadding: margins(24px, 0px, 24px, 11px);
|
||||||
settingsPremiumPreviewLinePadding: margins(18px, 0px, 18px, 8px);
|
settingsPremiumPreviewLinePadding: margins(18px, 0px, 18px, 8px);
|
||||||
|
|
||||||
settingsPremiumTitlePadding: margins(0px, 20px, 0px, 16px);
|
settingsPremiumTitlePadding: margins(0px, 20px, 0px, 16px);
|
||||||
|
settingsPremiumAboutTextStyle: TextStyle(defaultTextStyle) {
|
||||||
|
font: font(12px);
|
||||||
|
linkFont: font(12px underline);
|
||||||
|
linkFontOver: font(12px underline);
|
||||||
|
lineHeight: 18px;
|
||||||
|
}
|
||||||
settingsPremiumAbout: FlatLabel(defaultFlatLabel) {
|
settingsPremiumAbout: FlatLabel(defaultFlatLabel) {
|
||||||
style: TextStyle(defaultTextStyle) {
|
style: settingsPremiumAboutTextStyle;
|
||||||
font: font(12px);
|
|
||||||
linkFont: font(12px underline);
|
|
||||||
linkFontOver: font(12px underline);
|
|
||||||
lineHeight: 18px;
|
|
||||||
}
|
|
||||||
palette: TextPalette(defaultTextPalette) {
|
palette: TextPalette(defaultTextPalette) {
|
||||||
linkFg: premiumButtonFg;
|
linkFg: premiumButtonFg;
|
||||||
}
|
}
|
||||||
|
@ -485,5 +486,25 @@ settingsPremiumAbout: FlatLabel(defaultFlatLabel) {
|
||||||
}
|
}
|
||||||
settingsPremiumStatusPadding: margins(22px, 8px, 22px, 2px);
|
settingsPremiumStatusPadding: margins(22px, 8px, 22px, 2px);
|
||||||
|
|
||||||
|
settingsPremiumUserHeight: 223px;
|
||||||
|
settingsPremiumUserTitlePadding: margins(0px, 16px, 0px, 6px);
|
||||||
|
settingsPremiumUserTitle: FlatLabel(boxTitle) {
|
||||||
|
style: TextStyle(defaultTextStyle) {
|
||||||
|
font: boxTitleFont;
|
||||||
|
linkFont: boxTitleFont;
|
||||||
|
linkFontOver: font(16px semibold underline);
|
||||||
|
lineHeight: 14px;
|
||||||
|
}
|
||||||
|
minWidth: 300px;
|
||||||
|
maxHeight: 0px;
|
||||||
|
align: align(top);
|
||||||
|
}
|
||||||
|
settingsPremiumUserAbout: FlatLabel(boxDividerLabel) {
|
||||||
|
style: settingsPremiumAboutTextStyle;
|
||||||
|
minWidth: 315px;
|
||||||
|
maxHeight: 0px;
|
||||||
|
align: align(top);
|
||||||
|
}
|
||||||
|
|
||||||
settingsPremiumLock: icon{{ "emoji/premium_lock", windowActiveTextFg, point(0px, 1px) }};
|
settingsPremiumLock: icon{{ "emoji/premium_lock", windowActiveTextFg, point(0px, 1px) }};
|
||||||
settingsPremiumLockSkip: 3px;
|
settingsPremiumLockSkip: 3px;
|
||||||
|
|
|
@ -7,23 +7,38 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "settings/settings_premium.h"
|
#include "settings/settings_premium.h"
|
||||||
|
|
||||||
|
#include "boxes/premium_preview_box.h"
|
||||||
|
#include "boxes/sticker_set_box.h"
|
||||||
|
#include "chat_helpers/stickers_lottie.h" // LottiePlayerFromDocument.
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
|
#include "core/ui_integration.h" // MarkedTextContext.
|
||||||
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_document_media.h"
|
||||||
#include "data/data_peer_values.h"
|
#include "data/data_peer_values.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "data/stickers/data_custom_emoji.h" // SerializeCustomEmojiId.
|
||||||
|
#include "data/stickers/data_stickers.h"
|
||||||
|
#include "history/view/media/history_view_sticker.h" // EmojiSize.
|
||||||
#include "info/info_wrap_widget.h" // Info::Wrap.
|
#include "info/info_wrap_widget.h" // Info::Wrap.
|
||||||
|
#include "info/profile/info_profile_values.h"
|
||||||
#include "info/settings/info_settings_widget.h" // SectionCustomTopBarData.
|
#include "info/settings/info_settings_widget.h" // SectionCustomTopBarData.
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "boxes/premium_preview_box.h"
|
#include "lottie/lottie_single_player.h"
|
||||||
|
#include "main/main_account.h"
|
||||||
|
#include "main/main_app_config.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
#include "settings/settings_common.h"
|
#include "settings/settings_common.h"
|
||||||
#include "settings/settings_premium.h"
|
#include "settings/settings_premium.h"
|
||||||
#include "ui/abstract_button.h"
|
#include "ui/abstract_button.h"
|
||||||
#include "ui/basic_click_handlers.h"
|
#include "ui/basic_click_handlers.h"
|
||||||
#include "ui/effects/gradient.h"
|
#include "ui/effects/gradient.h"
|
||||||
#include "ui/effects/premium_graphics.h"
|
#include "ui/effects/premium_graphics.h"
|
||||||
#include "ui/effects/premium_stars.h"
|
#include "ui/effects/premium_stars_colored.h"
|
||||||
#include "ui/text/text_utilities.h"
|
|
||||||
#include "ui/text/format_values.h"
|
|
||||||
#include "ui/layers/generic_box.h"
|
#include "ui/layers/generic_box.h"
|
||||||
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/widgets/gradient_round_button.h"
|
#include "ui/widgets/gradient_round_button.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
|
@ -31,10 +46,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/wrap/slide_wrap.h"
|
#include "ui/wrap/slide_wrap.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "data/data_session.h"
|
|
||||||
#include "main/main_session.h"
|
|
||||||
#include "main/main_account.h"
|
|
||||||
#include "main/main_app_config.h"
|
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
@ -54,6 +65,10 @@ using SectionCustomTopBarData = Info::Settings::SectionCustomTopBarData;
|
||||||
constexpr auto kBodyAnimationPart = 0.90;
|
constexpr auto kBodyAnimationPart = 0.90;
|
||||||
constexpr auto kTitleAdditionalScale = 0.15;
|
constexpr auto kTitleAdditionalScale = 0.15;
|
||||||
|
|
||||||
|
[[nodiscard]] QString Svg() {
|
||||||
|
return u":/gui/icons/settings/star.svg"_q;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Ref {
|
namespace Ref {
|
||||||
namespace Gift {
|
namespace Gift {
|
||||||
|
|
||||||
|
@ -352,6 +367,395 @@ QRectF TopBarAbstract::starRect(
|
||||||
starSize);
|
starSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EmojiStatusTopBar final {
|
||||||
|
public:
|
||||||
|
EmojiStatusTopBar(
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
Fn<void(QRect)> callback,
|
||||||
|
QSizeF size);
|
||||||
|
|
||||||
|
void setCenter(QPointF position);
|
||||||
|
void paint(QPainter &p);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPixmap paintedPixmap(const QSize &size) const;
|
||||||
|
|
||||||
|
QRectF _rect;
|
||||||
|
std::shared_ptr<Data::DocumentMedia> _media;
|
||||||
|
std::unique_ptr<Lottie::SinglePlayer> _lottie;
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EmojiStatusTopBar::EmojiStatusTopBar(
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
Fn<void(QRect)> callback,
|
||||||
|
QSizeF size)
|
||||||
|
: _rect(QPointF(), size) {
|
||||||
|
const auto sticker = document->sticker();
|
||||||
|
Assert(sticker != nullptr);
|
||||||
|
_media = document->createMediaView();
|
||||||
|
_media->checkStickerLarge();
|
||||||
|
_media->goodThumbnailWanted();
|
||||||
|
|
||||||
|
rpl::single() | rpl::then(
|
||||||
|
document->owner().session().downloaderTaskFinished()
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
if (!_media->loaded()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_lifetime.destroy();
|
||||||
|
if (sticker->isLottie()) {
|
||||||
|
_lottie = ChatHelpers::LottiePlayerFromDocument(
|
||||||
|
_media.get(),
|
||||||
|
ChatHelpers::StickerLottieSize::EmojiInteractionReserved7, //
|
||||||
|
size.toSize(),
|
||||||
|
Lottie::Quality::High);
|
||||||
|
|
||||||
|
_lifetime = _lottie->updates(
|
||||||
|
) | rpl::start_with_next([=](Lottie::Update update) {
|
||||||
|
v::match(update.data, [&](const Lottie::Information &) {
|
||||||
|
callback(_rect.toRect());
|
||||||
|
}, [&](const Lottie::DisplayFrameRequest &) {
|
||||||
|
callback(_rect.toRect());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiStatusTopBar::setCenter(QPointF position) {
|
||||||
|
const auto size = _rect.size();
|
||||||
|
const auto shift = QPointF(size.width() / 2., size.height() / 2.);
|
||||||
|
_rect = QRectF(QPointF(position - shift), QPointF(position + shift));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap EmojiStatusTopBar::paintedPixmap(const QSize &size) const {
|
||||||
|
const auto good = _media->goodThumbnail();
|
||||||
|
if (const auto image = _media->getStickerLarge()) {
|
||||||
|
return image->pix(size);
|
||||||
|
} else if (good) {
|
||||||
|
return good->pix(size);
|
||||||
|
} else if (const auto thumbnail = _media->thumbnail()) {
|
||||||
|
return thumbnail->pix(size, { .options = Images::Option::Blur });
|
||||||
|
}
|
||||||
|
return QPixmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmojiStatusTopBar::paint(QPainter &p) {
|
||||||
|
if (_lottie) {
|
||||||
|
if (_lottie->ready()) {
|
||||||
|
const auto info = _lottie->frameInfo({
|
||||||
|
.box = (_rect.size() * style::DevicePixelRatio()).toSize(),
|
||||||
|
});
|
||||||
|
|
||||||
|
p.drawImage(_rect, info.image);
|
||||||
|
_lottie->markFrameShown();
|
||||||
|
}
|
||||||
|
} else if (_media) {
|
||||||
|
p.drawPixmap(_rect, paintedPixmap(_rect.size().toSize()), _rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TopBarUser final : public TopBarAbstract {
|
||||||
|
public:
|
||||||
|
TopBarUser(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
|
void setPaused(bool paused) override;
|
||||||
|
void setTextPosition(int x, int y) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateTitle(
|
||||||
|
DocumentData *document,
|
||||||
|
TextWithEntities name,
|
||||||
|
not_null<Window::SessionController*> controller) const;
|
||||||
|
void updateAbout(DocumentData *document) const;
|
||||||
|
|
||||||
|
object_ptr<Ui::RpWidget> _content;
|
||||||
|
object_ptr<Ui::FlatLabel> _title;
|
||||||
|
object_ptr<Ui::FlatLabel> _about;
|
||||||
|
Ui::Premium::ColoredMiniStars _ministars;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
object_ptr<Ui::RpWidget> widget;
|
||||||
|
Ui::Text::String text;
|
||||||
|
Ui::Animations::Simple animation;
|
||||||
|
bool shown = false;
|
||||||
|
QPoint position;
|
||||||
|
} _smallTop;
|
||||||
|
|
||||||
|
std::unique_ptr<EmojiStatusTopBar> _emojiStatus;
|
||||||
|
QImage _imageStar;
|
||||||
|
|
||||||
|
QRectF _ministarsRect;
|
||||||
|
QRectF _starRect;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
TopBarUser::TopBarUser(
|
||||||
|
not_null<QWidget*> parent,
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<PeerData*> peer)
|
||||||
|
: TopBarAbstract(parent)
|
||||||
|
, _content(this)
|
||||||
|
, _title(_content, st::settingsPremiumUserTitle)
|
||||||
|
, _about(_content, st::settingsPremiumUserAbout)
|
||||||
|
, _ministars(_content)
|
||||||
|
, _smallTop({
|
||||||
|
.widget = object_ptr<Ui::RpWidget>(this),
|
||||||
|
.text = Ui::Text::String(
|
||||||
|
st::boxTitle.style,
|
||||||
|
tr::lng_premium_summary_title(tr::now)),
|
||||||
|
}) {
|
||||||
|
_starRect = TopBarAbstract::starRect(1., 1.);
|
||||||
|
|
||||||
|
auto documentValue = Info::Profile::EmojiStatusIdValue(
|
||||||
|
peer
|
||||||
|
) | rpl::map([=](DocumentId id) -> DocumentData* {
|
||||||
|
const auto document = id
|
||||||
|
? controller->session().data().document(id).get()
|
||||||
|
: nullptr;
|
||||||
|
return (document && document->sticker()) ? document : nullptr;
|
||||||
|
});
|
||||||
|
|
||||||
|
rpl::combine(
|
||||||
|
std::move(documentValue),
|
||||||
|
Info::Profile::NameValue(peer)
|
||||||
|
) | rpl::start_with_next([=](
|
||||||
|
DocumentData *document,
|
||||||
|
TextWithEntities name) {
|
||||||
|
if (document) {
|
||||||
|
_emojiStatus = std::make_unique<EmojiStatusTopBar>(
|
||||||
|
document,
|
||||||
|
[=](QRect r) { update(std::move(r)); },
|
||||||
|
HistoryView::Sticker::EmojiSize());
|
||||||
|
_imageStar = QImage();
|
||||||
|
} else {
|
||||||
|
auto svg = QSvgRenderer(Svg());
|
||||||
|
|
||||||
|
const auto size = _starRect.size().toSize();
|
||||||
|
auto frame = QImage(
|
||||||
|
size * style::DevicePixelRatio(),
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
frame.setDevicePixelRatio(style::DevicePixelRatio());
|
||||||
|
|
||||||
|
auto mask = frame;
|
||||||
|
mask.fill(Qt::transparent);
|
||||||
|
{
|
||||||
|
Painter p(&mask);
|
||||||
|
auto gradient = QLinearGradient(
|
||||||
|
0,
|
||||||
|
size.height(),
|
||||||
|
size.width(),
|
||||||
|
0);
|
||||||
|
gradient.setStops(Ui::Premium::ButtonGradientStops());
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(gradient);
|
||||||
|
p.drawRect(0, 0, size.width(), size.height());
|
||||||
|
}
|
||||||
|
frame.fill(Qt::transparent);
|
||||||
|
{
|
||||||
|
Painter q(&frame);
|
||||||
|
svg.render(&q, QRect(QPoint(), size));
|
||||||
|
q.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||||
|
q.drawImage(0, 0, mask);
|
||||||
|
}
|
||||||
|
_imageStar = std::move(frame);
|
||||||
|
|
||||||
|
_emojiStatus = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTitle(document, name, controller);
|
||||||
|
updateAbout(document);
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
|
rpl::combine(
|
||||||
|
_title->sizeValue(),
|
||||||
|
_about->sizeValue(),
|
||||||
|
_content->sizeValue()
|
||||||
|
) | rpl::start_with_next([=](
|
||||||
|
const QSize &titleSize,
|
||||||
|
const QSize &aboutSize,
|
||||||
|
const QSize &size) {
|
||||||
|
const auto rect = TopBarAbstract::starRect(1., 1.);
|
||||||
|
const auto &padding = st::settingsPremiumUserTitlePadding;
|
||||||
|
_title->moveToLeft(
|
||||||
|
(size.width() - titleSize.width()) / 2,
|
||||||
|
rect.top() + rect.height() + padding.top());
|
||||||
|
_about->moveToLeft(
|
||||||
|
(size.width() - aboutSize.width()) / 2,
|
||||||
|
_title->y() + titleSize.height() + padding.bottom());
|
||||||
|
|
||||||
|
const auto aboutBottom = _about->y() + _about->height();
|
||||||
|
const auto height = (aboutBottom > st::settingsPremiumUserHeight)
|
||||||
|
? aboutBottom + padding.bottom()
|
||||||
|
: st::settingsPremiumUserHeight;
|
||||||
|
{
|
||||||
|
const auto was = maximumHeight();
|
||||||
|
const auto now = height;
|
||||||
|
if (was != now) {
|
||||||
|
setMaximumHeight(now);
|
||||||
|
if (was == size.height()) {
|
||||||
|
resize(size.width(), now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_content->resize(size.width(), maximumHeight());
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
|
sizeValue(
|
||||||
|
) | rpl::start_with_next([=](const QSize &size) {
|
||||||
|
_content->resize(size.width(), maximumHeight());
|
||||||
|
_content->moveToLeft(0, -(_content->height() - size.height()));
|
||||||
|
|
||||||
|
_smallTop.widget->resize(size.width(), minimumHeight());
|
||||||
|
const auto shown = (minimumHeight() * 2 > size.height());
|
||||||
|
if (_smallTop.shown != shown) {
|
||||||
|
_smallTop.shown = shown;
|
||||||
|
_smallTop.animation.start(
|
||||||
|
[=] { _smallTop.widget->update(); },
|
||||||
|
_smallTop.shown ? 0. : 1.,
|
||||||
|
_smallTop.shown ? 1. : 0.,
|
||||||
|
st::infoTopBarDuration);
|
||||||
|
}
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
|
_smallTop.widget->paintRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
Painter p(_smallTop.widget);
|
||||||
|
|
||||||
|
p.setOpacity(_smallTop.animation.value(_smallTop.shown ? 1. : 0.));
|
||||||
|
paintEdges(p, st::boxBg);
|
||||||
|
|
||||||
|
p.setPen(st::boxTitleFg);
|
||||||
|
_smallTop.text.drawLeft(
|
||||||
|
p,
|
||||||
|
_smallTop.position.x(),
|
||||||
|
_smallTop.position.y(),
|
||||||
|
width(),
|
||||||
|
width());
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
|
_content->paintRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
Painter p(_content);
|
||||||
|
|
||||||
|
_ministars.paint(p);
|
||||||
|
|
||||||
|
if (_emojiStatus) {
|
||||||
|
_emojiStatus->paint(p);
|
||||||
|
} else if (!_imageStar.isNull()) {
|
||||||
|
p.drawImage(_starRect.topLeft(), _imageStar);
|
||||||
|
}
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TopBarUser::updateTitle(
|
||||||
|
DocumentData *document,
|
||||||
|
TextWithEntities name,
|
||||||
|
not_null<Window::SessionController*> controller) const {
|
||||||
|
if (!document) {
|
||||||
|
return _title->setMarkedText(
|
||||||
|
tr::lng_premium_summary_user_title(
|
||||||
|
tr::now,
|
||||||
|
lt_user,
|
||||||
|
std::move(name),
|
||||||
|
Ui::Text::WithEntities));
|
||||||
|
}
|
||||||
|
const auto stickerInfo = document->sticker();
|
||||||
|
if (!stickerInfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto &sets = document->owner().stickers().sets();
|
||||||
|
const auto it = sets.find(stickerInfo->set.id);
|
||||||
|
if (it == sets.cend()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto set = it->second.get();
|
||||||
|
|
||||||
|
const auto text = (set->thumbnailDocumentId ? QChar('0') : QChar())
|
||||||
|
+ set->title;
|
||||||
|
const auto linkIndex = 1;
|
||||||
|
const auto entityEmojiData = Data::SerializeCustomEmojiId(
|
||||||
|
{ set->thumbnailDocumentId });
|
||||||
|
const auto entities = EntitiesInText{
|
||||||
|
{ EntityType::CustomEmoji, 0, 1, entityEmojiData },
|
||||||
|
Ui::Text::Link(text, linkIndex).entities.front(),
|
||||||
|
};
|
||||||
|
auto title = tr::lng_premium_emoji_status_title(
|
||||||
|
tr::now,
|
||||||
|
lt_user,
|
||||||
|
std::move(name),
|
||||||
|
lt_link,
|
||||||
|
{ .text = text, .entities = entities, },
|
||||||
|
Ui::Text::WithEntities);
|
||||||
|
const auto context = Core::MarkedTextContext{
|
||||||
|
.session = &controller->session(),
|
||||||
|
.customEmojiRepaint = [=] { _title->update(); },
|
||||||
|
};
|
||||||
|
_title->setMarkedText(std::move(title), context);
|
||||||
|
auto link = std::make_shared<LambdaClickHandler>([=,
|
||||||
|
stickerSetIdentifier = stickerInfo->set] {
|
||||||
|
controller->show(
|
||||||
|
Box<StickerSetBox>(
|
||||||
|
controller,
|
||||||
|
stickerSetIdentifier,
|
||||||
|
Data::StickersType::Emoji),
|
||||||
|
Ui::LayerOption::KeepOther);
|
||||||
|
});
|
||||||
|
_title->setLink(linkIndex, std::move(link));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TopBarUser::updateAbout(DocumentData *document) const {
|
||||||
|
_about->setMarkedText((document
|
||||||
|
? tr::lng_premium_emoji_status_about
|
||||||
|
: tr::lng_premium_summary_user_about)(
|
||||||
|
tr::now,
|
||||||
|
Ui::Text::RichLangValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TopBarUser::setPaused(bool paused) {
|
||||||
|
_ministars.setPaused(paused);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TopBarUser::setTextPosition(int x, int y) {
|
||||||
|
_smallTop.position = { x, y };
|
||||||
|
}
|
||||||
|
|
||||||
|
void TopBarUser::paintEvent(QPaintEvent *e) {
|
||||||
|
Painter p(this);
|
||||||
|
|
||||||
|
TopBarAbstract::paintEdges(p, st::boxBg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TopBarUser::resizeEvent(QResizeEvent *e) {
|
||||||
|
_starRect = TopBarAbstract::starRect(1., 1.);
|
||||||
|
|
||||||
|
const auto &rect = _starRect;
|
||||||
|
const auto center = rect.center();
|
||||||
|
const auto size = QSize(
|
||||||
|
rect.width() * Ui::Premium::MiniStars::kSizeFactor,
|
||||||
|
rect.height());
|
||||||
|
const auto ministarsRect = QRect(
|
||||||
|
QPoint(center.x() - size.width(), center.y() - size.height()),
|
||||||
|
QPoint(center.x() + size.width(), center.y() + size.height()));
|
||||||
|
_ministars.setPosition(ministarsRect.topLeft());
|
||||||
|
_ministars.setSize(ministarsRect.size());
|
||||||
|
|
||||||
|
if (_emojiStatus) {
|
||||||
|
_emojiStatus->setCenter(_starRect.center());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TopBar final : public TopBarAbstract {
|
class TopBar final : public TopBarAbstract {
|
||||||
public:
|
public:
|
||||||
TopBar(
|
TopBar(
|
||||||
|
@ -399,7 +803,7 @@ TopBar::TopBar(
|
||||||
, _titlePadding(st::settingsPremiumTitlePadding)
|
, _titlePadding(st::settingsPremiumTitlePadding)
|
||||||
, _about(this, std::move(about), st::settingsPremiumAbout)
|
, _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(Svg()) {
|
||||||
std::move(
|
std::move(
|
||||||
title
|
title
|
||||||
) | rpl::start_with_next([=](QString text) {
|
) | rpl::start_with_next([=](QString text) {
|
||||||
|
@ -841,11 +1245,32 @@ QPointer<Ui::RpWidget> Premium::createPinnedToTop(
|
||||||
tr::lng_premium_summary_top_about(Ui::Text::RichLangValue));
|
tr::lng_premium_summary_top_about(Ui::Text::RichLangValue));
|
||||||
}();
|
}();
|
||||||
|
|
||||||
const auto content = Ui::CreateChild<TopBar>(
|
const auto emojiStatusData = Ref::EmojiStatus::Parse(_ref);
|
||||||
parent.get(),
|
const auto isEmojiStatus = (!!emojiStatusData);
|
||||||
_controller,
|
|
||||||
std::move(title),
|
auto peerWithPremium = [&]() -> PeerData* {
|
||||||
std::move(about));
|
if (isEmojiStatus) {
|
||||||
|
auto &data = _controller->session().data();
|
||||||
|
if (const auto peer = data.peer(emojiStatusData.peerId)) {
|
||||||
|
return peer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}();
|
||||||
|
|
||||||
|
const auto content = [&]() -> TopBarAbstract* {
|
||||||
|
if (peerWithPremium) {
|
||||||
|
return Ui::CreateChild<TopBarUser>(
|
||||||
|
parent.get(),
|
||||||
|
_controller,
|
||||||
|
peerWithPremium);
|
||||||
|
}
|
||||||
|
return Ui::CreateChild<TopBar>(
|
||||||
|
parent.get(),
|
||||||
|
_controller,
|
||||||
|
std::move(title),
|
||||||
|
std::move(about));
|
||||||
|
}();
|
||||||
_setPaused = [=](bool paused) {
|
_setPaused = [=](bool paused) {
|
||||||
content->setPaused(paused);
|
content->setPaused(paused);
|
||||||
if (_subscribe) {
|
if (_subscribe) {
|
||||||
|
@ -858,7 +1283,9 @@ QPointer<Ui::RpWidget> Premium::createPinnedToTop(
|
||||||
content->setRoundEdges(wrap == Info::Wrap::Layer);
|
content->setRoundEdges(wrap == Info::Wrap::Layer);
|
||||||
}, content->lifetime());
|
}, content->lifetime());
|
||||||
|
|
||||||
content->setMaximumHeight(st::introQrStepsTop);
|
content->setMaximumHeight(isEmojiStatus
|
||||||
|
? st::settingsPremiumUserHeight
|
||||||
|
: st::introQrStepsTop);
|
||||||
content->setMinimumHeight(st::infoLayerTopBarHeight);
|
content->setMinimumHeight(st::infoLayerTopBarHeight);
|
||||||
|
|
||||||
content->resize(content->width(), content->maximumHeight());
|
content->resize(content->width(), content->maximumHeight());
|
||||||
|
@ -870,9 +1297,11 @@ QPointer<Ui::RpWidget> Premium::createPinnedToTop(
|
||||||
content,
|
content,
|
||||||
object_ptr<Ui::IconButton>(
|
object_ptr<Ui::IconButton>(
|
||||||
content,
|
content,
|
||||||
isLayer
|
isEmojiStatus
|
||||||
? st::settingsPremiumLayerTopBarBack
|
? (isLayer ? st::infoTopBarBack : st::infoLayerTopBarBack)
|
||||||
: st::settingsPremiumTopBarBack),
|
: (isLayer
|
||||||
|
? st::settingsPremiumLayerTopBarBack
|
||||||
|
: st::settingsPremiumTopBarBack)),
|
||||||
st::infoTopBarScale);
|
st::infoTopBarScale);
|
||||||
_back->setDuration(0);
|
_back->setDuration(0);
|
||||||
_back->toggleOn(isLayer
|
_back->toggleOn(isLayer
|
||||||
|
@ -894,7 +1323,9 @@ QPointer<Ui::RpWidget> Premium::createPinnedToTop(
|
||||||
} else {
|
} else {
|
||||||
_close = base::make_unique_q<Ui::IconButton>(
|
_close = base::make_unique_q<Ui::IconButton>(
|
||||||
content,
|
content,
|
||||||
st::settingsPremiumTopBarClose);
|
isEmojiStatus
|
||||||
|
? st::infoTopBarClose
|
||||||
|
: st::settingsPremiumTopBarClose);
|
||||||
_close->addClickHandler([=] {
|
_close->addClickHandler([=] {
|
||||||
_controller->parentController()->hideLayer();
|
_controller->parentController()->hideLayer();
|
||||||
_controller->parentController()->hideSpecialLayer();
|
_controller->parentController()->hideSpecialLayer();
|
||||||
|
@ -921,10 +1352,27 @@ QPointer<Ui::RpWidget> Premium::createPinnedToBottom(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto buttonText = [&]() -> std::optional<rpl::producer<QString>> {
|
||||||
|
if (const auto emojiData = Ref::EmojiStatus::Parse(_ref)) {
|
||||||
|
auto &data = _controller->session().data();
|
||||||
|
if (const auto peer = data.peer(emojiData.peerId)) {
|
||||||
|
return Info::Profile::EmojiStatusIdValue(
|
||||||
|
peer
|
||||||
|
) | rpl::map([](DocumentId id) {
|
||||||
|
return id
|
||||||
|
? tr::lng_premium_emoji_status_button()
|
||||||
|
: tr::lng_premium_summary_user_button();
|
||||||
|
}) | rpl::flatten_latest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}();
|
||||||
|
|
||||||
_subscribe = CreateSubscribeButton({
|
_subscribe = CreateSubscribeButton({
|
||||||
_controller,
|
_controller,
|
||||||
content,
|
content,
|
||||||
[=] { return _ref; }
|
[ref = _ref] { return ref; },
|
||||||
|
std::move(buttonText),
|
||||||
});
|
});
|
||||||
|
|
||||||
_showFinished.events(
|
_showFinished.events(
|
||||||
|
|
Loading…
Add table
Reference in a new issue