From f13c6109db39b3ef85d471396cd5f434633cd633 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 23 Dec 2025 17:08:28 +0400 Subject: [PATCH] Special toast for stake game. --- Telegram/Resources/langs/lang.strings | 2 + .../SourceFiles/data/data_media_types.cpp | 127 ++++++++++-------- .../SourceFiles/ui/boxes/emoji_stake_box.cpp | 61 ++++++++- .../SourceFiles/ui/boxes/emoji_stake_box.h | 9 ++ Telegram/SourceFiles/ui/chat/chat.style | 5 + 5 files changed, 149 insertions(+), 55 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index d3cf75777f..8eaa4b143a 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -4577,6 +4577,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_about_random" = "Send a {emoji} emoji to any chat to try your luck."; "lng_about_random_send" = "Send"; +"lng_about_random_stake" = "Stake: {amount}"; +"lng_about_random_stake_change" = "change"; "lng_open_this_link" = "Open this link?"; "lng_open_link" = "Open"; diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index c4ede43283..8e613a2851 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -2529,64 +2529,83 @@ ClickHandlerPtr MediaDice::MakeHandler( } }; return std::make_shared([=](ClickContext context) { + const auto found = Ui::Emoji::Find(emoji); + const auto id = found ? found->id() : QString(); + const auto game = (id == QString::fromUtf8("\xf0\x9f\x8e\xb2")); const auto my = context.other.value(); const auto weak = my.sessionWindow; - auto config = Ui::Toast::Config{ - .text = { tr::lng_about_random(tr::now, lt_emoji, emoji) }, - .st = &st::historyDiceToast, - .duration = Ui::Toast::kDefaultDuration * 2, + const auto sendWith = [=](const QByteArray &hash, int64 nanoTon) { + auto message = Api::MessageToSend( + Api::SendAction(history)); + message.textWithTags.text = emoji; + + auto &action = message.action; + action.clearDraft = false; + + auto &options = action.options; + options.stakeNanoTon = nanoTon; + options.stakeSeedHash = hash; + + Api::SendDice(message); + + HideExisting(); }; - if (CanSend(history->peer, ChatRestriction::SendOther)) { - auto link = tr::link(tr::lng_about_random_send(tr::now)); - link.entities.push_back( - EntityInText(EntityType::Semibold, 0, link.text.size())); - config.text.append(' ').append(std::move(link)); - config.filter = crl::guard(&history->session(), [=]( - const ClickHandlerPtr &handler, - Qt::MouseButton button) { - const auto pack = &history->session().diceStickersPacks(); - if (button == Qt::LeftButton && !ShownToast.empty()) { - pack->resolveGameOptions([=]( - const Data::DiceGameOptions &options) { - const auto window = weak.get(); - const auto seedHash = options.seedHash; - const auto sendWithStake = [=](int64 stakeNanoTon) { - auto message = Api::MessageToSend( - Api::SendAction(history)); - message.textWithTags.text = emoji; - - auto &action = message.action; - action.clearDraft = false; - - auto &options = action.options; - options.stakeNanoTon = stakeNanoTon; - options.stakeSeedHash = seedHash; - - Api::SendDice(message); - }; - if (!options || !window) { - sendWithStake(0); - } else { - window->show(Ui::MakeEmojiGameStakeBox({ - .session = &window->session(), - .currentStake = options.previousSteakNanoTon, - .milliRewards = options.milliRewards, - .jackpotMilliReward = options.jackpotMilliReward, - .submit = sendWithStake, - })); - } - }); - HideExisting(); - } - return false; - }); - } - - HideExisting(); - if (const auto strong = weak.get()) { - ShownToast = strong->showToast(std::move(config)); + const auto sendAllowed = CanSend( + history->peer, + ChatRestriction::SendOther); + const auto showToast = [=](Ui::Toast::Config &&config) { + HideExisting(); + if (const auto strong = weak.get()) { + ShownToast = strong->showToast(std::move(config)); + } else { + ShownToast = Ui::Toast::Show(std::move(config)); + } + }; + const auto showSimple = [=] { + auto config = Ui::Toast::Config{ + .text = { tr::lng_about_random(tr::now, lt_emoji, emoji) }, + .st = &st::historyDiceToast, + .duration = Ui::Toast::kDefaultDuration * 2, + }; + if (sendAllowed) { + auto link = tr::link(tr::lng_about_random_send(tr::now)); + link.entities.push_back( + EntityInText(EntityType::Semibold, 0, link.text.size())); + config.text.append(' ').append(std::move(link)); + config.filter = crl::guard(&history->session(), [=]( + const ClickHandlerPtr &handler, + Qt::MouseButton button) { + if (button == Qt::LeftButton && !ShownToast.empty()) { + sendWith(QByteArray(), 0); + } + return false; + }); + } + showToast(std::move(config)); + }; + if (!game || !sendAllowed) { + showSimple(); } else { - ShownToast = Ui::Toast::Show(std::move(config)); + const auto pack = &history->session().diceStickersPacks(); + pack->resolveGameOptions([=]( + const Data::DiceGameOptions &options) { + const auto window = weak.get(); + const auto seedHash = options.seedHash; + const auto sendWithStake = [=](int64 stakeNanoTon) { + sendWith(seedHash, stakeNanoTon); + }; + if (!options || !window) { + showSimple(); + } else { + showToast(Ui::MakeEmojiGameStakeToast(window->uiShow(), { + .session = &window->session(), + .currentStake = options.previousSteakNanoTon, + .milliRewards = options.milliRewards, + .jackpotMilliReward = options.jackpotMilliReward, + .submit = sendWithStake, + })); + } + }); } }); } diff --git a/Telegram/SourceFiles/ui/boxes/emoji_stake_box.cpp b/Telegram/SourceFiles/ui/boxes/emoji_stake_box.cpp index 02ba622b60..3cf9b425cd 100644 --- a/Telegram/SourceFiles/ui/boxes/emoji_stake_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/emoji_stake_box.cpp @@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/custom_emoji_helper.h" #include "ui/text/custom_emoji_text_badge.h" #include "ui/text/text_lottie_custom_emoji.h" +#include "ui/toast/toast.h" #include "ui/widgets/fields/input_field.h" #include "ui/widgets/fields/number_input.h" #include "ui/widgets/buttons.h" @@ -428,7 +429,7 @@ void EmojiGameStakeBox( auto helper = Text::CustomEmojiHelper(); const auto beta = helper.paletteDependent( Text::CustomEmojiTextBadge( - tr::lng_stake_game_beta(tr::now), + tr::lng_stake_game_beta(tr::now).toUpper(), st::customEmojiTextBadge)); const auto sixText = helper.image({ .image = MakeEmojiFrame(6, st::emojiSize), @@ -589,4 +590,62 @@ void EmojiGameStakeBox( }, balance->lifetime()); } +Toast::Config MakeEmojiGameStakeToast( + std::shared_ptr show, + EmojiGameStakeArgs &&args) { + auto config = Toast::Config{ + .st = &st::historyDiceToast, + .duration = Ui::Toast::kDefaultDuration * 2, + }; + auto helper = Text::CustomEmojiHelper(); + static const auto makeBg = [] { + auto result = st::mediaviewTextLinkFg->c; + result.setAlphaF(0.12); + return result; + }; + struct State { + State() : bg(makeBg), badge(st::stakeChangeBadge) { + badge.textBg = badge.textBgOver = bg.color(); + } + + style::complex_color bg; + style::RoundButton badge; + }; + auto state = std::make_shared(); + const auto badge = helper.paletteDependent( + Ui::Text::CustomEmojiTextBadge( + tr::lng_about_random_stake_change(tr::now), + state->badge, + st::stateChangeBadgeMargin)); + const auto diamond = QString::fromUtf8("\xf0\x9f\x92\x8e"); + config.text.append( + tr::lng_about_random_stake( + tr::now, + lt_amount, + tr::bold(diamond + Ui::FormatTonAmount(args.currentStake).full), + tr::marked) + ).append(' ').append( + tr::link(badge, u"internal:stake_change"_q) + ).append(u" "_q.repeated(10)).append(tr::link( + tr::semibold(tr::lng_about_random_send(tr::now)), + u"internal:stake_send"_q)); + config.textContext = helper.context(); + + config.filter = [=, state = std::move(state)]( + const ClickHandlerPtr &handler, + Qt::MouseButton button) { + if (button == Qt::LeftButton) { + const auto url = handler ? handler->url() : QString(); + if (url == u"internal:stake_change"_q) { + show->show(Ui::MakeEmojiGameStakeBox(base::duplicate(args))); + } else if (url == u"internal:stake_send"_q) { + args.submit(args.currentStake); + } + } + return false; + }; + + return config; +} + } // namespace Ui diff --git a/Telegram/SourceFiles/ui/boxes/emoji_stake_box.h b/Telegram/SourceFiles/ui/boxes/emoji_stake_box.h index 7077fffc28..71451ac10b 100644 --- a/Telegram/SourceFiles/ui/boxes/emoji_stake_box.h +++ b/Telegram/SourceFiles/ui/boxes/emoji_stake_box.h @@ -13,8 +13,13 @@ namespace Main { class Session; } // namespace Main +namespace Ui::Toast { +struct Config; +} // namespace Ui::Toast + namespace Ui { +class Show; class InputField; class NumberInput; class VerticalLayout; @@ -57,4 +62,8 @@ void EmojiGameStakeBox(not_null box, EmojiGameStakeArgs &&args); return Box(EmojiGameStakeBox, std::move(args)); } +[[nodiscard]] Toast::Config MakeEmojiGameStakeToast( + std::shared_ptr show, + EmojiGameStakeArgs &&args); + } // namespace Ui diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index 21ebf08efc..5c8d9de706 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -1483,3 +1483,8 @@ stakePresetButton: RoundButton(defaultLightButton) { textBg: lightButtonBgOver; } stakePresetButtonSkip: point(8px, 8px); +stakeChangeBadge: RoundButton(defaultTableSmallButton) { + textFg: mediaviewTextLinkFg; + textFgOver: mediaviewTextLinkFg; +} +stateChangeBadgeMargin: margins(0px, 1px, 0px, 0px);