Add Stars/TON checks to suggestions.

This commit is contained in:
John Preston 2025-06-27 13:23:27 +04:00
parent 141fb875f9
commit c70f75b21a
13 changed files with 254 additions and 67 deletions

View file

@ -2269,6 +2269,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_todo_tasks_fallback#other" = "{count} tasks"; "lng_action_todo_tasks_fallback#other" = "{count} tasks";
"lng_action_todo_tasks_and_one" = "{tasks}, {task}"; "lng_action_todo_tasks_and_one" = "{tasks}, {task}";
"lng_action_todo_tasks_and_last" = "{tasks} and {task}"; "lng_action_todo_tasks_and_last" = "{tasks} and {task}";
"lng_action_suggest_success" = "{from} has received {amount} for publishing post.";
"lng_action_suggest_refund_user" = "User refunded the Stars so that post was deleted.";
"lng_action_suggest_refund_admin" = "Admin deleted the post early so that the price was refunded to the user.";
"lng_you_paid_stars#one" = "You paid {count} Star."; "lng_you_paid_stars#one" = "You paid {count} Star.";
"lng_you_paid_stars#other" = "You paid {count} Stars."; "lng_you_paid_stars#other" = "You paid {count} Stars.";
@ -4434,6 +4437,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_suggest_options_ton_price_about" = "Choose how many TON to pay to publish this message."; "lng_suggest_options_ton_price_about" = "Choose how many TON to pay to publish this message.";
"lng_suggest_options_date" = "Time"; "lng_suggest_options_date" = "Time";
"lng_suggest_options_date_any" = "Anytime"; "lng_suggest_options_date_any" = "Anytime";
"lng_suggest_options_date_publish" = "Publish";
"lng_suggest_options_date_now" = "Publish Now";
"lng_suggest_options_date_about" = "Select the date and time you want the message to be published."; "lng_suggest_options_date_about" = "Select the date and time you want the message to be published.";
"lng_suggest_options_offer" = "Offer {amount}"; "lng_suggest_options_offer" = "Offer {amount}";
"lng_suggest_options_update" = "Update Terms"; "lng_suggest_options_update" = "Update Terms";
@ -4473,7 +4478,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_suggest_menu_edit_time" = "Edit Time"; "lng_suggest_menu_edit_time" = "Edit Time";
"lng_suggest_decline_title" = "Decline"; "lng_suggest_decline_title" = "Decline";
"lng_suggest_decline_text" = "Do you want to decline publishing this post from {from}?"; "lng_suggest_decline_text" = "Do you want to decline publishing this post from {from}?";
"lng_suggest_decline_text_to" = "Do you want to decline publishing this post to {channel}?";
"lng_suggest_decline_reason" = "Add a reason (optional)"; "lng_suggest_decline_reason" = "Add a reason (optional)";
"lng_suggest_accept_title" = "Accept";
"lng_suggest_accept_text" = "Do you want to publish this post from {from}?";
"lng_suggest_accept_text_to" = "Do you want to publish this post to {channel}?";
"lng_suggest_accept_receive" = "{channel} will receive {amount} for publishing {date}.";
"lng_suggest_accept_receive_now" = "{channel} will receive {amount} for publishing right now.";
"lng_suggest_accept_pay" = "You will pay {amount} for publishing {date}.";
"lng_suggest_accept_pay_now" = "You will pay {amount} for publishing right now.";
"lng_suggest_accept_send" = "Send";
"lng_suggest_ton_amount#one" = "{count} TON";
"lng_suggest_ton_amount#other" = "{count} TON";
"lng_suggest_warn_title_stars" = "Stars will be lost"; "lng_suggest_warn_title_stars" = "Stars will be lost";
"lng_suggest_warn_title_ton" = "TON will be lost"; "lng_suggest_warn_title_ton" = "TON will be lost";
"lng_suggest_warn_text_stars" = "You won't receive **Stars** for the post if you delete it now. The post must remain visible for at least **24 hours** after it was published."; "lng_suggest_warn_text_stars" = "You won't receive **Stars** for the post if you delete it now. The post must remain visible for at least **24 hours** after it was published.";

View file

@ -11,7 +11,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unixtime.h" #include "base/unixtime.h"
#include "chat_helpers/message_field.h" #include "chat_helpers/message_field.h"
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "data/components/credits.h"
#include "data/data_changes.h" #include "data/data_changes.h"
#include "data/data_channel.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_saved_sublist.h" #include "data/data_saved_sublist.h"
#include "history/view/controls/history_view_suggest_options.h" #include "history/view/controls/history_view_suggest_options.h"
@ -22,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "settings/settings_credits_graphics.h"
#include "ui/boxes/choose_date_time.h" #include "ui/boxes/choose_date_time.h"
#include "ui/layers/generic_box.h" #include "ui/layers/generic_box.h"
#include "ui/boxes/confirm_box.h" #include "ui/boxes/confirm_box.h"
@ -75,6 +78,138 @@ void SendApproval(
}).send(); }).send();
} }
void ConfirmApproval(
std::shared_ptr<Main::SessionShow> show,
not_null<HistoryItem*> item,
TimeId scheduleDate = 0,
Fn<void()> accepted = nullptr) {
using Flag = MTPmessages_ToggleSuggestedPostApproval::Flag;
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
if (!suggestion
|| suggestion->accepted
|| suggestion->rejected
|| suggestion->requestId) {
return;
}
const auto id = item->fullId();
const auto price = suggestion->price;
const auto admin = item->history()->amMonoforumAdmin();
if (!admin && !price.empty()) {
const auto credits = &item->history()->session().credits();
if (price.ton()) {
if (!credits->tonLoaded()) {
credits->tonLoad();
return;
} else if (price > credits->tonBalance()) {
const auto peer = item->history()->peer;
show->show(
Box(HistoryView::InsufficientTonBox, peer, price));
return;
}
} else {
if (!credits->loaded()) {
credits->load();
return;
} else if (price > credits->balance()) {
using namespace Settings;
const auto peer = item->history()->peer;
const auto broadcast = peer->monoforumBroadcast();
const auto broadcastId = (broadcast ? broadcast : peer)->id;
const auto done = [=](SmallBalanceResult result) {
if (result == SmallBalanceResult::Success
|| result == SmallBalanceResult::Already) {
const auto item = peer->owner().message(id);
if (item) {
ConfirmApproval(
show,
item,
scheduleDate,
accepted);
}
}
};
MaybeRequestBalanceIncrease(
show,
int(base::SafeRound(price.value())),
SmallBalanceForSuggest{ broadcastId },
done);
return;
}
}
}
const auto peer = item->history()->peer;
const auto broadcast = peer->monoforumBroadcast();
const auto channelName = (broadcast ? broadcast : peer)->name();
const auto amount = Lang::FormatCreditsAmountWithCurrency(price);
const auto date = langDateTime(base::unixtime::parse(scheduleDate));
show->show(Box([=](not_null<Ui::GenericBox*> box) {
const auto callback = std::make_shared<Fn<void()>>();
auto text = admin
? tr::lng_suggest_accept_text(
tr::now,
lt_from,
Ui::Text::Bold(item->from()->shortName()),
Ui::Text::WithEntities)
: tr::lng_suggest_accept_text_to(
tr::now,
lt_channel,
Ui::Text::Bold(channelName),
Ui::Text::WithEntities);
if (price) {
text.append("\n\n").append(admin
? (scheduleDate
? tr::lng_suggest_accept_receive(
tr::now,
lt_channel,
Ui::Text::Bold(channelName),
lt_amount,
Ui::Text::Bold(amount),
lt_date,
Ui::Text::Bold(date),
Ui::Text::WithEntities)
: tr::lng_suggest_accept_receive_now(
tr::now,
lt_channel,
Ui::Text::Bold(channelName),
lt_amount,
Ui::Text::Bold(amount),
Ui::Text::WithEntities))
: (scheduleDate
? tr::lng_suggest_accept_pay(
tr::now,
lt_amount,
Ui::Text::Bold(amount),
lt_date,
Ui::Text::Bold(date),
Ui::Text::WithEntities)
: tr::lng_suggest_accept_pay_now(
tr::now,
lt_amount,
Ui::Text::Bold(amount),
Ui::Text::WithEntities)));
}
Ui::ConfirmBox(box, {
.text = text,
.confirmed = [=](Fn<void()> close) { (*callback)(); close(); },
.confirmText = tr::lng_suggest_accept_send(),
.title = tr::lng_suggest_accept_title(),
});
*callback = [=, weak = Ui::MakeWeak(box)] {
if (const auto onstack = accepted) {
onstack();
}
const auto item = show->session().data().message(id);
if (!item) {
return;
}
SendApproval(show, item, scheduleDate);
if (const auto strong = weak.data()) {
strong->closeBox();
}
};
}));
}
void SendDecline( void SendDecline(
std::shared_ptr<Main::SessionShow> show, std::shared_ptr<Main::SessionShow> show,
not_null<HistoryItem*> item, not_null<HistoryItem*> item,
@ -120,19 +255,23 @@ void RequestApprovalDate(
not_null<HistoryItem*> item) { not_null<HistoryItem*> item) {
const auto id = item->fullId(); const auto id = item->fullId();
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>(); const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
const auto done = [=](TimeId result) { const auto close = [=] {
if (const auto item = show->session().data().message(id)) {
SendApproval(show, item, result);
}
if (const auto strong = weak->data()) { if (const auto strong = weak->data()) {
strong->closeBox(); strong->closeBox();
} }
}; };
const auto done = [=](TimeId result) {
if (const auto item = show->session().data().message(id)) {
ConfirmApproval(show, item, result, close);
} else {
close();
}
};
using namespace HistoryView; using namespace HistoryView;
auto dateBox = Box(ChooseSuggestTimeBox, SuggestTimeBoxArgs{ auto dateBox = Box(ChooseSuggestTimeBox, SuggestTimeBoxArgs{
.session = &show->session(), .session = &show->session(),
.done = done, .done = done,
.mode = SuggestMode::New, .mode = SuggestMode::Publish,
}); });
*weak = dateBox.data(); *weak = dateBox.data();
show->show(std::move(dateBox)); show->show(std::move(dateBox));
@ -142,13 +281,22 @@ void RequestDeclineComment(
std::shared_ptr<Main::SessionShow> show, std::shared_ptr<Main::SessionShow> show,
not_null<HistoryItem*> item) { not_null<HistoryItem*> item) {
const auto id = item->fullId(); const auto id = item->fullId();
const auto admin = item->history()->amMonoforumAdmin();
const auto peer = item->history()->peer;
const auto broadcast = peer->monoforumBroadcast();
const auto channelName = (broadcast ? broadcast : peer)->name();
show->show(Box([=](not_null<Ui::GenericBox*> box) { show->show(Box([=](not_null<Ui::GenericBox*> box) {
const auto callback = std::make_shared<Fn<void()>>(); const auto callback = std::make_shared<Fn<void()>>();
Ui::ConfirmBox(box, { Ui::ConfirmBox(box, {
.text = tr::lng_suggest_decline_text( .text = (admin
lt_from, ? tr::lng_suggest_decline_text(
rpl::single(Ui::Text::Bold(item->from()->shortName())), lt_from,
Ui::Text::WithEntities), rpl::single(Ui::Text::Bold(item->from()->shortName())),
Ui::Text::WithEntities)
: tr::lng_suggest_decline_text_to(
lt_channel,
rpl::single(Ui::Text::Bold(channelName)),
Ui::Text::WithEntities)),
.confirmed = [=](Fn<void()> close) { (*callback)(); close(); }, .confirmed = [=](Fn<void()> close) { (*callback)(); close(); },
.confirmText = tr::lng_suggest_action_decline(), .confirmText = tr::lng_suggest_action_decline(),
.confirmStyle = &st::attentionBoxButton, .confirmStyle = &st::attentionBoxButton,
@ -264,12 +412,11 @@ void SuggestApprovalDate(
close); close);
}; };
using namespace HistoryView; using namespace HistoryView;
const auto admin = item->history()->amMonoforumAdmin();
auto dateBox = Box(ChooseSuggestTimeBox, SuggestTimeBoxArgs{ auto dateBox = Box(ChooseSuggestTimeBox, SuggestTimeBoxArgs{
.session = &show->session(), .session = &show->session(),
.done = done, .done = done,
.value = suggestion->date, .value = suggestion->date,
.mode = (admin ? SuggestMode::ChangeAdmin : SuggestMode::ChangeUser), .mode = SuggestMode::Change,
}); });
*weak = dateBox.data(); *weak = dateBox.data();
show->show(std::move(dateBox)); show->show(std::move(dateBox));
@ -318,7 +465,6 @@ void SuggestApprovalPrice(
if (!suggestion) { if (!suggestion) {
return; return;
} }
const auto admin = item->history()->amMonoforumAdmin();
using namespace HistoryView; using namespace HistoryView;
SuggestOfferForMessage(show, item, { SuggestOfferForMessage(show, item, {
.exists = uint32(1), .exists = uint32(1),
@ -326,7 +472,7 @@ void SuggestApprovalPrice(
.priceNano = uint32(suggestion->price.nano()), .priceNano = uint32(suggestion->price.nano()),
.ton = uint32(suggestion->price.ton() ? 1 : 0), .ton = uint32(suggestion->price.ton() ? 1 : 0),
.date = suggestion->date, .date = suggestion->date,
}, admin ? SuggestMode::ChangeAdmin : SuggestMode::ChangeUser); }, SuggestMode::Change);
} }
} // namespace } // namespace
@ -352,7 +498,7 @@ std::shared_ptr<ClickHandler> AcceptClickHandler(
} else if (!suggestion->date) { } else if (!suggestion->date) {
RequestApprovalDate(show, item); RequestApprovalDate(show, item);
} else { } else {
SendApproval(show, item); ConfirmApproval(show, item);
} }
}); });
} }

View file

@ -6093,11 +6093,25 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
}; };
auto prepareSuggestedPostSuccess = [&](const MTPDmessageActionSuggestedPostSuccess &data) { auto prepareSuggestedPostSuccess = [&](const MTPDmessageActionSuggestedPostSuccess &data) {
return PreparedServiceText{ { u"hello"_q } }; AssertIsDebug(); const auto price = CreditsAmountFromTL(&data.vprice());
const auto amount = Lang::FormatCreditsAmountWithCurrency(price);
auto result = PreparedServiceText();
result.links.push_back(_from->createOpenLink());
result.text = tr::lng_action_suggest_success(
tr::now,
lt_from,
Ui::Text::Link(_from->shortName(), 1),
lt_amount,
TextWithEntities{ amount },
Ui::Text::WithEntities);
return result;
}; };
auto prepareSuggestedPostRefund = [&](const MTPDmessageActionSuggestedPostRefund &data) { auto prepareSuggestedPostRefund = [&](const MTPDmessageActionSuggestedPostRefund &data) {
return PreparedServiceText{ { u"hello"_q } }; AssertIsDebug(); return PreparedServiceText{ { data.is_payer_initiated()
? tr::lng_action_suggest_refund_user(tr::now)
: tr::lng_action_suggest_refund_admin(tr::now)
} };
}; };
auto prepareConferenceCall = [&](const MTPDmessageActionConferenceCall &) -> PreparedServiceText { auto prepareConferenceCall = [&](const MTPDmessageActionConferenceCall &) -> PreparedServiceText {

View file

@ -224,7 +224,7 @@ std::optional<SendPaymentDetails> ComputePaymentDetails(
bool SuggestPaymentDataReady( bool SuggestPaymentDataReady(
not_null<PeerData*> peer, not_null<PeerData*> peer,
SuggestPostOptions suggest) { SuggestPostOptions suggest) {
if (!suggest.exists || !suggest.price()) { if (!suggest.exists || !suggest.price() || peer->amMonoforumAdmin()) {
return true; return true;
} else if (suggest.ton && !peer->session().credits().tonLoaded()) { } else if (suggest.ton && !peer->session().credits().tonLoaded()) {
peer->session().credits().tonLoad(); peer->session().credits().tonLoad();
@ -441,12 +441,13 @@ bool SendPaymentHelper::check(
PaidConfirmStyles styles) { PaidConfirmStyles styles) {
clear(); clear();
const auto admin = peer->amMonoforumAdmin();
const auto suggest = options.suggest; const auto suggest = options.suggest;
const auto starsApproved = options.starsApproved; const auto starsApproved = options.starsApproved;
const auto suggestPriceStars = suggest.ton const auto checkSuggestPriceStars = (admin || suggest.ton)
? 0 ? 0
: int(base::SafeRound(suggest.price().value())); : int(base::SafeRound(suggest.price().value()));
const auto suggestPriceTon = suggest.ton const auto checkSuggestPriceTon = (!admin && suggest.ton)
? suggest.price() ? suggest.price()
: CreditsAmount(); : CreditsAmount();
const auto details = ComputePaymentDetails(peer, messagesCount); const auto details = ComputePaymentDetails(peer, messagesCount);
@ -491,32 +492,33 @@ bool SendPaymentHelper::check(
} else if (const auto stars = details->stars; stars > starsApproved) { } else if (const auto stars = details->stars; stars > starsApproved) {
ShowSendPaidConfirm(show, peer, *details, [=] { ShowSendPaidConfirm(show, peer, *details, [=] {
resend(stars); resend(stars);
}, styles, suggestPriceStars); }, styles, checkSuggestPriceStars);
return false; return false;
} else if (suggestPriceStars } else if (checkSuggestPriceStars
&& (CreditsAmount(details->stars + suggestPriceStars) && (CreditsAmount(details->stars + checkSuggestPriceStars)
> peer->session().credits().balance())) { > peer->session().credits().balance())) {
const auto peerId = peer->id; using namespace Settings;
const auto broadcast = peer->monoforumBroadcast();
const auto broadcastId = (broadcast ? broadcast : peer)->id;
const auto forMessages = details->stars; const auto forMessages = details->stars;
const auto required = forMessages + suggestPriceStars; const auto required = forMessages + checkSuggestPriceStars;
const auto done = [=](Settings::SmallBalanceResult result) { const auto done = [=](SmallBalanceResult result) {
if (result == Settings::SmallBalanceResult::Success if (result == SmallBalanceResult::Success
|| result == Settings::SmallBalanceResult::Already) { || result == SmallBalanceResult::Already) {
resend(forMessages); resend(forMessages);
} }
}; };
using namespace Settings;
MaybeRequestBalanceIncrease( MaybeRequestBalanceIncrease(
show, show,
required, required,
SmallBalanceForSuggest{ peerId }, SmallBalanceForSuggest{ broadcastId },
done); done);
return false; return false;
} }
if (suggestPriceTon if (checkSuggestPriceTon
&& suggestPriceTon > peer->session().credits().tonBalance()) { && checkSuggestPriceTon > peer->session().credits().tonBalance()) {
show->show( using namespace HistoryView;
Box(HistoryView::InsufficientTonBox, peer, suggestPriceTon)); show->show(Box(InsufficientTonBox, peer, checkSuggestPriceTon));
return false; return false;
} }
return true; return true;

View file

@ -2275,11 +2275,7 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
} }
if (editDraft && editDraft->suggest) { if (editDraft && editDraft->suggest) {
using namespace HistoryView; using namespace HistoryView;
applySuggestOptions( applySuggestOptions(editDraft->suggest, SuggestMode::Change);
editDraft->suggest,
(_history->amMonoforumAdmin()
? SuggestMode::ChangeAdmin
: SuggestMode::ChangeUser));
} else { } else {
cancelSuggestPost(); cancelSuggestPost();
} }

View file

@ -793,7 +793,7 @@ void FieldHeader::editMessage(
_inPhotoEditOver.stop(); _inPhotoEditOver.stop();
} }
if (id && suggest) { if (id && suggest) {
applySuggestOptions(suggest, SuggestMode::ChangeAdmin); applySuggestOptions(suggest, SuggestMode::Change);
} else { } else {
cancelSuggestPost(); cancelSuggestPost();
} }

View file

@ -58,10 +58,13 @@ void ChooseSuggestTimeBox(
: (now + 86400); : (now + 86400);
const auto done = args.done; const auto done = args.done;
Ui::ChooseDateTimeBox(box, { Ui::ChooseDateTimeBox(box, {
.title = ((args.mode == SuggestMode::New) .title = ((args.mode == SuggestMode::New
|| args.mode == SuggestMode::Publish)
? tr::lng_suggest_options_date() ? tr::lng_suggest_options_date()
: tr::lng_suggest_menu_edit_time()), : tr::lng_suggest_menu_edit_time()),
.submit = ((args.mode == SuggestMode::New) .submit = ((args.mode == SuggestMode::Publish)
? tr::lng_suggest_options_date_publish()
: (args.mode == SuggestMode::New)
? tr::lng_settings_save() ? tr::lng_settings_save()
: tr::lng_suggest_options_update()), : tr::lng_suggest_options_update()),
.done = done, .done = done,
@ -70,7 +73,9 @@ void ChooseSuggestTimeBox(
.max = [=] { return now + max; }, .max = [=] { return now + max; },
}); });
box->addLeftButton(tr::lng_suggest_options_date_any(), [=] { box->addLeftButton((args.mode == SuggestMode::Publish)
? tr::lng_suggest_options_date_now()
: tr::lng_suggest_options_date_any(), [=] {
done(TimeId()); done(TimeId());
}); });
} }
@ -96,9 +101,14 @@ void ChooseSuggestPriceBox(
state->ton = (args.value.ton != 0); state->ton = (args.value.ton != 0);
const auto peer = args.peer; const auto peer = args.peer;
const auto admin = peer->amMonoforumAdmin();
const auto broadcast = peer->monoforumBroadcast();
const auto usePeer = broadcast ? broadcast : peer;
const auto session = &peer->session(); const auto session = &peer->session();
session->credits().load(); if (!admin) {
session->credits().tonLoad(); session->credits().load();
session->credits().tonLoad();
}
const auto limit = session->appConfig().suggestedPostStarsMax(); const auto limit = session->appConfig().suggestedPostStarsMax();
box->setTitle((args.mode == SuggestMode::New) box->setTitle((args.mode == SuggestMode::New)
@ -109,7 +119,7 @@ void ChooseSuggestPriceBox(
state->buttons.push_back({ state->buttons.push_back({
.text = Ui::Text::String( .text = Ui::Text::String(
st::semiboldTextStyle, st::semiboldTextStyle,
(args.mode == SuggestMode::ChangeAdmin (admin
? tr::lng_suggest_options_stars_request(tr::now) ? tr::lng_suggest_options_stars_request(tr::now)
: tr::lng_suggest_options_stars_offer(tr::now))), : tr::lng_suggest_options_stars_offer(tr::now))),
.active = !state->ton.current(), .active = !state->ton.current(),
@ -117,7 +127,7 @@ void ChooseSuggestPriceBox(
state->buttons.push_back({ state->buttons.push_back({
.text = Ui::Text::String( .text = Ui::Text::String(
st::semiboldTextStyle, st::semiboldTextStyle,
(args.mode == SuggestMode::ChangeAdmin (admin
? tr::lng_suggest_options_ton_request(tr::now) ? tr::lng_suggest_options_ton_request(tr::now)
: tr::lng_suggest_options_ton_offer(tr::now))), : tr::lng_suggest_options_ton_offer(tr::now))),
.active = state->ton.current(), .active = state->ton.current(),
@ -381,16 +391,15 @@ void ChooseSuggestPriceBox(
nanos % Ui::kNanosInOne, nanos % Ui::kNanosInOne,
ton ? CreditsType::Ton : CreditsType::Stars); ton ? CreditsType::Ton : CreditsType::Stars);
const auto credits = &session->credits(); const auto credits = &session->credits();
if (ton) { if (!admin && ton) {
if (!credits->tonLoaded()) { if (!credits->tonLoaded()) {
state->savePending = true; state->savePending = true;
return; return;
} else if (credits->tonBalance() < value) { } else if (credits->tonBalance() < value) {
box->uiShow()->show( box->uiShow()->show(Box(InsufficientTonBox, usePeer, value));
Box(InsufficientTonBox, peer, value));
return; return;
} }
} else { } else if (!admin) {
if (!credits->loaded()) { if (!credits->loaded()) {
state->savePending = true; state->savePending = true;
return; return;
@ -408,7 +417,7 @@ void ChooseSuggestPriceBox(
MaybeRequestBalanceIncrease( MaybeRequestBalanceIncrease(
Main::MakeSessionShow(box->uiShow(), session), Main::MakeSessionShow(box->uiShow(), session),
required, required,
SmallBalanceForSuggest{ peer->id }, SmallBalanceForSuggest{ usePeer->id },
done); done);
return; return;
} }

View file

@ -29,8 +29,8 @@ namespace HistoryView {
enum class SuggestMode { enum class SuggestMode {
New, New,
ChangeUser, Change,
ChangeAdmin, Publish,
}; };
struct SuggestTimeBoxArgs { struct SuggestTimeBoxArgs {

View file

@ -742,6 +742,8 @@ TextState Service::textState(QPoint point, StateRequest request) const {
result.link = done->lnk; result.link = done->lnk;
} else if (const auto append = item->Get<HistoryServiceTodoAppendTasks>()) { } else if (const auto append = item->Get<HistoryServiceTodoAppendTasks>()) {
result.link = append->lnk; result.link = append->lnk;
} else if (const auto finish = item->Get<HistoryServiceSuggestFinish>()) {
result.link = finish->lnk;
} else if (media && data()->showSimilarChannels()) { } else if (media && data()->showSimilarChannels()) {
result = media->textState(mediaPoint, request); result = media->textState(mediaPoint, request);
} }

View file

@ -70,8 +70,8 @@ QSize PremiumGift::size() {
TextWithEntities PremiumGift::title() { TextWithEntities PremiumGift::title() {
using namespace Ui::Text; using namespace Ui::Text;
if (tonGift()) { if (tonGift()) {
AssertIsDebug(); return { Lang::FormatCreditsAmountWithCurrency(
return { QString::number(_data.count / 1'000'000'000LL) + u" TON"_q }; CreditsAmount(0, _data.count, CreditsType::Ton)) };
} else if (starGift()) { } else if (starGift()) {
const auto peer = _parent->history()->peer; const auto peer = _parent->history()->peer;
return peer->isSelf() return peer->isSelf()

View file

@ -214,12 +214,8 @@ auto GenerateSuggestDecisionMedia(
? st::chatSuggestInfoMiddleMargin ? st::chatSuggestInfoMiddleMargin
: st::chatSuggestInfoLastMargin)); : st::chatSuggestInfoLastMargin));
if (price) { if (price) {
const auto amount = Ui::Text::Bold(price.ton() const auto amount = Ui::Text::Bold(
? (Lang::FormatCreditsAmountDecimal(price) + u" TON"_q) Lang::FormatCreditsAmountWithCurrency(price));
: tr::lng_prize_credits_amount(
tr::now,
lt_count_decimal,
price.value()));
pushText( pushText(
TextWithEntities( TextWithEntities(
).append(Emoji(kMoney)).append(' ').append( ).append(Emoji(kMoney)).append(' ').append(
@ -334,12 +330,7 @@ auto GenerateSuggestRequestMedia(
: tr::lng_suggest_action_price_label)(tr::now), : tr::lng_suggest_action_price_label)(tr::now),
Ui::Text::Bold(!suggest->price Ui::Text::Bold(!suggest->price
? tr::lng_suggest_action_price_free(tr::now) ? tr::lng_suggest_action_price_free(tr::now)
: suggest->price.ton() AssertIsDebug() : Lang::FormatCreditsAmountWithCurrency(suggest->price)),
? (Lang::FormatCreditsAmountDecimal(suggest->price) + u" TON"_q)
: tr::lng_prize_credits_amount(
tr::now,
lt_count,
suggest->price.value())),
}); });
entries.push_back({ entries.push_back({
((changes && changes->date) ((changes && changes->date)

View file

@ -968,6 +968,15 @@ QString FormatCreditsAmountRounded(CreditsAmount amount) {
return FormatExactCountDecimal(base::SafeRound(value * 100.) / 100.); return FormatExactCountDecimal(base::SafeRound(value * 100.) / 100.);
} }
QString FormatCreditsAmountWithCurrency(CreditsAmount amount) {
return (amount.ton()
? tr::lng_suggest_ton_amount
: tr::lng_prize_credits_amount)(
tr::now,
lt_count_decimal,
amount.value());
}
PluralResult Plural( PluralResult Plural(
ushort keyBase, ushort keyBase,
float64 value, float64 value,

View file

@ -34,6 +34,8 @@ struct ShortenedCount {
[[nodiscard]] QString FormatCreditsAmountDecimal(CreditsAmount amount); [[nodiscard]] QString FormatCreditsAmountDecimal(CreditsAmount amount);
[[nodiscard]] QString FormatCreditsAmountRounded(CreditsAmount amount); [[nodiscard]] QString FormatCreditsAmountRounded(CreditsAmount amount);
[[nodiscard]] QString FormatCreditsAmountWithCurrency(CreditsAmount amount);
struct PluralResult { struct PluralResult {
int keyShift = 0; int keyShift = 0;
QString replacement; QString replacement;