mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
Support failure animation.
This commit is contained in:
Binary file not shown.
@@ -4122,6 +4122,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_gift_craft_progress" = "Crafting";
|
||||
"lng_gift_craft_progress_chance" = "{percent} success chance";
|
||||
"lng_gift_craft_progress_fails" = "If crafting fails, all selected gifts will be consumed.";
|
||||
"lng_gift_craft_failed" = "Crafting failed. Gifts consumed :(";
|
||||
|
||||
"lng_auction_about_title" = "Auction";
|
||||
"lng_auction_about_subtitle" = "Join the battle for exclusive gifts.";
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
<file alias="passkeys.tgs">../../animations/passkeys.tgs</file>
|
||||
<file alias="ban.tgs">../../animations/ban.tgs</file>
|
||||
<file alias="cocoon.tgs">../../animations/cocoon.tgs</file>
|
||||
<file alias="bomb.tgs">../../animations/bomb.tgs</file>
|
||||
|
||||
<file alias="profile_muting.tgs">../../animations/profile/profile_muting.tgs</file>
|
||||
<file alias="profile_unmuting.tgs">../../animations/profile/profile_unmuting.tgs</file>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/effects/radial_animation.h"
|
||||
#include "ui/text/text_custom_emoji.h"
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace HistoryView {
|
||||
class StickerPlayer;
|
||||
} // namespace HistoryView
|
||||
|
||||
namespace Info::PeerGifts {
|
||||
class GiftButton;
|
||||
} // namespace Info::PeerGifts
|
||||
@@ -26,13 +34,11 @@ using CraftResultCallback = Fn<void(std::shared_ptr<Data::GiftUpgradeResult>)>;
|
||||
struct BackdropView {
|
||||
Data::UniqueGiftBackdrop colors;
|
||||
QImage gradient;
|
||||
|
||||
};
|
||||
|
||||
struct PatternView {
|
||||
std::unique_ptr<Text::CustomEmoji> emoji;
|
||||
base::flat_map<int, base::flat_map<float64, QImage>> emojis;
|
||||
|
||||
};
|
||||
|
||||
struct CraftState {
|
||||
@@ -84,6 +90,8 @@ struct CraftState {
|
||||
std::array<EmptySide, 6> forgeSides;
|
||||
EmptySide finalSide;
|
||||
|
||||
Main::Session *session = nullptr;
|
||||
|
||||
int containerHeight = 0;
|
||||
int craftingTop = 0;
|
||||
int craftingBottom = 0;
|
||||
@@ -93,13 +101,22 @@ struct CraftState {
|
||||
void paint(QPainter &p, QSize size, int craftingHeight, float64 slideProgress = 0.);
|
||||
void updateForGiftCount(int count);
|
||||
[[nodiscard]] EmptySide prepareEmptySide(int index) const;
|
||||
|
||||
};
|
||||
|
||||
struct FacePlacement {
|
||||
int face = -1;
|
||||
int rotation = 0;
|
||||
};
|
||||
|
||||
struct FailureAnimation {
|
||||
std::unique_ptr<HistoryView::StickerPlayer> player;
|
||||
QImage frame;
|
||||
DocumentData *document = nullptr;
|
||||
Animations::Simple scaleAnimation;
|
||||
bool scaleStarted = false;
|
||||
bool playerStarted = false;
|
||||
bool playerFinished = false;
|
||||
rpl::lifetime lifetime;
|
||||
};
|
||||
|
||||
struct CraftAnimationState {
|
||||
@@ -115,10 +132,11 @@ struct CraftAnimationState {
|
||||
int giftsLanded = 0;
|
||||
int totalGifts = 0;
|
||||
bool allGiftsLanded = false;
|
||||
bool currentPhaseFinished = false;
|
||||
std::array<FacePlacement, 4> giftToSide;
|
||||
Animations::Simple flightAnimation;
|
||||
|
||||
int currentConfigIndex = -1;
|
||||
int currentPhaseIndex = -1;
|
||||
crl::time animationStartTime = 0;
|
||||
float64 initialRotationX = 0.;
|
||||
float64 initialRotationY = 0.;
|
||||
@@ -134,11 +152,13 @@ struct CraftAnimationState {
|
||||
crl::time loadingStartedTime = 0;
|
||||
bool loadingFadingOut = false;
|
||||
|
||||
std::unique_ptr<FailureAnimation> failureAnimation;
|
||||
};
|
||||
|
||||
void StartCraftAnimation(
|
||||
not_null<VerticalLayout*> container,
|
||||
std::shared_ptr<CraftState> state,
|
||||
Fn<void(CraftResultCallback)> startRequest);
|
||||
Fn<void(CraftResultCallback)> startRequest,
|
||||
Fn<void()> closeOnFail);
|
||||
|
||||
} // namespace Ui
|
||||
|
||||
@@ -804,9 +804,10 @@ void ShowSelectGiftBox(
|
||||
}
|
||||
|
||||
void Craft(
|
||||
not_null<VerticalLayout*> container,
|
||||
not_null<GenericBox*> box,
|
||||
std::shared_ptr<CraftState> state,
|
||||
const std::vector<GiftForCraft> &gifts) {
|
||||
const std::vector<GiftForCraft> &gifts,
|
||||
Fn<void()> closeParent) {
|
||||
auto startRequest = [=](CraftResultCallback done) {
|
||||
constexpr auto kDelays = std::array<crl::time, 7>{
|
||||
100, 200, 300, 400, 500, 1000, 2000
|
||||
@@ -814,10 +815,11 @@ void Craft(
|
||||
const auto delay = kDelays[base::RandomIndex(kDelays.size())];
|
||||
const auto giftsCopy = gifts;
|
||||
|
||||
base::call_delayed(delay, container, [=] {
|
||||
const auto shouldSucceed = (base::RandomIndex(5) != 0);
|
||||
if (shouldSucceed && !giftsCopy.empty()) {
|
||||
const auto &chosen = giftsCopy[base::RandomIndex(giftsCopy.size())];
|
||||
base::call_delayed(delay, box, [=] {
|
||||
const auto shouldSucceed = true;// (base::RandomIndex(5) != 0);
|
||||
const auto count = int(giftsCopy.size());
|
||||
if (shouldSucceed && !count) {
|
||||
const auto &chosen = giftsCopy[base::RandomIndex(count)];
|
||||
auto info = Data::StarGift{
|
||||
.id = chosen.unique->initialGiftId,
|
||||
.unique = chosen.unique,
|
||||
@@ -834,14 +836,31 @@ void Craft(
|
||||
}
|
||||
});
|
||||
};
|
||||
StartCraftAnimation(container, std::move(state), std::move(startRequest));
|
||||
|
||||
const auto container = box->verticalLayout();
|
||||
const auto show = box->uiShow();
|
||||
const auto closeOnFail = crl::guard(box, [=] {
|
||||
if (const auto onstack = closeParent) {
|
||||
onstack();
|
||||
}
|
||||
box->closeBox();
|
||||
show->showToast(tr::lng_gift_craft_failed(tr::now));
|
||||
});
|
||||
StartCraftAnimation(
|
||||
container,
|
||||
std::move(state),
|
||||
std::move(startRequest),
|
||||
closeOnFail);
|
||||
}
|
||||
|
||||
void MakeCraftContent(
|
||||
not_null<GenericBox*> box,
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::vector<GiftForCraft> gifts,
|
||||
Fn<void()> closeParent,
|
||||
bool autoStartCraft) {
|
||||
Expects(!gifts.empty());
|
||||
|
||||
struct State {
|
||||
std::shared_ptr<CraftState> craftState;
|
||||
GradientButton *button = nullptr;
|
||||
@@ -861,9 +880,11 @@ void MakeCraftContent(
|
||||
bool crafting = false;
|
||||
};
|
||||
const auto session = &controller->session();
|
||||
const auto initialGiftId = gifts.front().unique->initialGiftId;
|
||||
const auto state = box->lifetime().make_state<State>();
|
||||
|
||||
state->craftState = std::make_shared<CraftState>();
|
||||
state->craftState->session = session;
|
||||
state->craftState->coversAnimate = true;
|
||||
|
||||
{
|
||||
@@ -935,7 +956,6 @@ void MakeCraftContent(
|
||||
}
|
||||
}, raw->lifetime());
|
||||
|
||||
const auto initialGiftId = state->chosen.current().front().unique->initialGiftId;
|
||||
std::move(
|
||||
crafting.editRequests
|
||||
) | rpl::on_next([=](int index) {
|
||||
@@ -1071,7 +1091,7 @@ void MakeCraftContent(
|
||||
|
||||
const auto renderWidget = [&](QWidget *widget) {
|
||||
const auto pos = widget->pos() - bottomRect.topLeft();
|
||||
widget->render(&bottomPart, pos, QRegion(), QWidget::DrawChildren);
|
||||
widget->render(&bottomPart, pos, {}, QWidget::DrawChildren);
|
||||
};
|
||||
renderWidget(state->about);
|
||||
renderWidget(state->attributes);
|
||||
@@ -1081,7 +1101,7 @@ void MakeCraftContent(
|
||||
cs->bottomPartY = aboutPos.y();
|
||||
cs->containerHeight = raw->height();
|
||||
|
||||
Craft(raw, state->craftState, state->chosen.current());
|
||||
Craft(box, state->craftState, state->chosen.current(), closeParent);
|
||||
};
|
||||
button->setClickedCallback(startCrafting);
|
||||
|
||||
@@ -1113,12 +1133,18 @@ void MakeCraftContent(
|
||||
void ShowGiftCraftBoxInternal(
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::vector<GiftForCraft> gifts,
|
||||
Fn<void()> closeParent,
|
||||
bool autoStartCraft) {
|
||||
controller->show(Box([=](not_null<GenericBox*> box) {
|
||||
box->setStyle(st::giftCraftBox);
|
||||
box->setWidth(st::boxWidth);
|
||||
box->setNoContentMargin(true);
|
||||
MakeCraftContent(box, controller, gifts, autoStartCraft);
|
||||
MakeCraftContent(
|
||||
box,
|
||||
controller,
|
||||
gifts,
|
||||
closeParent,
|
||||
autoStartCraft);
|
||||
AddUniqueCloseButton(box);
|
||||
|
||||
#if _DEBUG
|
||||
@@ -1132,7 +1158,7 @@ void ShowGiftCraftBoxInternal(
|
||||
} else {
|
||||
copy = full;
|
||||
}
|
||||
ShowGiftCraftBoxInternal(controller, copy, true);
|
||||
ShowGiftCraftBoxInternal(controller, copy, [] {}, true);
|
||||
});
|
||||
}, box->lifetime());
|
||||
}
|
||||
@@ -1145,7 +1171,8 @@ void ShowGiftCraftBoxInternal(
|
||||
void ShowGiftCraftInfoBox(
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<Data::UniqueGift> gift,
|
||||
Data::SavedStarGiftId savedId) {
|
||||
Data::SavedStarGiftId savedId,
|
||||
Fn<void()> closeParent) {
|
||||
controller->show(Box([=](not_null<GenericBox*> box) {
|
||||
const auto container = box->verticalLayout();
|
||||
auto cover = tr::lng_gift_craft_info_title(
|
||||
@@ -1189,10 +1216,15 @@ void ShowGiftCraftInfoBox(
|
||||
box->setNoContentMargin(true);
|
||||
|
||||
box->addButton(tr::lng_gift_craft_start_button(), [=] {
|
||||
const auto weak = base::make_weak(box);
|
||||
ShowGiftCraftBoxInternal(
|
||||
controller,
|
||||
{ GiftForCraft{ gift, savedId } },
|
||||
closeParent,
|
||||
false);
|
||||
if (const auto strong = box.get()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
@@ -1208,7 +1240,7 @@ void ShowTestGiftCraftBox(
|
||||
entry.manageId = std::move(gift.manageId);
|
||||
converted.push_back(std::move(entry));
|
||||
}
|
||||
ShowGiftCraftBoxInternal(controller, std::move(converted), true);
|
||||
ShowGiftCraftBoxInternal(controller, std::move(converted), [] {}, true);
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
||||
@@ -27,7 +27,8 @@ struct GiftForCraftEntry {
|
||||
void ShowGiftCraftInfoBox(
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<Data::UniqueGift> gift,
|
||||
Data::SavedStarGiftId savedId);
|
||||
Data::SavedStarGiftId savedId,
|
||||
Fn<void()> closeParent);
|
||||
|
||||
void ShowTestGiftCraftBox(
|
||||
not_null<Window::SessionController*> controller,
|
||||
|
||||
@@ -1579,7 +1579,11 @@ void GenericCreditsEntryBody(
|
||||
const auto unique = e.uniqueGift;
|
||||
const auto savedId = EntryToSavedStarGiftId(&show->session(), e);
|
||||
if (const auto window = show->resolveWindow()) {
|
||||
Ui::ShowGiftCraftInfoBox(window, unique, savedId);
|
||||
const auto closeParent = crl::guard(box, [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
using namespace Ui;
|
||||
ShowGiftCraftInfoBox(window, unique, savedId, closeParent);
|
||||
}
|
||||
} : Fn<void()>();
|
||||
AddUniqueCloseMoreButton(box, st, [=](not_null<Ui::PopupMenu*> menu) {
|
||||
|
||||
@@ -1685,7 +1685,9 @@ SessionController::SessionController(
|
||||
#if _DEBUG // TEST: Auto-open craft box on startup
|
||||
constexpr auto kGiftsCount = 4;
|
||||
crl::on_main(this, [=] {
|
||||
return;
|
||||
if (rand() % 2 == 0) {
|
||||
return;
|
||||
}
|
||||
const auto user = session->user();
|
||||
session->api().request(MTPpayments_GetSavedStarGifts(
|
||||
MTP_flags(MTPpayments_GetSavedStarGifts::Flag::f_exclude_unlimited),
|
||||
|
||||
Reference in New Issue
Block a user