Confirm making an offer.
This commit is contained in:
@@ -2353,6 +2353,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_action_gift_offer" = "{user} offered you {cost} for {name}.";
|
||||
"lng_action_gift_offer_you" = "You offered {cost} for {name}.";
|
||||
"lng_action_gift_offer_state_expires" = "This offer expires in {time}.";
|
||||
"lng_action_gift_offer_time_large" = "{hours} h";
|
||||
"lng_action_gift_offer_time_medium" = "{hours} h {minutes} m";
|
||||
"lng_action_gift_offer_time_small" = "{minutes} m";
|
||||
"lng_action_gift_offer_state_accepted" = "This offer was accepted.";
|
||||
@@ -3137,6 +3138,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_credits_small_balance_for_message" = "Buy **Stars** to send messages to {user}.";
|
||||
"lng_credits_small_balance_for_messages" = "Buy **Stars** to send messages.";
|
||||
"lng_credits_small_balance_for_suggest" = "Buy **Stars** to suggest post to {channel}.";
|
||||
"lng_credits_small_balance_for_offer" = "Buy **Stars** to offer for this gift.";
|
||||
"lng_credits_small_balance_for_search" = "Buy **Stars** to search through public posts.";
|
||||
"lng_credits_small_balance_fallback" = "Buy **Stars** to unlock content and services on Telegram.";
|
||||
"lng_credits_purchase_blocked" = "Sorry, you can't purchase this item with Telegram Stars.";
|
||||
@@ -3966,6 +3968,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_gift_offer_you_get" = "You will receive {cost} after fees.";
|
||||
"lng_gift_offer_value_higher" = "{percent} higher";
|
||||
"lng_gift_offer_sell_for" = "Sell for {price}";
|
||||
"lng_gift_offer_confirm_title" = "Confirm Offer";
|
||||
"lng_gift_offer_confirm_text" = "Do you want to offer {cost} to {user} for {name}?";
|
||||
"lng_gift_offer_table_offer" = "Offer";
|
||||
"lng_gift_offer_table_fee" = "Fee";
|
||||
"lng_gift_offer_table_duration" = "Duration";
|
||||
"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";
|
||||
|
||||
@@ -3564,31 +3564,122 @@ void SendOfferBuyGift(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
std::shared_ptr<Data::UniqueGift> unique,
|
||||
SuggestOptions options,
|
||||
Fn<void()> done) {
|
||||
int starsPerMessage,
|
||||
Fn<void(bool)> done) {
|
||||
const auto randomId = base::RandomValue<uint64>();
|
||||
const auto owner = show->session().data().peer(unique->ownerId);
|
||||
|
||||
using Flag = MTPpayments_SendStarGiftOffer::Flag;
|
||||
show->session().api().request(MTPpayments_SendStarGiftOffer(
|
||||
MTP_flags(Flag() | Flag()),//Flag::f_allow_paid_stars)
|
||||
MTP_flags(starsPerMessage ? Flag::f_allow_paid_stars : Flag()),
|
||||
owner->input,
|
||||
MTP_string(unique->slug),
|
||||
StarsAmountToTL(options.price()),
|
||||
MTP_int(options.offerDuration),
|
||||
MTP_long(randomId),
|
||||
MTP_long(0) // allow_paid_stars
|
||||
MTP_long(starsPerMessage)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
show->session().api().applyUpdates(result);
|
||||
done();
|
||||
done(true);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (error.type() == u""_q) {
|
||||
|
||||
} else {
|
||||
show->showToast(error.type());
|
||||
}
|
||||
done(false);
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ConfirmOfferBuyGift(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
std::shared_ptr<Data::UniqueGift> unique,
|
||||
SuggestOptions options,
|
||||
Fn<void()> done) {
|
||||
const auto owner = show->session().data().peer(unique->ownerId);
|
||||
const auto fee = owner->starsPerMessageChecked();
|
||||
const auto price = options.price();
|
||||
const auto sent = std::make_shared<bool>();
|
||||
const auto send = [=](Fn<void()> close) {
|
||||
if (*sent) {
|
||||
return;
|
||||
}
|
||||
*sent = true;
|
||||
SendOfferBuyGift(show, unique, options, fee, [=](bool ok) {
|
||||
*sent = false;
|
||||
if (ok) {
|
||||
if (const auto window = show->resolveWindow()) {
|
||||
window->showPeerHistory(owner->id);
|
||||
}
|
||||
done();
|
||||
close();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
show->show(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
Ui::ConfirmBox(box, {
|
||||
.text = tr::lng_gift_offer_confirm_text(
|
||||
tr::now,
|
||||
lt_cost,
|
||||
tr::bold(PrepareCreditsAmountText(options.price())),
|
||||
lt_user,
|
||||
tr::bold(owner->shortName()),
|
||||
lt_name,
|
||||
tr::bold(Data::UniqueGiftName(*unique)),
|
||||
tr::marked),
|
||||
.confirmed = send,
|
||||
.confirmText = tr::lng_payments_pay_amount(
|
||||
tr::now,
|
||||
lt_amount,
|
||||
Ui::Text::IconEmoji(price.ton()
|
||||
? &st::buttonTonIconEmoji
|
||||
: &st::buttonStarIconEmoji
|
||||
).append(Lang::FormatCreditsAmountDecimal(price.ton()
|
||||
? price
|
||||
: CreditsAmount(price.whole() + fee))),
|
||||
tr::marked),
|
||||
.title = tr::lng_gift_offer_confirm_title(),
|
||||
});
|
||||
|
||||
auto helper = Ui::Text::CustomEmojiHelper();
|
||||
const auto starIcon = helper.paletteDependent(
|
||||
Ui::Earn::IconCreditsEmoji());
|
||||
const auto tonIcon = helper.paletteDependent(
|
||||
Ui::Earn::IconCurrencyEmoji());
|
||||
const auto context = helper.context();
|
||||
const auto table = box->addRow(
|
||||
object_ptr<Ui::TableLayout>(box, st::defaultTable),
|
||||
st::boxPadding);
|
||||
const auto add = [&](tr::phrase<> label, TextWithEntities value) {
|
||||
table->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
table,
|
||||
label(),
|
||||
st::defaultTable.defaultLabel),
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
table,
|
||||
rpl::single(value),
|
||||
st::defaultTable.defaultValue,
|
||||
st::defaultPopupMenu,
|
||||
context),
|
||||
st::giveawayGiftCodeLabelMargin,
|
||||
st::giveawayGiftCodeValueMargin);
|
||||
};
|
||||
add(tr::lng_gift_offer_table_offer, tr::marked(price.ton()
|
||||
? tonIcon
|
||||
: starIcon).append(Lang::FormatCreditsAmountDecimal(price)));
|
||||
if (fee) {
|
||||
add(tr::lng_gift_offer_table_fee, tr::marked(starIcon).append(
|
||||
Lang::FormatCreditsAmountDecimal(CreditsAmount(fee))));
|
||||
}
|
||||
const auto hours = options.offerDuration / 3600;
|
||||
const auto duration = hours
|
||||
? tr::lng_hours(tr::now, lt_count, hours)
|
||||
: tr::lng_minutes(tr::now, lt_count, options.offerDuration / 60);
|
||||
add(tr::lng_gift_offer_table_duration, tr::marked(duration));
|
||||
}));
|
||||
}
|
||||
|
||||
void ShowOfferBuyBox(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
std::shared_ptr<Data::UniqueGift> unique) {
|
||||
@@ -3596,7 +3687,7 @@ void ShowOfferBuyBox(
|
||||
|
||||
const auto weak = std::make_shared<base::weak_qptr<Ui::BoxContent>>();
|
||||
const auto done = [=](SuggestOptions result) {
|
||||
SendOfferBuyGift(show, unique, result, [=] {
|
||||
ConfirmOfferBuyGift(show, unique, result, [=] {
|
||||
if (const auto strong = weak->get()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
@@ -3612,6 +3703,7 @@ void ShowOfferBuyBox(
|
||||
.done = done,
|
||||
.value = options,
|
||||
.mode = SuggestMode::Gift,
|
||||
.giftName = UniqueGiftName(*unique),
|
||||
});
|
||||
*weak = priceBox.data();
|
||||
show->show(std::move(priceBox));
|
||||
|
||||
@@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_item_components.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "info/channel_statistics/earn/earn_format.h"
|
||||
#include "info/channel_statistics/earn/earn_icons.h"
|
||||
#include "lang/lang_keys.h"
|
||||
@@ -415,6 +416,8 @@ void ChooseSuggestPriceBox(
|
||||
state->price = args.value.price();
|
||||
|
||||
const auto peer = args.peer;
|
||||
[[maybe_unused]] const auto details = ComputePaymentDetails(peer, 1);
|
||||
|
||||
const auto mode = args.mode;
|
||||
const auto admin = peer->amMonoforumAdmin();
|
||||
const auto broadcast = peer->monoforumBroadcast();
|
||||
@@ -610,7 +613,7 @@ void ChooseSuggestPriceBox(
|
||||
|
||||
Ui::AddSkip(container);
|
||||
|
||||
if (args.mode == SuggestMode::Gift) {
|
||||
if (mode == SuggestMode::Gift) {
|
||||
const auto day = 86400;
|
||||
auto durations = std::vector{
|
||||
day / 4,
|
||||
@@ -715,14 +718,15 @@ void ChooseSuggestPriceBox(
|
||||
box->uiShow()->show(Box(InsufficientTonBox, usePeer, value));
|
||||
return;
|
||||
}
|
||||
} else if (!admin) {
|
||||
}
|
||||
const auto requiredStars = peer->starsPerMessageChecked()
|
||||
+ (ton ? 0 : int(base::SafeRound(value.value())));
|
||||
if (!admin && requiredStars) {
|
||||
if (!credits->loaded()) {
|
||||
state->savePending = true;
|
||||
return;
|
||||
}
|
||||
const auto required = peer->starsPerMessageChecked()
|
||||
+ int(base::SafeRound(value.value()));
|
||||
if (credits->balance() < CreditsAmount(required)) {
|
||||
if (credits->balance() < CreditsAmount(requiredStars)) {
|
||||
using namespace Settings;
|
||||
const auto done = [=](SmallBalanceResult result) {
|
||||
if (result == SmallBalanceResult::Success
|
||||
@@ -730,10 +734,13 @@ void ChooseSuggestPriceBox(
|
||||
state->save();
|
||||
}
|
||||
};
|
||||
const auto source = (mode == SuggestMode::Gift)
|
||||
? Settings::SmallBalanceSource(SmallBalanceForOffer())
|
||||
: SmallBalanceForSuggest{ usePeer->id };
|
||||
MaybeRequestBalanceIncrease(
|
||||
Main::MakeSessionShow(box->uiShow(), session),
|
||||
required,
|
||||
SmallBalanceForSuggest{ usePeer->id },
|
||||
requiredStars,
|
||||
source,
|
||||
done);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -690,12 +690,17 @@ TextWithEntities GiftServiceBox::subtitle() {
|
||||
if (left >= 3600) {
|
||||
const auto hours = left / 3600;
|
||||
const auto minutes = (left % 3600) / 60;
|
||||
time = tr::lng_action_gift_offer_time_medium(
|
||||
tr::now,
|
||||
lt_hours,
|
||||
QString::number(hours),
|
||||
lt_minutes,
|
||||
QString::number(minutes));
|
||||
time = minutes
|
||||
? tr::lng_action_gift_offer_time_medium(
|
||||
tr::now,
|
||||
lt_hours,
|
||||
QString::number(hours),
|
||||
lt_minutes,
|
||||
QString::number(minutes))
|
||||
: tr::lng_action_gift_offer_time_large(
|
||||
tr::now,
|
||||
lt_hours,
|
||||
QString::number(hours));
|
||||
} else {
|
||||
const auto minutes = left / 60;
|
||||
time = tr::lng_action_gift_offer_time_small(
|
||||
|
||||
@@ -2934,6 +2934,8 @@ void SmallBalanceBox(
|
||||
return value.recipientId
|
||||
? owner->peer(value.recipientId)->shortName()
|
||||
: QString();
|
||||
}, [](SmallBalanceForOffer) {
|
||||
return QString();
|
||||
}, [](SmallBalanceForSearch) {
|
||||
return QString();
|
||||
});
|
||||
@@ -2994,6 +2996,8 @@ void SmallBalanceBox(
|
||||
lt_channel,
|
||||
rpl::single(Ui::Text::Bold(name)),
|
||||
Ui::Text::RichLangValue)
|
||||
: v::is<SmallBalanceForOffer>(source)
|
||||
? tr::lng_credits_small_balance_for_offer(tr::rich)
|
||||
: v::is<SmallBalanceForSearch>(source)
|
||||
? tr::lng_credits_small_balance_for_search(
|
||||
Ui::Text::RichLangValue)
|
||||
|
||||
@@ -253,6 +253,8 @@ struct SmallBalanceForMessage {
|
||||
struct SmallBalanceForSuggest {
|
||||
PeerId recipientId;
|
||||
};
|
||||
struct SmallBalanceForOffer {
|
||||
};
|
||||
struct SmallBalanceForSearch {
|
||||
};
|
||||
struct SmallBalanceSource : std::variant<
|
||||
@@ -264,6 +266,7 @@ struct SmallBalanceSource : std::variant<
|
||||
SmallBalanceStarGift,
|
||||
SmallBalanceForMessage,
|
||||
SmallBalanceForSuggest,
|
||||
SmallBalanceForOffer,
|
||||
SmallBalanceForSearch> {
|
||||
using variant::variant;
|
||||
};
|
||||
|
||||
@@ -92,6 +92,9 @@ starIconEmojiLarge: IconEmoji {
|
||||
starIconEmojiInline: IconEmoji(starIconEmojiSmall) {
|
||||
padding: margins(0px, 3px, 0px, 0px);
|
||||
}
|
||||
buttonStarIconEmoji: IconEmoji(starIconEmoji) {
|
||||
padding: margins(4px, 2px, 4px, 0px);
|
||||
}
|
||||
|
||||
tonIconEmoji: IconEmoji {
|
||||
icon: icon{{ "chat/mini_ton_bold", currencyFg }};
|
||||
@@ -104,6 +107,9 @@ tonIconEmojiLarge: IconEmoji {
|
||||
tonIconEmojiInSmall: IconEmoji(tonIconEmoji) {
|
||||
padding: margins(0px, 2px, 0px, 0px);
|
||||
}
|
||||
buttonTonIconEmoji: IconEmoji(tonIconEmoji) {
|
||||
padding: margins(1px, 3px, 1px, 0px);
|
||||
}
|
||||
|
||||
creditsHistoryEntryTypeAds: icon {{ "folders/folders_channels", premiumButtonFg }};
|
||||
creditsHistorySearchPostsIcon: icon {{ "box_search", historyPeerUserpicFg }};
|
||||
|
||||
Reference in New Issue
Block a user