2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-22 10:17:10 +00:00

Show star rating preview.

This commit is contained in:
John Preston 2025-08-01 16:13:15 +04:00
parent e1b2f940ad
commit 62c9666013
9 changed files with 94 additions and 11 deletions

View File

@ -1878,9 +1878,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stars_rating_title" = "Rating"; "lng_stars_rating_title" = "Rating";
"lng_stars_rating_future" = "Future 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" = "The rating updates in 21 days after purchases.\n{count} point is pending. {link}";
"lng_stars_rating_pending#one" = "{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#other" = "{count} points are pending. {link}";
"lng_stars_rating_pending_preview" = "Preview {arrow}"; "lng_stars_rating_pending_preview" = "Preview {arrow}";
"lng_stars_rating_pending_back" = "Back {arrow}"; "lng_stars_rating_pending_back" = "Back {arrow}";
"lng_stars_rating_about" = "This rating reflects **{name}'s** activity on Telegram. What affects it:"; "lng_stars_rating_about" = "This rating reflects **{name}'s** activity on Telegram. What affects it:";

View File

@ -22,4 +22,13 @@ struct StarsRating {
friend inline bool operator==(StarsRating, StarsRating) = default; friend inline bool operator==(StarsRating, StarsRating) = default;
}; };
struct StarsRatingPending {
StarsRating value;
TimeId date = 0;
explicit operator bool() const {
return value && date;
}
};
} // namespace Data } // namespace Data

View File

@ -5185,6 +5185,16 @@ int Session::commonStarsPerMessage(
return (i != end(_commonStarsPerMessage)) ? i->second : 0; return (i != end(_commonStarsPerMessage)) ? i->second : 0;
} }
void Session::setPendingStarsRating(StarsRatingPending value) {
_pendingStarsRating = value
? std::make_unique<StarsRatingPending>(value)
: nullptr;
}
StarsRatingPending Session::pendingStarsRating() const {
return _pendingStarsRating ? *_pendingStarsRating : StarsRatingPending();
}
void Session::clearLocalStorage() { void Session::clearLocalStorage() {
_cache->close(); _cache->close();
_cache->clear(); _cache->clear();

View File

@ -72,6 +72,7 @@ class BusinessInfo;
struct ReactionId; struct ReactionId;
struct UnavailableReason; struct UnavailableReason;
struct CreditsStatusSlice; struct CreditsStatusSlice;
struct StarsRatingPending;
struct UniqueGift; struct UniqueGift;
struct RepliesReadTillUpdate { struct RepliesReadTillUpdate {
@ -872,6 +873,9 @@ public:
[[nodiscard]] int commonStarsPerMessage( [[nodiscard]] int commonStarsPerMessage(
not_null<const ChannelData*> channel) const; not_null<const ChannelData*> channel) const;
void setPendingStarsRating(StarsRatingPending value);
[[nodiscard]] StarsRatingPending pendingStarsRating() const;
void clearLocalStorage(); void clearLocalStorage();
private: private:
@ -1226,6 +1230,8 @@ private:
MsgId _nonHistoryEntryId = ShortcutMaxMsgId; MsgId _nonHistoryEntryId = ShortcutMaxMsgId;
std::unique_ptr<StarsRatingPending> _pendingStarsRating;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
}; };

View File

@ -874,6 +874,12 @@ void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update) {
user->setBotVerifyDetails( user->setBotVerifyDetails(
ParseBotVerifyDetails(update.vbot_verification())); ParseBotVerifyDetails(update.vbot_verification()));
user->setStarsRating(ParseStarsRating(update.vstars_rating())); 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()) { if (const auto gifts = update.vdisallowed_gifts()) {
const auto &data = gifts->data(); const auto &data = gifts->data();

View File

@ -652,7 +652,10 @@ Cover::Cover(
this, this,
_controller->uiShow(), _controller->uiShow(),
_peer->isSelf() ? QString() : _peer->shortName(), _peer->isSelf() ? QString() : _peer->shortName(),
Data::StarsRatingValue(_peer)) Data::StarsRatingValue(_peer),
(_peer->isSelf()
? [=] { return _peer->owner().pendingStarsRating(); }
: Fn<Data::StarsRatingPending()>()))
: nullptr) : nullptr)
, _status(this, _st.status) , _status(this, _st.status)
, _showLastSeen(this, tr::lng_status_lastseen_when(), _st.showLastSeen) , _showLastSeen(this, tr::lng_status_lastseen_when(), _st.showLastSeen)

View File

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/painter.h" #include "ui/painter.h"
#include "ui/rp_widget.h" #include "ui/rp_widget.h"
#include "ui/ui_utility.h" #include "ui/ui_utility.h"
#include "styles/style_chat.h" // textMoreIconEmoji
#include "styles/style_info.h" #include "styles/style_info.h"
#include "styles/style_info_levels.h" #include "styles/style_info_levels.h"
#include "styles/style_layers.h" #include "styles/style_layers.h"
@ -258,16 +259,18 @@ void FillRatingLimit(
void AboutRatingBox( void AboutRatingBox(
not_null<GenericBox*> box, not_null<GenericBox*> box,
const QString &name, const QString &name,
Counters data) { Counters data,
Data::StarsRatingPending pending) {
box->setWidth(st::boxWideWidth); box->setWidth(st::boxWideWidth);
box->setStyle(st::boostBox); box->setStyle(st::boostBox);
struct State { struct State {
rpl::variable<Counters> data; rpl::variable<Counters> data;
rpl::variable<bool> pending;
rpl::variable<bool> full; rpl::variable<bool> full;
}; };
const auto state = box->lifetime().make_state<State>(); const auto state = box->lifetime().make_state<State>();
state->data = std::move(data); state->data = data;
FillRatingLimit( FillRatingLimit(
BoxShowFinishes(box), BoxShowFinishes(box),
@ -278,7 +281,10 @@ void AboutRatingBox(
box->setMaxHeight(st::boostBoxMaxHeight); 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() auto text = !name.isEmpty()
? tr::lng_stars_rating_about( ? tr::lng_stars_rating_about(
@ -292,6 +298,41 @@ void AboutRatingBox(
object_ptr<Ui::FlatLabel>(box, std::move(title), st::infoStarsTitle), object_ptr<Ui::FlatLabel>(box, std::move(title), st::infoStarsTitle),
st::boxRowPadding + QMargins(0, st::boostTitleSkip / 2, 0, 0)); 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<Ui::FlatLabel>(
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( const auto aboutLabel = box->addRow(
object_ptr<Ui::FlatLabel>( object_ptr<Ui::FlatLabel>(
box, box,
@ -395,11 +436,13 @@ StarsRating::StarsRating(
QWidget *parent, QWidget *parent,
std::shared_ptr<Ui::Show> show, std::shared_ptr<Ui::Show> show,
const QString &name, const QString &name,
rpl::producer<Counters> value) rpl::producer<Counters> value,
Fn<Data::StarsRatingPending()> pending)
: _widget(std::make_unique<Ui::AbstractButton>(parent)) : _widget(std::make_unique<Ui::AbstractButton>(parent))
, _show(std::move(show)) , _show(std::move(show))
, _name(name) , _name(name)
, _value(std::move(value)) { , _value(std::move(value))
, _pending(std::move(pending)) {
init(); init();
} }
@ -417,7 +460,9 @@ void StarsRating::init() {
if (!_value.current()) { if (!_value.current()) {
return; 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()); _widget->resize(_widget->width(), st::level1.icon.height());

View File

@ -32,7 +32,8 @@ public:
QWidget *parent, QWidget *parent,
std::shared_ptr<Ui::Show> show, std::shared_ptr<Ui::Show> show,
const QString &name, const QString &name,
rpl::producer<Data::StarsRating> value); rpl::producer<Data::StarsRating> value,
Fn<Data::StarsRatingPending()> pending);
~StarsRating(); ~StarsRating();
void raise(); void raise();
@ -55,6 +56,7 @@ private:
Ui::Text::String _collapsedText; Ui::Text::String _collapsedText;
rpl::variable<Data::StarsRating> _value; rpl::variable<Data::StarsRating> _value;
Fn<Data::StarsRatingPending()> _pending;
rpl::variable<int> _widthValue; rpl::variable<int> _widthValue;
const style::LevelShape *_shape = nullptr; const style::LevelShape *_shape = nullptr;

View File

@ -286,6 +286,9 @@ boostText: FlatLabel(defaultFlatLabel) {
minWidth: 40px; minWidth: 40px;
align: align(top); align: align(top);
} }
boostTextPending: FlatLabel(boostText) {
textFg: windowSubTextFg;
}
boostReassignText: FlatLabel(defaultFlatLabel) { boostReassignText: FlatLabel(defaultFlatLabel) {
minWidth: 40px; minWidth: 40px;
align: align(top); align: align(top);