mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-17 22:57:11 +02:00
Allow pay for upgrade when sending.
This commit is contained in:
parent
42c350243a
commit
5df632264f
15 changed files with 445 additions and 198 deletions
|
@ -2031,11 +2031,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_action_gift_got_subtitle" = "Gift from {user}";
|
||||
"lng_action_gift_got_stars_text#one" = "Display this gift on your page or convert it to **{count}** Star.";
|
||||
"lng_action_gift_got_stars_text#other" = "Display this gift on your page or convert it to **{count}** Stars.";
|
||||
"lng_action_gift_got_upgradable_text" = "Upgrade this gift to a unique collectible.";
|
||||
"lng_action_gift_got_gift_text" = "You can keep this gift on your page.";
|
||||
"lng_action_gift_can_remove_text" = "You can remove this gift from your page.";
|
||||
"lng_action_gift_sent_subtitle" = "Gift for {user}";
|
||||
"lng_action_gift_sent_text#one" = "{user} can display this gift on their page or convert it to {count} Star.";
|
||||
"lng_action_gift_sent_text#other" = "{user} can display this gift on their page or convert it to {count} Stars.";
|
||||
"lng_action_gift_sent_upgradable" = "{user} can upgrade this gift to a unique collectible.";
|
||||
"lng_action_gift_premium_months#one" = "{count} Month Premium";
|
||||
"lng_action_gift_premium_months#other" = "{count} Months Premium";
|
||||
"lng_action_gift_premium_about" = "Subscription for exclusive Telegram features.";
|
||||
|
@ -3227,6 +3229,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_gift_send_message" = "Enter Message";
|
||||
"lng_gift_send_anonymous" = "Hide My Name";
|
||||
"lng_gift_send_anonymous_about" = "You can hide your name and message from visitors to {user}'s profile. {recipient} will still see your name and message.";
|
||||
"lng_gift_send_unique" = "Make Unique for {price}";
|
||||
"lng_gift_send_unique_about" = "Enable this to let {user} turn your gift into a unique collectible. {link}";
|
||||
"lng_gift_send_unique_link" = "Learn More >";
|
||||
"lng_gift_send_premium_about" = "Only {user} will see your message.";
|
||||
"lng_gift_send_button" = "Send a Gift for {cost}";
|
||||
"lng_gift_sent_title" = "Gift Sent!";
|
||||
|
@ -3235,6 +3240,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_gift_limited_of_one" = "unique";
|
||||
"lng_gift_limited_of_count" = "1 of {amount}";
|
||||
"lng_gift_price_unique" = "Unique";
|
||||
"lng_gift_view_unpack" = "Unpack";
|
||||
"lng_gift_anonymous_hint" = "Only you can see the sender's name.";
|
||||
"lng_gift_hidden_hint" = "This gift is hidden. Only you can see it.";
|
||||
"lng_gift_visible_hint" = "This gift is visible to visitors of your page.";
|
||||
|
@ -3286,6 +3292,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_gift_sell_small#other" = "sell for {count} Stars";
|
||||
"lng_gift_upgrade_title" = "Upgrade Gift";
|
||||
"lng_gift_upgrade_about" = "Turn your gift into a unique collectible\nthat you can transfer or auction.";
|
||||
"lng_gift_upgrade_preview_title" = "Make Unique";
|
||||
"lng_gift_upgrade_preview_about" = "Let {name} turn your gift into a unique collectible.";
|
||||
"lng_gift_upgrade_unique_title" = "Unique";
|
||||
"lng_gift_upgrade_unique_about" = "Get a unique number, model, backdrop and symbol for your gift.";
|
||||
"lng_gift_upgrade_transferable_title" = "Transferable";
|
||||
|
@ -3293,7 +3301,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_gift_upgrade_tradable_title" = "Tradable";
|
||||
"lng_gift_upgrade_tradable_about" = "Sell or auction your gift on third-party NFT marketplaces.";
|
||||
"lng_gift_upgrade_button" = "Upgrade for {price}";
|
||||
"lng_gift_upgrade_add_sender" = "Add sender's name";
|
||||
"lng_gift_upgrade_free" = "Upgrade for Free";
|
||||
"lng_gift_upgrade_confirm" = "Confirm";
|
||||
"lng_gift_upgrade_add_my" = "Add my name to the gift";
|
||||
"lng_gift_upgrade_add_sender" = "Add sender's name to the gift";
|
||||
"lng_gift_upgrade_add_comment" = "Add sender's name and comment";
|
||||
"lng_gift_upgraded_title" = "Gift Upgraded";
|
||||
"lng_gift_upgraded_about" = "Your gift {name} now has unique attributes and can be transferred to others";
|
||||
|
|
|
@ -130,7 +130,8 @@ constexpr auto kRarityTooltipDuration = 3 * crl::time(1000);
|
|||
not_null<QWidget*> parent,
|
||||
not_null<Window::SessionNavigation*> controller,
|
||||
PeerId id,
|
||||
bool withSendGiftButton = false) {
|
||||
rpl::producer<QString> button = nullptr,
|
||||
Fn<void()> handler = nullptr) {
|
||||
auto result = object_ptr<Ui::AbstractButton>(parent);
|
||||
const auto raw = result.data();
|
||||
|
||||
|
@ -141,19 +142,17 @@ constexpr auto kRarityTooltipDuration = 3 * crl::time(1000);
|
|||
const auto userpic = Ui::CreateChild<Ui::UserpicButton>(raw, peer, st);
|
||||
const auto label = Ui::CreateChild<Ui::FlatLabel>(
|
||||
raw,
|
||||
withSendGiftButton ? peer->shortName() : peer->name(),
|
||||
(button && handler) ? peer->shortName() : peer->name(),
|
||||
st::giveawayGiftCodeValue);
|
||||
const auto send = withSendGiftButton
|
||||
const auto send = (button && handler)
|
||||
? Ui::CreateChild<Ui::RoundButton>(
|
||||
raw,
|
||||
tr::lng_gift_send_small(),
|
||||
std::move(button),
|
||||
st::starGiftSmallButton)
|
||||
: nullptr;
|
||||
if (send) {
|
||||
send->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||
send->setClickedCallback([=] {
|
||||
Ui::ShowStarGiftBox(controller->parentController(), peer);
|
||||
});
|
||||
send->setClickedCallback(std::move(handler));
|
||||
}
|
||||
rpl::combine(
|
||||
raw->widthValue(),
|
||||
|
@ -1204,19 +1203,25 @@ void AddStarGiftTable(
|
|||
const auto session = &controller->session();
|
||||
const auto unique = entry.uniqueGift.get();
|
||||
if (unique) {
|
||||
const auto ownerId = PeerId(entry.bareGiftOwnerId);
|
||||
auto send = entry.in ? tr::lng_gift_unique_owner_change() : nullptr;
|
||||
auto handler = entry.in ? Fn<void()>([=] {}) : nullptr;
|
||||
AddTableRow(
|
||||
table,
|
||||
tr::lng_gift_unique_owner(),
|
||||
MakePeerTableValue(table, controller, peerId, false),
|
||||
MakePeerTableValue(table, controller, ownerId, send, handler),
|
||||
st::giveawayGiftCodePeerMargin);
|
||||
//"lng_gift_unique_owner_change" = "change";
|
||||
} else if (peerId) {
|
||||
const auto user = session->data().peer(peerId)->asUser();
|
||||
const auto withSendButton = entry.in && user && !user->isBot();
|
||||
auto send = withSendButton ? tr::lng_gift_send_small() : nullptr;
|
||||
auto handler = send ? Fn<void()>([=] {
|
||||
Ui::ShowStarGiftBox(controller->parentController(), user);
|
||||
}) : nullptr;
|
||||
AddTableRow(
|
||||
table,
|
||||
tr::lng_credits_box_history_entry_peer_in(),
|
||||
MakePeerTableValue(table, controller, peerId, withSendButton),
|
||||
MakePeerTableValue(table, controller, peerId, send, handler),
|
||||
st::giveawayGiftCodePeerMargin);
|
||||
} else if (!entry.soldOutInfo) {
|
||||
AddTableRow(
|
||||
|
@ -1390,6 +1395,12 @@ void AddStarGiftTable(
|
|||
: nullptr;
|
||||
const auto date = base::unixtime::parse(original.date).date();
|
||||
const auto dateText = TextWithEntities{ langDayOfMonth(date) };
|
||||
const auto makeContext = [=](Fn<void()> update) {
|
||||
return Core::MarkedTextContext{
|
||||
.session = session,
|
||||
.customEmojiRepaint = std::move(update),
|
||||
};
|
||||
};
|
||||
auto label = object_ptr<Ui::FlatLabel>(
|
||||
table,
|
||||
(from
|
||||
|
@ -1427,7 +1438,9 @@ void AddStarGiftTable(
|
|||
lt_text,
|
||||
rpl::single(original.message),
|
||||
Ui::Text::WithEntities))),
|
||||
st::giveawayGiftMessage);
|
||||
st::giveawayGiftMessage,
|
||||
st::defaultPopupMenu,
|
||||
makeContext);
|
||||
const auto showBoxLink = [=](not_null<PeerData*> peer) {
|
||||
return std::make_shared<LambdaClickHandler>([=] {
|
||||
controller->uiShow()->showBox(
|
||||
|
|
|
@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "history/admin_log/history_admin_log_item.h"
|
||||
#include "history/view/media/history_view_media_generic.h"
|
||||
#include "history/view/media/history_view_unique_gift.h"
|
||||
#include "history/view/history_view_element.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
|
@ -67,6 +68,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/vertical_list.h"
|
||||
#include "ui/widgets/fields/input_field.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "window/section_widget.h"
|
||||
|
@ -92,6 +94,7 @@ constexpr auto kGiftMessageLimit = 255;
|
|||
constexpr auto kSentToastDuration = 3 * crl::time(1000);
|
||||
constexpr auto kSwitchUpgradeCoverInterval = 3 * crl::time(1000);
|
||||
constexpr auto kCrossfadeDuration = crl::time(400);
|
||||
constexpr auto kUpgradeDoneToastDuration = 4 * crl::time(1000);
|
||||
|
||||
using namespace HistoryView;
|
||||
using namespace Info::PeerGifts;
|
||||
|
@ -111,6 +114,7 @@ struct GiftDetails {
|
|||
TextWithEntities text;
|
||||
uint64 randomId = 0;
|
||||
bool anonymous = false;
|
||||
bool upgraded = false;
|
||||
};
|
||||
|
||||
class PreviewDelegate final : public DefaultElementDelegate {
|
||||
|
@ -250,11 +254,15 @@ auto GenerateGiftMedia(
|
|||
tr::now,
|
||||
Text::RichLangValue);
|
||||
}, [&](const GiftTypeStars &gift) {
|
||||
return tr::lng_action_gift_got_stars_text(
|
||||
tr::now,
|
||||
lt_count,
|
||||
gift.info.starsConverted,
|
||||
Text::RichLangValue);
|
||||
return data.upgraded
|
||||
? tr::lng_action_gift_got_upgradable_text(
|
||||
tr::now,
|
||||
Text::RichLangValue)
|
||||
: tr::lng_action_gift_got_stars_text(
|
||||
tr::now,
|
||||
lt_count,
|
||||
gift.info.starsConverted,
|
||||
Text::RichLangValue);
|
||||
});
|
||||
auto description = data.text.empty()
|
||||
? std::move(textFallback)
|
||||
|
@ -268,6 +276,14 @@ auto GenerateGiftMedia(
|
|||
.session = &parent->history()->session(),
|
||||
.customEmojiRepaint = [parent] { parent->repaint(); },
|
||||
});
|
||||
|
||||
push(HistoryView::MakeGenericButtonPart(
|
||||
(data.upgraded
|
||||
? tr::lng_gift_view_unpack(tr::now)
|
||||
: tr::lng_sticker_premium_view(tr::now)),
|
||||
st::giftBoxButtonMargin,
|
||||
[parent] { parent->repaint(); },
|
||||
nullptr));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -401,7 +417,8 @@ PreviewWrap::PreviewWrap(
|
|||
|
||||
void ShowSentToast(
|
||||
not_null<Window::SessionController*> window,
|
||||
const GiftDescriptor &descriptor) {
|
||||
const GiftDescriptor &descriptor,
|
||||
const GiftDetails &details) {
|
||||
const auto &st = st::historyPremiumToast;
|
||||
const auto skip = st.padding.top();
|
||||
const auto size = st.style.font->height * 2;
|
||||
|
@ -414,10 +431,12 @@ void ShowSentToast(
|
|||
tr::now,
|
||||
Text::RichLangValue);
|
||||
}, [&](const GiftTypeStars &gift) {
|
||||
const auto amount = gift.info.stars
|
||||
+ (details.upgraded ? gift.info.starsToUpgrade : 0);
|
||||
return tr::lng_gift_sent_about(
|
||||
tr::now,
|
||||
lt_count,
|
||||
gift.info.stars,
|
||||
amount,
|
||||
Text::RichLangValue);
|
||||
});
|
||||
const auto strong = window->showToast({
|
||||
|
@ -475,7 +494,8 @@ void PreviewWrap::prepare(rpl::producer<GiftDetails> details) {
|
|||
const auto cost = v::match(descriptor, [&](GiftTypePremium data) {
|
||||
return FillAmountAndCurrency(data.cost, data.currency, true);
|
||||
}, [&](GiftTypeStars data) {
|
||||
const auto stars = data.info.stars;
|
||||
const auto stars = data.info.stars
|
||||
+ (details.upgraded ? data.info.starsToUpgrade : 0);
|
||||
return stars
|
||||
? tr::lng_gift_stars_title(tr::now, lt_count, stars)
|
||||
: QString();
|
||||
|
@ -1063,6 +1083,7 @@ void SendGift(
|
|||
.user = peer->asUser(),
|
||||
.limitedCount = gift.info.limitedCount,
|
||||
.anonymous = details.anonymous,
|
||||
.upgraded = details.upgraded,
|
||||
}, done, processNonPanelPaymentFormFactory);
|
||||
});
|
||||
}
|
||||
|
@ -1090,6 +1111,24 @@ void SendGift(
|
|||
return result;
|
||||
}
|
||||
|
||||
void ShowGiftUpgradedToast(
|
||||
base::weak_ptr<Window::SessionController> weak,
|
||||
not_null<Main::Session*> session,
|
||||
const MTPUpdates & result) {
|
||||
const auto gift = FindUniqueGift(session, result);
|
||||
if (const auto strong = gift ? weak.get() : nullptr) {
|
||||
strong->showToast({
|
||||
.title = tr::lng_gift_upgraded_title(tr::now),
|
||||
.text = tr::lng_gift_upgraded_about(
|
||||
tr::now,
|
||||
lt_name,
|
||||
Text::Bold(Data::UniqueGiftName(*gift)),
|
||||
Ui::Text::WithEntities),
|
||||
.duration = kUpgradeDoneToastDuration,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void SendUpgradeRequest(
|
||||
not_null<Window::SessionController*> controller,
|
||||
Settings::SmallBalanceResult result,
|
||||
|
@ -1108,17 +1147,7 @@ void SendUpgradeRequest(
|
|||
)).done([=](const MTPpayments_PaymentResult &result) {
|
||||
result.match([&](const MTPDpayments_paymentResult &data) {
|
||||
session->api().applyUpdates(data.vupdates());
|
||||
const auto gift = FindUniqueGift(session, data.vupdates());
|
||||
if (const auto strong = gift ? weak.get() : nullptr) {
|
||||
strong->showToast({
|
||||
.title = tr::lng_gift_upgraded_title(tr::now),
|
||||
.text = tr::lng_gift_upgraded_about(
|
||||
tr::now,
|
||||
lt_name,
|
||||
Text::Bold(Data::UniqueGiftName(*gift)),
|
||||
Ui::Text::WithEntities),
|
||||
});
|
||||
}
|
||||
ShowGiftUpgradedToast(weak, session, data.vupdates());
|
||||
}, [](const MTPDpayments_paymentVerificationNeeded &data) {
|
||||
});
|
||||
done(Payments::CheckoutResult::Paid);
|
||||
|
@ -1150,17 +1179,8 @@ void UpgradeGift(
|
|||
MTP_int(messageId.bare)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
session->api().applyUpdates(result);
|
||||
const auto gift = FindUniqueGift(session, result);
|
||||
if (const auto strong = gift ? weak.get() : nullptr) {
|
||||
strong->showToast({
|
||||
.title = tr::lng_gift_upgraded_title(tr::now),
|
||||
.text = tr::lng_gift_upgraded_about(
|
||||
tr::now,
|
||||
lt_name,
|
||||
Text::Bold(Data::UniqueGiftName(*gift)),
|
||||
Ui::Text::WithEntities),
|
||||
});
|
||||
}
|
||||
ShowGiftUpgradedToast(weak, session, result);
|
||||
done(Payments::CheckoutResult::Paid);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (const auto strong = weak.get()) {
|
||||
strong->showToast(error.type());
|
||||
|
@ -1233,6 +1253,69 @@ void SoldOutBox(
|
|||
Data::SubscriptionEntry());
|
||||
}
|
||||
|
||||
void AddUpgradeButton(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<Main::Session*> session,
|
||||
int cost,
|
||||
QString name,
|
||||
Fn<void(bool)> toggled,
|
||||
Fn<void()> preview) {
|
||||
const auto button = container->add(
|
||||
object_ptr<SettingsButton>(
|
||||
container,
|
||||
rpl::single(QString()),
|
||||
st::settingsButtonNoIcon));
|
||||
button->toggleOn(rpl::single(false))->toggledValue(
|
||||
) | rpl::start_with_next(toggled, button->lifetime());
|
||||
|
||||
const auto makeContext = [session](Fn<void()> update) {
|
||||
return Core::MarkedTextContext{
|
||||
.session = session,
|
||||
.customEmojiRepaint = std::move(update),
|
||||
};
|
||||
};
|
||||
auto star = session->data().customEmojiManager().creditsEmoji();
|
||||
const auto label = Ui::CreateChild<Ui::FlatLabel>(
|
||||
button,
|
||||
tr::lng_gift_send_unique(
|
||||
lt_price,
|
||||
rpl::single(star.append(' '
|
||||
+ Lang::FormatStarsAmountDecimal(
|
||||
StarsAmount{ cost }))),
|
||||
Text::WithEntities),
|
||||
st::boxLabel,
|
||||
st::defaultPopupMenu,
|
||||
std::move(makeContext));
|
||||
label->show();
|
||||
label->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
button->widthValue() | rpl::start_with_next([=](int outer) {
|
||||
const auto padding = st::settingsButtonNoIcon.padding;
|
||||
const auto inner = outer
|
||||
- padding.left()
|
||||
- padding.right()
|
||||
- st::settingsButtonNoIcon.toggleSkip
|
||||
- 2 * st::settingsButtonNoIcon.toggle.border
|
||||
- 2 * st::settingsButtonNoIcon.toggle.diameter
|
||||
- 2 * st::settingsButtonNoIcon.toggle.width;
|
||||
label->resizeToWidth(inner);
|
||||
label->moveToLeft(padding.left(), padding.top(), outer);
|
||||
}, label->lifetime());
|
||||
|
||||
AddSkip(container);
|
||||
const auto about = AddDividerText(
|
||||
container,
|
||||
tr::lng_gift_send_unique_about(
|
||||
lt_user,
|
||||
rpl::single(TextWithEntities{ name }),
|
||||
lt_link,
|
||||
tr::lng_gift_send_unique_link() | Text::ToLink(),
|
||||
Text::WithEntities));
|
||||
about->setClickHandlerFilter([=](const auto &...) {
|
||||
preview();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
void SendGiftBox(
|
||||
not_null<GenericBox*> box,
|
||||
not_null<Window::SessionController*> window,
|
||||
|
@ -1247,20 +1330,6 @@ void SendGiftBox(
|
|||
});
|
||||
|
||||
const auto session = &window->session();
|
||||
auto cost = rpl::single([&] {
|
||||
return v::match(descriptor, [&](const GiftTypePremium &data) {
|
||||
if (data.currency == kCreditsCurrency) {
|
||||
return CreditsEmojiSmall(session).append(
|
||||
Lang::FormatCountDecimal(std::abs(data.cost)));
|
||||
}
|
||||
return TextWithEntities{
|
||||
FillAmountAndCurrency(data.cost, data.currency),
|
||||
};
|
||||
}, [&](const GiftTypeStars &data) {
|
||||
return CreditsEmojiSmall(session).append(
|
||||
Lang::FormatCountDecimal(std::abs(data.info.stars)));
|
||||
});
|
||||
}());
|
||||
|
||||
struct State {
|
||||
rpl::variable<GiftDetails> details;
|
||||
|
@ -1272,7 +1341,26 @@ void SendGiftBox(
|
|||
.descriptor = descriptor,
|
||||
.randomId = base::RandomValue<uint64>(),
|
||||
};
|
||||
const auto document = LookupGiftSticker(&window->session(), descriptor);
|
||||
|
||||
auto cost = state->details.value(
|
||||
) | rpl::map([session](const GiftDetails &details) {
|
||||
return v::match(details.descriptor, [&](const GiftTypePremium &data) {
|
||||
if (data.currency == kCreditsCurrency) {
|
||||
return CreditsEmojiSmall(session).append(
|
||||
Lang::FormatCountDecimal(std::abs(data.cost)));
|
||||
}
|
||||
return TextWithEntities{
|
||||
FillAmountAndCurrency(data.cost, data.currency),
|
||||
};
|
||||
}, [&](const GiftTypeStars &data) {
|
||||
const auto amount = std::abs(data.info.stars)
|
||||
+ (details.upgraded ? data.info.starsToUpgrade : 0);
|
||||
return CreditsEmojiSmall(session).append(
|
||||
Lang::FormatCountDecimal(amount));
|
||||
});
|
||||
});
|
||||
|
||||
const auto document = LookupGiftSticker(session, descriptor);
|
||||
if ((state->media = document ? document->createMediaView() : nullptr)) {
|
||||
state->media->checkStickerLarge();
|
||||
}
|
||||
|
@ -1283,7 +1371,7 @@ void SendGiftBox(
|
|||
session,
|
||||
state->details.value()));
|
||||
|
||||
const auto limit = StarGiftMessageLimit(&window->session());
|
||||
const auto limit = StarGiftMessageLimit(session);
|
||||
const auto text = AddPartInput(
|
||||
window,
|
||||
container,
|
||||
|
@ -1309,7 +1397,7 @@ void SendGiftBox(
|
|||
return true;
|
||||
};
|
||||
InitMessageFieldHandlers({
|
||||
.session = &window->session(),
|
||||
.session = session,
|
||||
.show = window->uiShow(),
|
||||
.field = text,
|
||||
.customEmojiPaused = [=] {
|
||||
|
@ -1328,11 +1416,39 @@ void SendGiftBox(
|
|||
Emoji::SuggestionsController::Init(
|
||||
box->getDelegate()->outerContainer(),
|
||||
text,
|
||||
&window->session(),
|
||||
session,
|
||||
{ .suggestCustomEmoji = true, .allowCustomWithoutPremium = allow });
|
||||
|
||||
if (v::is<GiftTypeStars>(descriptor)) {
|
||||
AddDivider(container);
|
||||
if (const auto stars = std::get_if<GiftTypeStars>(&descriptor)) {
|
||||
if (const auto cost = stars->info.starsToUpgrade; cost > 0) {
|
||||
const auto user = peer->asUser();
|
||||
Assert(user != nullptr);
|
||||
|
||||
const auto id = stars->info.id;
|
||||
const auto name = user->shortName();
|
||||
const auto showing = std::make_shared<bool>();
|
||||
AddDivider(container);
|
||||
AddSkip(container);
|
||||
AddUpgradeButton(container, session, cost, name, [=](bool on) {
|
||||
auto now = state->details.current();
|
||||
now.upgraded = on;
|
||||
state->details = std::move(now);
|
||||
}, [=] {
|
||||
if (*showing) {
|
||||
return;
|
||||
}
|
||||
*showing = true;
|
||||
ShowStarGiftUpgradeBox({
|
||||
.controller = window,
|
||||
.stargiftId = id,
|
||||
.ready = [=](bool) { *showing = false; },
|
||||
.user = user,
|
||||
.cost = int(cost),
|
||||
});
|
||||
});
|
||||
} else {
|
||||
AddDivider(container);
|
||||
}
|
||||
AddSkip(container);
|
||||
container->add(
|
||||
object_ptr<SettingsButton>(
|
||||
|
@ -1373,7 +1489,7 @@ void SendGiftBox(
|
|||
if (result == Payments::CheckoutResult::Paid) {
|
||||
const auto copy = state->media;
|
||||
window->showPeerHistory(peer);
|
||||
ShowSentToast(window, descriptor);
|
||||
ShowSentToast(window, descriptor, details);
|
||||
}
|
||||
if (const auto strong = weak.data()) {
|
||||
box->closeBox();
|
||||
|
@ -1894,13 +2010,10 @@ void AddUniqueGiftCover(
|
|||
}, cover->lifetime());
|
||||
}
|
||||
|
||||
struct UpgradeArgs {
|
||||
struct UpgradeArgs : StarGiftUpgradeArgs {
|
||||
std::vector<Data::UniqueGiftModel> models;
|
||||
std::vector<Data::UniqueGiftPattern> patterns;
|
||||
std::vector<Data::UniqueGiftBackdrop> backdrops;
|
||||
not_null<UserData*> user;
|
||||
MsgId itemId = 0;
|
||||
int stars = 0;
|
||||
};
|
||||
|
||||
[[nodiscard]] rpl::producer<Data::UniqueGift> MakeUpgradeGiftStream(
|
||||
|
@ -1925,22 +2038,31 @@ struct UpgradeArgs {
|
|||
|
||||
const auto put = [=] {
|
||||
const auto index = [](std::vector<int> &indices, const auto &v) {
|
||||
if (indices.empty()) {
|
||||
const auto fill = [&] {
|
||||
if (!indices.empty()) {
|
||||
return;
|
||||
}
|
||||
indices = ranges::views::ints(0) | ranges::views::take(
|
||||
v.size()
|
||||
) | ranges::to_vector;
|
||||
ranges::shuffle(indices);
|
||||
};
|
||||
fill();
|
||||
const auto result = indices.back();
|
||||
indices.pop_back();
|
||||
fill();
|
||||
if (indices.back() == result) {
|
||||
std::swap(indices.front(), indices.back());
|
||||
}
|
||||
const auto index = base::RandomIndex(indices.size());
|
||||
const auto i = begin(indices) + index;
|
||||
const auto result = *i;
|
||||
indices.erase(i);
|
||||
return result;
|
||||
};
|
||||
auto &models = state->data.models;
|
||||
auto &patterns = state->data.patterns;
|
||||
auto &backdrops = state->data.backdrops;
|
||||
consumer.put_next(Data::UniqueGift{
|
||||
.title = tr::lng_gift_upgrade_title(tr::now),
|
||||
.title = (state->data.itemId
|
||||
? tr::lng_gift_upgrade_title(tr::now)
|
||||
: tr::lng_gift_upgrade_preview_title(tr::now)),
|
||||
.model = models[index(state->modelIndices, models)],
|
||||
.pattern = patterns[index(state->patternIndices, patterns)],
|
||||
.backdrop = backdrops[index(state->backdropIndices, backdrops)],
|
||||
|
@ -1962,7 +2084,11 @@ void AddUpgradeGiftCover(
|
|||
AddUniqueGiftCover(
|
||||
container,
|
||||
MakeUpgradeGiftStream(args),
|
||||
tr::lng_gift_upgrade_about());
|
||||
(args.itemId
|
||||
? tr::lng_gift_upgrade_about()
|
||||
: tr::lng_gift_upgrade_preview_about(
|
||||
lt_name,
|
||||
rpl::single(args.user->shortName()))));
|
||||
}
|
||||
|
||||
void UpgradeBox(
|
||||
|
@ -2025,45 +2151,75 @@ void UpgradeBox(
|
|||
&st::menuIconReplace,
|
||||
true);
|
||||
|
||||
container->add(
|
||||
object_ptr<PlainShadow>(container),
|
||||
st::boxRowPadding + QMargins(0, st::defaultVerticalListSkip, 0, 0));
|
||||
|
||||
box->setStyle(st::giftBox);
|
||||
|
||||
struct State {
|
||||
bool sent = false;
|
||||
bool preserveDetails = false;
|
||||
};
|
||||
const auto stars = args.stars;
|
||||
const auto session = &controller->session();
|
||||
const auto state = std::make_shared<State>();
|
||||
const auto button = box->addButton(rpl::single(QString()), [=] {
|
||||
if (state->sent) {
|
||||
const auto preview = !args.itemId;
|
||||
|
||||
if (!preview) {
|
||||
const auto skip = st::defaultVerticalListSkip;
|
||||
container->add(
|
||||
object_ptr<PlainShadow>(container),
|
||||
st::boxRowPadding + QMargins(0, skip, 0, skip));
|
||||
const auto checkbox = container->add(
|
||||
object_ptr<CenterWrap<Checkbox>>(
|
||||
container,
|
||||
object_ptr<Checkbox>(container, args.canAddComment
|
||||
? tr::lng_gift_upgrade_add_comment(tr::now)
|
||||
: args.canAddSender
|
||||
? tr::lng_gift_upgrade_add_sender(tr::now)
|
||||
: tr::lng_gift_upgrade_add_my(tr::now))),
|
||||
st::defaultCheckbox.margin)->entity();
|
||||
checkbox->checkedChanges() | rpl::start_with_next([=](bool checked) {
|
||||
state->preserveDetails = checked;
|
||||
}, checkbox->lifetime());
|
||||
}
|
||||
|
||||
box->setStyle(preview ? st::giftBox : st::upgradeGiftBox);
|
||||
|
||||
const auto cost = args.cost;
|
||||
const auto session = &controller->session();
|
||||
auto buttonText = preview ? tr::lng_box_ok() : rpl::single(QString());
|
||||
const auto button = box->addButton(std::move(buttonText), [=] {
|
||||
if (preview) {
|
||||
box->closeBox();
|
||||
return;
|
||||
} else if (state->sent) {
|
||||
return;
|
||||
}
|
||||
state->sent = true;
|
||||
const auto keepDetails = true;
|
||||
const auto keepDetails = state->preserveDetails;
|
||||
const auto weak = Ui::MakeWeak(box);
|
||||
const auto done = [=](Payments::CheckoutResult result) {
|
||||
if (result != Payments::CheckoutResult::Paid) {
|
||||
state->sent = false;
|
||||
} else if (const auto strong = weak.data()) {
|
||||
strong->closeBox();
|
||||
} else {
|
||||
controller->showPeerHistory(args.user);
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
}
|
||||
};
|
||||
UpgradeGift(controller, args.itemId, keepDetails, stars, done);
|
||||
UpgradeGift(controller, args.itemId, keepDetails, cost, done);
|
||||
});
|
||||
auto star = session->data().customEmojiManager().creditsEmoji();
|
||||
SetButtonMarkedLabel(
|
||||
button,
|
||||
tr::lng_gift_upgrade_button(
|
||||
lt_price,
|
||||
rpl::single(star.append(
|
||||
' ' + Lang::FormatStarsAmountDecimal(StarsAmount{ 25 }))),
|
||||
Ui::Text::WithEntities),
|
||||
&controller->session(),
|
||||
st::creditsBoxButtonLabel,
|
||||
&st::giftBox.button.textFg);
|
||||
if (!preview) {
|
||||
auto star = session->data().customEmojiManager().creditsEmoji();
|
||||
SetButtonMarkedLabel(
|
||||
button,
|
||||
(cost
|
||||
? tr::lng_gift_upgrade_button(
|
||||
lt_price,
|
||||
rpl::single(star.append(
|
||||
' ' + Lang::FormatStarsAmountDecimal(
|
||||
StarsAmount{ cost }))),
|
||||
Ui::Text::WithEntities)
|
||||
: tr::lng_gift_upgrade_confirm(Ui::Text::WithEntities)),
|
||||
&controller->session(),
|
||||
st::creditsBoxButtonLabel,
|
||||
&st::giftBox.button.textFg);
|
||||
}
|
||||
rpl::combine(
|
||||
box->widthValue(),
|
||||
button->widthValue()
|
||||
|
@ -2118,45 +2274,41 @@ void PaintPoints(
|
|||
}
|
||||
}
|
||||
|
||||
void ShowStarGiftUpgradeBox(
|
||||
not_null<Window::SessionController*> controller,
|
||||
uint64 stargiftId,
|
||||
not_null<UserData*> user,
|
||||
MsgId itemId,
|
||||
int stars,
|
||||
Fn<void(bool)> ready) {
|
||||
const auto weak = base::make_weak(controller);
|
||||
user->session().api().request(MTPpayments_GetStarGiftUpgradePreview(
|
||||
MTP_long(stargiftId)
|
||||
void ShowStarGiftUpgradeBox(StarGiftUpgradeArgs &&args) {
|
||||
const auto weak = base::make_weak(args.controller);
|
||||
const auto session = &args.user->session();
|
||||
session->api().request(MTPpayments_GetStarGiftUpgradePreview(
|
||||
MTP_long(args.stargiftId)
|
||||
)).done([=](const MTPpayments_StarGiftUpgradePreview &result) {
|
||||
const auto strong = weak.get();
|
||||
if (!strong) {
|
||||
ready(false);
|
||||
if (const auto onstack = args.ready) {
|
||||
onstack(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const auto &data = result.data();
|
||||
const auto session = &user->session();
|
||||
auto args = UpgradeArgs{
|
||||
.user = user,
|
||||
.itemId = itemId,
|
||||
.stars = stars,
|
||||
};
|
||||
auto upgrade = UpgradeArgs{ args };
|
||||
for (const auto &attribute : data.vsample_attributes().v) {
|
||||
attribute.match([&](const MTPDstarGiftAttributeModel &data) {
|
||||
args.models.push_back(Api::FromTL(session, data));
|
||||
upgrade.models.push_back(Api::FromTL(session, data));
|
||||
}, [&](const MTPDstarGiftAttributePattern &data) {
|
||||
args.patterns.push_back(Api::FromTL(session, data));
|
||||
upgrade.patterns.push_back(Api::FromTL(session, data));
|
||||
}, [&](const MTPDstarGiftAttributeBackdrop &data) {
|
||||
args.backdrops.push_back(Api::FromTL(data));
|
||||
upgrade.backdrops.push_back(Api::FromTL(data));
|
||||
}, [](const auto &) {});
|
||||
}
|
||||
controller->show(Box(UpgradeBox, controller, std::move(args)));
|
||||
ready(true);
|
||||
strong->show(Box(UpgradeBox, strong, std::move(upgrade)));
|
||||
if (const auto onstack = args.ready) {
|
||||
onstack(true);
|
||||
}
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (const auto strong = weak.get()) {
|
||||
strong->showToast(error.type());
|
||||
}
|
||||
ready(false);
|
||||
if (const auto onstack = args.ready) {
|
||||
onstack(false);
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,13 +46,17 @@ void PaintPoints(
|
|||
const QRect &rect,
|
||||
float64 shown = 1.);
|
||||
|
||||
void ShowStarGiftUpgradeBox(
|
||||
not_null<Window::SessionController*> controller,
|
||||
uint64 stargiftId,
|
||||
not_null<UserData*> user,
|
||||
MsgId itemId,
|
||||
int stars,
|
||||
Fn<void(bool)> ready);
|
||||
struct StarGiftUpgradeArgs {
|
||||
not_null<Window::SessionController*> controller;
|
||||
base::required<uint64> stargiftId;
|
||||
Fn<void(bool)> ready;
|
||||
not_null<UserData*> user;
|
||||
MsgId itemId = 0;
|
||||
int cost = 0;
|
||||
bool canAddSender = false;
|
||||
bool canAddComment = false;
|
||||
};
|
||||
void ShowStarGiftUpgradeBox(StarGiftUpgradeArgs &&args);
|
||||
|
||||
void AddUniqueCloseButton(not_null<GenericBox*> box);
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ struct CreditsHistoryEntry final {
|
|||
uint64 barePeerId = 0;
|
||||
uint64 bareGiveawayMsgId = 0;
|
||||
uint64 bareGiftStickerId = 0;
|
||||
uint64 bareGiftOwnerId = 0;
|
||||
uint64 bareActorId = 0;
|
||||
uint64 stargiftId = 0;
|
||||
std::shared_ptr<UniqueGift> uniqueGift;
|
||||
|
@ -87,6 +88,7 @@ struct CreditsHistoryEntry final {
|
|||
bool fromGiftsList : 1 = false;
|
||||
bool soldOutInfo : 1 = false;
|
||||
bool canUpgradeGift : 1 = false;
|
||||
bool hasGiftComment : 1 = false;
|
||||
bool reaction : 1 = false;
|
||||
bool refunded : 1 = false;
|
||||
bool pending : 1 = false;
|
||||
|
|
|
@ -5407,7 +5407,8 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
|||
const auto peer = isSelf ? _history->peer : _from;
|
||||
const auto stars = action.vgift().match([&](
|
||||
const MTPDstarGift &data) {
|
||||
return uint64(data.vstars().v);
|
||||
return uint64(data.vstars().v)
|
||||
+ uint64(data.vupgrade_stars().value_or_empty());
|
||||
}, [](const MTPDstarGiftUnique &) {
|
||||
return uint64();
|
||||
});
|
||||
|
|
|
@ -78,14 +78,24 @@ TextWithEntities PremiumGift::subtitle() {
|
|||
return !_data.message.empty()
|
||||
? _data.message
|
||||
: outgoingGift()
|
||||
? tr::lng_action_gift_sent_text(
|
||||
? (_data.starsUpgradedBySender
|
||||
? tr::lng_action_gift_sent_upgradable(
|
||||
tr::now,
|
||||
lt_user,
|
||||
Ui::Text::Bold(_parent->history()->peer->shortName()),
|
||||
Ui::Text::RichLangValue)
|
||||
: tr::lng_action_gift_sent_text(
|
||||
tr::now,
|
||||
lt_count,
|
||||
_data.starsConverted,
|
||||
lt_user,
|
||||
Ui::Text::Bold(_parent->history()->peer->shortName()),
|
||||
Ui::Text::RichLangValue))
|
||||
: _data.starsUpgradedBySender
|
||||
? tr::lng_action_gift_got_upgradable_text(
|
||||
tr::now,
|
||||
lt_count,
|
||||
_data.starsConverted,
|
||||
lt_user,
|
||||
Ui::Text::Bold(_parent->history()->peer->shortName()),
|
||||
Ui::Text::RichLangValue)
|
||||
: (_data.converted
|
||||
: ((_data.converted || !_data.starsConverted)
|
||||
? tr::lng_gift_got_stars
|
||||
: tr::lng_action_gift_got_stars_text)(
|
||||
tr::now,
|
||||
|
@ -147,6 +157,8 @@ rpl::producer<QString> PremiumGift::button() {
|
|||
? nullptr
|
||||
: creditsPrize()
|
||||
? tr::lng_view_button_giftcode()
|
||||
: (starGift() && _data.starsUpgradedBySender && !_data.upgraded)
|
||||
? tr::lng_gift_view_unpack()
|
||||
: (gift() && (outgoingGift() || !_data.unclaimed))
|
||||
? tr::lng_sticker_premium_view()
|
||||
: tr::lng_prize_open();
|
||||
|
|
|
@ -96,9 +96,9 @@ public:
|
|||
ButtonPart(
|
||||
const QString &text,
|
||||
QMargins margins,
|
||||
QColor bg,
|
||||
Fn<void()> repaint,
|
||||
ClickHandlerPtr link);
|
||||
ClickHandlerPtr link,
|
||||
QColor bg = QColor(0, 0, 0, 0));
|
||||
|
||||
void draw(
|
||||
Painter &p,
|
||||
|
@ -126,6 +126,7 @@ private:
|
|||
ClickHandlerPtr _link;
|
||||
std::unique_ptr<Ui::RippleAnimation> _ripple;
|
||||
mutable Ui::Premium::ColoredMiniStars _stars;
|
||||
mutable std::optional<QColor> _starsLastColor;
|
||||
Fn<void()> _repaint;
|
||||
|
||||
mutable QPoint _lastPoint;
|
||||
|
@ -135,9 +136,9 @@ private:
|
|||
ButtonPart::ButtonPart(
|
||||
const QString &text,
|
||||
QMargins margins,
|
||||
QColor bg,
|
||||
Fn<void()> repaint,
|
||||
ClickHandlerPtr link)
|
||||
ClickHandlerPtr link,
|
||||
QColor bg)
|
||||
: _text(st::semiboldTextStyle, text)
|
||||
, _margins(margins)
|
||||
, _bg(bg)
|
||||
|
@ -152,13 +153,6 @@ ButtonPart::ButtonPart(
|
|||
repaint();
|
||||
}, Ui::Premium::MiniStars::Type::SlowStars)
|
||||
, _repaint(std::move(repaint)) {
|
||||
_stars.setColorOverride(QGradientStops{
|
||||
{ 0., QColor(255, 255, 255, 255 * .3) },
|
||||
{ 1., QColor(255, 255, 255) },
|
||||
});
|
||||
const auto padding = _size.height() / 2;
|
||||
_stars.setCenter(
|
||||
Rect(_size) - QMargins(padding, 0, padding, 0));
|
||||
}
|
||||
|
||||
void ButtonPart::draw(
|
||||
|
@ -168,17 +162,32 @@ void ButtonPart::draw(
|
|||
int outerWidth) const {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
|
||||
const auto position = QPoint(
|
||||
const auto customColors = (_bg.alpha() > 0);
|
||||
|
||||
const auto position = QPoint(
|
||||
(outerWidth - width()) / 2 + _margins.left(),
|
||||
_margins.top());
|
||||
p.translate(position);
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(_bg);
|
||||
p.setBrush(customColors ? QBrush(_bg) : context.st->msgServiceBg());
|
||||
const auto radius = _size.height() / 2.;
|
||||
const auto r = Rect(_size);
|
||||
p.drawRoundedRect(r, radius, radius);
|
||||
|
||||
auto white = QColor(255, 255, 255);
|
||||
const auto fg = customColors ? white : context.st->msgServiceFg()->c;
|
||||
if (!_starsLastColor || *_starsLastColor != fg) {
|
||||
_starsLastColor = fg;
|
||||
_stars.setColorOverride(QGradientStops{
|
||||
{ 0., anim::with_alpha(fg, .3) },
|
||||
{ 1., fg },
|
||||
});
|
||||
const auto padding = _size.height() / 2;
|
||||
_stars.setCenter(
|
||||
Rect(_size) - QMargins(padding, 0, padding, 0));
|
||||
}
|
||||
|
||||
auto clipPath = QPainterPath();
|
||||
clipPath.addRoundedRect(r, radius, radius);
|
||||
p.setClipPath(clipPath);
|
||||
|
@ -186,20 +195,22 @@ void ButtonPart::draw(
|
|||
_stars.paint(p);
|
||||
p.setClipping(false);
|
||||
|
||||
auto white = QColor(255, 255, 255);
|
||||
p.setPen(white);
|
||||
if (_ripple) {
|
||||
const auto opacity = p.opacity();
|
||||
const auto ripple = customColors
|
||||
? anim::with_alpha(fg, .3)
|
||||
: context.messageStyle()->msgWaveformInactive->c;
|
||||
p.setOpacity(st::historyPollRippleOpacity);
|
||||
white.setAlphaF(0.3);
|
||||
_ripple->paint(
|
||||
p,
|
||||
0,
|
||||
0,
|
||||
width(),
|
||||
&white);
|
||||
&ripple);
|
||||
p.setOpacity(opacity);
|
||||
}
|
||||
|
||||
p.setPen(fg);
|
||||
_text.draw(
|
||||
p,
|
||||
0,
|
||||
|
@ -456,9 +467,9 @@ auto GenerateUniqueGiftMedia(
|
|||
push(std::make_unique<ButtonPart>(
|
||||
tr::lng_sticker_premium_view(tr::now),
|
||||
st::chatUniqueButtonPadding,
|
||||
gift->backdrop.patternColor,
|
||||
[=] { parent->repaint(); },
|
||||
std::move(link)));
|
||||
std::move(link),
|
||||
gift->backdrop.patternColor));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -537,4 +548,13 @@ Fn<void(Painter&, const Ui::ChatPaintContext &)> UniqueGiftBg(
|
|||
};
|
||||
}
|
||||
|
||||
std::unique_ptr<MediaGenericPart> MakeGenericButtonPart(
|
||||
const QString &text,
|
||||
QMargins margins,
|
||||
Fn<void()> repaint,
|
||||
ClickHandlerPtr link,
|
||||
QColor bg) {
|
||||
return std::make_unique<ButtonPart>(text, margins, repaint, link, bg);
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -29,8 +29,15 @@ auto GenerateUniqueGiftMedia(
|
|||
not_null<Data::UniqueGift*> gift)
|
||||
-> Fn<void(Fn<void(std::unique_ptr<MediaGenericPart>)>)>;
|
||||
|
||||
Fn<void(Painter&, const Ui::ChatPaintContext &)> UniqueGiftBg(
|
||||
[[nodiscard]] Fn<void(Painter&, const Ui::ChatPaintContext &)> UniqueGiftBg(
|
||||
not_null<Element*> view,
|
||||
not_null<Data::UniqueGift*> gift);
|
||||
|
||||
[[nodiscard]] std::unique_ptr<MediaGenericPart> MakeGenericButtonPart(
|
||||
const QString &text,
|
||||
QMargins margins,
|
||||
Fn<void()> repaint,
|
||||
ClickHandlerPtr link,
|
||||
QColor bg = QColor(0, 0, 0, 0));
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -326,6 +326,7 @@ void InnerWidget::showGift(int index) {
|
|||
_window->show(Box(
|
||||
::Settings::UserStarGiftBox,
|
||||
_window,
|
||||
_user,
|
||||
_entries[index].gift));
|
||||
}
|
||||
|
||||
|
|
|
@ -383,7 +383,8 @@ MTPInputInvoice Form::inputInvoice() const {
|
|||
using Flag = MTPDinputInvoiceStarGift::Flag;
|
||||
return MTP_inputInvoiceStarGift(
|
||||
MTP_flags((gift->anonymous ? Flag::f_hide_name : Flag(0))
|
||||
| (gift->message.empty() ? Flag(0) : Flag::f_message)),
|
||||
| (gift->message.empty() ? Flag(0) : Flag::f_message)
|
||||
| (gift->upgraded ? Flag::f_include_upgrade : Flag(0))),
|
||||
gift->user->inputUser,
|
||||
MTP_long(gift->giftId),
|
||||
MTP_textWithEntities(
|
||||
|
|
|
@ -180,6 +180,7 @@ struct InvoiceStarGift {
|
|||
not_null<UserData*> user;
|
||||
int limitedCount = 0;
|
||||
bool anonymous = false;
|
||||
bool upgraded = false;
|
||||
};
|
||||
|
||||
struct InvoiceId {
|
||||
|
|
|
@ -1182,25 +1182,28 @@ void ReceiptCreditsBox(
|
|||
box,
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
((couldConvert || nonConvertible)
|
||||
? (e.savedToProfile
|
||||
? tr::lng_action_gift_can_remove_text
|
||||
: tr::lng_action_gift_got_gift_text)(
|
||||
Ui::Text::WithEntities)
|
||||
: rpl::combine(
|
||||
(canConvert
|
||||
? tr::lng_action_gift_got_stars_text
|
||||
: tr::lng_gift_got_stars)(
|
||||
lt_count,
|
||||
rpl::single(e.starsConverted * 1.),
|
||||
Ui::Text::RichLangValue),
|
||||
tr::lng_paid_about_link()
|
||||
) | rpl::map([](
|
||||
TextWithEntities text,
|
||||
QString link) {
|
||||
return text.append(' ').append(
|
||||
Ui::Text::Link(link));
|
||||
})),
|
||||
(e.starsUpgradedBySender
|
||||
? tr::lng_action_gift_got_upgradable_text(
|
||||
Ui::Text::RichLangValue)
|
||||
: ((couldConvert || nonConvertible)
|
||||
? (e.savedToProfile
|
||||
? tr::lng_action_gift_can_remove_text
|
||||
: tr::lng_action_gift_got_gift_text)(
|
||||
Ui::Text::WithEntities)
|
||||
: rpl::combine(
|
||||
(canConvert
|
||||
? tr::lng_action_gift_got_stars_text
|
||||
: tr::lng_gift_got_stars)(
|
||||
lt_count,
|
||||
rpl::single(e.starsConverted * 1.),
|
||||
Ui::Text::RichLangValue),
|
||||
tr::lng_paid_about_link()
|
||||
) | rpl::map([](
|
||||
TextWithEntities text,
|
||||
QString link) {
|
||||
return text.append(' ').append(
|
||||
Ui::Text::Link(link));
|
||||
}))),
|
||||
st::creditsBoxAbout)))->entity();
|
||||
about->setClickHandlerFilter([=](const auto &...) {
|
||||
Core::App().iv().openWithIvPreferred(
|
||||
|
@ -1297,6 +1300,32 @@ void ReceiptCreditsBox(
|
|||
done);
|
||||
};
|
||||
|
||||
const auto upgradeGuard = std::make_shared<bool>();
|
||||
const auto upgrade = [=] {
|
||||
if (const auto window = weakWindow.get()) {
|
||||
const auto itemId = MsgId(e.bareMsgId);
|
||||
if (*upgradeGuard) {
|
||||
return;
|
||||
}
|
||||
*upgradeGuard = true;
|
||||
using namespace Ui;
|
||||
ShowStarGiftUpgradeBox({
|
||||
.controller = window,
|
||||
.stargiftId = e.stargiftId,
|
||||
.ready = [=](bool) { *upgradeGuard = false; },
|
||||
.user = starGiftSender,
|
||||
.itemId = itemId,
|
||||
.cost = e.starsUpgradedBySender ? 0 : e.starsToUpgrade,
|
||||
.canAddSender = !e.anonymous,
|
||||
.canAddComment = !e.anonymous && e.hasGiftComment,
|
||||
});
|
||||
}
|
||||
};
|
||||
const auto canUpgrade = e.stargiftId
|
||||
&& e.canUpgradeGift
|
||||
&& !e.uniqueGift;
|
||||
const auto canUpgradeFree = canUpgrade && (e.starsUpgradedBySender > 0);
|
||||
|
||||
if (isStarGift && e.id.isEmpty()) {
|
||||
const auto convert = [=, weak = Ui::MakeWeak(box)] {
|
||||
const auto stars = e.starsConverted;
|
||||
|
@ -1340,28 +1369,7 @@ void ReceiptCreditsBox(
|
|||
}
|
||||
});
|
||||
};
|
||||
const auto upgradeGuard = std::make_shared<bool>();
|
||||
const auto upgrade = [=] {
|
||||
if (const auto window = weakWindow.get()) {
|
||||
const auto itemId = MsgId(e.bareMsgId);
|
||||
if (*upgradeGuard) {
|
||||
return;
|
||||
}
|
||||
*upgradeGuard = true;
|
||||
using namespace Ui;
|
||||
ShowStarGiftUpgradeBox(
|
||||
window,
|
||||
e.stargiftId,
|
||||
starGiftSender,
|
||||
itemId,
|
||||
e.starsUpgradedBySender ? 0 : e.starsToUpgrade,
|
||||
[=](bool) { *upgradeGuard = false; });
|
||||
}
|
||||
};
|
||||
const auto canToggle = canConvert || couldConvert || nonConvertible;
|
||||
const auto canUpgrade = e.stargiftId
|
||||
&& e.canUpgradeGift
|
||||
&& !e.uniqueGift;
|
||||
|
||||
AddStarGiftTable(
|
||||
controller,
|
||||
|
@ -1479,6 +1487,8 @@ void ReceiptCreditsBox(
|
|||
? tr::lng_credits_subscription_off_button()
|
||||
: toRejoin
|
||||
? tr::lng_credits_subscription_off_rejoin_button()
|
||||
: canUpgradeFree
|
||||
? tr::lng_gift_upgrade_free()
|
||||
: tr::lng_box_ok()));
|
||||
const auto send = [=, weak = Ui::MakeWeak(box)] {
|
||||
if (toRejoin) {
|
||||
|
@ -1531,6 +1541,8 @@ void ReceiptCreditsBox(
|
|||
if (willBusy) {
|
||||
state->confirmButtonBusy = true;
|
||||
send();
|
||||
} else if (canUpgradeFree) {
|
||||
upgrade();
|
||||
} else {
|
||||
box->closeBox();
|
||||
}
|
||||
|
@ -1607,6 +1619,7 @@ void CreditsPrizeBox(
|
|||
void UserStarGiftBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<UserData*> owner,
|
||||
const Data::UserStarGift &data) {
|
||||
Settings::ReceiptCreditsBox(
|
||||
box,
|
||||
|
@ -1618,7 +1631,9 @@ void UserStarGiftBox(
|
|||
.bareMsgId = uint64(data.messageId.bare),
|
||||
.barePeerId = data.fromId.value,
|
||||
.bareGiftStickerId = data.info.document->id,
|
||||
.bareGiftOwnerId = owner->id.value,
|
||||
.stargiftId = data.info.id,
|
||||
.uniqueGift = data.info.unique,
|
||||
.peerType = Data::CreditsHistoryEntry::PeerType::Peer,
|
||||
.limitedCount = data.info.limitedCount,
|
||||
.limitedLeft = data.info.limitedLeft,
|
||||
|
@ -1650,6 +1665,7 @@ void StarGiftViewBox(
|
|||
.bareMsgId = uint64(item->id.bare),
|
||||
.barePeerId = item->history()->peer->id.value,
|
||||
.bareGiftStickerId = data.document ? data.document->id : 0,
|
||||
.bareGiftOwnerId = item->history()->session().userPeerId().value,
|
||||
.stargiftId = data.stargiftId,
|
||||
.uniqueGift = data.unique,
|
||||
.peerType = Data::CreditsHistoryEntry::PeerType::Peer,
|
||||
|
@ -1663,6 +1679,7 @@ void StarGiftViewBox(
|
|||
.stargift = true,
|
||||
.savedToProfile = data.saved,
|
||||
.canUpgradeGift = data.upgradable,
|
||||
.hasGiftComment = !data.message.empty(),
|
||||
.in = true,
|
||||
.gift = true,
|
||||
};
|
||||
|
|
|
@ -100,6 +100,7 @@ void CreditsPrizeBox(
|
|||
void UserStarGiftBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<UserData*> owner,
|
||||
const Data::UserStarGift &data);
|
||||
void StarGiftViewBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
|
|
|
@ -120,7 +120,8 @@ giftBoxButtonBottom: 12px;
|
|||
giftBoxButtonPadding: margins(8px, 4px, 8px, 4px);
|
||||
giftBoxPreviewStickerPadding: margins(10px, 12px, 10px, 16px);
|
||||
giftBoxPreviewTitlePadding: margins(12px, 4px, 12px, 4px);
|
||||
giftBoxPreviewTextPadding: margins(12px, 4px, 12px, 24px);
|
||||
giftBoxPreviewTextPadding: margins(12px, 4px, 12px, 4px);
|
||||
giftBoxButtonMargin: margins(12px, 8px, 12px, 12px);
|
||||
giftBoxStickerTop: 0px;
|
||||
giftBoxStickerStarTop: 24px;
|
||||
giftBoxStickerSize: size(80px, 80px);
|
||||
|
@ -192,3 +193,6 @@ uniqueCloseButton: IconButton(boxTitleClose) {
|
|||
color: shadowFg;
|
||||
}
|
||||
}
|
||||
upgradeGiftBox: Box(giftBox) {
|
||||
buttonPadding: margins(22px, 3px, 22px, 22px);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue