mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 23:27:09 +02:00
Update API scheme, new paid.
This commit is contained in:
parent
852ab19760
commit
960cf7a34b
22 changed files with 302 additions and 290 deletions
Telegram
Resources/langs
SourceFiles
api
apiwrap.cppapiwrap.hboxes
data
data_channel.cppdata_channel.hdata_chat_participant_status.cppdata_chat_participant_status.hdata_peer.cppdata_peer.hdata_user.cppdata_user.h
history
media/stories
mtproto/scheme
|
@ -3650,6 +3650,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_send_anonymous_ph" = "Send anonymously...";
|
||||
"lng_story_reply_ph" = "Reply privately...";
|
||||
"lng_story_comment_ph" = "Comment story...";
|
||||
"lng_message_paid_ph" = "Message for {amount}";
|
||||
"lng_send_text_no" = "Text not allowed.";
|
||||
"lng_send_text_no_about" = "The admins of this group only allow sending {types}.";
|
||||
"lng_send_text_type_and_last" = "{types} and {last}";
|
||||
|
@ -4822,7 +4823,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_slowmode_seconds#one" = "{count} second";
|
||||
"lng_slowmode_seconds#other" = "{count} seconds";
|
||||
|
||||
"lng_payment_for_message" = "Pay {cost} for 1 Message";
|
||||
"lng_payment_confirm_title" = "Confirm payment";
|
||||
"lng_payment_confirm_text#one" = "{name} charges **{count}** Star per message.";
|
||||
"lng_payment_confirm_text#other" = "{name} charges **{count}** Stars per message.";
|
||||
|
|
|
@ -25,6 +25,7 @@ struct SendOptions {
|
|||
TimeId scheduled = 0;
|
||||
BusinessShortcutId shortcutId = 0;
|
||||
EffectId effectId = 0;
|
||||
int starsApproved = 0;
|
||||
bool silent = false;
|
||||
bool handleSupportSwitch = false;
|
||||
bool invertCaption = false;
|
||||
|
|
|
@ -37,7 +37,7 @@ Polls::Polls(not_null<ApiWrap*> api)
|
|||
|
||||
void Polls::create(
|
||||
const PollData &data,
|
||||
const SendAction &action,
|
||||
SendAction action,
|
||||
Fn<void()> done,
|
||||
Fn<void()> fail) {
|
||||
_session->api().sendAction(action);
|
||||
|
@ -59,7 +59,9 @@ void Polls::create(
|
|||
history->startSavingCloudDraft(topicRootId);
|
||||
}
|
||||
const auto silentPost = ShouldSendSilent(peer, action.options);
|
||||
const auto starsPaid = peer->commitStarsForMessage();
|
||||
const auto starsPaid = std::min(
|
||||
peer->starsPerMessageChecked(),
|
||||
action.options.starsApproved);
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||
}
|
||||
|
@ -73,6 +75,7 @@ void Polls::create(
|
|||
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||
}
|
||||
if (starsPaid) {
|
||||
action.options.starsApproved -= starsPaid;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||
}
|
||||
const auto sendAs = action.options.sendAs;
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
|
||||
void create(
|
||||
const PollData &data,
|
||||
const SendAction &action,
|
||||
SendAction action,
|
||||
Fn<void()> done,
|
||||
Fn<void()> fail);
|
||||
void sendVotes(
|
||||
|
|
|
@ -95,8 +95,9 @@ void SendSimpleMedia(SendAction action, MTPInputMedia inputMedia) {
|
|||
const auto messagePostAuthor = peer->isBroadcast()
|
||||
? session->user()->name()
|
||||
: QString();
|
||||
const auto starsPaid = peer->commitStarsForMessage();
|
||||
|
||||
const auto starsPaid = std::min(
|
||||
peer->starsPerMessageChecked(),
|
||||
action.options.starsApproved);
|
||||
if (action.options.scheduled) {
|
||||
flags |= MessageFlag::IsOrWasScheduled;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
|
||||
|
@ -113,6 +114,7 @@ void SendSimpleMedia(SendAction action, MTPInputMedia inputMedia) {
|
|||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||
}
|
||||
if (starsPaid) {
|
||||
action.options.starsApproved -= starsPaid;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||
}
|
||||
|
||||
|
@ -165,7 +167,7 @@ void SendExistingMedia(
|
|||
? (*localMessageId)
|
||||
: session->data().nextLocalMessageId());
|
||||
const auto randomId = base::RandomValue<uint64>();
|
||||
const auto &action = message.action;
|
||||
auto &action = message.action;
|
||||
|
||||
auto flags = NewMessageFlags(peer);
|
||||
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
||||
|
@ -195,8 +197,9 @@ void SendExistingMedia(
|
|||
sendFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
||||
}
|
||||
const auto captionText = caption.text;
|
||||
const auto starsPaid = peer->commitStarsForMessage();
|
||||
|
||||
const auto starsPaid = std::min(
|
||||
peer->starsPerMessageChecked(),
|
||||
action.options.starsApproved);
|
||||
if (action.options.scheduled) {
|
||||
flags |= MessageFlag::IsOrWasScheduled;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
|
||||
|
@ -213,6 +216,7 @@ void SendExistingMedia(
|
|||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||
}
|
||||
if (starsPaid) {
|
||||
action.options.starsApproved -= starsPaid;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||
}
|
||||
|
||||
|
@ -351,7 +355,7 @@ bool SendDice(MessageToSend &message) {
|
|||
message.action.generateLocal = true;
|
||||
|
||||
|
||||
const auto &action = message.action;
|
||||
auto &action = message.action;
|
||||
api->sendAction(action);
|
||||
|
||||
const auto newId = FullMsgId(
|
||||
|
@ -390,8 +394,11 @@ bool SendDice(MessageToSend &message) {
|
|||
flags |= MessageFlag::InvertMedia;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||
}
|
||||
const auto starsPaid = peer->commitStarsForMessage();
|
||||
const auto starsPaid = std::min(
|
||||
peer->starsPerMessageChecked(),
|
||||
action.options.starsApproved);
|
||||
if (starsPaid) {
|
||||
action.options.starsApproved -= starsPaid;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||
}
|
||||
|
||||
|
|
|
@ -3883,8 +3883,11 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
|||
sendFlags |= MTPmessages_SendMessage::Flag::f_effect;
|
||||
mediaFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||
}
|
||||
const auto starsPaid = peer->commitStarsForMessage();
|
||||
const auto starsPaid = std::min(
|
||||
peer->starsPerMessageChecked(),
|
||||
action.options.starsApproved);
|
||||
if (starsPaid) {
|
||||
action.options.starsApproved -= starsPaid;
|
||||
sendFlags |= MTPmessages_SendMessage::Flag::f_allow_paid_stars;
|
||||
mediaFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||
}
|
||||
|
@ -4020,7 +4023,7 @@ void ApiWrap::sendBotStart(
|
|||
void ApiWrap::sendInlineResult(
|
||||
not_null<UserData*> bot,
|
||||
not_null<InlineBots::Result*> data,
|
||||
const SendAction &action,
|
||||
SendAction action,
|
||||
std::optional<MsgId> localMessageId,
|
||||
Fn<void(bool)> done) {
|
||||
sendAction(action);
|
||||
|
@ -4060,8 +4063,11 @@ void ApiWrap::sendInlineResult(
|
|||
if (action.options.hideViaBot) {
|
||||
sendFlags |= SendFlag::f_hide_via;
|
||||
}
|
||||
const auto starsPaid = peer->commitStarsForMessage();
|
||||
const auto starsPaid = std::min(
|
||||
peer->starsPerMessageChecked(),
|
||||
action.options.starsApproved);
|
||||
if (starsPaid) {
|
||||
action.options.starsApproved -= starsPaid;
|
||||
sendFlags |= SendFlag::f_allow_paid_stars;
|
||||
}
|
||||
|
||||
|
@ -4244,7 +4250,12 @@ void ApiWrap::sendMediaWithRandomId(
|
|||
Api::ConvertOption::SkipLocal);
|
||||
|
||||
const auto updateRecentStickers = Api::HasAttachedStickers(media);
|
||||
const auto starsPaid = peer->commitStarsForMessage();
|
||||
const auto starsPaid = std::min(
|
||||
peer->starsPerMessageChecked(),
|
||||
options.starsApproved);
|
||||
if (starsPaid) {
|
||||
options.starsApproved -= starsPaid;
|
||||
}
|
||||
|
||||
using Flag = MTPmessages_SendMedia::Flag;
|
||||
const auto flags = Flag(0)
|
||||
|
@ -4304,7 +4315,7 @@ void ApiWrap::sendMultiPaidMedia(
|
|||
Expects(album->options.price > 0);
|
||||
|
||||
const auto groupId = album->groupId;
|
||||
const auto &options = album->options;
|
||||
auto &options = album->options;
|
||||
const auto randomId = album->items.front().randomId;
|
||||
auto medias = album->items | ranges::view::transform([](
|
||||
const SendingAlbum::Item &part) {
|
||||
|
@ -4322,7 +4333,12 @@ void ApiWrap::sendMultiPaidMedia(
|
|||
_session,
|
||||
caption.entities,
|
||||
Api::ConvertOption::SkipLocal);
|
||||
const auto starsPaid = peer->commitStarsForMessage();
|
||||
const auto starsPaid = std::min(
|
||||
peer->starsPerMessageChecked(),
|
||||
options.starsApproved);
|
||||
if (starsPaid) {
|
||||
options.starsApproved -= starsPaid;
|
||||
}
|
||||
|
||||
using Flag = MTPmessages_SendMedia::Flag;
|
||||
const auto flags = Flag(0)
|
||||
|
@ -4452,7 +4468,12 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
|||
const auto history = sample->history();
|
||||
const auto replyTo = sample->replyTo();
|
||||
const auto sendAs = album->options.sendAs;
|
||||
const auto starsPaid = history->peer->commitStarsForMessage();
|
||||
const auto starsPaid = std::min(
|
||||
history->peer->starsPerMessageChecked(),
|
||||
album->options.starsApproved);
|
||||
if (starsPaid) {
|
||||
album->options.starsApproved -= starsPaid;
|
||||
}
|
||||
using Flag = MTPmessages_SendMultiMedia::Flag;
|
||||
const auto flags = Flag(0)
|
||||
| (replyTo ? Flag::f_reply_to : Flag(0))
|
||||
|
|
|
@ -368,7 +368,7 @@ public:
|
|||
void sendInlineResult(
|
||||
not_null<UserData*> bot,
|
||||
not_null<InlineBots::Result*> data,
|
||||
const SendAction &action,
|
||||
SendAction action,
|
||||
std::optional<MsgId> localMessageId,
|
||||
Fn<void(bool)> done = nullptr);
|
||||
void sendMessageFail(
|
||||
|
|
|
@ -1568,7 +1568,12 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
|
|||
: topicRootId;
|
||||
const auto peer = thread->peer();
|
||||
const auto threadHistory = thread->owningHistory();
|
||||
const auto starsPaid = peer->commitStarsForMessage();
|
||||
const auto starsPaid = std::min(
|
||||
peer->starsPerMessageChecked(),
|
||||
options.starsApproved);
|
||||
if (starsPaid) {
|
||||
options.starsApproved -= starsPaid;
|
||||
}
|
||||
histories.sendRequest(threadHistory, requestType, [=](
|
||||
Fn<void()> finish) {
|
||||
const auto session = &threadHistory->session();
|
||||
|
|
|
@ -880,48 +880,6 @@ void ChannelData::setStarsPerMessage(int stars) {
|
|||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
return _peerGiftsCount;
|
||||
}
|
||||
|
|
|
@ -153,7 +153,6 @@ private:
|
|||
Data::ChatBotCommands _botCommands;
|
||||
std::unique_ptr<Data::Forum> _forum;
|
||||
int _starsPerMessage = 0;
|
||||
int _starsForMessageLocked = 0;
|
||||
|
||||
friend class ChannelData;
|
||||
|
||||
|
@ -464,10 +463,6 @@ public:
|
|||
|
||||
void setStarsPerMessage(int stars);
|
||||
[[nodiscard]] int starsPerMessage() const;
|
||||
[[nodiscard]] int starsForMessageLocked() const;
|
||||
void lockStarsForMessage();
|
||||
[[nodiscard]] int commitStarsForMessage();
|
||||
void cancelStarsForMessage();
|
||||
|
||||
[[nodiscard]] int peerGiftsCount() const;
|
||||
void setPeerGiftsCount(int count);
|
||||
|
|
|
@ -17,10 +17,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_user.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "storage/storage_account.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -425,4 +430,59 @@ void ShowSendErrorToast(
|
|||
});
|
||||
}
|
||||
|
||||
void ShowSendPaidConfirm(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<PeerData*> peer,
|
||||
SendError error,
|
||||
Fn<void()> confirmed) {
|
||||
return ShowSendPaidConfirm(navigation->uiShow(), peer, error, confirmed);
|
||||
}
|
||||
|
||||
void ShowSendPaidConfirm(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
Data::SendError error,
|
||||
Fn<void()> confirmed) {
|
||||
const auto session = &peer->session();
|
||||
if (session->local().isPeerTrustedPayForMessage(peer->id)) {
|
||||
confirmed();
|
||||
return;
|
||||
}
|
||||
//const auto messages = error.paidMessages;
|
||||
const auto stars = error.paidStars;
|
||||
show->showBox(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
const auto trust = std::make_shared<QPointer<Ui::Checkbox>>();
|
||||
const auto proceed = [=](Fn<void()> close) {
|
||||
if ((*trust)->checked()) {
|
||||
session->local().markPeerTrustedPayForMessage(peer->id);
|
||||
}
|
||||
confirmed();
|
||||
close();
|
||||
};
|
||||
Ui::ConfirmBox(box, {
|
||||
.text = tr::lng_payment_confirm_text(
|
||||
tr::now,
|
||||
lt_count,
|
||||
stars,
|
||||
lt_name,
|
||||
Ui::Text::Bold(peer->shortName()),
|
||||
Ui::Text::RichLangValue).append(' ').append(
|
||||
tr::lng_payment_confirm_sure(
|
||||
tr::now,
|
||||
lt_count,
|
||||
stars,
|
||||
Ui::Text::RichLangValue)),
|
||||
.confirmed = proceed,
|
||||
.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));
|
||||
}));
|
||||
}
|
||||
|
||||
} // namespace Data
|
||||
|
|
|
@ -189,17 +189,26 @@ struct SendError {
|
|||
|
||||
struct Args {
|
||||
QString text;
|
||||
int paidStars = 0;
|
||||
int paidMessages = 0;
|
||||
int boostsToLift = 0;
|
||||
bool resolving = false;
|
||||
bool premiumToLift = false;
|
||||
};
|
||||
SendError(Args &&args)
|
||||
: text(std::move(args.text))
|
||||
, paidStars(args.paidStars)
|
||||
, paidMessages(args.paidMessages)
|
||||
, boostsToLift(args.boostsToLift)
|
||||
, resolving(args.resolving)
|
||||
, premiumToLift(args.premiumToLift) {
|
||||
}
|
||||
|
||||
QString text;
|
||||
int paidStars = 0;
|
||||
int paidMessages = 0;
|
||||
int boostsToLift = 0;
|
||||
bool resolving = false;
|
||||
bool premiumToLift = false;
|
||||
|
||||
[[nodiscard]] SendError value_or(SendError other) const {
|
||||
|
@ -244,4 +253,15 @@ void ShowSendErrorToast(
|
|||
not_null<PeerData*> peer,
|
||||
SendError error);
|
||||
|
||||
void ShowSendPaidConfirm(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<PeerData*> peer,
|
||||
SendError error,
|
||||
Fn<void()> confirmed);
|
||||
void ShowSendPaidConfirm(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
SendError error,
|
||||
Fn<void()> confirmed);
|
||||
|
||||
} // namespace Data
|
||||
|
|
|
@ -1459,38 +1459,13 @@ int PeerData::starsPerMessage() const {
|
|||
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();
|
||||
int PeerData::starsPerMessageChecked() const {
|
||||
if (const auto channel = asChannel()) {
|
||||
return (channel->adminRights() || channel->amCreator())
|
||||
? 0
|
||||
: channel->starsPerMessage();
|
||||
}
|
||||
return starsPerMessage();
|
||||
}
|
||||
|
||||
Data::GroupCall *PeerData::groupCall() const {
|
||||
|
|
|
@ -269,10 +269,7 @@ public:
|
|||
[[nodiscard]] bool canManageGroupCall() const;
|
||||
|
||||
[[nodiscard]] int starsPerMessage() const;
|
||||
[[nodiscard]] int starsForMessageLocked() const;
|
||||
void lockStarsForMessage();
|
||||
[[nodiscard]] int commitStarsForMessage();
|
||||
void cancelStarsForMessage();
|
||||
[[nodiscard]] int starsPerMessageChecked() const;
|
||||
|
||||
[[nodiscard]] UserData *asBot();
|
||||
[[nodiscard]] const UserData *asBot() const;
|
||||
|
|
|
@ -552,38 +552,6 @@ void UserData::setStarsPerMessage(int stars) {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
bool UserData::canAddContact() const {
|
||||
return canShareThisContact() && !isContact();
|
||||
}
|
||||
|
|
|
@ -184,10 +184,6 @@ public:
|
|||
|
||||
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 canAddContact() const;
|
||||
|
@ -279,7 +275,6 @@ private:
|
|||
int _commonChatsCount = 0;
|
||||
int _peerGiftsCount = 0;
|
||||
int _starsPerMessage = 0;
|
||||
int _starsForMessageLocked = 0;
|
||||
ContactStatus _contactStatus = ContactStatus::Unknown;
|
||||
CallsStatus _callsStatus = CallsStatus::Unknown;
|
||||
|
||||
|
|
|
@ -93,10 +93,33 @@ Data::SendError GetErrorForSending(
|
|||
return tr::lng_forward_cant(tr::now);
|
||||
}
|
||||
}
|
||||
if (peer->slowmodeApplied()) {
|
||||
const auto count = (hasText ? 1 : 0)
|
||||
const auto countMessages = [&] {
|
||||
auto result = 0;
|
||||
if (hasText) {
|
||||
auto sending = TextWithEntities();
|
||||
auto left = TextWithEntities{
|
||||
request.text->text,
|
||||
TextUtilities::ConvertTextTagsToEntities(request.text->tags)
|
||||
};
|
||||
auto prepareFlags = Ui::ItemTextOptions(
|
||||
thread->owningHistory(),
|
||||
peer->session().user()).flags;
|
||||
TextUtilities::PrepareForSending(left, prepareFlags);
|
||||
|
||||
while (TextUtilities::CutPart(sending, left, MaxMessageSize)) {
|
||||
++result;
|
||||
}
|
||||
if (!result) {
|
||||
++result;
|
||||
}
|
||||
}
|
||||
return result
|
||||
+ (request.story ? 1 : 0)
|
||||
+ (request.mediaMessage ? 1 : 0)
|
||||
+ (request.forward ? int(request.forward->size()) : 0);
|
||||
};
|
||||
if (peer->slowmodeApplied()) {
|
||||
const auto count = countMessages();
|
||||
if (const auto history = peer->owner().historyLoaded(peer)) {
|
||||
if (!request.ignoreSlowmodeCountdown
|
||||
&& (history->latestSendingMessage() != nullptr)
|
||||
|
@ -135,6 +158,28 @@ Data::SendError GetErrorForSending(
|
|||
}
|
||||
}
|
||||
|
||||
if (const auto user = peer->asUser()) {
|
||||
if (user->hasStarsPerMessage()
|
||||
&& !user->messageMoneyRestrictionsKnown()) {
|
||||
user->updateFull();
|
||||
return Data::SendError({ .resolving = true });
|
||||
}
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
if (!channel->isFullLoaded()) {
|
||||
channel->updateFull();
|
||||
return Data::SendError({ .resolving = true });
|
||||
}
|
||||
}
|
||||
if (!peer->session().credits().loaded()) {
|
||||
peer->session().credits().load();
|
||||
return Data::SendError({ .resolving = true });
|
||||
} else if (const auto perMessage = peer->starsPerMessageChecked()) {
|
||||
const auto count = countMessages();
|
||||
return Data::SendError({
|
||||
.paidStars = count * perMessage,
|
||||
.paidMessages = count,
|
||||
});
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ struct SendingErrorRequest {
|
|||
const Data::Story *story = nullptr;
|
||||
const TextWithTags *text = nullptr;
|
||||
bool ignoreSlowmodeCountdown = false;
|
||||
bool mediaMessage = false;
|
||||
};
|
||||
[[nodiscard]] Data::SendError GetErrorForSending(
|
||||
not_null<PeerData*> peer,
|
||||
|
|
|
@ -266,7 +266,6 @@ HistoryWidget::HistoryWidget(
|
|||
tr::lng_channel_mute(tr::now).toUpper(),
|
||||
st::historyComposeButton)
|
||||
, _reportMessages(this, QString(), st::historyComposeButton)
|
||||
, _payForMessage(this, QString(), st::historyComposeButton)
|
||||
, _attachToggle(this, st::historyAttach)
|
||||
, _tabbedSelectorToggle(this, st::historyAttachEmoji)
|
||||
, _botKeyboardShow(this, st::historyBotKeyboardShow)
|
||||
|
@ -384,7 +383,6 @@ HistoryWidget::HistoryWidget(
|
|||
_muteUnmute->addClickHandler([=] { toggleMuteUnmute(); });
|
||||
setupGiftToChannelButton();
|
||||
_reportMessages->addClickHandler([=] { reportSelectedMessages(); });
|
||||
_payForMessage->addClickHandler([=] { payForMessage(); });
|
||||
_field->submits(
|
||||
) | rpl::start_with_next([=](Qt::KeyboardModifiers modifiers) {
|
||||
sendWithModifiers(modifiers);
|
||||
|
@ -525,7 +523,6 @@ HistoryWidget::HistoryWidget(
|
|||
_joinChannel->hide();
|
||||
_muteUnmute->hide();
|
||||
_reportMessages->hide();
|
||||
_payForMessage->hide();
|
||||
|
||||
initVoiceRecordBar();
|
||||
|
||||
|
@ -816,7 +813,7 @@ HistoryWidget::HistoryWidget(
|
|||
|
||||
const auto was = (_sendAs != nullptr);
|
||||
refreshSendAsToggle();
|
||||
if (was != (_sendAs != nullptr) || _peer->starsPerMessage()) {
|
||||
if (was != (_sendAs != nullptr)) {
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
orderWidgets();
|
||||
|
@ -839,8 +836,10 @@ HistoryWidget::HistoryWidget(
|
|||
return;
|
||||
}
|
||||
}
|
||||
if ((flags & PeerUpdateFlag::BotStartToken)
|
||||
|| (flags & PeerUpdateFlag::StarsPerMessage)) {
|
||||
if (flags & PeerUpdateFlag::StarsPerMessage) {
|
||||
updateFieldPlaceholder();
|
||||
}
|
||||
if (flags & PeerUpdateFlag::BotStartToken) {
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
}
|
||||
|
@ -878,7 +877,9 @@ HistoryWidget::HistoryWidget(
|
|||
}
|
||||
if (flags & PeerUpdateFlag::FullInfo) {
|
||||
fullInfoUpdated();
|
||||
if (const auto channel = _peer->asChannel()) {
|
||||
if (_peer->starsPerMessageChecked()) {
|
||||
session().credits().load();
|
||||
} else if (const auto channel = _peer->asChannel()) {
|
||||
if (channel->allowedReactions().paidEnabled) {
|
||||
session().credits().load();
|
||||
}
|
||||
|
@ -886,6 +887,15 @@ HistoryWidget::HistoryWidget(
|
|||
}
|
||||
}, lifetime());
|
||||
|
||||
session().credits().loadedValue(
|
||||
) | rpl::filter(
|
||||
rpl::mappers::_1
|
||||
) | rpl::take(1) | rpl::start_with_next([=] {
|
||||
if (const auto callback = base::take(_resendOnFullUpdated)) {
|
||||
callback();
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
using Type = Data::DefaultNotify;
|
||||
rpl::merge(
|
||||
session().data().notifySettings().defaultUpdates(Type::User),
|
||||
|
@ -1100,19 +1110,8 @@ void HistoryWidget::initVoiceRecordBar() {
|
|||
}, lifetime());
|
||||
|
||||
_voiceRecordBar->sendVoiceRequests(
|
||||
) | rpl::start_with_next([=](const auto &data) {
|
||||
if (!canWriteMessage() || data.bytes.isEmpty() || !_history) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto action = prepareSendAction(data.options);
|
||||
session().api().sendVoiceMessage(
|
||||
data.bytes,
|
||||
data.waveform,
|
||||
data.duration,
|
||||
data.video,
|
||||
action);
|
||||
_voiceRecordBar->clearListenState();
|
||||
) | rpl::start_with_next([=](const VoiceToSend &data) {
|
||||
sendVoice(data);
|
||||
}, lifetime());
|
||||
|
||||
_voiceRecordBar->cancelRequests(
|
||||
|
@ -1965,7 +1964,6 @@ void HistoryWidget::setInnerFocus() {
|
|||
|| isRecording()
|
||||
|| isJoinChannel()
|
||||
|| isBotStart()
|
||||
|| isPayForMessage()
|
||||
|| isBlocked()
|
||||
|| (!_canSendTexts && !_editMsgId)) {
|
||||
if (_scroll->isHidden()) {
|
||||
|
@ -2388,10 +2386,8 @@ void HistoryWidget::showHistory(
|
|||
|
||||
setHistory(nullptr);
|
||||
_list = nullptr;
|
||||
if (_peer) {
|
||||
_peer->cancelStarsForMessage();
|
||||
}
|
||||
_peer = nullptr;
|
||||
_resendOnFullUpdated = nullptr;
|
||||
_topicsRequested.clear();
|
||||
_canSendMessages = false;
|
||||
_canSendTexts = false;
|
||||
|
@ -3035,7 +3031,6 @@ bool HistoryWidget::canWriteMessage() const {
|
|||
&& !isJoinChannel()
|
||||
&& !isMuteUnmute()
|
||||
&& !isBotStart()
|
||||
&& !isPayForMessage()
|
||||
&& !isSearching();
|
||||
}
|
||||
|
||||
|
@ -3096,7 +3091,6 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
|| isJoinChannel()
|
||||
|| isMuteUnmute()
|
||||
|| isBotStart()
|
||||
|| isPayForMessage()
|
||||
|| isReportMessages()))) {
|
||||
const auto toggle = [&](Ui::FlatButton *shown) {
|
||||
const auto toggleOne = [&](not_null<Ui::FlatButton*> button) {
|
||||
|
@ -3108,7 +3102,6 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
}
|
||||
};
|
||||
toggleOne(_reportMessages);
|
||||
toggleOne(_payForMessage);
|
||||
toggleOne(_joinChannel);
|
||||
toggleOne(_muteUnmute);
|
||||
toggleOne(_botStart);
|
||||
|
@ -3122,8 +3115,6 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
toggle(_reportMessages);
|
||||
} else if (isBlocked()) {
|
||||
toggle(_unblock);
|
||||
} else if (isPayForMessage()) {
|
||||
toggle(_payForMessage);
|
||||
} else if (isJoinChannel()) {
|
||||
toggle(_joinChannel);
|
||||
} else if (isMuteUnmute()) {
|
||||
|
@ -3186,7 +3177,6 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_joinChannel->hide();
|
||||
_muteUnmute->hide();
|
||||
_reportMessages->hide();
|
||||
_payForMessage->hide();
|
||||
_send->show();
|
||||
updateSendButtonType();
|
||||
|
||||
|
@ -3300,7 +3290,6 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
_joinChannel->hide();
|
||||
_muteUnmute->hide();
|
||||
_reportMessages->hide();
|
||||
_payForMessage->hide();
|
||||
_attachToggle->hide();
|
||||
if (_silent) {
|
||||
_silent->hide();
|
||||
|
@ -4352,6 +4341,36 @@ Api::SendAction HistoryWidget::prepareSendAction(
|
|||
return result;
|
||||
}
|
||||
|
||||
void HistoryWidget::sendVoice(const VoiceToSend &data) {
|
||||
if (!canWriteMessage() || data.bytes.isEmpty() || !_history) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = data;
|
||||
copy.options.starsApproved = approved;
|
||||
sendVoice(copy);
|
||||
};
|
||||
const auto ignoreSlowmodeCountdown = data.options.scheduled != 0;
|
||||
if (showSendMessageError(
|
||||
{},
|
||||
ignoreSlowmodeCountdown,
|
||||
crl::guard(this, withPaymentApproved),
|
||||
data.options.starsApproved,
|
||||
true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto action = prepareSendAction(data.options);
|
||||
session().api().sendVoiceMessage(
|
||||
data.bytes,
|
||||
data.waveform,
|
||||
data.duration,
|
||||
data.video,
|
||||
action);
|
||||
_voiceRecordBar->clearListenState();
|
||||
}
|
||||
|
||||
void HistoryWidget::send(Api::SendOptions options) {
|
||||
if (!_history) {
|
||||
return;
|
||||
|
@ -4360,9 +4379,7 @@ void HistoryWidget::send(Api::SendOptions options) {
|
|||
return;
|
||||
} else if (!options.scheduled && showSlowmodeError()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_voiceRecordBar->isListenState()) {
|
||||
} else if (_voiceRecordBar->isListenState()) {
|
||||
_voiceRecordBar->requestToSendWithOptions(options);
|
||||
return;
|
||||
}
|
||||
|
@ -4376,9 +4393,16 @@ void HistoryWidget::send(Api::SendOptions options) {
|
|||
message.webPage = _preview->draft();
|
||||
|
||||
const auto ignoreSlowmodeCountdown = (options.scheduled != 0);
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = options;
|
||||
copy.starsApproved = approved;
|
||||
send(copy);
|
||||
};
|
||||
if (showSendMessageError(
|
||||
message.textWithTags,
|
||||
ignoreSlowmodeCountdown)) {
|
||||
ignoreSlowmodeCountdown,
|
||||
crl::guard(this, withPaymentApproved),
|
||||
options.starsApproved)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4541,53 +4565,7 @@ 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;
|
||||
|
@ -4595,7 +4573,6 @@ void HistoryWidget::payForMessageSure(bool trust) {
|
|||
const auto done = [=](Settings::SmallBalanceResult result) {
|
||||
if (result == Settings::SmallBalanceResult::Success
|
||||
|| result == Settings::SmallBalanceResult::Already) {
|
||||
_peer->lockStarsForMessage();
|
||||
if (canWriteMessage()) {
|
||||
setInnerFocus();
|
||||
}
|
||||
|
@ -5154,40 +5131,6 @@ bool HistoryWidget::isSearching() const {
|
|||
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 {
|
||||
return (_recordAvailability != Webrtc::RecordAvailability::None)
|
||||
&& !_voiceRecordBar->isListenState()
|
||||
|
@ -5245,7 +5188,6 @@ bool HistoryWidget::updateCmdStartShown() {
|
|||
&& _peer->asChannel()->mgInfo->botStatus > 0))) {
|
||||
if (!isBotStart()
|
||||
&& !isBlocked()
|
||||
&& !isPayForMessage()
|
||||
&& !_keyboard->hasMarkup()
|
||||
&& !_keyboard->forceReply()
|
||||
&& !_editMsgId) {
|
||||
|
@ -5659,7 +5601,7 @@ void HistoryWidget::moveFieldControls() {
|
|||
|
||||
// (_botMenu.button) (_attachToggle|_replaceMedia) (_sendAs) ---- _inlineResults ------------------------------ _tabbedPanel ------ _fieldBarCancel
|
||||
// (_attachDocument|_attachPhoto) _field (_ttlInfo) (_scheduled) (_silent|_cmdStart|_kbShow) (_kbHide|_tabbedSelectorToggle) _send
|
||||
// (_botStart|_unblock|_joinChannel|_muteUnmute|_reportMessages|_payForMessage)
|
||||
// (_botStart|_unblock|_joinChannel|_muteUnmute|_reportMessages)
|
||||
|
||||
auto buttonsBottom = bottom - _attachToggle->height();
|
||||
auto left = st::historySendRight;
|
||||
|
@ -5733,7 +5675,6 @@ void HistoryWidget::moveFieldControls() {
|
|||
_joinChannel->setGeometry(fullWidthButtonRect);
|
||||
_muteUnmute->setGeometry(fullWidthButtonRect);
|
||||
_reportMessages->setGeometry(fullWidthButtonRect);
|
||||
_payForMessage->setGeometry(fullWidthButtonRect);
|
||||
if (_sendRestriction) {
|
||||
_sendRestriction->setGeometry(fullWidthButtonRect);
|
||||
}
|
||||
|
@ -5824,14 +5765,21 @@ void HistoryWidget::updateFieldPlaceholder() {
|
|||
}
|
||||
|
||||
_field->setPlaceholder([&]() -> rpl::producer<QString> {
|
||||
const auto peer = _history ? _history->peer.get() : nullptr;
|
||||
if (_editMsgId) {
|
||||
return tr::lng_edit_message_text();
|
||||
} else if (!_history) {
|
||||
} else if (!peer) {
|
||||
return tr::lng_message_ph();
|
||||
} else if ((_kbShown || _keyboard->forceReply())
|
||||
&& !_keyboard->placeholder().isEmpty()) {
|
||||
return rpl::single(_keyboard->placeholder());
|
||||
} else if (const auto channel = _history->peer->asChannel()) {
|
||||
} else if (const auto stars = peer->starsPerMessageChecked()) {
|
||||
return tr::lng_message_paid_ph(
|
||||
lt_amount,
|
||||
tr::lng_prize_credits_amount(
|
||||
lt_count,
|
||||
rpl::single(stars * 1.)));
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
const auto topic = resolveReplyToTopic();
|
||||
const auto topicRootId = topic
|
||||
? topic->rootId()
|
||||
|
@ -5948,7 +5896,10 @@ Data::ForumTopic *HistoryWidget::resolveReplyToTopic() {
|
|||
|
||||
bool HistoryWidget::showSendMessageError(
|
||||
const TextWithTags &textWithTags,
|
||||
bool ignoreSlowmodeCountdown) {
|
||||
bool ignoreSlowmodeCountdown,
|
||||
Fn<void(int starsApproved)> resend,
|
||||
int starsApproved,
|
||||
bool mediaMessage) {
|
||||
if (!_canSendMessages) {
|
||||
return false;
|
||||
}
|
||||
|
@ -5960,8 +5911,17 @@ bool HistoryWidget::showSendMessageError(
|
|||
.forward = &_forwardPanel->items(),
|
||||
.text = &textWithTags,
|
||||
.ignoreSlowmodeCountdown = ignoreSlowmodeCountdown,
|
||||
.mediaMessage = mediaMessage,
|
||||
});
|
||||
if (!error) {
|
||||
if (resend && error.resolving) {
|
||||
_resendOnFullUpdated = [=] { resend(starsApproved); };
|
||||
return true;
|
||||
} else if (resend && error.paidStars > starsApproved) {
|
||||
Data::ShowSendPaidConfirm(controller(), _peer, error, [=] {
|
||||
resend(error.paidStars);
|
||||
});
|
||||
return true;
|
||||
} else if (!error) {
|
||||
return false;
|
||||
}
|
||||
Data::ShowSendErrorToast(controller(), _peer, error);
|
||||
|
@ -6174,25 +6134,18 @@ void HistoryWidget::handleHistoryChange(not_null<const History*> history) {
|
|||
const auto joinChannel = isJoinChannel();
|
||||
const auto muteUnmute = isMuteUnmute();
|
||||
const auto reportMessages = isReportMessages();
|
||||
const auto payForMessage = isPayForMessage();
|
||||
const auto update = false
|
||||
|| (_reportMessages->isHidden() == reportMessages)
|
||||
|| (!reportMessages && _unblock->isHidden() == unblock)
|
||||
|| (!reportMessages
|
||||
&& !unblock
|
||||
&& _payForMessage->isHidden() == payForMessage)
|
||||
|| (!reportMessages
|
||||
&& !unblock
|
||||
&& !payForMessage
|
||||
&& _botStart->isHidden() == botStart)
|
||||
|| (!reportMessages
|
||||
&& !unblock
|
||||
&& !payForMessage
|
||||
&& !botStart
|
||||
&& _joinChannel->isHidden() == joinChannel)
|
||||
|| (!reportMessages
|
||||
&& !unblock
|
||||
&& !payForMessage
|
||||
&& !botStart
|
||||
&& !joinChannel
|
||||
&& _muteUnmute->isHidden() == muteUnmute);
|
||||
|
@ -6556,7 +6509,6 @@ void HistoryWidget::updateHistoryGeometry(
|
|||
} else if (!editingMessage()
|
||||
&& (isSearching()
|
||||
|| isBlocked()
|
||||
|| isPayForMessage()
|
||||
|| isBotStart()
|
||||
|| isJoinChannel()
|
||||
|| isMuteUnmute()
|
||||
|
@ -6866,7 +6818,6 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
|
|||
if (!isSearching()
|
||||
&& !isBotStart()
|
||||
&& !isBlocked()
|
||||
&& !isPayForMessage()
|
||||
&& _canSendMessages
|
||||
&& (wasVisible
|
||||
|| (_replyTo && _replyEditMsg)
|
||||
|
@ -8528,6 +8479,9 @@ void HistoryWidget::fullInfoUpdated() {
|
|||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
}
|
||||
if (const auto callback = base::take(_resendOnFullUpdated)) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::handlePeerUpdate() {
|
||||
|
@ -8743,7 +8697,6 @@ void HistoryWidget::updateTopBarSelection() {
|
|||
|| (_list && _list->wasSelectedText())
|
||||
|| isRecording()
|
||||
|| isBotStart()
|
||||
|| isPayForMessage()
|
||||
|| isBlocked()
|
||||
|| (!_canSendTexts && !_editMsgId)) {
|
||||
_list->setFocus();
|
||||
|
|
|
@ -115,6 +115,7 @@ class TTLButton;
|
|||
class WebpageProcessor;
|
||||
class CharactersLimitLabel;
|
||||
class PhotoEditSpoilerManager;
|
||||
struct VoiceToSend;
|
||||
} // namespace HistoryView::Controls
|
||||
|
||||
class BotKeyboard;
|
||||
|
@ -318,6 +319,7 @@ protected:
|
|||
private:
|
||||
using TabbedPanel = ChatHelpers::TabbedPanel;
|
||||
using TabbedSelector = ChatHelpers::TabbedSelector;
|
||||
using VoiceToSend = HistoryView::Controls::VoiceToSend;
|
||||
enum ScrollChangeType {
|
||||
ScrollChangeNone,
|
||||
|
||||
|
@ -401,6 +403,7 @@ private:
|
|||
|
||||
[[nodiscard]] Api::SendAction prepareSendAction(
|
||||
Api::SendOptions options) const;
|
||||
void sendVoice(const VoiceToSend &data);
|
||||
void send(Api::SendOptions options);
|
||||
void sendWithModifiers(Qt::KeyboardModifiers modifiers);
|
||||
void sendScheduled(Api::SendOptions initialOptions);
|
||||
|
@ -422,7 +425,6 @@ private:
|
|||
[[nodiscard]] int computeMaxFieldHeight() const;
|
||||
void toggleMuteUnmute();
|
||||
void reportSelectedMessages();
|
||||
void payForMessage();
|
||||
void payForMessageSure(bool trust = false);
|
||||
void showKeyboardHideButton();
|
||||
void toggleKeyboard(bool manual = true);
|
||||
|
@ -468,7 +470,10 @@ private:
|
|||
std::optional<bool> compress) const;
|
||||
bool showSendMessageError(
|
||||
const TextWithTags &textWithTags,
|
||||
bool ignoreSlowmodeCountdown);
|
||||
bool ignoreSlowmodeCountdown,
|
||||
Fn<void(int starsApproved)> resend = nullptr,
|
||||
int starsApproved = 0,
|
||||
bool mediaMessage = false);
|
||||
|
||||
void sendingFilesConfirmed(
|
||||
Ui::PreparedList &&list,
|
||||
|
@ -642,7 +647,6 @@ private:
|
|||
[[nodiscard]] bool isJoinChannel() const;
|
||||
[[nodiscard]] bool isMuteUnmute() const;
|
||||
[[nodiscard]] bool isReportMessages() const;
|
||||
[[nodiscard]] bool isPayForMessage() const;
|
||||
bool updateCmdStartShown();
|
||||
void updateSendButtonType();
|
||||
[[nodiscard]] bool showRecordButton() const;
|
||||
|
@ -761,6 +765,7 @@ private:
|
|||
std::unique_ptr<ChatHelpers::FieldAutocomplete> _autocomplete;
|
||||
std::unique_ptr<Ui::Emoji::SuggestionsController> _emojiSuggestions;
|
||||
object_ptr<Support::Autocomplete> _supportAutocomplete;
|
||||
Fn<void()> _resendOnFullUpdated;
|
||||
|
||||
UserData *_inlineBot = nullptr;
|
||||
QString _inlineBotUsername;
|
||||
|
@ -781,8 +786,6 @@ private:
|
|||
QPointer<Ui::IconButton> _giftToChannelIn;
|
||||
QPointer<Ui::IconButton> _giftToChannelOut;
|
||||
object_ptr<Ui::FlatButton> _reportMessages;
|
||||
object_ptr<Ui::FlatButton> _payForMessage;
|
||||
mutable rpl::variable<int> _payForMessageStars;
|
||||
struct {
|
||||
object_ptr<Ui::RoundButton> button = { nullptr };
|
||||
QString text;
|
||||
|
|
|
@ -111,29 +111,33 @@ namespace Media::Stories {
|
|||
const auto threadPeer = thread->peer();
|
||||
const auto threadHistory = thread->owningHistory();
|
||||
const auto randomId = base::RandomValue<uint64>();
|
||||
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
||||
using SendFlag = MTPmessages_SendMedia::Flag;
|
||||
auto sendFlags = SendFlag(0) | SendFlag(0);
|
||||
if (action.replyTo) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
|
||||
sendFlags |= SendFlag::f_reply_to;
|
||||
}
|
||||
const auto silentPost = ShouldSendSilent(threadPeer, options);
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||
sendFlags |= SendFlag::f_silent;
|
||||
}
|
||||
if (options.scheduled) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
|
||||
sendFlags |= SendFlag::f_schedule_date;
|
||||
}
|
||||
if (options.shortcutId) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
|
||||
sendFlags |= SendFlag::f_quick_reply_shortcut;
|
||||
}
|
||||
if (options.effectId) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||
sendFlags |= SendFlag::f_effect;
|
||||
}
|
||||
if (options.invertCaption) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||
sendFlags |= SendFlag::f_invert_media;
|
||||
}
|
||||
const auto starsPaid = peer->commitStarsForMessage();
|
||||
const auto starsPaid = std::min(
|
||||
peer->starsPerMessageChecked(),
|
||||
options.starsApproved);
|
||||
if (starsPaid) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_allow_paid_stars;
|
||||
options.starsApproved -= starsPaid;
|
||||
sendFlags |= SendFlag::f_allow_paid_stars;
|
||||
}
|
||||
const auto done = [=] {
|
||||
if (!--state->requests) {
|
||||
|
|
|
@ -220,7 +220,7 @@ inputPeerNotifySettings#cacb6ae2 flags:# show_previews:flags.0?Bool silent:flags
|
|||
|
||||
peerNotifySettings#99622c0c flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int ios_sound:flags.3?NotificationSound android_sound:flags.4?NotificationSound other_sound:flags.5?NotificationSound stories_muted:flags.6?Bool stories_hide_sender:flags.7?Bool stories_ios_sound:flags.8?NotificationSound stories_android_sound:flags.9?NotificationSound stories_other_sound:flags.10?NotificationSound = PeerNotifySettings;
|
||||
|
||||
peerSettings#a8639d72 flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true business_bot_paused:flags.11?true business_bot_can_reply:flags.12?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int business_bot_id:flags.13?long business_bot_manage_url:flags.13?string charge_paid_message_stars:flags.14?long = PeerSettings;
|
||||
peerSettings#d8c39ec flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true business_bot_paused:flags.11?true business_bot_can_reply:flags.12?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int business_bot_id:flags.13?long business_bot_manage_url:flags.13?string charge_paid_message_stars:flags.14?long registration_month:flags.15?string phone_country:flags.16?string location_country:flags.17?string = PeerSettings;
|
||||
|
||||
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
|
||||
wallPaperNoFile#e0804116 id:long flags:# default:flags.1?true dark:flags.4?true settings:flags.2?WallPaperSettings = WallPaper;
|
||||
|
@ -1480,6 +1480,7 @@ inputInvoiceChatInviteSubscription#34e793f1 hash:string = InputInvoice;
|
|||
inputInvoiceStarGift#e8625e92 flags:# hide_name:flags.0?true include_upgrade:flags.2?true peer:InputPeer gift_id:long message:flags.1?TextWithEntities = InputInvoice;
|
||||
inputInvoiceStarGiftUpgrade#4d818d5d flags:# keep_original_details:flags.0?true stargift:InputSavedStarGift = InputInvoice;
|
||||
inputInvoiceStarGiftTransfer#4a5f5bd9 stargift:InputSavedStarGift to_id:InputPeer = InputInvoice;
|
||||
inputInvoicePremiumGiftStars#dabab2ef flags:# user_id:InputUser months:int message:flags.0?TextWithEntities = InputInvoice;
|
||||
|
||||
payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
|
||||
|
||||
|
@ -1495,7 +1496,7 @@ inputStorePaymentStarsTopup#dddd0f56 stars:long currency:string amount:long = In
|
|||
inputStorePaymentStarsGift#1d741ef7 user_id:InputUser stars:long currency:string amount:long = InputStorePaymentPurpose;
|
||||
inputStorePaymentStarsGiveaway#751f08fa flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true stars:long boost_peer:InputPeer additional_peers:flags.1?Vector<InputPeer> countries_iso2:flags.2?Vector<string> prize_description:flags.4?string random_id:long until_date:int currency:string amount:long users:int = InputStorePaymentPurpose;
|
||||
|
||||
premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption;
|
||||
premiumGiftOption#79c059f7 flags:# months:int currency:string amount:long bot_url:flags.1?string store_product:flags.0?string = PremiumGiftOption;
|
||||
|
||||
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue