mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Allow sending paid messages.
This commit is contained in:
parent
45c7829cd8
commit
bbc14ba74f
25 changed files with 497 additions and 143 deletions
|
@ -2789,6 +2789,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_credits_small_balance_reaction" = "Buy **Stars** and send them to {channel} to support their posts.";
|
"lng_credits_small_balance_reaction" = "Buy **Stars** and send them to {channel} to support their posts.";
|
||||||
"lng_credits_small_balance_subscribe" = "Buy **Stars** and subscribe to **{channel}** and other channels.";
|
"lng_credits_small_balance_subscribe" = "Buy **Stars** and subscribe to **{channel}** and other channels.";
|
||||||
"lng_credits_small_balance_star_gift" = "Buy **Stars** to send gifts to {user} and other contacts.";
|
"lng_credits_small_balance_star_gift" = "Buy **Stars** to send gifts to {user} and other contacts.";
|
||||||
|
"lng_credits_small_balance_for_message" = "Buy **Stars** to send messages to {user}.";
|
||||||
"lng_credits_small_balance_fallback" = "Buy **Stars** to unlock content and services on Telegram.";
|
"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.";
|
"lng_credits_purchase_blocked" = "Sorry, you can't purchase this item with Telegram Stars.";
|
||||||
"lng_credits_enough" = "You have enough stars at the moment. {link}";
|
"lng_credits_enough" = "You have enough stars at the moment. {link}";
|
||||||
|
@ -4821,8 +4822,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_slowmode_seconds#one" = "{count} second";
|
"lng_slowmode_seconds#one" = "{count} second";
|
||||||
"lng_slowmode_seconds#other" = "{count} seconds";
|
"lng_slowmode_seconds#other" = "{count} seconds";
|
||||||
|
|
||||||
"lng_payment_for_message#one" = "Pay {star}{count} for 1 Message";
|
"lng_payment_for_message" = "Pay {cost} for 1 Message";
|
||||||
"lng_payment_for_message#other" = "Pay {star}{count} for 1 Message";
|
|
||||||
"lng_payment_confirm_title" = "Confirm payment";
|
"lng_payment_confirm_title" = "Confirm payment";
|
||||||
"lng_payment_confirm_text#one" = "{name} charges **{count}** Star per message.";
|
"lng_payment_confirm_text#one" = "{name} charges **{count}** Star per message.";
|
||||||
"lng_payment_confirm_text#other" = "{name} charges **{count}** Stars per message.";
|
"lng_payment_confirm_text#other" = "{name} charges **{count}** Stars per message.";
|
||||||
|
@ -4830,8 +4830,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_payment_confirm_sure#other" = "Would you like to pay **{count}** Stars to send one message?";
|
"lng_payment_confirm_sure#other" = "Would you like to pay **{count}** Stars to send one message?";
|
||||||
"lng_payment_confirm_dont_ask" = "Don't ask me again";
|
"lng_payment_confirm_dont_ask" = "Don't ask me again";
|
||||||
"lng_payment_confirm_button" = "Pay for 1 Message";
|
"lng_payment_confirm_button" = "Pay for 1 Message";
|
||||||
"lng_payment_bar_text#one" = "{name} must pay {star}{count} for each message to you.";
|
"lng_payment_bar_text" = "{name} must pay {cost} for each message to you.";
|
||||||
"lng_payment_bar_text#other" = "{name} must pay {star}{count} for each message to you.";
|
|
||||||
"lng_payment_bar_button" = "Remove Fee";
|
"lng_payment_bar_button" = "Remove Fee";
|
||||||
"lng_payment_refund_title" = "Remove Fee";
|
"lng_payment_refund_title" = "Remove Fee";
|
||||||
"lng_payment_refund_text" = "Are you sure you want to allow {name} to message you for free?";
|
"lng_payment_refund_text" = "Are you sure you want to allow {name} to message you for free?";
|
||||||
|
|
|
@ -21,7 +21,6 @@ inline constexpr auto kScheduledUntilOnlineTimestamp = TimeId(0x7FFFFFFE);
|
||||||
|
|
||||||
struct SendOptions {
|
struct SendOptions {
|
||||||
uint64 price = 0;
|
uint64 price = 0;
|
||||||
int64 paidByStars = 0;
|
|
||||||
PeerData *sendAs = nullptr;
|
PeerData *sendAs = nullptr;
|
||||||
TimeId scheduled = 0;
|
TimeId scheduled = 0;
|
||||||
BusinessShortcutId shortcutId = 0;
|
BusinessShortcutId shortcutId = 0;
|
||||||
|
|
|
@ -59,6 +59,7 @@ void Polls::create(
|
||||||
history->startSavingCloudDraft(topicRootId);
|
history->startSavingCloudDraft(topicRootId);
|
||||||
}
|
}
|
||||||
const auto silentPost = ShouldSendSilent(peer, action.options);
|
const auto silentPost = ShouldSendSilent(peer, action.options);
|
||||||
|
const auto starsPaid = peer->commitStarsForMessage();
|
||||||
if (silentPost) {
|
if (silentPost) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +72,7 @@ void Polls::create(
|
||||||
if (action.options.effectId) {
|
if (action.options.effectId) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||||
}
|
}
|
||||||
if (action.options.paidByStars) {
|
if (starsPaid) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||||
}
|
}
|
||||||
const auto sendAs = action.options.sendAs;
|
const auto sendAs = action.options.sendAs;
|
||||||
|
@ -97,7 +98,7 @@ void Polls::create(
|
||||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||||
Data::ShortcutIdToMTP(_session, action.options.shortcutId),
|
Data::ShortcutIdToMTP(_session, action.options.shortcutId),
|
||||||
MTP_long(action.options.effectId),
|
MTP_long(action.options.effectId),
|
||||||
MTP_long(action.options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||||
if (clearCloudDraft) {
|
if (clearCloudDraft) {
|
||||||
history->finishSavingCloudDraft(
|
history->finishSavingCloudDraft(
|
||||||
|
|
|
@ -95,6 +95,7 @@ void SendSimpleMedia(SendAction action, MTPInputMedia inputMedia) {
|
||||||
const auto messagePostAuthor = peer->isBroadcast()
|
const auto messagePostAuthor = peer->isBroadcast()
|
||||||
? session->user()->name()
|
? session->user()->name()
|
||||||
: QString();
|
: QString();
|
||||||
|
const auto starsPaid = peer->commitStarsForMessage();
|
||||||
|
|
||||||
if (action.options.scheduled) {
|
if (action.options.scheduled) {
|
||||||
flags |= MessageFlag::IsOrWasScheduled;
|
flags |= MessageFlag::IsOrWasScheduled;
|
||||||
|
@ -111,7 +112,7 @@ void SendSimpleMedia(SendAction action, MTPInputMedia inputMedia) {
|
||||||
flags |= MessageFlag::InvertMedia;
|
flags |= MessageFlag::InvertMedia;
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||||
}
|
}
|
||||||
if (action.options.paidByStars) {
|
if (starsPaid) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +134,7 @@ void SendSimpleMedia(SendAction action, MTPInputMedia inputMedia) {
|
||||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||||
Data::ShortcutIdToMTP(session, action.options.shortcutId),
|
Data::ShortcutIdToMTP(session, action.options.shortcutId),
|
||||||
MTP_long(action.options.effectId),
|
MTP_long(action.options.effectId),
|
||||||
MTP_long(action.options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||||
api->sendMessageFail(error, peer, randomId);
|
api->sendMessageFail(error, peer, randomId);
|
||||||
|
@ -194,6 +195,7 @@ void SendExistingMedia(
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
||||||
}
|
}
|
||||||
const auto captionText = caption.text;
|
const auto captionText = caption.text;
|
||||||
|
const auto starsPaid = peer->commitStarsForMessage();
|
||||||
|
|
||||||
if (action.options.scheduled) {
|
if (action.options.scheduled) {
|
||||||
flags |= MessageFlag::IsOrWasScheduled;
|
flags |= MessageFlag::IsOrWasScheduled;
|
||||||
|
@ -210,7 +212,7 @@ void SendExistingMedia(
|
||||||
flags |= MessageFlag::InvertMedia;
|
flags |= MessageFlag::InvertMedia;
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||||
}
|
}
|
||||||
if (action.options.paidByStars) {
|
if (starsPaid) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +250,7 @@ void SendExistingMedia(
|
||||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||||
Data::ShortcutIdToMTP(session, action.options.shortcutId),
|
Data::ShortcutIdToMTP(session, action.options.shortcutId),
|
||||||
MTP_long(action.options.effectId),
|
MTP_long(action.options.effectId),
|
||||||
MTP_long(action.options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||||
if (error.code() == 400
|
if (error.code() == 400
|
||||||
|
@ -388,7 +390,8 @@ bool SendDice(MessageToSend &message) {
|
||||||
flags |= MessageFlag::InvertMedia;
|
flags |= MessageFlag::InvertMedia;
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||||
}
|
}
|
||||||
if (action.options.paidByStars) {
|
const auto starsPaid = peer->commitStarsForMessage();
|
||||||
|
if (starsPaid) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +426,7 @@ bool SendDice(MessageToSend &message) {
|
||||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||||
Data::ShortcutIdToMTP(session, action.options.shortcutId),
|
Data::ShortcutIdToMTP(session, action.options.shortcutId),
|
||||||
MTP_long(action.options.effectId),
|
MTP_long(action.options.effectId),
|
||||||
MTP_long(action.options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||||
api->sendMessageFail(error, peer, randomId, newId);
|
api->sendMessageFail(error, peer, randomId, newId);
|
||||||
|
|
|
@ -3883,7 +3883,8 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_effect;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_effect;
|
||||||
mediaFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
mediaFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||||
}
|
}
|
||||||
if (action.options.paidByStars) {
|
const auto starsPaid = peer->commitStarsForMessage();
|
||||||
|
if (starsPaid) {
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_allow_paid_stars;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_allow_paid_stars;
|
||||||
mediaFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
mediaFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||||
}
|
}
|
||||||
|
@ -3943,7 +3944,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||||
mtpShortcut,
|
mtpShortcut,
|
||||||
MTP_long(action.options.effectId),
|
MTP_long(action.options.effectId),
|
||||||
MTP_long(action.options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
), done, fail);
|
), done, fail);
|
||||||
} else {
|
} else {
|
||||||
histories.sendPreparedMessage(
|
histories.sendPreparedMessage(
|
||||||
|
@ -3962,7 +3963,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||||
mtpShortcut,
|
mtpShortcut,
|
||||||
MTP_long(action.options.effectId),
|
MTP_long(action.options.effectId),
|
||||||
MTP_long(action.options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
), done, fail);
|
), done, fail);
|
||||||
}
|
}
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
|
@ -4059,7 +4060,8 @@ void ApiWrap::sendInlineResult(
|
||||||
if (action.options.hideViaBot) {
|
if (action.options.hideViaBot) {
|
||||||
sendFlags |= SendFlag::f_hide_via;
|
sendFlags |= SendFlag::f_hide_via;
|
||||||
}
|
}
|
||||||
if (action.options.paidByStars) {
|
const auto starsPaid = peer->commitStarsForMessage();
|
||||||
|
if (starsPaid) {
|
||||||
sendFlags |= SendFlag::f_allow_paid_stars;
|
sendFlags |= SendFlag::f_allow_paid_stars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4100,7 +4102,7 @@ void ApiWrap::sendInlineResult(
|
||||||
MTP_int(action.options.scheduled),
|
MTP_int(action.options.scheduled),
|
||||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||||
Data::ShortcutIdToMTP(_session, action.options.shortcutId),
|
Data::ShortcutIdToMTP(_session, action.options.shortcutId),
|
||||||
MTP_long(action.options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||||
history->finishSavingCloudDraft(
|
history->finishSavingCloudDraft(
|
||||||
topicRootId,
|
topicRootId,
|
||||||
|
@ -4232,6 +4234,7 @@ void ApiWrap::sendMediaWithRandomId(
|
||||||
Fn<void(bool)> done) {
|
Fn<void(bool)> done) {
|
||||||
const auto history = item->history();
|
const auto history = item->history();
|
||||||
const auto replyTo = item->replyTo();
|
const auto replyTo = item->replyTo();
|
||||||
|
const auto peer = history->peer;
|
||||||
|
|
||||||
auto caption = item->originalText();
|
auto caption = item->originalText();
|
||||||
TextUtilities::Trim(caption);
|
TextUtilities::Trim(caption);
|
||||||
|
@ -4241,6 +4244,7 @@ void ApiWrap::sendMediaWithRandomId(
|
||||||
Api::ConvertOption::SkipLocal);
|
Api::ConvertOption::SkipLocal);
|
||||||
|
|
||||||
const auto updateRecentStickers = Api::HasAttachedStickers(media);
|
const auto updateRecentStickers = Api::HasAttachedStickers(media);
|
||||||
|
const auto starsPaid = peer->commitStarsForMessage();
|
||||||
|
|
||||||
using Flag = MTPmessages_SendMedia::Flag;
|
using Flag = MTPmessages_SendMedia::Flag;
|
||||||
const auto flags = Flag(0)
|
const auto flags = Flag(0)
|
||||||
|
@ -4254,10 +4258,9 @@ void ApiWrap::sendMediaWithRandomId(
|
||||||
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0))
|
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0))
|
||||||
| (options.effectId ? Flag::f_effect : Flag(0))
|
| (options.effectId ? Flag::f_effect : Flag(0))
|
||||||
| (options.invertCaption ? Flag::f_invert_media : Flag(0))
|
| (options.invertCaption ? Flag::f_invert_media : Flag(0))
|
||||||
| (options.paidByStars ? Flag::f_allow_paid_stars : Flag(0));
|
| (starsPaid ? Flag::f_allow_paid_stars : Flag(0));
|
||||||
|
|
||||||
auto &histories = history->owner().histories();
|
auto &histories = history->owner().histories();
|
||||||
const auto peer = history->peer;
|
|
||||||
const auto itemId = item->fullId();
|
const auto itemId = item->fullId();
|
||||||
histories.sendPreparedMessage(
|
histories.sendPreparedMessage(
|
||||||
history,
|
history,
|
||||||
|
@ -4282,7 +4285,7 @@ void ApiWrap::sendMediaWithRandomId(
|
||||||
(options.sendAs ? options.sendAs->input : MTP_inputPeerEmpty()),
|
(options.sendAs ? options.sendAs->input : MTP_inputPeerEmpty()),
|
||||||
Data::ShortcutIdToMTP(_session, options.shortcutId),
|
Data::ShortcutIdToMTP(_session, options.shortcutId),
|
||||||
MTP_long(options.effectId),
|
MTP_long(options.effectId),
|
||||||
MTP_long(options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||||
if (done) done(true);
|
if (done) done(true);
|
||||||
if (updateRecentStickers) {
|
if (updateRecentStickers) {
|
||||||
|
@ -4311,6 +4314,7 @@ void ApiWrap::sendMultiPaidMedia(
|
||||||
|
|
||||||
const auto history = item->history();
|
const auto history = item->history();
|
||||||
const auto replyTo = item->replyTo();
|
const auto replyTo = item->replyTo();
|
||||||
|
const auto peer = history->peer;
|
||||||
|
|
||||||
auto caption = item->originalText();
|
auto caption = item->originalText();
|
||||||
TextUtilities::Trim(caption);
|
TextUtilities::Trim(caption);
|
||||||
|
@ -4318,6 +4322,7 @@ void ApiWrap::sendMultiPaidMedia(
|
||||||
_session,
|
_session,
|
||||||
caption.entities,
|
caption.entities,
|
||||||
Api::ConvertOption::SkipLocal);
|
Api::ConvertOption::SkipLocal);
|
||||||
|
const auto starsPaid = peer->commitStarsForMessage();
|
||||||
|
|
||||||
using Flag = MTPmessages_SendMedia::Flag;
|
using Flag = MTPmessages_SendMedia::Flag;
|
||||||
const auto flags = Flag(0)
|
const auto flags = Flag(0)
|
||||||
|
@ -4331,10 +4336,9 @@ void ApiWrap::sendMultiPaidMedia(
|
||||||
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0))
|
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0))
|
||||||
| (options.effectId ? Flag::f_effect : Flag(0))
|
| (options.effectId ? Flag::f_effect : Flag(0))
|
||||||
| (options.invertCaption ? Flag::f_invert_media : Flag(0))
|
| (options.invertCaption ? Flag::f_invert_media : Flag(0))
|
||||||
| (options.paidByStars ? Flag::f_allow_paid_stars : Flag(0));
|
| (starsPaid ? Flag::f_allow_paid_stars : Flag(0));
|
||||||
|
|
||||||
auto &histories = history->owner().histories();
|
auto &histories = history->owner().histories();
|
||||||
const auto peer = history->peer;
|
|
||||||
const auto itemId = item->fullId();
|
const auto itemId = item->fullId();
|
||||||
album->sent = true;
|
album->sent = true;
|
||||||
histories.sendPreparedMessage(
|
histories.sendPreparedMessage(
|
||||||
|
@ -4358,7 +4362,7 @@ void ApiWrap::sendMultiPaidMedia(
|
||||||
(options.sendAs ? options.sendAs->input : MTP_inputPeerEmpty()),
|
(options.sendAs ? options.sendAs->input : MTP_inputPeerEmpty()),
|
||||||
Data::ShortcutIdToMTP(_session, options.shortcutId),
|
Data::ShortcutIdToMTP(_session, options.shortcutId),
|
||||||
MTP_long(options.effectId),
|
MTP_long(options.effectId),
|
||||||
MTP_long(options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||||
if (const auto album = _sendingAlbums.take(groupId)) {
|
if (const auto album = _sendingAlbums.take(groupId)) {
|
||||||
const auto copy = (*album)->items;
|
const auto copy = (*album)->items;
|
||||||
|
|
|
@ -1571,6 +1571,7 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
|
||||||
: topicRootId;
|
: topicRootId;
|
||||||
const auto peer = thread->peer();
|
const auto peer = thread->peer();
|
||||||
const auto threadHistory = thread->owningHistory();
|
const auto threadHistory = thread->owningHistory();
|
||||||
|
const auto starsPaid = peer->commitStarsForMessage();
|
||||||
histories.sendRequest(threadHistory, requestType, [=](
|
histories.sendRequest(threadHistory, requestType, [=](
|
||||||
Fn<void()> finish) {
|
Fn<void()> finish) {
|
||||||
const auto session = &threadHistory->session();
|
const auto session = &threadHistory->session();
|
||||||
|
@ -1583,9 +1584,7 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
|
||||||
| (options.shortcutId
|
| (options.shortcutId
|
||||||
? Flag::f_quick_reply_shortcut
|
? Flag::f_quick_reply_shortcut
|
||||||
: Flag(0))
|
: Flag(0))
|
||||||
| (options.paidByStars
|
| (starsPaid ? Flag::f_allow_paid_stars : Flag());
|
||||||
? Flag::f_allow_paid_stars
|
|
||||||
: Flag());
|
|
||||||
threadHistory->sendRequestId = api.request(
|
threadHistory->sendRequestId = api.request(
|
||||||
MTPmessages_ForwardMessages(
|
MTPmessages_ForwardMessages(
|
||||||
MTP_flags(sendFlags),
|
MTP_flags(sendFlags),
|
||||||
|
@ -1598,7 +1597,7 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
|
||||||
MTP_inputPeerEmpty(), // send_as
|
MTP_inputPeerEmpty(), // send_as
|
||||||
Data::ShortcutIdToMTP(session, options.shortcutId),
|
Data::ShortcutIdToMTP(session, options.shortcutId),
|
||||||
MTP_int(videoTimestamp.value_or(0)),
|
MTP_int(videoTimestamp.value_or(0)),
|
||||||
MTP_long(options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
)).done([=](const MTPUpdates &updates, mtpRequestId reqId) {
|
)).done([=](const MTPUpdates &updates, mtpRequestId reqId) {
|
||||||
threadHistory->session().api().applyUpdates(updates);
|
threadHistory->session().api().applyUpdates(updates);
|
||||||
state->requests.remove(reqId);
|
state->requests.remove(reqId);
|
||||||
|
|
|
@ -855,6 +855,10 @@ historyComposeButton: FlatButton {
|
||||||
color: historyComposeButtonBgRipple;
|
color: historyComposeButtonBgRipple;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
historyComposeButtonText: FlatLabel(defaultFlatLabel) {
|
||||||
|
style: semiboldTextStyle;
|
||||||
|
textFg: windowActiveTextFg;
|
||||||
|
}
|
||||||
historyGiftToChannel: IconButton(defaultIconButton) {
|
historyGiftToChannel: IconButton(defaultIconButton) {
|
||||||
width: 46px;
|
width: 46px;
|
||||||
height: 46px;
|
height: 46px;
|
||||||
|
|
|
@ -205,13 +205,13 @@ void BotGameUrlClickHandler::onClick(ClickContext context) const {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
if (_bot->isVerified()
|
if (_bot->isVerified()
|
||||||
|| _bot->session().local().isBotTrustedOpenGame(_bot->id)) {
|
|| _bot->session().local().isPeerTrustedOpenGame(_bot->id)) {
|
||||||
openGame();
|
openGame();
|
||||||
} else {
|
} else {
|
||||||
if (const auto controller = my.sessionWindow.get()) {
|
if (const auto controller = my.sessionWindow.get()) {
|
||||||
const auto callback = [=, bot = _bot](Fn<void()> close) {
|
const auto callback = [=, bot = _bot](Fn<void()> close) {
|
||||||
close();
|
close();
|
||||||
bot->session().local().markBotTrustedOpenGame(bot->id);
|
bot->session().local().markPeerTrustedOpenGame(bot->id);
|
||||||
openGame();
|
openGame();
|
||||||
};
|
};
|
||||||
controller->show(Ui::MakeConfirmBox({
|
controller->show(Ui::MakeConfirmBox({
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
|
|
||||||
#include "api/api_global_privacy.h"
|
#include "api/api_global_privacy.h"
|
||||||
|
#include "data/components/credits.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_channel_admins.h"
|
#include "data/data_channel_admins.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
@ -30,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "api/api_chat_invite.h"
|
#include "api/api_chat_invite.h"
|
||||||
#include "api/api_invite_links.h"
|
#include "api/api_invite_links.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
#include "storage/storage_account.h"
|
||||||
#include "ui/unread_badge.h"
|
#include "ui/unread_badge.h"
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
|
|
||||||
|
@ -861,7 +863,7 @@ void ChannelData::growSlowmodeLastMessage(TimeId when) {
|
||||||
|
|
||||||
int ChannelData::starsPerMessage() const {
|
int ChannelData::starsPerMessage() const {
|
||||||
if (const auto info = mgInfo.get()) {
|
if (const auto info = mgInfo.get()) {
|
||||||
return info->starsPerMessage;
|
return info->_starsPerMessage;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -870,8 +872,54 @@ void ChannelData::setStarsPerMessage(int stars) {
|
||||||
if (!mgInfo || starsPerMessage() == stars) {
|
if (!mgInfo || starsPerMessage() == stars) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mgInfo->starsPerMessage = stars;
|
const auto removed = mgInfo->_starsPerMessage && !stars;
|
||||||
|
mgInfo->_starsPerMessage = stars;
|
||||||
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
||||||
|
if (removed) {
|
||||||
|
session().local().clearPeerTrusted(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ChannelData::starsForMessageLocked() const {
|
||||||
|
if (const auto info = mgInfo.get()) {
|
||||||
|
return info->_starsForMessageLocked;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelData::lockStarsForMessage() {
|
||||||
|
const auto info = mgInfo.get();
|
||||||
|
if (!info || info->_starsForMessageLocked == info->_starsPerMessage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cancelStarsForMessage();
|
||||||
|
if (info->_starsPerMessage) {
|
||||||
|
info->_starsForMessageLocked = info->_starsPerMessage;
|
||||||
|
session().credits().lock(StarsAmount(info->_starsPerMessage));
|
||||||
|
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ChannelData::commitStarsForMessage() {
|
||||||
|
const auto info = mgInfo.get();
|
||||||
|
if (!info) {
|
||||||
|
return 0;
|
||||||
|
} else if (const auto stars = base::take(info->_starsForMessageLocked)) {
|
||||||
|
session().credits().withdrawLocked(StarsAmount(stars));
|
||||||
|
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
||||||
|
return stars;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelData::cancelStarsForMessage() {
|
||||||
|
const auto info = mgInfo.get();
|
||||||
|
if (!info) {
|
||||||
|
return;
|
||||||
|
} else if (const auto stars = base::take(info->_starsForMessageLocked)) {
|
||||||
|
session().credits().unlock(StarsAmount(stars));
|
||||||
|
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChannelData::peerGiftsCount() const {
|
int ChannelData::peerGiftsCount() const {
|
||||||
|
|
|
@ -14,6 +14,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_peer_bot_commands.h"
|
#include "data/data_peer_bot_commands.h"
|
||||||
#include "data/data_user_names.h"
|
#include "data/data_user_names.h"
|
||||||
|
|
||||||
|
class ChannelData;
|
||||||
|
|
||||||
struct ChannelLocation {
|
struct ChannelLocation {
|
||||||
QString address;
|
QString address;
|
||||||
Data::LocationPoint point;
|
Data::LocationPoint point;
|
||||||
|
@ -145,13 +147,15 @@ public:
|
||||||
int slowmodeSeconds = 0;
|
int slowmodeSeconds = 0;
|
||||||
TimeId slowmodeLastMessage = 0;
|
TimeId slowmodeLastMessage = 0;
|
||||||
|
|
||||||
int starsPerMessage = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ChatData *_migratedFrom = nullptr;
|
ChatData *_migratedFrom = nullptr;
|
||||||
ChannelLocation _location;
|
ChannelLocation _location;
|
||||||
Data::ChatBotCommands _botCommands;
|
Data::ChatBotCommands _botCommands;
|
||||||
std::unique_ptr<Data::Forum> _forum;
|
std::unique_ptr<Data::Forum> _forum;
|
||||||
|
int _starsPerMessage = 0;
|
||||||
|
int _starsForMessageLocked = 0;
|
||||||
|
|
||||||
|
friend class ChannelData;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -458,8 +462,12 @@ public:
|
||||||
[[nodiscard]] TimeId slowmodeLastMessage() const;
|
[[nodiscard]] TimeId slowmodeLastMessage() const;
|
||||||
void growSlowmodeLastMessage(TimeId when);
|
void growSlowmodeLastMessage(TimeId when);
|
||||||
|
|
||||||
[[nodiscard]] int starsPerMessage() const;
|
|
||||||
void setStarsPerMessage(int stars);
|
void setStarsPerMessage(int stars);
|
||||||
|
[[nodiscard]] int starsPerMessage() const;
|
||||||
|
[[nodiscard]] int starsForMessageLocked() const;
|
||||||
|
void lockStarsForMessage();
|
||||||
|
[[nodiscard]] int commitStarsForMessage();
|
||||||
|
void cancelStarsForMessage();
|
||||||
|
|
||||||
[[nodiscard]] int peerGiftsCount() const;
|
[[nodiscard]] int peerGiftsCount() const;
|
||||||
void setPeerGiftsCount(int count);
|
void setPeerGiftsCount(int count);
|
||||||
|
|
|
@ -1450,6 +1450,49 @@ bool PeerData::canManageGroupCall() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PeerData::starsPerMessage() const {
|
||||||
|
if (const auto user = asUser()) {
|
||||||
|
return user->starsPerMessage();
|
||||||
|
} else if (const auto channel = asChannel()) {
|
||||||
|
return channel->starsPerMessage();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PeerData::starsForMessageLocked() const {
|
||||||
|
if (const auto user = asUser()) {
|
||||||
|
return user->starsForMessageLocked();
|
||||||
|
} else if (const auto channel = asChannel()) {
|
||||||
|
return channel->starsForMessageLocked();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PeerData::lockStarsForMessage() {
|
||||||
|
if (const auto user = asUser()) {
|
||||||
|
user->lockStarsForMessage();
|
||||||
|
} else if (const auto channel = asChannel()) {
|
||||||
|
channel->lockStarsForMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PeerData::commitStarsForMessage() {
|
||||||
|
if (const auto user = asUser()) {
|
||||||
|
return user->commitStarsForMessage();
|
||||||
|
} else if (const auto channel = asChannel()) {
|
||||||
|
return channel->commitStarsForMessage();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PeerData::cancelStarsForMessage() {
|
||||||
|
if (const auto user = asUser()) {
|
||||||
|
user->cancelStarsForMessage();
|
||||||
|
} else if (const auto channel = asChannel()) {
|
||||||
|
channel->cancelStarsForMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Data::GroupCall *PeerData::groupCall() const {
|
Data::GroupCall *PeerData::groupCall() const {
|
||||||
if (const auto chat = asChat()) {
|
if (const auto chat = asChat()) {
|
||||||
return chat->groupCall();
|
return chat->groupCall();
|
||||||
|
|
|
@ -268,6 +268,12 @@ public:
|
||||||
[[nodiscard]] int slowmodeSecondsLeft() const;
|
[[nodiscard]] int slowmodeSecondsLeft() const;
|
||||||
[[nodiscard]] bool canManageGroupCall() const;
|
[[nodiscard]] bool canManageGroupCall() const;
|
||||||
|
|
||||||
|
[[nodiscard]] int starsPerMessage() const;
|
||||||
|
[[nodiscard]] int starsForMessageLocked() const;
|
||||||
|
void lockStarsForMessage();
|
||||||
|
[[nodiscard]] int commitStarsForMessage();
|
||||||
|
void cancelStarsForMessage();
|
||||||
|
|
||||||
[[nodiscard]] UserData *asBot();
|
[[nodiscard]] UserData *asBot();
|
||||||
[[nodiscard]] const UserData *asBot() const;
|
[[nodiscard]] const UserData *asBot() const;
|
||||||
[[nodiscard]] UserData *asUser();
|
[[nodiscard]] UserData *asUser();
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "api/api_sensitive_content.h"
|
#include "api/api_sensitive_content.h"
|
||||||
#include "api/api_statistics.h"
|
#include "api/api_statistics.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
|
#include "storage/storage_account.h"
|
||||||
#include "storage/storage_user_photos.h"
|
#include "storage/storage_user_photos.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "data/business/data_business_common.h"
|
#include "data/business/data_business_common.h"
|
||||||
|
@ -538,8 +539,44 @@ int UserData::starsPerMessage() const {
|
||||||
|
|
||||||
void UserData::setStarsPerMessage(int stars) {
|
void UserData::setStarsPerMessage(int stars) {
|
||||||
if (_starsPerMessage != stars) {
|
if (_starsPerMessage != stars) {
|
||||||
|
const auto removed = _starsPerMessage && !stars;
|
||||||
_starsPerMessage = stars;
|
_starsPerMessage = stars;
|
||||||
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
||||||
|
if (removed) {
|
||||||
|
session().local().clearPeerTrusted(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int UserData::starsForMessageLocked() const {
|
||||||
|
return _starsForMessageLocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserData::lockStarsForMessage() {
|
||||||
|
if (_starsPerMessage == _starsForMessageLocked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cancelStarsForMessage();
|
||||||
|
if (_starsPerMessage) {
|
||||||
|
_starsForMessageLocked = _starsPerMessage;
|
||||||
|
session().credits().lock(StarsAmount(_starsPerMessage));
|
||||||
|
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int UserData::commitStarsForMessage() {
|
||||||
|
if (const auto stars = base::take(_starsForMessageLocked)) {
|
||||||
|
session().credits().withdrawLocked(StarsAmount(stars));
|
||||||
|
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
||||||
|
return stars;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserData::cancelStarsForMessage() {
|
||||||
|
if (const auto stars = base::take(_starsForMessageLocked)) {
|
||||||
|
session().credits().unlock(StarsAmount(stars));
|
||||||
|
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/stars_amount.h"
|
#include "core/stars_amount.h"
|
||||||
|
#include "data/components/credits.h"
|
||||||
#include "data/data_birthday.h"
|
#include "data/data_birthday.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_chat_participant_status.h"
|
#include "data/data_chat_participant_status.h"
|
||||||
|
@ -179,8 +180,12 @@ public:
|
||||||
[[nodiscard]] bool canSendIgnoreRequirePremium() const;
|
[[nodiscard]] bool canSendIgnoreRequirePremium() const;
|
||||||
[[nodiscard]] bool readDatesPrivate() const;
|
[[nodiscard]] bool readDatesPrivate() const;
|
||||||
|
|
||||||
[[nodiscard]] int starsPerMessage() const;
|
|
||||||
void setStarsPerMessage(int stars);
|
void setStarsPerMessage(int stars);
|
||||||
|
[[nodiscard]] int starsPerMessage() const;
|
||||||
|
[[nodiscard]] int starsForMessageLocked() const;
|
||||||
|
void lockStarsForMessage();
|
||||||
|
[[nodiscard]] int commitStarsForMessage();
|
||||||
|
void cancelStarsForMessage();
|
||||||
|
|
||||||
[[nodiscard]] bool canShareThisContact() const;
|
[[nodiscard]] bool canShareThisContact() const;
|
||||||
[[nodiscard]] bool canAddContact() const;
|
[[nodiscard]] bool canAddContact() const;
|
||||||
|
@ -272,6 +277,7 @@ private:
|
||||||
int _commonChatsCount = 0;
|
int _commonChatsCount = 0;
|
||||||
int _peerGiftsCount = 0;
|
int _peerGiftsCount = 0;
|
||||||
int _starsPerMessage = 0;
|
int _starsPerMessage = 0;
|
||||||
|
int _starsForMessageLocked = 0;
|
||||||
ContactStatus _contactStatus = ContactStatus::Unknown;
|
ContactStatus _contactStatus = ContactStatus::Unknown;
|
||||||
CallsStatus _callsStatus = CallsStatus::Unknown;
|
CallsStatus _callsStatus = CallsStatus::Unknown;
|
||||||
|
|
||||||
|
|
|
@ -5577,7 +5577,23 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||||
auto preparePaidMessage = [&](
|
auto preparePaidMessage = [&](
|
||||||
const MTPDmessageActionPaidMessage &action) {
|
const MTPDmessageActionPaidMessage &action) {
|
||||||
auto result = PreparedServiceText();
|
auto result = PreparedServiceText();
|
||||||
result.text.text = u"paid for message"_q; AssertIsDebug();
|
const auto stars = action.vstars().v;
|
||||||
|
if (_from->isSelf()) {
|
||||||
|
result.text = tr::lng_action_paid_message_sent(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
stars,
|
||||||
|
Ui::Text::WithEntities);
|
||||||
|
} else {
|
||||||
|
result.links.push_back(_from->createOpenLink());
|
||||||
|
result.text = tr::lng_action_paid_message_got(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
stars,
|
||||||
|
lt_name,
|
||||||
|
Ui::Text::Link(_from->shortName(), 1),
|
||||||
|
Ui::Text::WithEntities);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "api/api_unread_things.h"
|
#include "api/api_unread_things.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
#include "boxes/delete_messages_box.h"
|
#include "boxes/delete_messages_box.h"
|
||||||
|
#include "boxes/send_credits_box.h"
|
||||||
#include "boxes/send_files_box.h"
|
#include "boxes/send_files_box.h"
|
||||||
#include "boxes/share_box.h"
|
#include "boxes/share_box.h"
|
||||||
#include "boxes/edit_caption_box.h"
|
#include "boxes/edit_caption_box.h"
|
||||||
|
@ -129,6 +130,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mtproto/mtproto_config.h"
|
#include "mtproto/mtproto_config.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "settings/business/settings_quick_replies.h"
|
#include "settings/business/settings_quick_replies.h"
|
||||||
|
#include "settings/settings_credits_graphics.h"
|
||||||
#include "storage/localimageloader.h"
|
#include "storage/localimageloader.h"
|
||||||
#include "storage/storage_account.h"
|
#include "storage/storage_account.h"
|
||||||
#include "storage/file_upload.h"
|
#include "storage/file_upload.h"
|
||||||
|
@ -146,6 +148,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/chat/chat_theme.h"
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/chat/chat_style.h"
|
#include "ui/chat/chat_style.h"
|
||||||
#include "ui/chat/continuous_scroll.h"
|
#include "ui/chat/continuous_scroll.h"
|
||||||
|
#include "ui/widgets/checkbox.h"
|
||||||
#include "ui/widgets/elastic_scroll.h"
|
#include "ui/widgets/elastic_scroll.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/item_text_options.h"
|
#include "ui/item_text_options.h"
|
||||||
|
@ -263,6 +266,7 @@ HistoryWidget::HistoryWidget(
|
||||||
tr::lng_channel_mute(tr::now).toUpper(),
|
tr::lng_channel_mute(tr::now).toUpper(),
|
||||||
st::historyComposeButton)
|
st::historyComposeButton)
|
||||||
, _reportMessages(this, QString(), st::historyComposeButton)
|
, _reportMessages(this, QString(), st::historyComposeButton)
|
||||||
|
, _payForMessage(this, QString(), st::historyComposeButton)
|
||||||
, _attachToggle(this, st::historyAttach)
|
, _attachToggle(this, st::historyAttach)
|
||||||
, _tabbedSelectorToggle(this, st::historyAttachEmoji)
|
, _tabbedSelectorToggle(this, st::historyAttachEmoji)
|
||||||
, _botKeyboardShow(this, st::historyBotKeyboardShow)
|
, _botKeyboardShow(this, st::historyBotKeyboardShow)
|
||||||
|
@ -380,6 +384,7 @@ HistoryWidget::HistoryWidget(
|
||||||
_muteUnmute->addClickHandler([=] { toggleMuteUnmute(); });
|
_muteUnmute->addClickHandler([=] { toggleMuteUnmute(); });
|
||||||
setupGiftToChannelButton();
|
setupGiftToChannelButton();
|
||||||
_reportMessages->addClickHandler([=] { reportSelectedMessages(); });
|
_reportMessages->addClickHandler([=] { reportSelectedMessages(); });
|
||||||
|
_payForMessage->addClickHandler([=] { payForMessage(); });
|
||||||
_field->submits(
|
_field->submits(
|
||||||
) | rpl::start_with_next([=](Qt::KeyboardModifiers modifiers) {
|
) | rpl::start_with_next([=](Qt::KeyboardModifiers modifiers) {
|
||||||
sendWithModifiers(modifiers);
|
sendWithModifiers(modifiers);
|
||||||
|
@ -520,6 +525,7 @@ HistoryWidget::HistoryWidget(
|
||||||
_joinChannel->hide();
|
_joinChannel->hide();
|
||||||
_muteUnmute->hide();
|
_muteUnmute->hide();
|
||||||
_reportMessages->hide();
|
_reportMessages->hide();
|
||||||
|
_payForMessage->hide();
|
||||||
|
|
||||||
initVoiceRecordBar();
|
initVoiceRecordBar();
|
||||||
|
|
||||||
|
@ -798,6 +804,7 @@ HistoryWidget::HistoryWidget(
|
||||||
| PeerUpdateFlag::MessagesTTL
|
| PeerUpdateFlag::MessagesTTL
|
||||||
| PeerUpdateFlag::ChatThemeEmoji
|
| PeerUpdateFlag::ChatThemeEmoji
|
||||||
| PeerUpdateFlag::FullInfo
|
| PeerUpdateFlag::FullInfo
|
||||||
|
| PeerUpdateFlag::StarsPerMessage
|
||||||
) | rpl::filter([=](const Data::PeerUpdate &update) {
|
) | rpl::filter([=](const Data::PeerUpdate &update) {
|
||||||
return (update.peer.get() == _peer);
|
return (update.peer.get() == _peer);
|
||||||
}) | rpl::map([](const Data::PeerUpdate &update) {
|
}) | rpl::map([](const Data::PeerUpdate &update) {
|
||||||
|
@ -809,7 +816,7 @@ HistoryWidget::HistoryWidget(
|
||||||
|
|
||||||
const auto was = (_sendAs != nullptr);
|
const auto was = (_sendAs != nullptr);
|
||||||
refreshSendAsToggle();
|
refreshSendAsToggle();
|
||||||
if (was != (_sendAs != nullptr)) {
|
if (was != (_sendAs != nullptr) || _peer->starsPerMessage()) {
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
orderWidgets();
|
orderWidgets();
|
||||||
|
@ -832,7 +839,8 @@ HistoryWidget::HistoryWidget(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags & PeerUpdateFlag::BotStartToken) {
|
if ((flags & PeerUpdateFlag::BotStartToken)
|
||||||
|
|| (flags & PeerUpdateFlag::StarsPerMessage)) {
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
|
@ -1957,6 +1965,7 @@ void HistoryWidget::setInnerFocus() {
|
||||||
|| isRecording()
|
|| isRecording()
|
||||||
|| isJoinChannel()
|
|| isJoinChannel()
|
||||||
|| isBotStart()
|
|| isBotStart()
|
||||||
|
|| isPayForMessage()
|
||||||
|| isBlocked()
|
|| isBlocked()
|
||||||
|| (!_canSendTexts && !_editMsgId)) {
|
|| (!_canSendTexts && !_editMsgId)) {
|
||||||
if (_scroll->isHidden()) {
|
if (_scroll->isHidden()) {
|
||||||
|
@ -2379,6 +2388,9 @@ void HistoryWidget::showHistory(
|
||||||
|
|
||||||
setHistory(nullptr);
|
setHistory(nullptr);
|
||||||
_list = nullptr;
|
_list = nullptr;
|
||||||
|
if (_peer) {
|
||||||
|
_peer->cancelStarsForMessage();
|
||||||
|
}
|
||||||
_peer = nullptr;
|
_peer = nullptr;
|
||||||
_topicsRequested.clear();
|
_topicsRequested.clear();
|
||||||
_canSendMessages = false;
|
_canSendMessages = false;
|
||||||
|
@ -3017,16 +3029,14 @@ bool HistoryWidget::contentOverlapped(const QRect &globalRect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryWidget::canWriteMessage() const {
|
bool HistoryWidget::canWriteMessage() const {
|
||||||
if (!_history || !_canSendMessages) {
|
return _history
|
||||||
return false;
|
&& _canSendMessages
|
||||||
}
|
&& !isBlocked()
|
||||||
if (isBlocked() || isJoinChannel() || isMuteUnmute() || isBotStart()) {
|
&& !isJoinChannel()
|
||||||
return false;
|
&& !isMuteUnmute()
|
||||||
}
|
&& !isBotStart()
|
||||||
if (isSearching()) {
|
&& !isPayForMessage()
|
||||||
return false;
|
&& !isSearching();
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateControlsVisibility() {
|
void HistoryWidget::updateControlsVisibility() {
|
||||||
|
@ -3086,6 +3096,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
|| isJoinChannel()
|
|| isJoinChannel()
|
||||||
|| isMuteUnmute()
|
|| isMuteUnmute()
|
||||||
|| isBotStart()
|
|| isBotStart()
|
||||||
|
|| isPayForMessage()
|
||||||
|| isReportMessages()))) {
|
|| isReportMessages()))) {
|
||||||
const auto toggle = [&](Ui::FlatButton *shown) {
|
const auto toggle = [&](Ui::FlatButton *shown) {
|
||||||
const auto toggleOne = [&](not_null<Ui::FlatButton*> button) {
|
const auto toggleOne = [&](not_null<Ui::FlatButton*> button) {
|
||||||
|
@ -3097,6 +3108,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
toggleOne(_reportMessages);
|
toggleOne(_reportMessages);
|
||||||
|
toggleOne(_payForMessage);
|
||||||
toggleOne(_joinChannel);
|
toggleOne(_joinChannel);
|
||||||
toggleOne(_muteUnmute);
|
toggleOne(_muteUnmute);
|
||||||
toggleOne(_botStart);
|
toggleOne(_botStart);
|
||||||
|
@ -3110,6 +3122,8 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
toggle(_reportMessages);
|
toggle(_reportMessages);
|
||||||
} else if (isBlocked()) {
|
} else if (isBlocked()) {
|
||||||
toggle(_unblock);
|
toggle(_unblock);
|
||||||
|
} else if (isPayForMessage()) {
|
||||||
|
toggle(_payForMessage);
|
||||||
} else if (isJoinChannel()) {
|
} else if (isJoinChannel()) {
|
||||||
toggle(_joinChannel);
|
toggle(_joinChannel);
|
||||||
} else if (isMuteUnmute()) {
|
} else if (isMuteUnmute()) {
|
||||||
|
@ -3172,6 +3186,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
_joinChannel->hide();
|
_joinChannel->hide();
|
||||||
_muteUnmute->hide();
|
_muteUnmute->hide();
|
||||||
_reportMessages->hide();
|
_reportMessages->hide();
|
||||||
|
_payForMessage->hide();
|
||||||
_send->show();
|
_send->show();
|
||||||
updateSendButtonType();
|
updateSendButtonType();
|
||||||
|
|
||||||
|
@ -3285,6 +3300,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
_joinChannel->hide();
|
_joinChannel->hide();
|
||||||
_muteUnmute->hide();
|
_muteUnmute->hide();
|
||||||
_reportMessages->hide();
|
_reportMessages->hide();
|
||||||
|
_payForMessage->hide();
|
||||||
_attachToggle->hide();
|
_attachToggle->hide();
|
||||||
if (_silent) {
|
if (_silent) {
|
||||||
_silent->hide();
|
_silent->hide();
|
||||||
|
@ -4525,6 +4541,73 @@ void HistoryWidget::reportSelectedMessages() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::payForMessage() {
|
||||||
|
if (!_peer || !session().credits().loaded()) {
|
||||||
|
return;
|
||||||
|
} else if (!_peer->starsPerMessage() || _peer->starsForMessageLocked()) {
|
||||||
|
updateControlsVisibility();
|
||||||
|
} else if (session().local().isPeerTrustedPayForMessage(_peer->id)) {
|
||||||
|
payForMessageSure();
|
||||||
|
} else {
|
||||||
|
const auto peer = _peer;
|
||||||
|
const auto count = peer->starsPerMessage();
|
||||||
|
controller()->show(Box([=](not_null<Ui::GenericBox*> box) {
|
||||||
|
const auto trust = std::make_shared<QPointer<Ui::Checkbox>>();
|
||||||
|
const auto confirmed = [=](Fn<void()> close) {
|
||||||
|
payForMessageSure((*trust)->checked());
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
Ui::ConfirmBox(box, {
|
||||||
|
.text = tr::lng_payment_confirm_text(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
count,
|
||||||
|
lt_name,
|
||||||
|
Ui::Text::Bold(peer->shortName()),
|
||||||
|
Ui::Text::RichLangValue).append(' ').append(
|
||||||
|
tr::lng_payment_confirm_sure(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
count,
|
||||||
|
Ui::Text::RichLangValue)),
|
||||||
|
.confirmed = confirmed,
|
||||||
|
.confirmText = tr::lng_payment_confirm_button(),
|
||||||
|
.title = tr::lng_payment_confirm_title(),
|
||||||
|
});
|
||||||
|
const auto skip = st::defaultCheckbox.margin.top();
|
||||||
|
*trust = box->addRow(
|
||||||
|
object_ptr<Ui::Checkbox>(
|
||||||
|
box,
|
||||||
|
tr::lng_payment_confirm_dont_ask(tr::now)),
|
||||||
|
st::boxRowPadding + QMargins(0, skip, 0, skip));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::payForMessageSure(bool trust) {
|
||||||
|
if (trust) {
|
||||||
|
session().local().markPeerTrustedPayForMessage(_peer->id);
|
||||||
|
}
|
||||||
|
const auto required = _peer->starsPerMessage();
|
||||||
|
if (!required) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto done = [=](Settings::SmallBalanceResult result) {
|
||||||
|
if (result == Settings::SmallBalanceResult::Success
|
||||||
|
|| result == Settings::SmallBalanceResult::Already) {
|
||||||
|
_peer->lockStarsForMessage();
|
||||||
|
if (canWriteMessage()) {
|
||||||
|
setInnerFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Settings::MaybeRequestBalanceIncrease(
|
||||||
|
controller()->uiShow(),
|
||||||
|
required,
|
||||||
|
Settings::SmallBalanceForMessage{ .recipientId = _peer->id },
|
||||||
|
crl::guard(this, done));
|
||||||
|
}
|
||||||
|
|
||||||
History *HistoryWidget::history() const {
|
History *HistoryWidget::history() const {
|
||||||
return _history;
|
return _history;
|
||||||
}
|
}
|
||||||
|
@ -5071,6 +5154,40 @@ bool HistoryWidget::isSearching() const {
|
||||||
return _composeSearch != nullptr;
|
return _composeSearch != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HistoryWidget::isPayForMessage() const {
|
||||||
|
const auto stars = _peer ? _peer->starsPerMessage() : 0;
|
||||||
|
const auto locked = _peer ? _peer->starsForMessageLocked() : 0;
|
||||||
|
if (!stars || locked) {
|
||||||
|
return false;
|
||||||
|
} else if (const auto channel = _peer->asChannel()) {
|
||||||
|
if (channel->amCreator() || channel->adminRights()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto creating = !_payForMessageStars.current();
|
||||||
|
_payForMessageStars = stars;
|
||||||
|
if (creating) {
|
||||||
|
session().credits().load();
|
||||||
|
|
||||||
|
auto text = _payForMessageStars.value(
|
||||||
|
) | rpl::map([session = &session()](int stars) {
|
||||||
|
return tr::lng_payment_for_message(
|
||||||
|
tr::now,
|
||||||
|
lt_cost,
|
||||||
|
Ui::CreditsEmojiSmall(session).append(
|
||||||
|
Lang::FormatCountDecimal(stars)),
|
||||||
|
Ui::Text::WithEntities);
|
||||||
|
});
|
||||||
|
Ui::SetButtonMarkedLabel(
|
||||||
|
_payForMessage,
|
||||||
|
std::move(text),
|
||||||
|
&session(),
|
||||||
|
st::historyComposeButtonText);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool HistoryWidget::showRecordButton() const {
|
bool HistoryWidget::showRecordButton() const {
|
||||||
return (_recordAvailability != Webrtc::RecordAvailability::None)
|
return (_recordAvailability != Webrtc::RecordAvailability::None)
|
||||||
&& !_voiceRecordBar->isListenState()
|
&& !_voiceRecordBar->isListenState()
|
||||||
|
@ -5128,6 +5245,7 @@ bool HistoryWidget::updateCmdStartShown() {
|
||||||
&& _peer->asChannel()->mgInfo->botStatus > 0))) {
|
&& _peer->asChannel()->mgInfo->botStatus > 0))) {
|
||||||
if (!isBotStart()
|
if (!isBotStart()
|
||||||
&& !isBlocked()
|
&& !isBlocked()
|
||||||
|
&& !isPayForMessage()
|
||||||
&& !_keyboard->hasMarkup()
|
&& !_keyboard->hasMarkup()
|
||||||
&& !_keyboard->forceReply()
|
&& !_keyboard->forceReply()
|
||||||
&& !_editMsgId) {
|
&& !_editMsgId) {
|
||||||
|
@ -5541,7 +5659,7 @@ void HistoryWidget::moveFieldControls() {
|
||||||
|
|
||||||
// (_botMenu.button) (_attachToggle|_replaceMedia) (_sendAs) ---- _inlineResults ------------------------------ _tabbedPanel ------ _fieldBarCancel
|
// (_botMenu.button) (_attachToggle|_replaceMedia) (_sendAs) ---- _inlineResults ------------------------------ _tabbedPanel ------ _fieldBarCancel
|
||||||
// (_attachDocument|_attachPhoto) _field (_ttlInfo) (_scheduled) (_silent|_cmdStart|_kbShow) (_kbHide|_tabbedSelectorToggle) _send
|
// (_attachDocument|_attachPhoto) _field (_ttlInfo) (_scheduled) (_silent|_cmdStart|_kbShow) (_kbHide|_tabbedSelectorToggle) _send
|
||||||
// (_botStart|_unblock|_joinChannel|_muteUnmute|_reportMessages)
|
// (_botStart|_unblock|_joinChannel|_muteUnmute|_reportMessages|_payForMessage)
|
||||||
|
|
||||||
auto buttonsBottom = bottom - _attachToggle->height();
|
auto buttonsBottom = bottom - _attachToggle->height();
|
||||||
auto left = st::historySendRight;
|
auto left = st::historySendRight;
|
||||||
|
@ -5615,6 +5733,7 @@ void HistoryWidget::moveFieldControls() {
|
||||||
_joinChannel->setGeometry(fullWidthButtonRect);
|
_joinChannel->setGeometry(fullWidthButtonRect);
|
||||||
_muteUnmute->setGeometry(fullWidthButtonRect);
|
_muteUnmute->setGeometry(fullWidthButtonRect);
|
||||||
_reportMessages->setGeometry(fullWidthButtonRect);
|
_reportMessages->setGeometry(fullWidthButtonRect);
|
||||||
|
_payForMessage->setGeometry(fullWidthButtonRect);
|
||||||
if (_sendRestriction) {
|
if (_sendRestriction) {
|
||||||
_sendRestriction->setGeometry(fullWidthButtonRect);
|
_sendRestriction->setGeometry(fullWidthButtonRect);
|
||||||
}
|
}
|
||||||
|
@ -6055,18 +6174,25 @@ void HistoryWidget::handleHistoryChange(not_null<const History*> history) {
|
||||||
const auto joinChannel = isJoinChannel();
|
const auto joinChannel = isJoinChannel();
|
||||||
const auto muteUnmute = isMuteUnmute();
|
const auto muteUnmute = isMuteUnmute();
|
||||||
const auto reportMessages = isReportMessages();
|
const auto reportMessages = isReportMessages();
|
||||||
|
const auto payForMessage = isPayForMessage();
|
||||||
const auto update = false
|
const auto update = false
|
||||||
|| (_reportMessages->isHidden() == reportMessages)
|
|| (_reportMessages->isHidden() == reportMessages)
|
||||||
|| (!reportMessages && _unblock->isHidden() == unblock)
|
|| (!reportMessages && _unblock->isHidden() == unblock)
|
||||||
|| (!reportMessages
|
|| (!reportMessages
|
||||||
&& !unblock
|
&& !unblock
|
||||||
|
&& _payForMessage->isHidden() == payForMessage)
|
||||||
|
|| (!reportMessages
|
||||||
|
&& !unblock
|
||||||
|
&& !payForMessage
|
||||||
&& _botStart->isHidden() == botStart)
|
&& _botStart->isHidden() == botStart)
|
||||||
|| (!reportMessages
|
|| (!reportMessages
|
||||||
&& !unblock
|
&& !unblock
|
||||||
|
&& !payForMessage
|
||||||
&& !botStart
|
&& !botStart
|
||||||
&& _joinChannel->isHidden() == joinChannel)
|
&& _joinChannel->isHidden() == joinChannel)
|
||||||
|| (!reportMessages
|
|| (!reportMessages
|
||||||
&& !unblock
|
&& !unblock
|
||||||
|
&& !payForMessage
|
||||||
&& !botStart
|
&& !botStart
|
||||||
&& !joinChannel
|
&& !joinChannel
|
||||||
&& _muteUnmute->isHidden() == muteUnmute);
|
&& _muteUnmute->isHidden() == muteUnmute);
|
||||||
|
@ -6430,6 +6556,7 @@ void HistoryWidget::updateHistoryGeometry(
|
||||||
} else if (!editingMessage()
|
} else if (!editingMessage()
|
||||||
&& (isSearching()
|
&& (isSearching()
|
||||||
|| isBlocked()
|
|| isBlocked()
|
||||||
|
|| isPayForMessage()
|
||||||
|| isBotStart()
|
|| isBotStart()
|
||||||
|| isJoinChannel()
|
|| isJoinChannel()
|
||||||
|| isMuteUnmute()
|
|| isMuteUnmute()
|
||||||
|
@ -6739,6 +6866,7 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
|
||||||
if (!isSearching()
|
if (!isSearching()
|
||||||
&& !isBotStart()
|
&& !isBotStart()
|
||||||
&& !isBlocked()
|
&& !isBlocked()
|
||||||
|
&& !isPayForMessage()
|
||||||
&& _canSendMessages
|
&& _canSendMessages
|
||||||
&& (wasVisible
|
&& (wasVisible
|
||||||
|| (_replyTo && _replyEditMsg)
|
|| (_replyTo && _replyEditMsg)
|
||||||
|
@ -8615,6 +8743,7 @@ void HistoryWidget::updateTopBarSelection() {
|
||||||
|| (_list && _list->wasSelectedText())
|
|| (_list && _list->wasSelectedText())
|
||||||
|| isRecording()
|
|| isRecording()
|
||||||
|| isBotStart()
|
|| isBotStart()
|
||||||
|
|| isPayForMessage()
|
||||||
|| isBlocked()
|
|| isBlocked()
|
||||||
|| (!_canSendTexts && !_editMsgId)) {
|
|| (!_canSendTexts && !_editMsgId)) {
|
||||||
_list->setFocus();
|
_list->setFocus();
|
||||||
|
|
|
@ -422,6 +422,8 @@ private:
|
||||||
[[nodiscard]] int computeMaxFieldHeight() const;
|
[[nodiscard]] int computeMaxFieldHeight() const;
|
||||||
void toggleMuteUnmute();
|
void toggleMuteUnmute();
|
||||||
void reportSelectedMessages();
|
void reportSelectedMessages();
|
||||||
|
void payForMessage();
|
||||||
|
void payForMessageSure(bool trust = false);
|
||||||
void showKeyboardHideButton();
|
void showKeyboardHideButton();
|
||||||
void toggleKeyboard(bool manual = true);
|
void toggleKeyboard(bool manual = true);
|
||||||
void startBotCommand();
|
void startBotCommand();
|
||||||
|
@ -640,6 +642,7 @@ private:
|
||||||
[[nodiscard]] bool isJoinChannel() const;
|
[[nodiscard]] bool isJoinChannel() const;
|
||||||
[[nodiscard]] bool isMuteUnmute() const;
|
[[nodiscard]] bool isMuteUnmute() const;
|
||||||
[[nodiscard]] bool isReportMessages() const;
|
[[nodiscard]] bool isReportMessages() const;
|
||||||
|
[[nodiscard]] bool isPayForMessage() const;
|
||||||
bool updateCmdStartShown();
|
bool updateCmdStartShown();
|
||||||
void updateSendButtonType();
|
void updateSendButtonType();
|
||||||
[[nodiscard]] bool showRecordButton() const;
|
[[nodiscard]] bool showRecordButton() const;
|
||||||
|
@ -778,6 +781,8 @@ private:
|
||||||
QPointer<Ui::IconButton> _giftToChannelIn;
|
QPointer<Ui::IconButton> _giftToChannelIn;
|
||||||
QPointer<Ui::IconButton> _giftToChannelOut;
|
QPointer<Ui::IconButton> _giftToChannelOut;
|
||||||
object_ptr<Ui::FlatButton> _reportMessages;
|
object_ptr<Ui::FlatButton> _reportMessages;
|
||||||
|
object_ptr<Ui::FlatButton> _payForMessage;
|
||||||
|
mutable rpl::variable<int> _payForMessageStars;
|
||||||
struct {
|
struct {
|
||||||
object_ptr<Ui::RoundButton> button = { nullptr };
|
object_ptr<Ui::RoundButton> button = { nullptr };
|
||||||
QString text;
|
QString text;
|
||||||
|
|
|
@ -348,6 +348,7 @@ private:
|
||||||
std::unique_ptr<ComposeControls> _composeControls;
|
std::unique_ptr<ComposeControls> _composeControls;
|
||||||
std::unique_ptr<ComposeSearch> _composeSearch;
|
std::unique_ptr<ComposeSearch> _composeSearch;
|
||||||
std::unique_ptr<Ui::FlatButton> _joinGroup;
|
std::unique_ptr<Ui::FlatButton> _joinGroup;
|
||||||
|
std::unique_ptr<Ui::FlatButton> _payForMessage;
|
||||||
std::unique_ptr<TopicReopenBar> _topicReopenBar;
|
std::unique_ptr<TopicReopenBar> _topicReopenBar;
|
||||||
std::unique_ptr<EmptyPainter> _emptyPainter;
|
std::unique_ptr<EmptyPainter> _emptyPainter;
|
||||||
bool _skipScrollEvent = false;
|
bool _skipScrollEvent = false;
|
||||||
|
|
|
@ -1015,12 +1015,12 @@ void WebViewInstance::resolveApp(
|
||||||
|
|
||||||
void WebViewInstance::confirmOpen(Fn<void()> done) {
|
void WebViewInstance::confirmOpen(Fn<void()> done) {
|
||||||
if (_bot->isVerified()
|
if (_bot->isVerified()
|
||||||
|| _session->local().isBotTrustedOpenWebView(_bot->id)) {
|
|| _session->local().isPeerTrustedOpenWebView(_bot->id)) {
|
||||||
done();
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto callback = [=](Fn<void()> close) {
|
const auto callback = [=](Fn<void()> close) {
|
||||||
_session->local().markBotTrustedOpenWebView(_bot->id);
|
_session->local().markPeerTrustedOpenWebView(_bot->id);
|
||||||
close();
|
close();
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
|
@ -1052,14 +1052,14 @@ void WebViewInstance::confirmAppOpen(
|
||||||
bool forceConfirmation) {
|
bool forceConfirmation) {
|
||||||
if (!forceConfirmation
|
if (!forceConfirmation
|
||||||
&& (_bot->isVerified()
|
&& (_bot->isVerified()
|
||||||
|| _session->local().isBotTrustedOpenWebView(_bot->id))) {
|
|| _session->local().isPeerTrustedOpenWebView(_bot->id))) {
|
||||||
done(writeAccess);
|
done(writeAccess);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_parentShow->show(Box([=](not_null<Ui::GenericBox*> box) {
|
_parentShow->show(Box([=](not_null<Ui::GenericBox*> box) {
|
||||||
const auto allowed = std::make_shared<Ui::Checkbox*>();
|
const auto allowed = std::make_shared<Ui::Checkbox*>();
|
||||||
const auto callback = [=](Fn<void()> close) {
|
const auto callback = [=](Fn<void()> close) {
|
||||||
_session->local().markBotTrustedOpenWebView(_bot->id);
|
_session->local().markPeerTrustedOpenWebView(_bot->id);
|
||||||
done((*allowed) && (*allowed)->checked());
|
done((*allowed) && (*allowed)->checked());
|
||||||
close();
|
close();
|
||||||
};
|
};
|
||||||
|
|
|
@ -131,7 +131,8 @@ namespace Media::Stories {
|
||||||
if (options.invertCaption) {
|
if (options.invertCaption) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||||
}
|
}
|
||||||
if (options.paidByStars) {
|
const auto starsPaid = peer->commitStarsForMessage();
|
||||||
|
if (starsPaid) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||||
}
|
}
|
||||||
const auto done = [=] {
|
const auto done = [=] {
|
||||||
|
@ -159,7 +160,7 @@ namespace Media::Stories {
|
||||||
MTP_inputPeerEmpty(),
|
MTP_inputPeerEmpty(),
|
||||||
Data::ShortcutIdToMTP(session, options.shortcutId),
|
Data::ShortcutIdToMTP(session, options.shortcutId),
|
||||||
MTP_long(options.effectId),
|
MTP_long(options.effectId),
|
||||||
MTP_long(options.paidByStars)
|
MTP_long(starsPaid)
|
||||||
), [=](
|
), [=](
|
||||||
const MTPUpdates &result,
|
const MTPUpdates &result,
|
||||||
const MTP::Response &response) {
|
const MTP::Response &response) {
|
||||||
|
|
|
@ -904,7 +904,7 @@ void Form::submit() {
|
||||||
if (index < list.size() && password.isEmpty()) {
|
if (index < list.size() && password.isEmpty()) {
|
||||||
_updates.fire(TmpPasswordRequired{});
|
_updates.fire(TmpPasswordRequired{});
|
||||||
return;
|
return;
|
||||||
} else if (!_session->local().isBotTrustedPayment(_details.botId)) {
|
} else if (!_session->local().isPeerTrustedPayment(_details.botId)) {
|
||||||
_updates.fire(BotTrustRequired{
|
_updates.fire(BotTrustRequired{
|
||||||
.bot = _session->data().user(_details.botId),
|
.bot = _session->data().user(_details.botId),
|
||||||
.provider = _session->data().user(_details.providerId),
|
.provider = _session->data().user(_details.providerId),
|
||||||
|
@ -1307,7 +1307,7 @@ void Form::acceptTerms() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Form::trustBot() {
|
void Form::trustBot() {
|
||||||
_session->local().markBotTrustedPayment(_details.botId);
|
_session->local().markPeerTrustedPayment(_details.botId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Form::processShippingOptions(const QVector<MTPShippingOption> &data) {
|
void Form::processShippingOptions(const QVector<MTPShippingOption> &data) {
|
||||||
|
|
|
@ -2090,6 +2090,8 @@ void SmallBalanceBox(
|
||||||
return QString();
|
return QString();
|
||||||
}, [&](SmallBalanceStarGift value) {
|
}, [&](SmallBalanceStarGift value) {
|
||||||
return owner->peer(value.recipientId)->shortName();
|
return owner->peer(value.recipientId)->shortName();
|
||||||
|
}, [&](SmallBalanceForMessage value) {
|
||||||
|
return owner->peer(value.recipientId)->shortName();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto needed = show->session().credits().balanceValue(
|
auto needed = show->session().credits().balanceValue(
|
||||||
|
@ -2128,6 +2130,11 @@ void SmallBalanceBox(
|
||||||
lt_user,
|
lt_user,
|
||||||
rpl::single(Ui::Text::Bold(name)),
|
rpl::single(Ui::Text::Bold(name)),
|
||||||
Ui::Text::RichLangValue)
|
Ui::Text::RichLangValue)
|
||||||
|
: v::is<SmallBalanceForMessage>(source)
|
||||||
|
? tr::lng_credits_small_balance_for_message(
|
||||||
|
lt_user,
|
||||||
|
rpl::single(Ui::Text::Bold(name)),
|
||||||
|
Ui::Text::RichLangValue)
|
||||||
: name.isEmpty()
|
: name.isEmpty()
|
||||||
? tr::lng_credits_small_balance_fallback(
|
? tr::lng_credits_small_balance_fallback(
|
||||||
Ui::Text::RichLangValue)
|
Ui::Text::RichLangValue)
|
||||||
|
|
|
@ -200,12 +200,16 @@ struct SmallBalanceDeepLink {
|
||||||
struct SmallBalanceStarGift {
|
struct SmallBalanceStarGift {
|
||||||
PeerId recipientId;
|
PeerId recipientId;
|
||||||
};
|
};
|
||||||
|
struct SmallBalanceForMessage {
|
||||||
|
PeerId recipientId;
|
||||||
|
};
|
||||||
struct SmallBalanceSource : std::variant<
|
struct SmallBalanceSource : std::variant<
|
||||||
SmallBalanceBot,
|
SmallBalanceBot,
|
||||||
SmallBalanceReaction,
|
SmallBalanceReaction,
|
||||||
SmallBalanceSubscription,
|
SmallBalanceSubscription,
|
||||||
SmallBalanceDeepLink,
|
SmallBalanceDeepLink,
|
||||||
SmallBalanceStarGift> {
|
SmallBalanceStarGift,
|
||||||
|
SmallBalanceForMessage> {
|
||||||
using variant::variant;
|
using variant::variant;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ enum { // Local Storage Keys
|
||||||
lskSavedGifsOld = 0x0e, // no data
|
lskSavedGifsOld = 0x0e, // no data
|
||||||
lskSavedGifs = 0x0f, // no data
|
lskSavedGifs = 0x0f, // no data
|
||||||
lskStickersKeys = 0x10, // no data
|
lskStickersKeys = 0x10, // no data
|
||||||
lskTrustedBots = 0x11, // no data
|
lskTrustedPeers = 0x11, // no data
|
||||||
lskFavedStickers = 0x12, // no data
|
lskFavedStickers = 0x12, // no data
|
||||||
lskExportSettings = 0x13, // no data
|
lskExportSettings = 0x13, // no data
|
||||||
lskBackgroundOld = 0x14, // no data
|
lskBackgroundOld = 0x14, // no data
|
||||||
|
@ -220,7 +220,7 @@ base::flat_set<QString> Account::collectGoodNames() const {
|
||||||
_legacyBackgroundKeyDay,
|
_legacyBackgroundKeyDay,
|
||||||
_recentHashtagsAndBotsKey,
|
_recentHashtagsAndBotsKey,
|
||||||
_exportSettingsKey,
|
_exportSettingsKey,
|
||||||
_trustedBotsKey,
|
_trustedPeersKey,
|
||||||
_installedMasksKey,
|
_installedMasksKey,
|
||||||
_recentMasksKey,
|
_recentMasksKey,
|
||||||
_archivedMasksKey,
|
_archivedMasksKey,
|
||||||
|
@ -308,7 +308,7 @@ Account::ReadMapResult Account::readMapWith(
|
||||||
base::flat_map<PeerId, FileKey> draftsMap;
|
base::flat_map<PeerId, FileKey> draftsMap;
|
||||||
base::flat_map<PeerId, FileKey> draftCursorsMap;
|
base::flat_map<PeerId, FileKey> draftCursorsMap;
|
||||||
base::flat_map<PeerId, bool> draftsNotReadMap;
|
base::flat_map<PeerId, bool> draftsNotReadMap;
|
||||||
quint64 locationsKey = 0, reportSpamStatusesKey = 0, trustedBotsKey = 0;
|
quint64 locationsKey = 0, reportSpamStatusesKey = 0, trustedPeersKey = 0;
|
||||||
quint64 recentStickersKeyOld = 0;
|
quint64 recentStickersKeyOld = 0;
|
||||||
quint64 installedStickersKey = 0, featuredStickersKey = 0, recentStickersKey = 0, favedStickersKey = 0, archivedStickersKey = 0;
|
quint64 installedStickersKey = 0, featuredStickersKey = 0, recentStickersKey = 0, favedStickersKey = 0, archivedStickersKey = 0;
|
||||||
quint64 installedMasksKey = 0, recentMasksKey = 0, archivedMasksKey = 0;
|
quint64 installedMasksKey = 0, recentMasksKey = 0, archivedMasksKey = 0;
|
||||||
|
@ -371,8 +371,8 @@ Account::ReadMapResult Account::readMapWith(
|
||||||
map.stream >> reportSpamStatusesKey;
|
map.stream >> reportSpamStatusesKey;
|
||||||
ClearKey(reportSpamStatusesKey, _basePath);
|
ClearKey(reportSpamStatusesKey, _basePath);
|
||||||
} break;
|
} break;
|
||||||
case lskTrustedBots: {
|
case lskTrustedPeers: {
|
||||||
map.stream >> trustedBotsKey;
|
map.stream >> trustedPeersKey;
|
||||||
} break;
|
} break;
|
||||||
case lskRecentStickersOld: {
|
case lskRecentStickersOld: {
|
||||||
map.stream >> recentStickersKeyOld;
|
map.stream >> recentStickersKeyOld;
|
||||||
|
@ -459,7 +459,7 @@ Account::ReadMapResult Account::readMapWith(
|
||||||
_draftsNotReadMap = draftsNotReadMap;
|
_draftsNotReadMap = draftsNotReadMap;
|
||||||
|
|
||||||
_locationsKey = locationsKey;
|
_locationsKey = locationsKey;
|
||||||
_trustedBotsKey = trustedBotsKey;
|
_trustedPeersKey = trustedPeersKey;
|
||||||
_recentStickersKeyOld = recentStickersKeyOld;
|
_recentStickersKeyOld = recentStickersKeyOld;
|
||||||
_installedStickersKey = installedStickersKey;
|
_installedStickersKey = installedStickersKey;
|
||||||
_featuredStickersKey = featuredStickersKey;
|
_featuredStickersKey = featuredStickersKey;
|
||||||
|
@ -573,7 +573,7 @@ void Account::writeMap() {
|
||||||
if (!_draftsMap.empty()) mapSize += sizeof(quint32) * 2 + _draftsMap.size() * sizeof(quint64) * 2;
|
if (!_draftsMap.empty()) mapSize += sizeof(quint32) * 2 + _draftsMap.size() * sizeof(quint64) * 2;
|
||||||
if (!_draftCursorsMap.empty()) mapSize += sizeof(quint32) * 2 + _draftCursorsMap.size() * sizeof(quint64) * 2;
|
if (!_draftCursorsMap.empty()) mapSize += sizeof(quint32) * 2 + _draftCursorsMap.size() * sizeof(quint64) * 2;
|
||||||
if (_locationsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
if (_locationsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
if (_trustedBotsKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
if (_trustedPeersKey) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
if (_recentStickersKeyOld) mapSize += sizeof(quint32) + sizeof(quint64);
|
if (_recentStickersKeyOld) mapSize += sizeof(quint32) + sizeof(quint64);
|
||||||
if (_installedStickersKey || _featuredStickersKey || _recentStickersKey || _archivedStickersKey) {
|
if (_installedStickersKey || _featuredStickersKey || _recentStickersKey || _archivedStickersKey) {
|
||||||
mapSize += sizeof(quint32) + 4 * sizeof(quint64);
|
mapSize += sizeof(quint32) + 4 * sizeof(quint64);
|
||||||
|
@ -619,8 +619,8 @@ void Account::writeMap() {
|
||||||
if (_locationsKey) {
|
if (_locationsKey) {
|
||||||
mapData.stream << quint32(lskLocations) << quint64(_locationsKey);
|
mapData.stream << quint32(lskLocations) << quint64(_locationsKey);
|
||||||
}
|
}
|
||||||
if (_trustedBotsKey) {
|
if (_trustedPeersKey) {
|
||||||
mapData.stream << quint32(lskTrustedBots) << quint64(_trustedBotsKey);
|
mapData.stream << quint32(lskTrustedPeers) << quint64(_trustedPeersKey);
|
||||||
}
|
}
|
||||||
if (_recentStickersKeyOld) {
|
if (_recentStickersKeyOld) {
|
||||||
mapData.stream << quint32(lskRecentStickersOld) << quint64(_recentStickersKeyOld);
|
mapData.stream << quint32(lskRecentStickersOld) << quint64(_recentStickersKeyOld);
|
||||||
|
@ -693,7 +693,7 @@ void Account::reset() {
|
||||||
_draftsMap.clear();
|
_draftsMap.clear();
|
||||||
_draftCursorsMap.clear();
|
_draftCursorsMap.clear();
|
||||||
_draftsNotReadMap.clear();
|
_draftsNotReadMap.clear();
|
||||||
_locationsKey = _trustedBotsKey = 0;
|
_locationsKey = _trustedPeersKey = 0;
|
||||||
_recentStickersKeyOld = 0;
|
_recentStickersKeyOld = 0;
|
||||||
_installedStickersKey = 0;
|
_installedStickersKey = 0;
|
||||||
_featuredStickersKey = 0;
|
_featuredStickersKey = 0;
|
||||||
|
@ -3147,47 +3147,47 @@ void Account::readSelf(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::writeTrustedBots() {
|
void Account::writeTrustedPeers() {
|
||||||
if (_trustedBots.empty()) {
|
if (_trustedPeers.empty()) {
|
||||||
if (_trustedBotsKey) {
|
if (_trustedPeersKey) {
|
||||||
ClearKey(_trustedBotsKey, _basePath);
|
ClearKey(_trustedPeersKey, _basePath);
|
||||||
_trustedBotsKey = 0;
|
_trustedPeersKey = 0;
|
||||||
writeMapDelayed();
|
writeMapDelayed();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!_trustedBotsKey) {
|
if (!_trustedPeersKey) {
|
||||||
_trustedBotsKey = GenerateKey(_basePath);
|
_trustedPeersKey = GenerateKey(_basePath);
|
||||||
writeMapQueued();
|
writeMapQueued();
|
||||||
}
|
}
|
||||||
quint32 size = sizeof(qint32) + _trustedBots.size() * sizeof(quint64);
|
quint32 size = sizeof(qint32) + _trustedPeers.size() * sizeof(quint64);
|
||||||
EncryptedDescriptor data(size);
|
EncryptedDescriptor data(size);
|
||||||
data.stream << qint32(_trustedBots.size());
|
data.stream << qint32(_trustedPeers.size());
|
||||||
for (const auto &[peerId, mask] : _trustedBots) {
|
for (const auto &[peerId, mask] : _trustedPeers) {
|
||||||
// value: 8 bit mask, 56 bit bot peer_id.
|
// value: 8 bit mask, 56 bit peer_id.
|
||||||
auto value = SerializePeerId(peerId);
|
auto value = SerializePeerId(peerId);
|
||||||
Assert((value >> 56) == 0);
|
Assert((value >> 56) == 0);
|
||||||
value |= (quint64(mask) << 56);
|
value |= (quint64(mask) << 56);
|
||||||
data.stream << value;
|
data.stream << value;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileWriteDescriptor file(_trustedBotsKey, _basePath);
|
FileWriteDescriptor file(_trustedPeersKey, _basePath);
|
||||||
file.writeEncrypted(data, _localKey);
|
file.writeEncrypted(data, _localKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::readTrustedBots() {
|
void Account::readTrustedPeers() {
|
||||||
if (_trustedBotsRead) {
|
if (_trustedPeersRead) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_trustedBotsRead = true;
|
_trustedPeersRead = true;
|
||||||
if (!_trustedBotsKey) {
|
if (!_trustedPeersKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileReadDescriptor trusted;
|
FileReadDescriptor trusted;
|
||||||
if (!ReadEncryptedFile(trusted, _trustedBotsKey, _basePath, _localKey)) {
|
if (!ReadEncryptedFile(trusted, _trustedPeersKey, _basePath, _localKey)) {
|
||||||
ClearKey(_trustedBotsKey, _basePath);
|
ClearKey(_trustedPeersKey, _basePath);
|
||||||
_trustedBotsKey = 0;
|
_trustedPeersKey = 0;
|
||||||
writeMapDelayed();
|
writeMapDelayed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3197,76 +3197,106 @@ void Account::readTrustedBots() {
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
auto value = quint64();
|
auto value = quint64();
|
||||||
trusted.stream >> value;
|
trusted.stream >> value;
|
||||||
const auto mask = base::flags<BotTrustFlag>::from_raw(
|
const auto mask = base::flags<PeerTrustFlag>::from_raw(
|
||||||
uchar(value >> 56));
|
uchar(value >> 56));
|
||||||
const auto peerIdSerialized = value & ~(0xFFULL << 56);
|
const auto peerIdSerialized = value & ~(0xFFULL << 56);
|
||||||
const auto peerId = DeserializePeerId(peerIdSerialized);
|
const auto peerId = DeserializePeerId(peerIdSerialized);
|
||||||
_trustedBots.emplace(peerId, mask);
|
_trustedPeers.emplace(peerId, mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::markBotTrustedOpenGame(PeerId botId) {
|
void Account::markPeerTrustedOpenGame(PeerId peerId) {
|
||||||
if (isBotTrustedOpenGame(botId)) {
|
if (isPeerTrustedOpenGame(peerId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto i = _trustedBots.find(botId);
|
const auto i = _trustedPeers.find(peerId);
|
||||||
if (i == end(_trustedBots)) {
|
if (i == end(_trustedPeers)) {
|
||||||
_trustedBots.emplace(botId, BotTrustFlag());
|
_trustedPeers.emplace(peerId, PeerTrustFlag());
|
||||||
} else {
|
} else {
|
||||||
i->second &= ~BotTrustFlag::NoOpenGame;
|
i->second &= ~PeerTrustFlag::NoOpenGame;
|
||||||
}
|
}
|
||||||
writeTrustedBots();
|
writeTrustedPeers();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Account::isBotTrustedOpenGame(PeerId botId) {
|
bool Account::isPeerTrustedOpenGame(PeerId peerId) {
|
||||||
readTrustedBots();
|
readTrustedPeers();
|
||||||
const auto i = _trustedBots.find(botId);
|
const auto i = _trustedPeers.find(peerId);
|
||||||
return (i != end(_trustedBots))
|
return (i != end(_trustedPeers))
|
||||||
&& ((i->second & BotTrustFlag::NoOpenGame) == 0);
|
&& ((i->second & PeerTrustFlag::NoOpenGame) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::markBotTrustedPayment(PeerId botId) {
|
void Account::markPeerTrustedPayment(PeerId peerId) {
|
||||||
if (isBotTrustedPayment(botId)) {
|
if (isPeerTrustedPayment(peerId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto i = _trustedBots.find(botId);
|
const auto i = _trustedPeers.find(peerId);
|
||||||
if (i == end(_trustedBots)) {
|
if (i == end(_trustedPeers)) {
|
||||||
_trustedBots.emplace(
|
_trustedPeers.emplace(
|
||||||
botId,
|
peerId,
|
||||||
BotTrustFlag::NoOpenGame | BotTrustFlag::Payment);
|
PeerTrustFlag::NoOpenGame | PeerTrustFlag::Payment);
|
||||||
} else {
|
} else {
|
||||||
i->second |= BotTrustFlag::Payment;
|
i->second |= PeerTrustFlag::Payment;
|
||||||
}
|
}
|
||||||
writeTrustedBots();
|
writeTrustedPeers();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Account::isBotTrustedPayment(PeerId botId) {
|
bool Account::isPeerTrustedPayment(PeerId peerId) {
|
||||||
readTrustedBots();
|
readTrustedPeers();
|
||||||
const auto i = _trustedBots.find(botId);
|
const auto i = _trustedPeers.find(peerId);
|
||||||
return (i != end(_trustedBots))
|
return (i != end(_trustedPeers))
|
||||||
&& ((i->second & BotTrustFlag::Payment) != 0);
|
&& ((i->second & PeerTrustFlag::Payment) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::markBotTrustedOpenWebView(PeerId botId) {
|
void Account::markPeerTrustedOpenWebView(PeerId peerId) {
|
||||||
if (isBotTrustedOpenWebView(botId)) {
|
if (isPeerTrustedOpenWebView(peerId)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto i = _trustedBots.find(botId);
|
const auto i = _trustedPeers.find(peerId);
|
||||||
if (i == end(_trustedBots)) {
|
if (i == end(_trustedPeers)) {
|
||||||
_trustedBots.emplace(
|
_trustedPeers.emplace(
|
||||||
botId,
|
peerId,
|
||||||
BotTrustFlag::NoOpenGame | BotTrustFlag::OpenWebView);
|
PeerTrustFlag::NoOpenGame | PeerTrustFlag::OpenWebView);
|
||||||
} else {
|
} else {
|
||||||
i->second |= BotTrustFlag::OpenWebView;
|
i->second |= PeerTrustFlag::OpenWebView;
|
||||||
}
|
}
|
||||||
writeTrustedBots();
|
writeTrustedPeers();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Account::isBotTrustedOpenWebView(PeerId botId) {
|
bool Account::isPeerTrustedOpenWebView(PeerId peerId) {
|
||||||
readTrustedBots();
|
readTrustedPeers();
|
||||||
const auto i = _trustedBots.find(botId);
|
const auto i = _trustedPeers.find(peerId);
|
||||||
return (i != end(_trustedBots))
|
return (i != end(_trustedPeers))
|
||||||
&& ((i->second & BotTrustFlag::OpenWebView) != 0);
|
&& ((i->second & PeerTrustFlag::OpenWebView) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Account::markPeerTrustedPayForMessage(PeerId peerId) {
|
||||||
|
if (isPeerTrustedPayForMessage(peerId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto i = _trustedPeers.find(peerId);
|
||||||
|
if (i == end(_trustedPeers)) {
|
||||||
|
_trustedPeers.emplace(
|
||||||
|
peerId,
|
||||||
|
PeerTrustFlag::NoOpenGame | PeerTrustFlag::PayForMessage);
|
||||||
|
} else {
|
||||||
|
i->second |= PeerTrustFlag::PayForMessage;
|
||||||
|
}
|
||||||
|
writeTrustedPeers();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Account::isPeerTrustedPayForMessage(PeerId peerId) {
|
||||||
|
readTrustedPeers();
|
||||||
|
const auto i = _trustedPeers.find(peerId);
|
||||||
|
return (i != end(_trustedPeers))
|
||||||
|
&& ((i->second & PeerTrustFlag::PayForMessage) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Account::clearPeerTrusted(PeerId peerId) {
|
||||||
|
const auto i = _trustedPeers.find(peerId);
|
||||||
|
if (i != end(_trustedPeers)) {
|
||||||
|
_trustedPeers.erase(i);
|
||||||
|
writeTrustedPeers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::enforceModernStorageIdBots() {
|
void Account::enforceModernStorageIdBots() {
|
||||||
|
|
|
@ -167,12 +167,15 @@ public:
|
||||||
const QByteArray& serialized,
|
const QByteArray& serialized,
|
||||||
int32 streamVersion);
|
int32 streamVersion);
|
||||||
|
|
||||||
void markBotTrustedOpenGame(PeerId botId);
|
void markPeerTrustedOpenGame(PeerId peerId);
|
||||||
[[nodiscard]] bool isBotTrustedOpenGame(PeerId botId);
|
[[nodiscard]] bool isPeerTrustedOpenGame(PeerId peerId);
|
||||||
void markBotTrustedPayment(PeerId botId);
|
void markPeerTrustedPayment(PeerId peerId);
|
||||||
[[nodiscard]] bool isBotTrustedPayment(PeerId botId);
|
[[nodiscard]] bool isPeerTrustedPayment(PeerId peerId);
|
||||||
void markBotTrustedOpenWebView(PeerId botId);
|
void markPeerTrustedOpenWebView(PeerId peerId);
|
||||||
[[nodiscard]] bool isBotTrustedOpenWebView(PeerId botId);
|
[[nodiscard]] bool isPeerTrustedOpenWebView(PeerId peerId);
|
||||||
|
void markPeerTrustedPayForMessage(PeerId peerId);
|
||||||
|
[[nodiscard]] bool isPeerTrustedPayForMessage(PeerId peerId);
|
||||||
|
void clearPeerTrusted(PeerId peerId);
|
||||||
|
|
||||||
void enforceModernStorageIdBots();
|
void enforceModernStorageIdBots();
|
||||||
[[nodiscard]] Webview::StorageId resolveStorageIdBots();
|
[[nodiscard]] Webview::StorageId resolveStorageIdBots();
|
||||||
|
@ -203,12 +206,13 @@ private:
|
||||||
IncorrectPasscode,
|
IncorrectPasscode,
|
||||||
Failed,
|
Failed,
|
||||||
};
|
};
|
||||||
enum class BotTrustFlag : uchar {
|
enum class PeerTrustFlag : uchar {
|
||||||
NoOpenGame = (1 << 0),
|
NoOpenGame = (1 << 0),
|
||||||
Payment = (1 << 1),
|
Payment = (1 << 1),
|
||||||
OpenWebView = (1 << 2),
|
OpenWebView = (1 << 2),
|
||||||
|
PayForMessage = (1 << 3),
|
||||||
};
|
};
|
||||||
friend inline constexpr bool is_flag_type(BotTrustFlag) { return true; };
|
friend inline constexpr bool is_flag_type(PeerTrustFlag) { return true; };
|
||||||
|
|
||||||
[[nodiscard]] base::flat_set<QString> collectGoodNames() const;
|
[[nodiscard]] base::flat_set<QString> collectGoodNames() const;
|
||||||
[[nodiscard]] auto prepareReadSettingsContext() const
|
[[nodiscard]] auto prepareReadSettingsContext() const
|
||||||
|
@ -261,8 +265,8 @@ private:
|
||||||
Data::StickersSetFlags readingFlags = 0);
|
Data::StickersSetFlags readingFlags = 0);
|
||||||
void importOldRecentStickers();
|
void importOldRecentStickers();
|
||||||
|
|
||||||
void readTrustedBots();
|
void readTrustedPeers();
|
||||||
void writeTrustedBots();
|
void writeTrustedPeers();
|
||||||
|
|
||||||
void readMediaLastPlaybackPositions();
|
void readMediaLastPlaybackPositions();
|
||||||
void writeMediaLastPlaybackPositions();
|
void writeMediaLastPlaybackPositions();
|
||||||
|
@ -295,7 +299,7 @@ private:
|
||||||
Fn<std::optional<QByteArray>()> _downloadsSerialize;
|
Fn<std::optional<QByteArray>()> _downloadsSerialize;
|
||||||
|
|
||||||
FileKey _locationsKey = 0;
|
FileKey _locationsKey = 0;
|
||||||
FileKey _trustedBotsKey = 0;
|
FileKey _trustedPeersKey = 0;
|
||||||
FileKey _installedStickersKey = 0;
|
FileKey _installedStickersKey = 0;
|
||||||
FileKey _featuredStickersKey = 0;
|
FileKey _featuredStickersKey = 0;
|
||||||
FileKey _recentStickersKey = 0;
|
FileKey _recentStickersKey = 0;
|
||||||
|
@ -324,8 +328,8 @@ private:
|
||||||
qint32 _cacheTotalTimeLimit = 0;
|
qint32 _cacheTotalTimeLimit = 0;
|
||||||
qint32 _cacheBigFileTotalTimeLimit = 0;
|
qint32 _cacheBigFileTotalTimeLimit = 0;
|
||||||
|
|
||||||
base::flat_map<PeerId, base::flags<BotTrustFlag>> _trustedBots;
|
base::flat_map<PeerId, base::flags<PeerTrustFlag>> _trustedPeers;
|
||||||
bool _trustedBotsRead = false;
|
bool _trustedPeersRead = false;
|
||||||
bool _readingUserSettings = false;
|
bool _readingUserSettings = false;
|
||||||
bool _recentHashtagsAndBotsWereRead = false;
|
bool _recentHashtagsAndBotsWereRead = false;
|
||||||
bool _searchSuggestionsRead = false;
|
bool _searchSuggestionsRead = false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue