diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 3d6a8326b5..19202a273c 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -4148,6 +4148,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_craft_failed_about#one" = "This crafting attempt was unsuccessful.\n**{count}** gift was lost."; "lng_gift_craft_failed_about#other" = "This crafting attempt was unsuccessful.\n**{count}** gifts were lost."; "lng_gift_craft_new_button" = "Craft New Gift"; +"lng_gift_craft_unavailable" = "Crafting unavailable"; +"lng_gift_craft_when" = "This gift will become available for crafting on {date} at {time}."; "lng_auction_about_title" = "Auction"; "lng_auction_about_subtitle" = "Join the battle for exclusive gifts."; diff --git a/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp b/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp index 53318cad65..773f7b6cfb 100644 --- a/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp @@ -8,8 +8,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/star_gift_craft_animation.h" #include "base/call_delayed.h" +#include "base/unixtime.h" #include "boxes/star_gift_box.h" #include "boxes/star_gift_cover_box.h" +#include "boxes/star_gift_craft_box.h" #include "chat_helpers/compose/compose_show.h" #include "chat_helpers/stickers_lottie.h" #include "data/data_credits.h" @@ -23,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "settings/settings_credits_graphics.h" #include "ui/boxes/boost_box.h" +#include "ui/boxes/confirm_box.h" #include "ui/image/image_prepare.h" #include "ui/layers/generic_box.h" #include "ui/widgets/gradient_round_button.h" @@ -1478,7 +1481,7 @@ void StartCraftAnimation( not_null box, std::shared_ptr show, std::shared_ptr shared, - Fn startRequest, + Fn callback)> startRequest, Fn closeParent, Fn closeCurrent)> retryWithNewGift) { const auto container = box->verticalLayout(); @@ -1832,11 +1835,24 @@ void StartCraftAnimation( if (startRequest) { const auto weak = base::make_weak(raw); - startRequest([=](std::shared_ptr result) { + startRequest([=](CraftResult result) { if (!weak) { return; + } else if (v::is(result)) { + box->uiShow()->show(MakeInformBox({ + .text = v::get(result).type, + })); + box->closeBox(); + return; + } else if (v::is(result)) { + const auto when = base::unixtime::now() + + v::get(result).seconds; + ShowCraftLaterError(box->uiShow(), when); + box->closeBox(); + return; } - state->craftResult = std::move(result); + using Result = std::shared_ptr; + state->craftResult = v::get(result); if (const auto result = state->craftResult->get()) { state->successAnimation = std::make_unique< CraftDoneAnimation diff --git a/Telegram/SourceFiles/boxes/star_gift_craft_animation.h b/Telegram/SourceFiles/boxes/star_gift_craft_animation.h index dc68b56e11..a1073d7cdf 100644 --- a/Telegram/SourceFiles/boxes/star_gift_craft_animation.h +++ b/Telegram/SourceFiles/boxes/star_gift_craft_animation.h @@ -38,7 +38,18 @@ class RpWidget; class VerticalLayout; class UniqueGiftCoverWidget; -using CraftResultCallback = Fn)>; +struct CraftResultError { + QString type; +}; + +struct CraftResultWait { + TimeId seconds = 0; +}; + +using CraftResult = std::variant< + std::shared_ptr, + CraftResultError, + CraftResultWait>; struct BackdropView { Data::UniqueGiftBackdrop colors; @@ -205,7 +216,7 @@ void StartCraftAnimation( not_null box, std::shared_ptr show, std::shared_ptr state, - Fn startRequest, + Fn callback)> startRequest, Fn closeParent, Fn closeCurrent)> retryWithNewGift); diff --git a/Telegram/SourceFiles/boxes/star_gift_craft_box.cpp b/Telegram/SourceFiles/boxes/star_gift_craft_box.cpp index f606fc3b13..8d204e9100 100644 --- a/Telegram/SourceFiles/boxes/star_gift_craft_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_craft_box.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/call_delayed.h" #include "base/random.h" +#include "base/unixtime.h" #include "boxes/star_gift_auction_box.h" #include "boxes/star_gift_craft_animation.h" #include "boxes/star_gift_preview_box.h" @@ -29,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_app_config.h" #include "main/main_session.h" #include "ui/boxes/about_cocoon_box.h" // AddUniqueCloseButton. +#include "ui/boxes/confirm_box.h" #include "ui/controls/button_labels.h" #include "ui/controls/feature_list.h" #include "ui/effects/numbers_animation.h" @@ -933,7 +935,7 @@ void Craft( const std::vector &gifts, Fn closeParent) { auto show = controller->uiShow(); - auto startRequest = [=](CraftResultCallback done) { + auto startRequest = [=](Fn done) { #if 0 constexpr auto kDelays = std::array{ 100, 200, 300, 400, 500, 1000, 2000 @@ -978,7 +980,15 @@ void Craft( session->data().nextForUpgradeGiftInvalidate(session->user()); done(FindUniqueGift(session, result)); }).fail([=](const MTP::Error &error) { - show->showToast(error.type()); + const auto type = error.type(); + const auto waitPrefix = u"STARGIFT_CRAFT_TOO_EARLY_"_q; + if (type.startsWith(waitPrefix)) { + done(CraftResultWait{ + .seconds = type.mid(waitPrefix.size()).toInt(), + }); + } else { + done(CraftResultError{ type }); + } }).send(); }; const auto requested = std::make_shared(); @@ -989,11 +999,14 @@ void Craft( } *requested = true; ShowSelectGiftBox(controller, giftId, [=](GiftForCraft chosen) { - ShowGiftCraftBox( - controller, - { chosen }, - closeParent, - false); + const auto unique = chosen.unique; + if (!ShowCraftLaterError(show, unique)) { + ShowGiftCraftBox( + controller, + { chosen }, + closeParent, + false); + } closeCurrent(); }, {}, [=] { *requested = false; }); }; @@ -1208,13 +1221,16 @@ void MakeCraftContent( } state->requestingIndex = index; const auto callback = [=](GiftForCraft chosen) { - auto copy = state->chosen.current(); - if (state->requestingIndex < copy.size()) { - copy[state->requestingIndex] = chosen; - } else { - copy.push_back(chosen); + const auto unique = chosen.unique; + if (!ShowCraftLaterError(controller->uiShow(), unique)) { + auto copy = state->chosen.current(); + if (state->requestingIndex < copy.size()) { + copy[state->requestingIndex] = chosen; + } else { + copy.push_back(chosen); + } + state->chosen = std::move(copy); } - state->chosen = std::move(copy); }; ShowSelectGiftBox( controller, @@ -1496,4 +1512,33 @@ void ShowTestGiftCraftBox( ShowGiftCraftBox(controller, std::move(converted), [] {}, true); } +bool ShowCraftLaterError( + std::shared_ptr show, + std::shared_ptr gift) { + const auto now = base::unixtime::now(); + if (gift->canCraftAt <= now) { + return false; + } + ShowCraftLaterError(show, gift->canCraftAt); + return true; +} + +void ShowCraftLaterError( + std::shared_ptr show, + TimeId when) { + const auto data = base::unixtime::parse(when); + const auto time = QLocale().toString(data.time(), QLocale::ShortFormat); + const auto date = langDayOfMonthShort(data.date()); + + show->show(MakeInformBox({ + .text = tr::lng_gift_craft_when( + lt_date, + rpl::single(tr::bold(date)), + lt_time, + rpl::single(tr::bold(time)), + tr::marked), + .title = tr::lng_gift_craft_unavailable(), + })); +} + } // namespace Ui diff --git a/Telegram/SourceFiles/boxes/star_gift_craft_box.h b/Telegram/SourceFiles/boxes/star_gift_craft_box.h index ab455df736..c2d279104f 100644 --- a/Telegram/SourceFiles/boxes/star_gift_craft_box.h +++ b/Telegram/SourceFiles/boxes/star_gift_craft_box.h @@ -19,6 +19,8 @@ class SessionController; namespace Ui { +class Show; + struct GiftForCraftEntry { std::shared_ptr unique; Data::SavedStarGiftId manageId; @@ -34,4 +36,12 @@ void ShowTestGiftCraftBox( not_null controller, std::vector gifts); +[[nodiscard]] bool ShowCraftLaterError( + std::shared_ptr show, + std::shared_ptr gift); + +void ShowCraftLaterError( + std::shared_ptr show, + TimeId when); + } // namespace Ui diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index 28f37044d1..680dda6a7c 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -1584,6 +1584,9 @@ void GenericCreditsEntryBody( const auto canCraft = CanCraftGift(session, e); const auto craft = canCraft ? [=] { const auto unique = e.uniqueGift; + if (Ui::ShowCraftLaterError(show, unique)) { + return; + } const auto savedId = EntryToSavedStarGiftId(&show->session(), e); if (const auto window = show->resolveWindow()) { const auto closeParent = crl::guard(box, [=] {