mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
Support hosted unique gifts.
This commit is contained in:
@@ -2231,6 +2231,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_action_gift_transferred_unknown" = "Someone transferred you a gift";
|
||||
"lng_action_gift_transferred_unknown_channel" = "Someone transferred a gift to {channel}";
|
||||
"lng_action_gift_transferred_self" = "You transferred a unique collectible";
|
||||
"lng_action_gift_displayed_self" = "You've started displaying {name} on your Telegram profile page.";
|
||||
"lng_action_gift_transferred_self_channel" = "You transferred a gift to {channel}";
|
||||
"lng_action_gift_transferred_mine" = "You transferred a gift to {user}";
|
||||
"lng_action_gift_received_anonymous" = "Unknown user sent you a gift for {cost}";
|
||||
@@ -3684,6 +3685,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_gift_released_by" = "released by {name}";
|
||||
"lng_gift_unique_owner" = "Owner";
|
||||
"lng_gift_unique_address_copied" = "Address copied to clipboard.";
|
||||
"lng_gift_unique_telegram" = "Telegram";
|
||||
"lng_gift_unique_status" = "Status";
|
||||
"lng_gift_unique_status_non" = "Non-Unique";
|
||||
"lng_gift_unique_upgrade" = "Upgrade";
|
||||
@@ -3822,6 +3824,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_gift_transfer_sell" = "Sell";
|
||||
"lng_gift_transfer_update" = "Change Price";
|
||||
"lng_gift_transfer_unlist" = "Unlist";
|
||||
"lng_gift_transfer_locked_title" = "Action Locked";
|
||||
"lng_gift_transfer_locked_text" = "Transfer this gift to your Telegram account on Fragment to unlock this action.";
|
||||
"lng_gift_sell_unlist_title" = "Unlist {name}";
|
||||
"lng_gift_sell_unlist_sure" = "Are you sure you want to unlist your gift?";
|
||||
"lng_gift_sell_title" = "Price in Stars";
|
||||
|
||||
@@ -915,11 +915,15 @@ std::optional<Data::StarGift> FromTL(
|
||||
.initialGiftId = data.vgift_id().v,
|
||||
.slug = qs(data.vslug()),
|
||||
.title = qs(data.vtitle()),
|
||||
.giftAddress = qs(data.vgift_address().value_or_empty()),
|
||||
.ownerAddress = qs(data.vowner_address().value_or_empty()),
|
||||
.ownerName = qs(data.vowner_name().value_or_empty()),
|
||||
.ownerId = (data.vowner_id()
|
||||
? peerFromMTP(*data.vowner_id())
|
||||
: PeerId()),
|
||||
.hostId = (data.vhost_id()
|
||||
? peerFromMTP(*data.vhost_id())
|
||||
: PeerId()),
|
||||
.releasedBy = releasedBy,
|
||||
.themeUser = themeUser,
|
||||
.nanoTonForResale = FindTonForResale(data.vresell_amount()),
|
||||
|
||||
@@ -1618,6 +1618,38 @@ void AddStarGiftTable(
|
||||
tr::lng_gift_unique_owner(),
|
||||
std::move(label));
|
||||
}
|
||||
|
||||
if (const auto hostId = PeerId(entry.bareGiftHostId)) {
|
||||
const auto was = std::make_shared<std::optional<CollectibleId>>();
|
||||
const auto handleChange = [=](
|
||||
not_null<Ui::RpWidget*> badge,
|
||||
EmojiStatusId emojiStatusId) {
|
||||
const auto id = emojiStatusId.collectible
|
||||
? emojiStatusId.collectible->id
|
||||
: 0;
|
||||
const auto show = [&](const auto &phrase) {
|
||||
showTooltip(badge, phrase(
|
||||
lt_name,
|
||||
rpl::single(Ui::Text::Bold(UniqueGiftName(*unique))),
|
||||
Ui::Text::WithEntities));
|
||||
};
|
||||
if (!*was || *was == id) {
|
||||
*was = id;
|
||||
return;
|
||||
} else if (*was == unique->id) {
|
||||
show(tr::lng_gift_wear_end_toast);
|
||||
} else if (id == unique->id) {
|
||||
show(tr::lng_gift_wear_start_toast);
|
||||
}
|
||||
*was = id;
|
||||
};
|
||||
AddTableRow(
|
||||
table,
|
||||
tr::lng_gift_unique_telegram(),
|
||||
MakePeerWithStatusValue(table, show, hostId, handleChange),
|
||||
st::giveawayGiftCodePeerMargin);
|
||||
}
|
||||
|
||||
} else if (giftToChannel) {
|
||||
AddTableRow(
|
||||
table,
|
||||
|
||||
@@ -2807,6 +2807,7 @@ void AddBlock(
|
||||
&& !state->myLoading) {
|
||||
state->myLoading = Data::MyUniqueGiftsSlice(
|
||||
&peer->session(),
|
||||
Data::MyUniqueType::OnlyOwned,
|
||||
state->my.offset
|
||||
) | rpl::start_with_next([=](MyGiftsDescriptor &&descriptor) {
|
||||
state->myLoading.destroy();
|
||||
@@ -3631,7 +3632,8 @@ void ShowStarGiftBox(
|
||||
}, i->second.lifetime);
|
||||
|
||||
Data::MyUniqueGiftsSlice(
|
||||
session
|
||||
session,
|
||||
Data::MyUniqueType::OnlyOwned
|
||||
) | rpl::start_with_next([=](MyGiftsDescriptor &&gifts) {
|
||||
auto &entry = Map[session];
|
||||
entry.my = std::move(gifts);
|
||||
@@ -3714,6 +3716,7 @@ void AddUniqueGiftCover(
|
||||
Released() : white(QColor(255, 255, 255)) {
|
||||
}
|
||||
|
||||
rpl::variable<TextWithEntities> subtitleText;
|
||||
style::owned_color white;
|
||||
style::FlatLabel st;
|
||||
PeerData *by = nullptr;
|
||||
@@ -3743,7 +3746,7 @@ void AddUniqueGiftCover(
|
||||
) | rpl::map([](const Data::UniqueGift &now) { return now.title; }),
|
||||
st::uniqueGiftTitle);
|
||||
title->setTextColorOverride(QColor(255, 255, 255));
|
||||
auto subtitleText = subtitleOverride
|
||||
released->subtitleText = subtitleOverride
|
||||
? std::move(
|
||||
subtitleOverride
|
||||
) | Ui::Text::ToWithEntities() | rpl::type_erased()
|
||||
@@ -3764,9 +3767,13 @@ void AddUniqueGiftCover(
|
||||
TextWithEntities{ QString::number(gift.number) },
|
||||
Ui::Text::WithEntities);
|
||||
});
|
||||
if (!released->by) {
|
||||
released->st = st::uniqueGiftSubtitle;
|
||||
released->st.palette.linkFg = released->white.color();
|
||||
}
|
||||
const auto subtitle = CreateChild<FlatLabel>(
|
||||
cover,
|
||||
std::move(subtitleText),
|
||||
released->subtitleText.value(),
|
||||
released->st);
|
||||
if (released->by) {
|
||||
const auto button = CreateChild<AbstractButton>(cover);
|
||||
|
||||
@@ -949,3 +949,19 @@ bool ShowTransferGiftLater(
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShowActionLocked(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
const QString &slug) {
|
||||
const auto open = [=] {
|
||||
UrlClickHandler::Open(u"https://fragment.com/gift/"_q
|
||||
+ slug
|
||||
+ u"?collection=my"_q);
|
||||
};
|
||||
show->show(Ui::MakeConfirmBox({
|
||||
.text = tr::lng_gift_transfer_locked_text(),
|
||||
.confirmed = [=](Fn<void()> close) { open(); close(); },
|
||||
.confirmText = tr::lng_gift_transfer_confirm_button(),
|
||||
.title = tr::lng_gift_transfer_locked_title(),
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -64,3 +64,7 @@ void SetPeerTheme(
|
||||
not_null<PeerData*> peer,
|
||||
const QString &token,
|
||||
const std::shared_ptr<Ui::ChatTheme> &theme);
|
||||
|
||||
void ShowActionLocked(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
const QString &slug);
|
||||
|
||||
@@ -66,6 +66,7 @@ struct CreditsHistoryEntry final {
|
||||
uint64 bareGiveawayMsgId = 0;
|
||||
uint64 bareGiftStickerId = 0;
|
||||
uint64 bareGiftOwnerId = 0;
|
||||
uint64 bareGiftHostId = 0;
|
||||
uint64 bareGiftReleasedById = 0;
|
||||
uint64 bareGiftResaleRecipientId = 0;
|
||||
uint64 bareActorId = 0;
|
||||
|
||||
@@ -120,6 +120,7 @@ GiftAttributeId IdFor(const UniqueGiftPattern &value) {
|
||||
|
||||
rpl::producer<MyGiftsDescriptor> MyUniqueGiftsSlice(
|
||||
not_null<Main::Session*> session,
|
||||
MyUniqueType type,
|
||||
QString offset) {
|
||||
return [=](auto consumer) {
|
||||
using Flag = MTPpayments_GetSavedStarGifts::Flag;
|
||||
@@ -128,7 +129,10 @@ rpl::producer<MyGiftsDescriptor> MyUniqueGiftsSlice(
|
||||
MTPpayments_GetSavedStarGifts(
|
||||
MTP_flags(Flag::f_exclude_upgradable
|
||||
| Flag::f_exclude_unupgradable
|
||||
| Flag::f_exclude_unlimited),
|
||||
| Flag::f_exclude_unlimited
|
||||
| ((type == MyUniqueType::OnlyOwned)
|
||||
? Flag::f_exclude_hosted
|
||||
: Flag())),
|
||||
user->input,
|
||||
MTP_int(0), // collection_id
|
||||
MTP_string(offset),
|
||||
|
||||
@@ -66,9 +66,11 @@ struct UniqueGift {
|
||||
uint64 initialGiftId = 0;
|
||||
QString slug;
|
||||
QString title;
|
||||
QString giftAddress;
|
||||
QString ownerAddress;
|
||||
QString ownerName;
|
||||
PeerId ownerId = 0;
|
||||
PeerId hostId = 0;
|
||||
PeerData *releasedBy = nullptr;
|
||||
PeerData *themeUser = nullptr;
|
||||
int64 nanoTonForResale = -1;
|
||||
@@ -253,8 +255,14 @@ struct MyGiftsDescriptor {
|
||||
QString offset;
|
||||
};
|
||||
|
||||
enum class MyUniqueType {
|
||||
OwnedAndHosted,
|
||||
OnlyOwned,
|
||||
};
|
||||
|
||||
[[nodiscard]] rpl::producer<MyGiftsDescriptor> MyUniqueGiftsSlice(
|
||||
not_null<Main::Session*> session,
|
||||
MyUniqueType type,
|
||||
QString offset = QString());
|
||||
|
||||
struct ResaleGiftsDescriptor {
|
||||
|
||||
@@ -1461,7 +1461,8 @@ void History::newItemAdded(not_null<HistoryItem*> item) {
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto gift = media->gift()) {
|
||||
if (const auto unique = gift->unique.get()) {
|
||||
if (unique->ownerId == session().userPeerId()) {
|
||||
if (unique->ownerId == session().userPeerId()
|
||||
|| unique->hostId == session().userPeerId()) {
|
||||
owner().emojiStatuses().refreshCollectibles();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6231,6 +6231,18 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||
lt_user,
|
||||
Ui::Text::Link(from->shortName(), 1),
|
||||
Ui::Text::WithEntities);
|
||||
} else if (action.is_assigned()) {
|
||||
const auto gift = Api::FromTL(
|
||||
&history()->session(),
|
||||
action.vgift());
|
||||
result.text = tr::lng_action_gift_displayed_self(
|
||||
tr::now,
|
||||
lt_name,
|
||||
TextWithEntities{ (gift && gift->unique)
|
||||
? Data::UniqueGiftName(*gift->unique)
|
||||
: QString(),
|
||||
},
|
||||
Ui::Text::WithEntities);
|
||||
} else {
|
||||
result.text = resale
|
||||
? tr::lng_action_gift_self_bought(
|
||||
|
||||
@@ -968,11 +968,29 @@ void ProcessReceivedSubscriptions(
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] bool ShowResellButton(
|
||||
not_null<Main::Session*> session,
|
||||
const Data::CreditsHistoryEntry &e) {
|
||||
const auto unique = e.uniqueGift.get();
|
||||
const auto host = (unique && unique->hostId)
|
||||
? session->data().peer(unique->hostId).get()
|
||||
: (unique && unique->ownerId)
|
||||
? session->data().peer(unique->ownerId).get()
|
||||
: nullptr;
|
||||
return !host
|
||||
? false
|
||||
: host->isSelf()
|
||||
? e.in
|
||||
: false;
|
||||
// Currently we're not reselling channel gifts.
|
||||
// (host->isChannel() && host->asChannel()->canTransferGifts());
|
||||
}
|
||||
|
||||
[[nodiscard]] bool CanResellGift(
|
||||
not_null<Main::Session*> session,
|
||||
const Data::CreditsHistoryEntry &e) {
|
||||
const auto unique = e.uniqueGift.get();
|
||||
const auto owner = unique
|
||||
const auto owner = (unique && unique->ownerId)
|
||||
? session->data().peer(unique->ownerId).get()
|
||||
: nullptr;
|
||||
return !owner
|
||||
@@ -1101,45 +1119,60 @@ void FillUniqueGiftMenu(
|
||||
}
|
||||
}, st.theme ? st.theme : &st::menuIconChangeColors);
|
||||
}
|
||||
const auto owner = unique->ownerId
|
||||
? show->session().data().peer(unique->ownerId).get()
|
||||
: (PeerData*)nullptr;
|
||||
const auto host = unique->hostId
|
||||
? show->session().data().peer(unique->hostId).get()
|
||||
: owner;
|
||||
if (!host) {
|
||||
return;
|
||||
}
|
||||
const auto transfer = savedId
|
||||
&& (savedId.isUser() ? e.in : savedId.chat()->canTransferGifts())
|
||||
&& (unique->starsForTransfer >= 0);
|
||||
if (transfer) {
|
||||
menu->addAction(tr::lng_gift_transfer_button(tr::now), [=] {
|
||||
if (const auto window = show->resolveWindow()) {
|
||||
if (!owner) {
|
||||
ShowActionLocked(show, unique->slug);
|
||||
} else if (const auto window = show->resolveWindow()) {
|
||||
ShowTransferGiftBox(window, unique, savedId);
|
||||
}
|
||||
}, st.transfer ? st.transfer : &st::menuIconReplace);
|
||||
}
|
||||
const auto owner = show->session().data().peer(unique->ownerId);
|
||||
const auto wear = owner->isSelf()
|
||||
const auto wear = host->isSelf()
|
||||
? e.in
|
||||
: (owner->isChannel() && owner->asChannel()->canEditEmoji());
|
||||
: (host->isChannel() && host->asChannel()->canEditEmoji());
|
||||
if (wear) {
|
||||
const auto name = UniqueGiftName(*unique);
|
||||
const auto now = owner->emojiStatusId().collectible;
|
||||
const auto now = host->emojiStatusId().collectible;
|
||||
if (now && unique->slug == now->slug) {
|
||||
menu->addAction(tr::lng_gift_transfer_take_off(tr::now), [=] {
|
||||
show->session().data().emojiStatuses().set(owner, {});
|
||||
show->session().data().emojiStatuses().set(host, {});
|
||||
}, st.takeoff ? st.takeoff : &st::menuIconNftTakeOff);
|
||||
} else {
|
||||
menu->addAction(tr::lng_gift_transfer_wear(tr::now), [=] {
|
||||
ShowUniqueGiftWearBox(show, owner, *unique, st.giftWearBox
|
||||
ShowUniqueGiftWearBox(show, host, *unique, st.giftWearBox
|
||||
? *st.giftWearBox
|
||||
: GiftWearBoxStyleOverride());
|
||||
}, st.wear ? st.wear : &st::menuIconNftWear);
|
||||
}
|
||||
}
|
||||
if (CanResellGift(&show->session(), e)) {
|
||||
if (ShowResellButton(&show->session(), e)) {
|
||||
const auto can = CanResellGift(&show->session(), e);
|
||||
const auto inResale = (unique->starsForResale > 0);
|
||||
const auto editPrice = (inResale
|
||||
? tr::lng_gift_transfer_update
|
||||
: tr::lng_gift_transfer_sell)(tr::now);
|
||||
menu->addAction(editPrice, [=] {
|
||||
const auto style = st.giftWearBox
|
||||
? *st.giftWearBox
|
||||
: GiftWearBoxStyleOverride();
|
||||
ShowUniqueGiftSellBox(show, unique, savedId, style);
|
||||
if (!can) {
|
||||
ShowActionLocked(show, unique->slug);
|
||||
} else {
|
||||
const auto style = st.giftWearBox
|
||||
? *st.giftWearBox
|
||||
: GiftWearBoxStyleOverride();
|
||||
ShowUniqueGiftSellBox(show, unique, savedId, style);
|
||||
}
|
||||
}, st.resell ? st.resell : &st::menuIconTagSell);
|
||||
if (inResale) {
|
||||
menu->addAction(tr::lng_gift_transfer_unlist(tr::now), [=] {
|
||||
@@ -1807,6 +1840,40 @@ void GenericCreditsEntryBox(
|
||||
}
|
||||
|
||||
Ui::AddSkip(content);
|
||||
|
||||
const auto addGiftLinkTON = [&] {
|
||||
if (!uniqueGift) {
|
||||
return;
|
||||
}
|
||||
const auto address = !uniqueGift->giftAddress.isEmpty()
|
||||
? uniqueGift->giftAddress
|
||||
: uniqueGift->ownerAddress;
|
||||
if (address.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
const auto label = box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_gift_in_blockchain(
|
||||
lt_link,
|
||||
tr::lng_gift_in_blockchain_link_arrow(
|
||||
lt_arrow,
|
||||
rpl::single(arrow),
|
||||
Ui::Text::WithEntities
|
||||
) | Ui::Text::ToLink(),
|
||||
Ui::Text::WithEntities),
|
||||
st::creditsBoxAboutDivider),
|
||||
style::al_top);
|
||||
label->setClickHandlerFilter([=](const auto &...) {
|
||||
UrlClickHandler::Open(TonAddressUrl(session, address));
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
if (starGiftCanManage) {
|
||||
addGiftLinkTON();
|
||||
}
|
||||
|
||||
Ui::AddSkip(content);
|
||||
|
||||
struct State final {
|
||||
@@ -2040,25 +2107,8 @@ void GenericCreditsEntryBox(
|
||||
toggleVisibility(!e.savedToProfile);
|
||||
return false;
|
||||
});
|
||||
} else if (uniqueGift && !uniqueGift->ownerAddress.isEmpty()) {
|
||||
const auto label = box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_gift_in_blockchain(
|
||||
lt_link,
|
||||
tr::lng_gift_in_blockchain_link_arrow(
|
||||
lt_arrow,
|
||||
rpl::single(arrow),
|
||||
Ui::Text::WithEntities
|
||||
) | Ui::Text::ToLink(),
|
||||
Ui::Text::WithEntities),
|
||||
st::creditsBoxAboutDivider),
|
||||
style::al_top);
|
||||
label->setClickHandlerFilter([=](const auto &...) {
|
||||
UrlClickHandler::Open(
|
||||
TonAddressUrl(session, uniqueGift->ownerAddress));
|
||||
return false;
|
||||
});
|
||||
} else {
|
||||
addGiftLinkTON();
|
||||
}
|
||||
if (s) {
|
||||
const auto user = peer ? peer->asUser() : nullptr;
|
||||
@@ -2531,6 +2581,7 @@ void GlobalStarGiftBox(
|
||||
CreditsEntryBoxStyleOverrides st) {
|
||||
const auto selfId = show->session().userPeerId();
|
||||
const auto ownerId = data.unique ? data.unique->ownerId.value : 0;
|
||||
const auto hostId = data.unique ? data.unique->hostId.value : 0;
|
||||
Settings::GenericCreditsEntryBox(
|
||||
box,
|
||||
show,
|
||||
@@ -2538,6 +2589,7 @@ void GlobalStarGiftBox(
|
||||
.credits = CreditsAmount(data.stars),
|
||||
.bareGiftStickerId = data.document->id,
|
||||
.bareGiftOwnerId = ownerId,
|
||||
.bareGiftHostId = hostId,
|
||||
.bareGiftResaleRecipientId = ((resale.recipientId != selfId)
|
||||
? resale.recipientId.value
|
||||
: 0),
|
||||
@@ -2560,6 +2612,12 @@ Data::CreditsHistoryEntry SavedStarGiftEntry(
|
||||
not_null<PeerData*> owner,
|
||||
const Data::SavedStarGift &data) {
|
||||
const auto chatGiftPeer = data.manageId.chat();
|
||||
const auto ownerId = data.info.unique
|
||||
? data.info.unique->ownerId
|
||||
: owner->id;
|
||||
const auto hostId = data.info.unique
|
||||
? data.info.unique->hostId
|
||||
: PeerId();
|
||||
return {
|
||||
.description = data.message,
|
||||
.date = base::unixtime::parse(data.date),
|
||||
@@ -2567,7 +2625,8 @@ Data::CreditsHistoryEntry SavedStarGiftEntry(
|
||||
.bareMsgId = uint64(data.manageId.userMessageId().bare),
|
||||
.barePeerId = data.fromId.value,
|
||||
.bareGiftStickerId = data.info.document->id,
|
||||
.bareGiftOwnerId = owner->id.value,
|
||||
.bareGiftOwnerId = ownerId.value,
|
||||
.bareGiftHostId = hostId.value,
|
||||
.bareActorId = data.fromId.value,
|
||||
.bareEntryOwnerId = chatGiftPeer ? chatGiftPeer->id.value : 0,
|
||||
.giftChannelSavedId = data.manageId.chatSavedId(),
|
||||
@@ -2647,6 +2706,7 @@ void ShowStarGiftViewBox(
|
||||
const auto fromId = incoming ? peer->id : peer->session().userPeerId();
|
||||
const auto toId = incoming ? peer->session().userPeerId() : peer->id;
|
||||
const auto ownerId = data.unique ? data.unique->ownerId : toId;
|
||||
const auto hostId = data.unique ? data.unique->hostId : PeerId();
|
||||
const auto nextToUpgradeStickerId = upgradeNext
|
||||
? upgradeNext->info.document->id
|
||||
: uint64();
|
||||
@@ -2667,6 +2727,7 @@ void ShowStarGiftViewBox(
|
||||
.barePeerId = fromId.value,
|
||||
.bareGiftStickerId = data.document ? data.document->id : 0,
|
||||
.bareGiftOwnerId = ownerId.value,
|
||||
.bareGiftHostId = hostId.value,
|
||||
.bareGiftReleasedById = (data.stargiftReleasedBy
|
||||
? data.stargiftReleasedBy->id.value
|
||||
: 0),
|
||||
|
||||
@@ -592,26 +592,11 @@ void SubTabs::shakeTransform(
|
||||
/ float64(kShakeXDuration);
|
||||
const auto pY = (diff % kShakeYDuration)
|
||||
/ float64(kShakeYDuration);
|
||||
const auto pA = (diff % kShakeADuration)
|
||||
/ float64(kShakeADuration);
|
||||
|
||||
constexpr auto kMaxA = 2.;
|
||||
constexpr auto kMaxTranslation = .5;
|
||||
constexpr auto kAStep = 1. / 5;
|
||||
constexpr auto kXStep = 1. / 5;
|
||||
constexpr auto kYStep = 1. / 4;
|
||||
|
||||
// 0, -kMaxA, 0, kMaxA, 0.
|
||||
const auto angle = (pA < kAStep)
|
||||
? anim::interpolateF(0., -kMaxA, pA / kAStep)
|
||||
: (pA < kAStep * 2.)
|
||||
? anim::interpolateF(-kMaxA, 0, (pA - kAStep) / kAStep)
|
||||
: (pA < kAStep * 3.)
|
||||
? anim::interpolateF(0, kMaxA, (pA - kAStep * 2.) / kAStep)
|
||||
: (pA < kAStep * 4.)
|
||||
? anim::interpolateF(kMaxA, 0, (pA - kAStep * 3.) / kAStep)
|
||||
: anim::interpolateF(0, 0., (pA - kAStep * 4.) / kAStep);
|
||||
|
||||
// 0, kMaxTranslation, 0, -kMaxTranslation, 0.
|
||||
const auto x = (pX < kXStep)
|
||||
? anim::interpolateF(0., kMaxTranslation, pX / kXStep)
|
||||
|
||||
Reference in New Issue
Block a user