@@ -157,13 +157,19 @@ void FillRatingLimit(
157157 rpl::producer<> showFinished,
158158 not_null<VerticalLayout*> container,
159159 rpl::producer<Counters> data,
160+ Premium::BubbleType type,
160161 style::margins limitLinePadding,
161- int starsForScale) {
162+ int starsForScale,
163+ bool hideCount) {
162164 const auto addSkip = [&](int skip) {
163165 container->add (object_ptr<Ui::FixedHeightWidget>(container, skip));
164166 };
165167
168+ const auto negative = (type == Premium::BubbleType::NegativeRating);
166169 const auto ratio = [=](Counters rating) {
170+ if (negative) {
171+ return 0.5 ;
172+ }
167173 const auto min = rating.thisLevelStars ;
168174 const auto max = rating.nextLevelStars ;
169175
@@ -213,12 +219,14 @@ void FillRatingLimit(
213219 });
214220 Premium::AddBubbleRow (
215221 container,
216- st::boostBubble,
222+ (hideCount ? st::iconOnlyPremiumBubble : st:: boostBubble) ,
217223 std::move (showFinished),
218224 rpl::duplicate (bubbleRowState),
219- Premium::BubbleType::StarRating,
220- BubbleTextFactory (starsForScale),
221- &st::infoStarsCrown,
225+ type,
226+ (hideCount
227+ ? [](int ) { return QString (); }
228+ : BubbleTextFactory (starsForScale)),
229+ negative ? &st::levelNegativeBubble : &st::infoStarsCrown,
222230 limitLinePadding);
223231 addSkip (st::premiumLineTextSkip);
224232
@@ -227,30 +235,35 @@ void FillRatingLimit(
227235 };
228236 auto limitState = std::move (
229237 bubbleRowState
230- ) | rpl::map ([](const Premium::BubbleRowState &state) {
238+ ) | rpl::map ([negative ](const Premium::BubbleRowState &state) {
231239 return Premium::LimitRowState{
232- .ratio = state.ratio ,
233- .animateFromZero = state.animateFromZero ,
240+ .ratio = negative ? 0.5 : state.ratio ,
241+ .animateFromZero = !negative && state.animateFromZero ,
234242 .dynamic = state.dynamic
235243 };
236244 });
237245 auto left = rpl::duplicate (
238246 adjustedData
239247 ) | rpl::map ([=](Counters counters) {
240- return level (counters.level );
248+ return (counters. level < 0 ) ? QString () : level (counters.level );
241249 });
242250 auto right = rpl::duplicate (
243251 adjustedData
244252 ) | rpl::map ([=](Counters counters) {
245- return level (counters.level + 1 );
253+ return (counters.level < 0 )
254+ ? tr::lng_stars_rating_negative_label (tr::now)
255+ : level (counters.level + 1 );
246256 });
247257 Premium::AddLimitRow (
248258 container,
249- st::boostLimits,
259+ (negative ? st::negativeStarsLimits : st:: boostLimits) ,
250260 Premium::LimitRowLabels{
251261 .leftLabel = std::move (left),
252262 .rightLabel = std::move (right),
253- .activeLineBg = [=] { return st::windowBgActive->b ; },
263+ .activeLineBg = [=] { return negative
264+ ? st::attentionButtonFg->b
265+ : st::windowBgActive->b ;
266+ },
254267 },
255268 std::move (limitState),
256269 limitLinePadding);
@@ -276,8 +289,12 @@ void AboutRatingBox(
276289 BoxShowFinishes (box),
277290 box->verticalLayout (),
278291 state->data .value (),
292+ (data.level < 0
293+ ? Premium::BubbleType::NegativeRating
294+ : Premium::BubbleType::StarRating),
279295 st::boxRowPadding,
280- data.stars );
296+ data.stars ,
297+ (data.level < 0 && !data.stars ));
281298
282299 box->setMaxHeight (st::boostBoxMaxHeight);
283300
@@ -294,10 +311,40 @@ void AboutRatingBox(
294311 : tr::lng_stars_rating_about_your (
295312 Ui::Text::RichLangValue) | rpl::type_erased ();
296313
314+ if (data.level < 0 ) {
315+ auto text = (data.stars < 0 )
316+ ? tr::lng_stars_rating_negative_your (
317+ lt_count_decimal,
318+ rpl::single (-data.stars * 1 .),
319+ Ui::Text::RichLangValue)
320+ : tr::lng_stars_rating_negative (
321+ lt_name,
322+ rpl::single (TextWithEntities{ name }),
323+ Ui::Text::RichLangValue);
324+ const auto aboutNegative = box->addRow (
325+ object_ptr<Ui::FlatLabel>(
326+ box,
327+ std::move (text),
328+ st::boostTextNegative),
329+ (st::boxRowPadding
330+ + QMargins (0 , st::boostTextSkip, 0 , st::boostBottomSkip)));
331+ aboutNegative->setTryMakeSimilarLines (true );
332+ }
333+
297334 box->addRow (
298335 object_ptr<Ui::FlatLabel>(box, std::move (title), st::infoStarsTitle),
299336 st::boxRowPadding + QMargins (0 , st::boostTitleSkip / 2 , 0 , 0 ));
300337
338+ AssertIsDebug ();
339+ pending = {
340+ .value = {
341+ .level = 10 ,
342+ .stars = 100 ,
343+ .thisLevelStars = 90 ,
344+ .nextLevelStars = 110 ,
345+ },
346+ .date = 86400 ,
347+ };
301348 if (pending) {
302349 auto text = state->pending .value (
303350 ) | rpl::map ([=](bool value) {
@@ -398,6 +445,9 @@ void AboutRatingBox(
398445}
399446
400447[[nodiscard]] not_null<const style::LevelShape*> SelectShape (int level) {
448+ if (level < 0 ) {
449+ return &st::levelNegative;
450+ }
401451 struct Shape {
402452 int level = 0 ;
403453 not_null<const style::LevelShape*> shape;
@@ -480,7 +530,9 @@ void StarsRating::updateData(Data::StarsRating rating) {
480530 _shape = SelectShape (rating.level );
481531 _collapsedText.setText (
482532 st::levelStyle,
483- Lang::FormatCountDecimal (rating.level ));
533+ (rating.level < 0
534+ ? QString ()
535+ : Lang::FormatCountDecimal (rating.level )));
484536 _widthValue = _shape->icon .width () - st::levelMargin.left ();
485537 }
486538 updateWidth ();
0 commit comments