Process offers with accept / reject.

This commit is contained in:
John Preston
2025-11-28 18:21:50 +04:00
parent 1e89ee4e50
commit 31ea4cfe80
5 changed files with 197 additions and 3 deletions
+7
View File
@@ -2291,8 +2291,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_proximity_distance_km#other" = "{count} km";
"lng_action_webview_data_done" = "Data from the \"{text}\" button was transferred to the bot.";
"lng_action_gift_received" = "{user} sent you a gift for {cost}";
"lng_action_gift_received_sold" = "{user} sold you a gift for {cost}";
"lng_action_gift_unique_received" = "{user} sent you a unique collectible item";
"lng_action_gift_sent" = "You sent a gift for {cost}";
"lng_action_gift_sent_sold" = "You sold a gift for {cost}";
"lng_action_gift_unique_sent" = "You sent a unique collectible item";
"lng_action_gift_upgraded" = "{user} turned the gift from you into a unique collectible";
"lng_action_gift_upgraded_channel" = "{user} turned this gift to {channel} into a unique collectible";
@@ -3959,6 +3961,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_offer_duration" = "Offer Duration";
"lng_gift_offer_duration_about" = "Choose how long {user} can accept your offer. When the time expires, the amount will be refunded.";
"lng_gift_offer_cost_button" = "Offer {cost}";
"lng_gift_offer_confirm_reject" = "Do you want to reject the offer?";
"lng_gift_offer_confirm_accept" = "Do you want to sell {name} to {user} for {cost}?";
"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_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";
+23 -2
View File
@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "base/unixtime.h"
#include "boxes/transfer_gift_box.h"
#include "chat_helpers/message_field.h"
#include "core/click_handler_types.h"
#include "data/components/credits.h"
@@ -504,6 +505,20 @@ void SuggestApprovalPrice(
}, SuggestMode::Change);
}
void ConfirmGiftSaleAccept(
not_null<Window::SessionController*> window,
not_null<HistoryItem*> item,
not_null<HistoryMessageSuggestion*> suggestion) {
ShowGiftSaleAcceptBox(window, item, suggestion);
}
void ConfirmGiftSaleDecline(
not_null<Window::SessionController*> window,
not_null<HistoryItem*> item,
not_null<HistoryMessageSuggestion*> suggestion) {
ShowGiftSaleRejectBox(window, item, suggestion);
}
} // namespace
std::shared_ptr<ClickHandler> AcceptClickHandler(
@@ -524,6 +539,8 @@ std::shared_ptr<ClickHandler> AcceptClickHandler(
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (!suggestion) {
return;
} else if (suggestion->gift) {
ConfirmGiftSaleAccept(controller, item, suggestion);
} else if (!suggestion->date) {
RequestApprovalDate(show, item);
} else {
@@ -546,8 +563,12 @@ std::shared_ptr<ClickHandler> DeclineClickHandler(
if (!item) {
return;
}
RequestDeclineComment(controller->uiShow(), item);
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (suggestion && suggestion->gift) {
ConfirmGiftSaleDecline(controller, item, suggestion);
} else {
RequestDeclineComment(controller->uiShow(), item);
}
});
}
@@ -24,7 +24,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_star_gift.h"
#include "data/data_thread.h"
#include "data/data_user.h"
#include "history/history.h"
#include "history/history_item.h"
#include "history/history_item_components.h"
#include "lang/lang_keys.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
#include "payments/payments_checkout_process.h"
#include "ui/boxes/confirm_box.h"
@@ -492,6 +496,26 @@ void TransferGift(
}
}
void ResolveGiftSaleOffer(
not_null<Window::SessionController*> window,
MsgId id,
bool accept,
Fn<void(bool)> done) {
using Flag = MTPpayments_ResolveStarGiftOffer::Flag;
const auto session = &window->session();
const auto show = window->uiShow();
session->api().request(MTPpayments_ResolveStarGiftOffer(
MTP_flags(accept ? Flag() : Flag::f_decline),
MTP_int(id.bare)
)).done([=](const MTPUpdates &result) {
session->api().applyUpdates(result);
done(true);
}).fail([=](const MTP::Error &error) {
show->showToast(error.type());
done(false);
}).send();
}
void BuyResaleGift(
std::shared_ptr<ChatHelpers::Show> show,
not_null<PeerData*> to,
@@ -687,6 +711,122 @@ void ShowTransferGiftBox(
Ui::LayerOption::KeepOther);
}
void ShowGiftSaleAcceptBox(
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item,
not_null<HistoryMessageSuggestion*> suggestion) {
const auto id = item->id;
const auto peer = item->history()->peer;
const auto gift = suggestion->gift;
const auto price = suggestion->price;
const auto &appConfig = controller->session().appConfig();
const auto starsThousandths = appConfig.giftResaleStarsThousandths();
const auto nanoTonThousandths = appConfig.giftResaleNanoTonThousandths();
controller->show(Box([=](not_null<Ui::GenericBox*> box) {
auto button = tr::lng_gift_offer_sell_for(
lt_price,
rpl::single(Ui::Text::IconEmoji(
&st::starIconEmoji
).append(Lang::FormatCreditsAmountDecimal(
price
))),
tr::marked);
struct State {
bool sent = false;
};
const auto state = std::make_shared<State>();
auto callback = [=] {
if (state->sent) {
return;
}
state->sent = true;
const auto weak = base::make_weak(controller);
const auto weakBox = base::make_weak(box);
ResolveGiftSaleOffer(controller, id, true, [=](bool ok) {
state->sent = false;
if (ok) {
if (const auto strong = weak.get()) {
strong->showPeerHistory(peer->id);
}
if (const auto strong = weakBox.get()) {
strong->closeBox();
}
}
});
};
const auto receive = price.ton()
? ((price.value() * nanoTonThousandths) / 1000.)
: ((int64(price.value()) * starsThousandths) / 1000);
box->addRow(
CreateGiftTransfer(box->verticalLayout(), gift, peer),
QMargins(0, st::boxPadding.top(), 0, 0));
Ui::ConfirmBox(box, {
.text = tr::lng_gift_offer_confirm_accept(
tr::now,
lt_name,
tr::bold(UniqueGiftName(*gift)),
lt_user,
tr::bold(peer->shortName()),
lt_cost,
tr::bold(PrepareCreditsAmountText(price)),
tr::marked
).append(u"\n\n"_q).append(tr::lng_gift_offer_you_get(
tr::now,
lt_cost,
tr::bold(price.stars()
? tr::lng_action_gift_for_stars(
tr::now,
lt_count_decimal,
receive)
: tr::lng_action_gift_for_ton(
tr::now,
lt_count_decimal,
receive)),
tr::marked)),
.confirmed = std::move(callback),
.confirmText = std::move(button),
});
const auto show = controller->uiShow();
AddTransferGiftTable(show, box->verticalLayout(), gift);
}));
}
void ShowGiftSaleRejectBox(
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item,
not_null<HistoryMessageSuggestion*> suggestion) {
struct State {
bool sent = false;
};
const auto id = item->id;
const auto state = std::make_shared<State>();
auto callback = [=](Fn<void()> close) {
if (state->sent) {
return;
}
state->sent = true;
const auto weak = base::make_weak(controller);
ResolveGiftSaleOffer(controller, id, false, [=](bool ok) {
state->sent = false;
if (ok) {
close();
}
});
};
controller->show(Ui::MakeConfirmBox({
.text = tr::lng_gift_offer_confirm_reject(),
.confirmed = std::move(callback),
.confirmText = tr::lng_action_gift_offer_decline(),
}));
}
void SetThemeFromUniqueGift(
not_null<Window::SessionController*> window,
std::shared_ptr<Data::UniqueGift> unique) {
@@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
struct HistoryMessageSuggestion;
namespace Window {
class SessionController;
} // namespace Window
@@ -36,6 +38,15 @@ void ShowTransferGiftBox(
std::shared_ptr<Data::UniqueGift> gift,
Data::SavedStarGiftId savedId);
void ShowGiftSaleAcceptBox(
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item,
not_null<HistoryMessageSuggestion*> suggestion);
void ShowGiftSaleRejectBox(
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item,
not_null<HistoryMessageSuggestion*> suggestion);
void ShowBuyResaleGiftBox(
std::shared_ptr<ChatHelpers::Show> show,
std::shared_ptr<Data::UniqueGift> gift,
+16 -1
View File
@@ -6202,6 +6202,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
auto result = PreparedServiceText();
const auto isSelf = _from->isSelf();
const auto resale = CreditsAmountFromTL(action.vresale_amount());
const auto fromOffer = action.is_from_offer();
const auto resaleCost = !resale
? tr::marked()
: tr::marked(PrepareCreditsAmountText(resale));
@@ -6283,7 +6284,21 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
if (!resale || !isSelf) {
result.links.push_back(from->createOpenLink());
}
result.text = resale
result.text = fromOffer
? (isSelf
? tr::lng_action_gift_sent_sold(
tr::now,
lt_cost,
resaleCost,
Ui::Text::WithEntities)
: tr::lng_action_gift_received_sold(
tr::now,
lt_user,
Ui::Text::Link(peer->shortName(), 1), // Link 1.
lt_cost,
resaleCost,
Ui::Text::WithEntities))
: resale
? (isSelf
? tr::lng_action_gift_sent(
tr::now,