diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index e5394d5b74..5cde1ca953 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -4659,10 +4659,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_paid_comment_about" = "Highlight and pin your message by adding Stars for {name}."; "lng_paid_comment_button" = "Add {stars}"; "lng_paid_comment_pin_about" = "pin in chat"; -"lng_paid_comment_pin_minutes#one" = "{count}m"; -"lng_paid_comment_pin_minutes#other" = "{count}m"; -"lng_paid_comment_pin_hours#one" = "{count}h"; -"lng_paid_comment_pin_hours#other" = "{count}h"; "lng_paid_comment_limit_about#one" = "character"; "lng_paid_comment_limit_about#other" = "characters"; "lng_paid_comment_emoji_about#one" = "emoji"; diff --git a/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp b/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp index ba9391908d..f0fea7f159 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_messages_ui.cpp @@ -779,7 +779,7 @@ void MessagesUi::setupMessagesWidget() { entry.text.draw(p, { .position = { x + leftSkip, - y + padding.top() + y + padding.top(), }, .availableWidth = entry.width - leftSkip - padding.right(), .palette = &st::groupCallMessagePalette, diff --git a/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.cpp b/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.cpp new file mode 100644 index 0000000000..deca77d454 --- /dev/null +++ b/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.cpp @@ -0,0 +1,156 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "calls/group/ui/calls_group_stars_coloring.h" + +#include "base/object_ptr.h" +#include "lang/lang_keys.h" +#include "ui/widgets/labels.h" +#include "ui/painter.h" +#include "ui/rp_widget.h" +#include "styles/style_credits.h" +#include "styles/style_layers.h" +#include "styles/style_premium.h" + +namespace Calls::Group::Ui { +namespace { + +[[nodiscard]] not_null MakeInfoBlock( + not_null parent, + rpl::producer title, + rpl::producer subtext) { + const auto result = CreateChild(parent); + + const auto titleHeight = st::videoStreamInfoTitle.style.font->height; + const auto subtextHeight = st::videoStreamInfoSubtext.style.font->height; + const auto height = titleHeight + subtextHeight; + + result->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(result); + auto hq = PainterHighQualityEnabler(p); + p.setPen(Qt::NoPen); + p.setBrush(st::groupCallMembersBgOver); + const auto radius = st::boxRadius; + p.drawRoundedRect(result->rect(), radius, radius); + }, result->lifetime()); + + result->resize( + result ->width(), + QSize(height, height).grownBy(st::videoStreamInfoPadding).height()); + + const auto titleLabel = CreateChild( + result, + std::move(title), + st::videoStreamInfoTitle); + const auto subtextLabel = CreateChild( + result, + std::move(subtext), + st::videoStreamInfoSubtext); + + rpl::combine( + result->widthValue(), + titleLabel->widthValue(), + subtextLabel->widthValue() + ) | rpl::start_with_next([=](int width, int titlew, int subtextw) { + const auto padding = st::videoStreamInfoPadding; + titleLabel->moveToLeft((width - titlew) / 2, padding.top(), width); + subtextLabel->moveToLeft( + (width - subtextw) / 2, + padding.top() + titleHeight, + width); + }, result->lifetime()); + + return result; +} + +} // namespace + +StarsColoring StarsColoringForCount(int stars) { + const auto list = std::vector{ + { st::creditsBg3->c, st::creditsBg2->c, 50, 1, 60, 1 }, + { st::creditsBg3->c, st::creditsBg2->c, 100, 1, 80, 2 }, + { st::creditsBg3->c, st::creditsBg2->c, 250, 5, 110, 3 }, + { st::creditsBg3->c, st::creditsBg2->c, 500, 10, 150, 4 }, + { st::creditsBg3->c, st::creditsBg2->c, 2000, 15, 200, 7 }, + { st::creditsBg3->c, st::creditsBg2->c, 7500, 30, 280, 10 }, + { st::creditsBg3->c, st::creditsBg2->c, 0, 60, 400, 20 }, + }; + for (const auto &entry : list) { + if (!entry.tillStars || stars < entry.tillStars) { + return entry; + } + } + Unexpected("StarsColoringForCount: should not reach here."); +} + +object_ptr VideoStreamStarsLevel( + not_null box, + rpl::producer starsValue) { + auto result = object_ptr(box.get()); + const auto raw = result.data(); + + struct State { + rpl::variable stars; + rpl::variable coloring; + std::vector> blocks; + }; + const auto state = raw->lifetime().make_state(); + state->stars = std::move(starsValue); + state->coloring = state->stars.value( + ) | rpl::map([](int stars) { + return StarsColoringForCount(stars); + }); + + state->blocks.push_back(MakeInfoBlock(raw, state->coloring.value( + ) | rpl::map([=](const StarsColoring &value) { + const auto minutes = value.minutesPin; + return (minutes >= 60) + ? tr::lng_hours_tiny(tr::now, lt_count, minutes / 60) + : tr::lng_minutes_tiny(tr::now, lt_count, minutes); + }), tr::lng_paid_comment_pin_about())); + + state->blocks.push_back(MakeInfoBlock(raw, state->coloring.value( + ) | rpl::map([=](const StarsColoring &value) { + return QString::number(value.charactersMax); + }), state->coloring.value() | rpl::map([=](const StarsColoring &value) { + return tr::lng_paid_comment_limit_about( + tr::now, + lt_count, + value.charactersMax); + }))); + + state->blocks.push_back(MakeInfoBlock(raw, state->coloring.value( + ) | rpl::map([=](const StarsColoring &value) { + return QString::number(value.emojiLimit); + }), state->coloring.value() | rpl::map([=](const StarsColoring &value) { + return tr::lng_paid_comment_emoji_about( + tr::now, + lt_count, + value.emojiLimit); + }))); + + raw->resize(raw->width(), state->blocks.front()->height()); + raw->widthValue() | rpl::start_with_next([=](int width) { + const auto count = int(state->blocks.size()); + const auto skip = (st::boxRowPadding.left() / 2); + const auto single = (width - skip * (count - 1)) / float64(count); + if (single < 1.) { + return; + } + auto x = 0.; + const auto w = int(base::SafeRound(single)); + for (const auto &block : state->blocks) { + block->resizeToWidth(w); + block->moveToLeft(int(base::SafeRound(x)), 0); + x += single + skip; + } + }, raw->lifetime()); + + return result; +} + +} // namespace Calls::Group::Ui diff --git a/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.h b/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.h new file mode 100644 index 0000000000..e821e21d75 --- /dev/null +++ b/Telegram/SourceFiles/calls/group/ui/calls_group_stars_coloring.h @@ -0,0 +1,40 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace Ui { +class RpWidget; +} // namespace Ui + +namespace Calls::Group::Ui { + +using namespace ::Ui; + +struct StarsColoring { + QColor bg1; + QColor bg2; + int tillStars = 0; + int minutesPin = 0; + int charactersMax = 0; + int emojiLimit = 0; + + friend inline auto operator<=>( + const StarsColoring &, + const StarsColoring &) = default; + friend inline bool operator==( + const StarsColoring &, + const StarsColoring &) = default; +}; + +[[nodiscard]] StarsColoring StarsColoringForCount(int stars); + +[[nodiscard]] object_ptr VideoStreamStarsLevel( + not_null box, + rpl::producer starsValue); + +} // namespace Calls::Group::Ui diff --git a/Telegram/SourceFiles/payments/ui/payments_reaction_box.cpp b/Telegram/SourceFiles/payments/ui/payments_reaction_box.cpp index 2ae38d3017..79a9ae9e61 100644 --- a/Telegram/SourceFiles/payments/ui/payments_reaction_box.cpp +++ b/Telegram/SourceFiles/payments/ui/payments_reaction_box.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "payments/ui/payments_reaction_box.h" #include "base/qt/qt_compare.h" +#include "calls/group/ui/calls_group_stars_coloring.h" #include "lang/lang_keys.h" #include "ui/boxes/boost_box.h" // MakeBoostFeaturesBadge. #include "ui/controls/who_reacted_context_action.h" @@ -546,6 +547,13 @@ void PaidReactionsBox( dark ? st::darkEditStarsClose : st::boxTitleClose, [=] { box->closeBox(); }); + if (args.videoStreamChoosing) { + using namespace Calls::Group::Ui; + box->addRow( + VideoStreamStarsLevel(box, state->chosen.value()), + st::boxRowPadding + QMargins(0, st::paidReactTitleSkip, 0, 0)); + } + box->addRow( object_ptr( box, diff --git a/Telegram/SourceFiles/ui/effects/premium.style b/Telegram/SourceFiles/ui/effects/premium.style index 345df28603..48466390e0 100644 --- a/Telegram/SourceFiles/ui/effects/premium.style +++ b/Telegram/SourceFiles/ui/effects/premium.style @@ -548,3 +548,21 @@ starrefPopupMenu: PopupMenu(defaultPopupMenu) { widthMax: 200px; } } + +videoStreamInfoPadding: margins(12px, 8px, 12px, 8px); +videoStreamInfoTitle: FlatLabel(defaultFlatLabel) { + minWidth: 40px; + textFg: groupCallMembersFg; + align: align(top); + style: TextStyle(boxTextStyle) { + font: font(18px semibold); + } +} +videoStreamInfoSubtext: FlatLabel(defaultFlatLabel) { + minWidth: 40px; + textFg: groupCallMembersFg; + align: align(top); + style: TextStyle(defaultTextStyle) { + font: font(12px); + } +} diff --git a/Telegram/cmake/td_ui.cmake b/Telegram/cmake/td_ui.cmake index 6adf58bd83..902f1f9353 100644 --- a/Telegram/cmake/td_ui.cmake +++ b/Telegram/cmake/td_ui.cmake @@ -66,6 +66,8 @@ PRIVATE calls/group/ui/calls_group_recording_box.h calls/group/ui/calls_group_scheduled_labels.cpp calls/group/ui/calls_group_scheduled_labels.h + calls/group/ui/calls_group_stars_coloring.cpp + calls/group/ui/calls_group_stars_coloring.h calls/group/ui/desktop_capture_choose_source.cpp calls/group/ui/desktop_capture_choose_source.h calls/ui/calls_device_menu.cpp