diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 6bc8e0a3dc..7290984b24 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1878,9 +1878,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_stars_rating_title" = "Rating"; "lng_stars_rating_future" = "Future Rating"; -"lng_stars_rating_subtitle" = "The rating update updates in 21 days after purchases."; -"lng_stars_rating_pending#one" = "{count} point is pending. {link}"; -"lng_stars_rating_pending#other" = "{count} points are pending. {link}"; +"lng_stars_rating_pending#one" = "The rating updates in 21 days after purchases.\n{count} point is pending. {link}"; +"lng_stars_rating_pending#other" = "The rating updates in 21 days after purchases.\n{count} points are pending. {link}"; "lng_stars_rating_pending_preview" = "Preview {arrow}"; "lng_stars_rating_pending_back" = "Back {arrow}"; "lng_stars_rating_about" = "This rating reflects **{name}'s** activity on Telegram. What affects it:"; diff --git a/Telegram/SourceFiles/data/data_peer_common.h b/Telegram/SourceFiles/data/data_peer_common.h index d3231c3be1..656f089f9f 100644 --- a/Telegram/SourceFiles/data/data_peer_common.h +++ b/Telegram/SourceFiles/data/data_peer_common.h @@ -22,4 +22,13 @@ struct StarsRating { friend inline bool operator==(StarsRating, StarsRating) = default; }; +struct StarsRatingPending { + StarsRating value; + TimeId date = 0; + + explicit operator bool() const { + return value && date; + } +}; + } // namespace Data diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 88a62f1494..bef5a20e52 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -5185,6 +5185,16 @@ int Session::commonStarsPerMessage( return (i != end(_commonStarsPerMessage)) ? i->second : 0; } +void Session::setPendingStarsRating(StarsRatingPending value) { + _pendingStarsRating = value + ? std::make_unique(value) + : nullptr; +} + +StarsRatingPending Session::pendingStarsRating() const { + return _pendingStarsRating ? *_pendingStarsRating : StarsRatingPending(); +} + void Session::clearLocalStorage() { _cache->close(); _cache->clear(); diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 8260fd042f..cdcbb5cd4b 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -72,6 +72,7 @@ class BusinessInfo; struct ReactionId; struct UnavailableReason; struct CreditsStatusSlice; +struct StarsRatingPending; struct UniqueGift; struct RepliesReadTillUpdate { @@ -872,6 +873,9 @@ public: [[nodiscard]] int commonStarsPerMessage( not_null channel) const; + void setPendingStarsRating(StarsRatingPending value); + [[nodiscard]] StarsRatingPending pendingStarsRating() const; + void clearLocalStorage(); private: @@ -1226,6 +1230,8 @@ private: MsgId _nonHistoryEntryId = ShortcutMaxMsgId; + std::unique_ptr _pendingStarsRating; + rpl::lifetime _lifetime; }; diff --git a/Telegram/SourceFiles/data/data_user.cpp b/Telegram/SourceFiles/data/data_user.cpp index d3c09a06f6..967d7b5669 100644 --- a/Telegram/SourceFiles/data/data_user.cpp +++ b/Telegram/SourceFiles/data/data_user.cpp @@ -874,6 +874,12 @@ void ApplyUserUpdate(not_null user, const MTPDuserFull &update) { user->setBotVerifyDetails( ParseBotVerifyDetails(update.vbot_verification())); user->setStarsRating(ParseStarsRating(update.vstars_rating())); + if (user->isSelf()) { + user->owner().setPendingStarsRating({ + .value = ParseStarsRating(update.vstars_my_pending_rating()), + .date = update.vstars_my_pending_rating_date().value_or_empty(), + }); + } if (const auto gifts = update.vdisallowed_gifts()) { const auto &data = gifts->data(); diff --git a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp index 0f7941977a..6a79eca9c7 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_cover.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_cover.cpp @@ -652,7 +652,10 @@ Cover::Cover( this, _controller->uiShow(), _peer->isSelf() ? QString() : _peer->shortName(), - Data::StarsRatingValue(_peer)) + Data::StarsRatingValue(_peer), + (_peer->isSelf() + ? [=] { return _peer->owner().pendingStarsRating(); } + : Fn())) : nullptr) , _status(this, _st.status) , _showLastSeen(this, tr::lng_status_lastseen_when(), _st.showLastSeen) diff --git a/Telegram/SourceFiles/ui/controls/stars_rating.cpp b/Telegram/SourceFiles/ui/controls/stars_rating.cpp index 32dcf87b5a..0adfa4e500 100644 --- a/Telegram/SourceFiles/ui/controls/stars_rating.cpp +++ b/Telegram/SourceFiles/ui/controls/stars_rating.cpp @@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/painter.h" #include "ui/rp_widget.h" #include "ui/ui_utility.h" +#include "styles/style_chat.h" // textMoreIconEmoji #include "styles/style_info.h" #include "styles/style_info_levels.h" #include "styles/style_layers.h" @@ -258,16 +259,18 @@ void FillRatingLimit( void AboutRatingBox( not_null box, const QString &name, - Counters data) { + Counters data, + Data::StarsRatingPending pending) { box->setWidth(st::boxWideWidth); box->setStyle(st::boostBox); struct State { rpl::variable data; + rpl::variable pending; rpl::variable full; }; const auto state = box->lifetime().make_state(); - state->data = std::move(data); + state->data = data; FillRatingLimit( BoxShowFinishes(box), @@ -278,7 +281,10 @@ void AboutRatingBox( box->setMaxHeight(st::boostBoxMaxHeight); - auto title = tr::lng_stars_rating_title();; + auto title = rpl::conditional( + state->pending.value(), + tr::lng_stars_rating_future(), + tr::lng_stars_rating_title()); auto text = !name.isEmpty() ? tr::lng_stars_rating_about( @@ -292,6 +298,41 @@ void AboutRatingBox( object_ptr(box, std::move(title), st::infoStarsTitle), st::boxRowPadding + QMargins(0, st::boostTitleSkip / 2, 0, 0)); + if (pending) { + auto text = state->pending.value( + ) | rpl::map([=](bool value) { + return tr::lng_stars_rating_pending( + tr::now, + lt_count_decimal, + pending.value.stars - data.stars, + lt_link, + Ui::Text::Link((value + ? tr::lng_stars_rating_pending_back + : tr::lng_stars_rating_pending_preview)( + tr::now, + lt_arrow, + Ui::Text::IconEmoji(&st::textMoreIconEmoji), + Ui::Text::WithEntities)), + Ui::Text::RichLangValue); + }); + const auto aboutPending = box->addRow( + object_ptr( + box, + std::move(text), + st::boostTextPending), + (st::boxRowPadding + + QMargins(0, st::boostTextSkip, 0, st::boostBottomSkip))); + aboutPending->setTryMakeSimilarLines(true); + aboutPending->setClickHandlerFilter([=](const auto &...) { + state->pending = !state->pending.current(); + state->data = state->pending.current() + ? pending.value + : data; + box->verticalLayout()->resizeToWidth(box->width()); + return false; + }); + } + const auto aboutLabel = box->addRow( object_ptr( box, @@ -395,11 +436,13 @@ StarsRating::StarsRating( QWidget *parent, std::shared_ptr show, const QString &name, - rpl::producer value) + rpl::producer value, + Fn pending) : _widget(std::make_unique(parent)) , _show(std::move(show)) , _name(name) -, _value(std::move(value)) { +, _value(std::move(value)) +, _pending(std::move(pending)) { init(); } @@ -417,7 +460,9 @@ void StarsRating::init() { if (!_value.current()) { return; } - _show->show(Box(AboutRatingBox, _name, _value.current())); + _show->show(Box(AboutRatingBox, _name, _value.current(), _pending + ? _pending() + : Data::StarsRatingPending())); }); _widget->resize(_widget->width(), st::level1.icon.height()); diff --git a/Telegram/SourceFiles/ui/controls/stars_rating.h b/Telegram/SourceFiles/ui/controls/stars_rating.h index 4393c81e5f..a803810c47 100644 --- a/Telegram/SourceFiles/ui/controls/stars_rating.h +++ b/Telegram/SourceFiles/ui/controls/stars_rating.h @@ -32,7 +32,8 @@ public: QWidget *parent, std::shared_ptr show, const QString &name, - rpl::producer value); + rpl::producer value, + Fn pending); ~StarsRating(); void raise(); @@ -55,6 +56,7 @@ private: Ui::Text::String _collapsedText; rpl::variable _value; + Fn _pending; rpl::variable _widthValue; const style::LevelShape *_shape = nullptr; diff --git a/Telegram/SourceFiles/ui/effects/premium.style b/Telegram/SourceFiles/ui/effects/premium.style index f5353f100c..75422a7514 100644 --- a/Telegram/SourceFiles/ui/effects/premium.style +++ b/Telegram/SourceFiles/ui/effects/premium.style @@ -286,6 +286,9 @@ boostText: FlatLabel(defaultFlatLabel) { minWidth: 40px; align: align(top); } +boostTextPending: FlatLabel(boostText) { + textFg: windowSubTextFg; +} boostReassignText: FlatLabel(defaultFlatLabel) { minWidth: 40px; align: align(top);