mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 05:07:10 +02:00
Add sending paid stories replies.
This commit is contained in:
parent
fe2df96953
commit
1684465e04
14 changed files with 442 additions and 156 deletions
|
@ -2167,14 +2167,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_action_set_chat_intro" = "{from} added the message below for all empty chats. How?";
|
||||
"lng_action_payment_refunded" = "{peer} refunded {amount}";
|
||||
"lng_action_paid_message_sent#one" = "You paid {count} Star to {action}";
|
||||
"lng_action_paid_message_sent#other" = "You paid {count} Star to {action}";
|
||||
"lng_action_paid_message_group#one" = "{from} paid {count} Star to {action}";
|
||||
"lng_action_paid_message_group#other" = "{from} paid {count} Star to {action}";
|
||||
"lng_action_paid_message_sent#other" = "You paid {count} Stars to {action}";
|
||||
"lng_action_paid_message_one" = "send a message";
|
||||
"lng_action_paid_message_some#one" = "send {count} message";
|
||||
"lng_action_paid_message_some#other" = "send {count} messages";
|
||||
"lng_action_paid_message_got#one" = "You received {count} Star from {name}";
|
||||
"lng_action_paid_message_got#other" = "You received {count} Stars from {name}";
|
||||
"lng_you_paid_stars#one" = "You paid {count} Star.";
|
||||
"lng_you_paid_stars#other" = "You paid {count} Stars.";
|
||||
|
||||
"lng_similar_channels_title" = "Similar channels";
|
||||
"lng_similar_channels_view_all" = "View all";
|
||||
|
|
|
@ -382,13 +382,15 @@ bool SendPaymentHelper::check(
|
|||
not_null<PeerData*> peer,
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int)> resend) {
|
||||
Fn<void(int)> resend,
|
||||
PaidConfirmStyles styles) {
|
||||
return check(
|
||||
navigation->uiShow(),
|
||||
peer,
|
||||
messagesCount,
|
||||
starsApproved,
|
||||
std::move(resend));
|
||||
std::move(resend),
|
||||
styles);
|
||||
}
|
||||
|
||||
bool SendPaymentHelper::check(
|
||||
|
@ -396,8 +398,10 @@ bool SendPaymentHelper::check(
|
|||
not_null<PeerData*> peer,
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int)> resend) {
|
||||
_lifetime.destroy();
|
||||
Fn<void(int)> resend,
|
||||
PaidConfirmStyles styles) {
|
||||
clear();
|
||||
|
||||
const auto details = ComputePaymentDetails(peer, messagesCount);
|
||||
if (!details) {
|
||||
_resend = [=] { resend(starsApproved); };
|
||||
|
@ -426,12 +430,17 @@ bool SendPaymentHelper::check(
|
|||
} else if (const auto stars = details->stars; stars > starsApproved) {
|
||||
ShowSendPaidConfirm(show, peer, *details, [=] {
|
||||
resend(stars);
|
||||
});
|
||||
}, styles);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SendPaymentHelper::clear() {
|
||||
_lifetime.destroy();
|
||||
_resend = nullptr;
|
||||
}
|
||||
|
||||
void RequestDependentMessageItem(
|
||||
not_null<HistoryItem*> item,
|
||||
PeerId peerId,
|
||||
|
|
|
@ -179,13 +179,17 @@ public:
|
|||
not_null<PeerData*> peer,
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int)> resend);
|
||||
Fn<void(int)> resend,
|
||||
PaidConfirmStyles styles = {});
|
||||
[[nodiscard]] bool check(
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
not_null<PeerData*> peer,
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int)> resend);
|
||||
Fn<void(int)> resend,
|
||||
PaidConfirmStyles styles = {});
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
Fn<void()> _resend;
|
||||
|
|
|
@ -225,16 +225,6 @@ const auto kPsaAboutPrefix = "cloud_lng_about_psa_";
|
|||
|
||||
} // namespace
|
||||
|
||||
struct HistoryWidget::SendingFiles {
|
||||
std::vector<Ui::PreparedGroup> groups;
|
||||
Ui::SendFilesWay way;
|
||||
TextWithTags caption;
|
||||
Api::SendOptions options;
|
||||
int totalCount = 0;
|
||||
bool sendComment = false;
|
||||
bool ctrlShiftEnter = false;
|
||||
};
|
||||
|
||||
HistoryWidget::HistoryWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller)
|
||||
|
@ -898,17 +888,6 @@ HistoryWidget::HistoryWidget(
|
|||
}
|
||||
}, lifetime());
|
||||
|
||||
if (!session().credits().loaded()) {
|
||||
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),
|
||||
|
@ -2400,7 +2379,7 @@ void HistoryWidget::showHistory(
|
|||
setHistory(nullptr);
|
||||
_list = nullptr;
|
||||
_peer = nullptr;
|
||||
_resendOnFullUpdated = nullptr;
|
||||
_sendPayment.clear();
|
||||
_topicsRequested.clear();
|
||||
_canSendMessages = false;
|
||||
_canSendTexts = false;
|
||||
|
@ -4412,7 +4391,7 @@ void HistoryWidget::send(Api::SendOptions options) {
|
|||
if (showSendMessageError(
|
||||
message.textWithTags,
|
||||
ignoreSlowmodeCountdown,
|
||||
crl::guard(this, withPaymentApproved),
|
||||
withPaymentApproved,
|
||||
options.starsApproved)) {
|
||||
return;
|
||||
}
|
||||
|
@ -4735,6 +4714,19 @@ FullMsgId HistoryWidget::cornerButtonsCurrentId() {
|
|||
: FullMsgId();
|
||||
}
|
||||
|
||||
bool HistoryWidget::checkSendPayment(
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int)> withPaymentApproved) {
|
||||
return _peer
|
||||
&& _sendPayment.check(
|
||||
controller(),
|
||||
_peer,
|
||||
messagesCount,
|
||||
starsApproved,
|
||||
std::move(withPaymentApproved));
|
||||
}
|
||||
|
||||
void HistoryWidget::checkSuggestToGigagroup() {
|
||||
const auto group = _peer ? _peer->asMegagroup() : nullptr;
|
||||
if (!group || !group->owner().suggestToGigagroup(group)) {
|
||||
|
@ -5890,7 +5882,7 @@ Data::ForumTopic *HistoryWidget::resolveReplyToTopic() {
|
|||
bool HistoryWidget::showSendMessageError(
|
||||
const TextWithTags &textWithTags,
|
||||
bool ignoreSlowmodeCountdown,
|
||||
Fn<void(int starsApproved)> resend,
|
||||
Fn<void(int starsApproved)> withPaymentApproved,
|
||||
int starsApproved) {
|
||||
if (!_canSendMessages) {
|
||||
return false;
|
||||
|
@ -5908,25 +5900,12 @@ bool HistoryWidget::showSendMessageError(
|
|||
Data::ShowSendErrorToast(controller(), _peer, error);
|
||||
return true;
|
||||
}
|
||||
return resend
|
||||
&& !checkSendPayment(request.messagesCount, starsApproved, resend);
|
||||
}
|
||||
|
||||
bool HistoryWidget::checkSendPayment(
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int starsApproved)> resend) {
|
||||
const auto details = ComputePaymentDetails(_peer, messagesCount);
|
||||
if (!details) {
|
||||
_resendOnFullUpdated = [=] { resend(starsApproved); };
|
||||
return false;
|
||||
} else if (const auto stars = details->stars; stars > starsApproved) {
|
||||
ShowSendPaidConfirm(controller(), _peer, *details, [=] {
|
||||
resend(stars);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return withPaymentApproved
|
||||
&& !checkSendPayment(
|
||||
request.messagesCount,
|
||||
starsApproved,
|
||||
withPaymentApproved);
|
||||
}
|
||||
|
||||
bool HistoryWidget::confirmSendingFiles(const QStringList &files) {
|
||||
|
@ -6012,11 +5991,11 @@ bool HistoryWidget::confirmSendingFiles(
|
|||
}
|
||||
|
||||
void HistoryWidget::sendingFilesConfirmed(
|
||||
Ui::PreparedList &&list,
|
||||
Ui::SendFilesWay way,
|
||||
TextWithTags &&caption,
|
||||
Api::SendOptions options,
|
||||
bool ctrlShiftEnter) {
|
||||
Ui::PreparedList &&list,
|
||||
Ui::SendFilesWay way,
|
||||
TextWithTags &&caption,
|
||||
Api::SendOptions options,
|
||||
bool ctrlShiftEnter) {
|
||||
Expects(list.filesToProcess.empty());
|
||||
|
||||
const auto compress = way.sendImagesAsPhotos();
|
||||
|
@ -6024,55 +6003,51 @@ void HistoryWidget::sendingFilesConfirmed(
|
|||
return;
|
||||
}
|
||||
|
||||
const auto filesCount = int(list.files.size());
|
||||
auto groups = DivideByGroups(
|
||||
std::move(list),
|
||||
way,
|
||||
_peer->slowmodeApplied());
|
||||
const auto sendComment = !caption.text.isEmpty()
|
||||
&& (groups.size() != 1 || !groups.front().sentWithCaption());
|
||||
sendingFilesConfirmed(std::make_shared<SendingFiles>(SendingFiles{
|
||||
.groups = std::move(groups),
|
||||
.way = way,
|
||||
.caption = std::move(caption),
|
||||
.options = options,
|
||||
.totalCount = filesCount + (sendComment ? 1 : 0),
|
||||
.sendComment = sendComment,
|
||||
.ctrlShiftEnter = ctrlShiftEnter,
|
||||
}));
|
||||
auto bundle = PrepareFilesBundle(
|
||||
std::move(groups),
|
||||
way,
|
||||
std::move(caption),
|
||||
ctrlShiftEnter);
|
||||
sendingFilesConfirmed(std::move(bundle), options);
|
||||
}
|
||||
|
||||
void HistoryWidget::sendingFilesConfirmed(
|
||||
std::shared_ptr<SendingFiles> args) {
|
||||
std::shared_ptr<Ui::PreparedBundle> bundle,
|
||||
Api::SendOptions options) {
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
args->options.starsApproved = approved;
|
||||
sendingFilesConfirmed(args);
|
||||
auto copy = options;
|
||||
copy.starsApproved = approved;
|
||||
sendingFilesConfirmed(bundle, copy);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
args->totalCount,
|
||||
args->options.starsApproved,
|
||||
bundle->totalCount,
|
||||
options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto compress = args->way.sendImagesAsPhotos();
|
||||
const auto compress = bundle->way.sendImagesAsPhotos();
|
||||
const auto type = compress ? SendMediaType::Photo : SendMediaType::File;
|
||||
auto action = prepareSendAction(args->options);
|
||||
auto action = prepareSendAction(options);
|
||||
action.clearDraft = false;
|
||||
if (args->sendComment) {
|
||||
if (bundle->sendComment) {
|
||||
auto message = Api::MessageToSend(action);
|
||||
message.textWithTags = base::take(args->caption);
|
||||
message.textWithTags = base::take(bundle->caption);
|
||||
session().api().sendMessage(std::move(message));
|
||||
}
|
||||
for (auto &group : args->groups) {
|
||||
for (auto &group : bundle->groups) {
|
||||
const auto album = (group.type != Ui::AlbumType::None)
|
||||
? std::make_shared<SendingAlbum>()
|
||||
: nullptr;
|
||||
session().api().sendFiles(
|
||||
std::move(group.list),
|
||||
type,
|
||||
base::take(args->caption),
|
||||
base::take(bundle->caption),
|
||||
album,
|
||||
action);
|
||||
}
|
||||
|
@ -8545,9 +8520,6 @@ void HistoryWidget::fullInfoUpdated() {
|
|||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
}
|
||||
if (const auto callback = base::take(_resendOnFullUpdated)) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::handlePeerUpdate() {
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/controls/history_view_compose_media_edit_manager.h"
|
||||
#include "history/view/history_view_corner_buttons.h"
|
||||
#include "history/history_drag_area.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "history/history_view_highlight_manager.h"
|
||||
#include "history/history_view_top_toast.h"
|
||||
#include "history/history.h"
|
||||
|
@ -69,6 +70,7 @@ class PinnedBar;
|
|||
class GroupCallBar;
|
||||
class RequestsBar;
|
||||
struct PreparedList;
|
||||
struct PreparedBundle;
|
||||
class SendFilesWay;
|
||||
class SendAsButton;
|
||||
class SpoilerAnimation;
|
||||
|
@ -320,7 +322,6 @@ private:
|
|||
using TabbedPanel = ChatHelpers::TabbedPanel;
|
||||
using TabbedSelector = ChatHelpers::TabbedSelector;
|
||||
using VoiceToSend = HistoryView::Controls::VoiceToSend;
|
||||
struct SendingFiles;
|
||||
enum ScrollChangeType {
|
||||
ScrollChangeNone,
|
||||
|
||||
|
@ -359,6 +360,11 @@ private:
|
|||
bool cornerButtonsUnreadMayBeShown() override;
|
||||
bool cornerButtonsHas(HistoryView::CornerButtonType type) override;
|
||||
|
||||
[[nodiscard]] bool checkSendPayment(
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int)> withPaymentApproved);
|
||||
|
||||
void checkSuggestToGigagroup();
|
||||
void processReply();
|
||||
void setReplyFieldsFromProcessing();
|
||||
|
@ -471,12 +477,8 @@ private:
|
|||
bool showSendMessageError(
|
||||
const TextWithTags &textWithTags,
|
||||
bool ignoreSlowmodeCountdown,
|
||||
Fn<void(int starsApproved)> resend = nullptr,
|
||||
Fn<void(int starsApproved)> withPaymentApproved = nullptr,
|
||||
int starsApproved = 0);
|
||||
bool checkSendPayment(
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int starsApproved)> resend);
|
||||
|
||||
void sendingFilesConfirmed(
|
||||
Ui::PreparedList &&list,
|
||||
|
@ -484,7 +486,9 @@ private:
|
|||
TextWithTags &&caption,
|
||||
Api::SendOptions options,
|
||||
bool ctrlShiftEnter);
|
||||
void sendingFilesConfirmed(std::shared_ptr<SendingFiles> args);
|
||||
void sendingFilesConfirmed(
|
||||
std::shared_ptr<Ui::PreparedBundle> bundle,
|
||||
Api::SendOptions options);
|
||||
|
||||
void uploadFile(const QByteArray &fileContent, SendMediaType type);
|
||||
void itemRemoved(not_null<const HistoryItem*> item);
|
||||
|
@ -769,7 +773,6 @@ 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;
|
||||
|
@ -874,6 +877,8 @@ private:
|
|||
|
||||
int _topDelta = 0;
|
||||
|
||||
SendPaymentHelper _sendPayment;
|
||||
|
||||
rpl::event_stream<> _cancelRequests;
|
||||
|
||||
};
|
||||
|
|
|
@ -1722,13 +1722,20 @@ void ComposeControls::updateFieldPlaceholder() {
|
|||
}
|
||||
|
||||
_field->setPlaceholder([&] {
|
||||
const auto peer = _history ? _history->peer.get() : nullptr;
|
||||
if (_fieldCustomPlaceholder) {
|
||||
return rpl::duplicate(_fieldCustomPlaceholder);
|
||||
} else if (isEditingMessage()) {
|
||||
return tr::lng_edit_message_text();
|
||||
} else if (!_history) {
|
||||
} else if (!peer) {
|
||||
return tr::lng_message_ph();
|
||||
} 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()) {
|
||||
if (channel->isBroadcast()) {
|
||||
return session().data().notifySettings().silentPosts(channel)
|
||||
? tr::lng_broadcast_silent_ph()
|
||||
|
@ -3120,6 +3127,7 @@ void ComposeControls::initWebpageProcess() {
|
|||
| Data::PeerUpdate::Flag::Notifications
|
||||
| Data::PeerUpdate::Flag::MessagesTTL
|
||||
| Data::PeerUpdate::Flag::FullInfo
|
||||
| Data::PeerUpdate::Flag::StarsPerMessage
|
||||
) | rpl::filter([peer = _history->peer](const Data::PeerUpdate &update) {
|
||||
return (update.peer.get() == peer);
|
||||
}) | rpl::map([](const Data::PeerUpdate &update) {
|
||||
|
@ -3135,6 +3143,9 @@ void ComposeControls::initWebpageProcess() {
|
|||
if (flags & Data::PeerUpdate::Flag::MessagesTTL) {
|
||||
updateMessagesTTLShown();
|
||||
}
|
||||
if (flags & Data::PeerUpdate::Flag::StarsPerMessage) {
|
||||
updateFieldPlaceholder();
|
||||
}
|
||||
if (flags & Data::PeerUpdate::Flag::FullInfo) {
|
||||
if (updateBotCommandShown()) {
|
||||
updateControlsVisibility();
|
||||
|
|
|
@ -384,6 +384,9 @@ QString DateTooltipText(not_null<Element*> view) {
|
|||
if (item->isScheduled() && item->isSilent()) {
|
||||
dateText += '\n' + QChar(0xD83D) + QChar(0xDD15);
|
||||
}
|
||||
if (const auto stars = item->out() ? item->starsPaid() : 0) {
|
||||
dateText += '\n' + tr::lng_you_paid_stars(tr::now, lt_count, stars);
|
||||
}
|
||||
return dateText;
|
||||
}
|
||||
|
||||
|
|
|
@ -476,22 +476,12 @@ void Message::initPaidInformation() {
|
|||
lt_action,
|
||||
action(),
|
||||
Ui::Text::WithEntities)
|
||||
: history()->peer->isUser()
|
||||
? tr::lng_action_paid_message_got(
|
||||
: tr::lng_action_paid_message_got(
|
||||
tr::now,
|
||||
lt_count,
|
||||
info.stars,
|
||||
lt_name,
|
||||
Ui::Text::Link(item->from()->shortName(), 1),
|
||||
Ui::Text::WithEntities)
|
||||
: tr::lng_action_paid_message_group(
|
||||
tr::now,
|
||||
lt_count,
|
||||
info.stars,
|
||||
lt_from,
|
||||
Ui::Text::Link(item->from()->shortName(), 1),
|
||||
lt_action,
|
||||
action(),
|
||||
Ui::Text::WithEntities),
|
||||
};
|
||||
if (!item->out()) {
|
||||
|
|
|
@ -733,8 +733,8 @@ void RepliesWidget::setupComposeControls() {
|
|||
}, lifetime());
|
||||
|
||||
_composeControls->sendVoiceRequests(
|
||||
) | rpl::start_with_next([=](ComposeControls::VoiceToSend &&data) {
|
||||
sendVoice(std::move(data));
|
||||
) | rpl::start_with_next([=](const ComposeControls::VoiceToSend &data) {
|
||||
sendVoice(data);
|
||||
}, lifetime());
|
||||
|
||||
_composeControls->sendCommandRequests(
|
||||
|
@ -1070,25 +1070,59 @@ void RepliesWidget::sendingFilesConfirmed(
|
|||
std::move(list),
|
||||
way,
|
||||
_history->peer->slowmodeApplied());
|
||||
const auto type = way.sendImagesAsPhotos()
|
||||
? SendMediaType::Photo
|
||||
: SendMediaType::File;
|
||||
auto bundle = PrepareFilesBundle(
|
||||
std::move(groups),
|
||||
way,
|
||||
std::move(caption),
|
||||
ctrlShiftEnter);
|
||||
sendingFilesConfirmed(std::move(bundle), options);
|
||||
}
|
||||
|
||||
bool RepliesWidget::checkSendPayment(
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int)> withPaymentApproved) {
|
||||
return _sendPayment.check(
|
||||
controller(),
|
||||
_history->peer,
|
||||
messagesCount,
|
||||
starsApproved,
|
||||
std::move(withPaymentApproved));
|
||||
}
|
||||
|
||||
void RepliesWidget::sendingFilesConfirmed(
|
||||
std::shared_ptr<Ui::PreparedBundle> bundle,
|
||||
Api::SendOptions options) {
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = options;
|
||||
copy.starsApproved = approved;
|
||||
sendingFilesConfirmed(bundle, copy);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
bundle->totalCount,
|
||||
options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto compress = bundle->way.sendImagesAsPhotos();
|
||||
const auto type = compress ? SendMediaType::Photo : SendMediaType::File;
|
||||
auto action = prepareSendAction(options);
|
||||
action.clearDraft = false;
|
||||
if ((groups.size() != 1 || !groups.front().sentWithCaption())
|
||||
&& !caption.text.isEmpty()) {
|
||||
if (bundle->sendComment) {
|
||||
auto message = Api::MessageToSend(action);
|
||||
message.textWithTags = base::take(caption);
|
||||
message.textWithTags = base::take(bundle->caption);
|
||||
session().api().sendMessage(std::move(message));
|
||||
}
|
||||
for (auto &group : groups) {
|
||||
for (auto &group : bundle->groups) {
|
||||
const auto album = (group.type != Ui::AlbumType::None)
|
||||
? std::make_shared<SendingAlbum>()
|
||||
: nullptr;
|
||||
session().api().sendFiles(
|
||||
std::move(group.list),
|
||||
type,
|
||||
base::take(caption),
|
||||
base::take(bundle->caption),
|
||||
album,
|
||||
action);
|
||||
}
|
||||
|
@ -1227,7 +1261,20 @@ void RepliesWidget::send() {
|
|||
send({});
|
||||
}
|
||||
|
||||
void RepliesWidget::sendVoice(ComposeControls::VoiceToSend &&data) {
|
||||
void RepliesWidget::sendVoice(const ComposeControls::VoiceToSend &data) {
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = data;
|
||||
copy.options.starsApproved = approved;
|
||||
sendVoice(copy);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
1,
|
||||
data.options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto action = prepareSendAction(data.options);
|
||||
session().api().sendVoiceMessage(
|
||||
data.bytes,
|
||||
|
@ -1254,19 +1301,32 @@ void RepliesWidget::send(Api::SendOptions options) {
|
|||
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
||||
message.webPage = _composeControls->webPageDraft();
|
||||
|
||||
const auto error = GetErrorForSending(
|
||||
_history->peer,
|
||||
{
|
||||
.topicRootId = _topic ? _topic->rootId() : MsgId(0),
|
||||
.forward = &_composeControls->forwardItems(),
|
||||
.text = &message.textWithTags,
|
||||
.ignoreSlowmodeCountdown = (options.scheduled != 0),
|
||||
});
|
||||
auto request = SendingErrorRequest{
|
||||
.topicRootId = _topic ? _topic->rootId() : MsgId(0),
|
||||
.forward = &_composeControls->forwardItems(),
|
||||
.text = &message.textWithTags,
|
||||
.ignoreSlowmodeCountdown = (options.scheduled != 0),
|
||||
};
|
||||
request.messagesCount = ComputeSendingMessagesCount(_history, request);
|
||||
const auto error = GetErrorForSending(_history->peer, request);
|
||||
if (error) {
|
||||
Data::ShowSendErrorToast(controller(), _history->peer, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!options.scheduled) {
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = options;
|
||||
copy.starsApproved = approved;
|
||||
send(copy);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
request.messagesCount,
|
||||
options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
session().api().sendMessage(std::move(message));
|
||||
|
||||
_composeControls->clear();
|
||||
|
@ -1420,6 +1480,18 @@ bool RepliesWidget::sendExistingDocument(
|
|||
|| ShowSendPremiumError(controller(), document)) {
|
||||
return false;
|
||||
}
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = messageToSend;
|
||||
copy.action.options.starsApproved = approved;
|
||||
sendExistingDocument(document, std::move(copy), localId);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
1,
|
||||
messageToSend.action.options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Api::SendExistingDocument(
|
||||
std::move(messageToSend),
|
||||
|
@ -1448,6 +1520,19 @@ bool RepliesWidget::sendExistingPhoto(
|
|||
return false;
|
||||
}
|
||||
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = options;
|
||||
copy.starsApproved = approved;
|
||||
sendExistingPhoto(photo, copy);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
1,
|
||||
options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Api::SendExistingPhoto(
|
||||
Api::MessageToSend(prepareSendAction(options)),
|
||||
photo);
|
||||
|
@ -1478,6 +1563,19 @@ void RepliesWidget::sendInlineResult(
|
|||
not_null<UserData*> bot,
|
||||
Api::SendOptions options,
|
||||
std::optional<MsgId> localMessageId) {
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = options;
|
||||
copy.starsApproved = approved;
|
||||
sendInlineResult(result, bot, copy, localMessageId);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
1,
|
||||
options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto action = prepareSendAction(options);
|
||||
action.generateLocal = true;
|
||||
session().api().sendInlineResult(
|
||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/section_memento.h"
|
||||
#include "history/view/history_view_corner_buttons.h"
|
||||
#include "history/view/history_view_list_widget.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "history/history_view_swipe_data.h"
|
||||
#include "data/data_messages.h"
|
||||
#include "base/timer.h"
|
||||
|
@ -38,6 +39,7 @@ class PlainShadow;
|
|||
class FlatButton;
|
||||
class PinnedBar;
|
||||
struct PreparedList;
|
||||
struct PreparedBundle;
|
||||
class SendFilesWay;
|
||||
} // namespace Ui
|
||||
|
||||
|
@ -207,6 +209,11 @@ private:
|
|||
void checkActivation() override;
|
||||
void doSetInnerFocus() override;
|
||||
|
||||
[[nodiscard]] bool checkSendPayment(
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int)> withPaymentApproved);
|
||||
|
||||
void onScroll();
|
||||
void updateInnerVisibleArea();
|
||||
void updateControlsGeometry();
|
||||
|
@ -251,7 +258,7 @@ private:
|
|||
Api::SendOptions options) const;
|
||||
void send();
|
||||
void send(Api::SendOptions options);
|
||||
void sendVoice(Controls::VoiceToSend &&data);
|
||||
void sendVoice(const Controls::VoiceToSend &data);
|
||||
void edit(
|
||||
not_null<HistoryItem*> item,
|
||||
Api::SendOptions options,
|
||||
|
@ -308,6 +315,9 @@ private:
|
|||
TextWithTags &&caption,
|
||||
Api::SendOptions options,
|
||||
bool ctrlShiftEnter);
|
||||
void sendingFilesConfirmed(
|
||||
std::shared_ptr<Ui::PreparedBundle> bundle,
|
||||
Api::SendOptions options);
|
||||
|
||||
bool sendExistingDocument(
|
||||
not_null<DocumentData*> document,
|
||||
|
@ -380,6 +390,8 @@ private:
|
|||
|
||||
HistoryView::ChatPaintGestureHorizontalData _gestureHorizontal;
|
||||
|
||||
SendPaymentHelper _sendPayment;
|
||||
|
||||
int _lastScrollTop = 0;
|
||||
int _topicReopenBarHeight = 0;
|
||||
int _scrollTopDelta = 0;
|
||||
|
|
|
@ -15,11 +15,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/unixtime.h"
|
||||
#include "boxes/premium_limits_box.h"
|
||||
#include "boxes/send_files_box.h"
|
||||
#include "boxes/share_box.h" // ShareBoxStyleOverrides
|
||||
#include "chat_helpers/compose/compose_show.h"
|
||||
#include "chat_helpers/tabbed_selector.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "core/mime_type.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_chat_participant_status.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_message_reaction_id.h"
|
||||
|
@ -28,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_user.h"
|
||||
#include "history/view/controls/compose_controls_common.h"
|
||||
#include "history/view/controls/history_view_compose_controls.h"
|
||||
#include "history/view/history_view_schedule_box.h" // ScheduleBoxStyleArgs
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "history/history.h"
|
||||
#include "inline_bots/inline_bot_result.h"
|
||||
|
@ -36,6 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "media/stories/media_stories_controller.h"
|
||||
#include "media/stories/media_stories_stealth.h"
|
||||
#include "menu/menu_send.h"
|
||||
#include "settings/settings_credits_graphics.h" // DarkCreditsEntryBoxStyle
|
||||
#include "storage/localimageloader.h"
|
||||
#include "storage/storage_account.h"
|
||||
#include "storage/storage_media_prepare.h"
|
||||
|
@ -52,14 +56,19 @@ namespace {
|
|||
|
||||
[[nodiscard]] rpl::producer<QString> PlaceholderText(
|
||||
const std::shared_ptr<ChatHelpers::Show> &show,
|
||||
rpl::producer<bool> isComment) {
|
||||
rpl::producer<bool> isComment,
|
||||
rpl::producer<int> starsPerMessage) {
|
||||
return rpl::combine(
|
||||
show->session().data().stories().stealthModeValue(),
|
||||
std::move(isComment)
|
||||
) | rpl::map([](Data::StealthMode value, bool isComment) {
|
||||
return std::tuple(value.enabledTill, isComment);
|
||||
std::move(isComment),
|
||||
std::move(starsPerMessage)
|
||||
) | rpl::map([](
|
||||
Data::StealthMode value,
|
||||
bool isComment,
|
||||
int starsPerMessage) {
|
||||
return std::tuple(value.enabledTill, isComment, starsPerMessage);
|
||||
}) | rpl::distinct_until_changed(
|
||||
) | rpl::map([](TimeId till, bool isComment) {
|
||||
) | rpl::map([](TimeId till, bool isComment, int starsPerMessage) {
|
||||
return rpl::single(
|
||||
rpl::empty
|
||||
) | rpl::then(
|
||||
|
@ -71,7 +80,13 @@ namespace {
|
|||
}) | rpl::then(
|
||||
rpl::single(0)
|
||||
) | rpl::map([=](TimeId left) {
|
||||
return left
|
||||
return starsPerMessage
|
||||
? tr::lng_message_paid_ph(
|
||||
lt_amount,
|
||||
tr::lng_prize_credits_amount(
|
||||
lt_count,
|
||||
rpl::single(starsPerMessage * 1.)))
|
||||
: left
|
||||
? tr::lng_stealth_mode_countdown(
|
||||
lt_left,
|
||||
rpl::single(TimeLeftText(left)))
|
||||
|
@ -128,7 +143,8 @@ ReplyArea::ReplyArea(not_null<Controller*> controller)
|
|||
.stickerOrEmojiChosen = _controller->stickerOrEmojiChosen(),
|
||||
.customPlaceholder = PlaceholderText(
|
||||
_controller->uiShow(),
|
||||
rpl::deferred([=] { return _isComment.value(); })),
|
||||
rpl::deferred([=] { return _isComment.value(); }),
|
||||
rpl::deferred([=] { return _starsForMessage.value(); })),
|
||||
.voiceCustomCancelText = tr::lng_record_cancel_stories(tr::now),
|
||||
.voiceLockFromBottom = true,
|
||||
.features = {
|
||||
|
@ -199,7 +215,7 @@ bool ReplyArea::sendReaction(const Data::ReactionId &id) {
|
|||
}
|
||||
}
|
||||
return !message.textWithTags.empty()
|
||||
&& send(std::move(message), {}, true);
|
||||
&& send(std::move(message), true);
|
||||
}
|
||||
|
||||
void ReplyArea::send(Api::SendOptions options) {
|
||||
|
@ -209,29 +225,45 @@ void ReplyArea::send(Api::SendOptions options) {
|
|||
message.textWithTags = _controls->getTextWithAppliedMarkdown();
|
||||
message.webPage = webPageDraft;
|
||||
|
||||
send(std::move(message), options);
|
||||
send(std::move(message));
|
||||
}
|
||||
|
||||
bool ReplyArea::send(
|
||||
Api::MessageToSend message,
|
||||
Api::SendOptions options,
|
||||
bool skipToast) {
|
||||
if (!options.scheduled && showSlowmodeError()) {
|
||||
if (!message.action.options.scheduled && showSlowmodeError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto error = GetErrorForSending(
|
||||
_data.peer,
|
||||
{
|
||||
.topicRootId = MsgId(0),
|
||||
.text = &message.textWithTags,
|
||||
.ignoreSlowmodeCountdown = (options.scheduled != 0),
|
||||
});
|
||||
auto request = SendingErrorRequest{
|
||||
.topicRootId = MsgId(0),
|
||||
.text = &message.textWithTags,
|
||||
.ignoreSlowmodeCountdown = (message.action.options.scheduled != 0),
|
||||
};
|
||||
request.messagesCount = ComputeSendingMessagesCount(
|
||||
message.action.history,
|
||||
request);
|
||||
const auto error = GetErrorForSending(_data.peer, request);
|
||||
if (error) {
|
||||
Data::ShowSendErrorToast(_controller->uiShow(), _data.peer, error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!message.action.options.scheduled) {
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = message;
|
||||
copy.action.options.starsApproved = approved;
|
||||
send(copy);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
request.messagesCount,
|
||||
message.action.options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
session().api().sendMessage(std::move(message));
|
||||
|
||||
finishSending(skipToast);
|
||||
|
@ -239,7 +271,40 @@ bool ReplyArea::send(
|
|||
return true;
|
||||
}
|
||||
|
||||
void ReplyArea::sendVoice(VoiceToSend &&data) {
|
||||
bool ReplyArea::checkSendPayment(
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int)> withPaymentApproved) {
|
||||
const auto st1 = ::Settings::DarkCreditsEntryBoxStyle();
|
||||
const auto st2 = st1.shareBox.get();
|
||||
const auto st3 = st2 ? st2->scheduleBox.get() : nullptr;
|
||||
return _data.peer
|
||||
&& _sendPayment.check(
|
||||
_controller->uiShow(),
|
||||
_data.peer,
|
||||
messagesCount,
|
||||
starsApproved,
|
||||
std::move(withPaymentApproved),
|
||||
{
|
||||
.label = st3 ? st3->chooseDateTimeArgs.labelStyle : nullptr,
|
||||
.checkbox = st2 ? st2->checkbox : nullptr,
|
||||
});
|
||||
}
|
||||
|
||||
void ReplyArea::sendVoice(const VoiceToSend &data) {
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = data;
|
||||
copy.options.starsApproved = approved;
|
||||
sendVoice(copy);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
1,
|
||||
data.options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto action = prepareSendAction(data.options);
|
||||
session().api().sendVoiceMessage(
|
||||
data.bytes,
|
||||
|
@ -269,6 +334,18 @@ bool ReplyArea::sendExistingDocument(
|
|||
|| Window::ShowSendPremiumError(show, document)) {
|
||||
return false;
|
||||
}
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = messageToSend;
|
||||
copy.action.options.starsApproved = approved;
|
||||
sendExistingDocument(document, std::move(copy), localId);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
1,
|
||||
messageToSend.action.options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Api::SendExistingDocument(std::move(messageToSend), document, localId);
|
||||
|
||||
|
@ -296,6 +373,18 @@ bool ReplyArea::sendExistingPhoto(
|
|||
} else if (showSlowmodeError()) {
|
||||
return false;
|
||||
}
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = options;
|
||||
copy.starsApproved = approved;
|
||||
sendExistingPhoto(photo, copy);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
1,
|
||||
options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Api::SendExistingPhoto(
|
||||
Api::MessageToSend(prepareSendAction(options)),
|
||||
|
@ -322,6 +411,19 @@ void ReplyArea::sendInlineResult(
|
|||
not_null<UserData*> bot,
|
||||
Api::SendOptions options,
|
||||
std::optional<MsgId> localMessageId) {
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = options;
|
||||
copy.starsApproved = approved;
|
||||
sendInlineResult(result, bot, copy, localMessageId);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
1,
|
||||
options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto action = prepareSendAction(options);
|
||||
action.generateLocal = true;
|
||||
session().api().sendInlineResult(
|
||||
|
@ -564,25 +666,47 @@ void ReplyArea::sendingFilesConfirmed(
|
|||
std::move(list),
|
||||
way,
|
||||
_data.peer->slowmodeApplied());
|
||||
const auto type = way.sendImagesAsPhotos()
|
||||
? SendMediaType::Photo
|
||||
: SendMediaType::File;
|
||||
auto bundle = PrepareFilesBundle(
|
||||
std::move(groups),
|
||||
way,
|
||||
std::move(caption),
|
||||
ctrlShiftEnter);
|
||||
sendingFilesConfirmed(std::move(bundle), options);
|
||||
}
|
||||
|
||||
void ReplyArea::sendingFilesConfirmed(
|
||||
std::shared_ptr<Ui::PreparedBundle> bundle,
|
||||
Api::SendOptions options) {
|
||||
const auto withPaymentApproved = [=](int approved) {
|
||||
auto copy = options;
|
||||
copy.starsApproved = approved;
|
||||
sendingFilesConfirmed(bundle, copy);
|
||||
};
|
||||
const auto checked = checkSendPayment(
|
||||
bundle->totalCount,
|
||||
options.starsApproved,
|
||||
withPaymentApproved);
|
||||
if (!checked) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto compress = bundle->way.sendImagesAsPhotos();
|
||||
const auto type = compress ? SendMediaType::Photo : SendMediaType::File;
|
||||
auto action = prepareSendAction(options);
|
||||
action.clearDraft = false;
|
||||
if ((groups.size() != 1 || !groups.front().sentWithCaption())
|
||||
&& !caption.text.isEmpty()) {
|
||||
if (bundle->sendComment) {
|
||||
auto message = Api::MessageToSend(action);
|
||||
message.textWithTags = base::take(caption);
|
||||
message.textWithTags = base::take(bundle->caption);
|
||||
session().api().sendMessage(std::move(message));
|
||||
}
|
||||
for (auto &group : groups) {
|
||||
for (auto &group : bundle->groups) {
|
||||
const auto album = (group.type != Ui::AlbumType::None)
|
||||
? std::make_shared<SendingAlbum>()
|
||||
: nullptr;
|
||||
session().api().sendFiles(
|
||||
std::move(group.list),
|
||||
type,
|
||||
base::take(caption),
|
||||
base::take(bundle->caption),
|
||||
album,
|
||||
action);
|
||||
}
|
||||
|
@ -618,8 +742,8 @@ void ReplyArea::initActions() {
|
|||
}, _lifetime);
|
||||
|
||||
_controls->sendVoiceRequests(
|
||||
) | rpl::start_with_next([=](VoiceToSend &&data) {
|
||||
sendVoice(std::move(data));
|
||||
) | rpl::start_with_next([=](const VoiceToSend &data) {
|
||||
sendVoice(data);
|
||||
}, _lifetime);
|
||||
|
||||
_controls->attachRequests(
|
||||
|
@ -697,6 +821,16 @@ void ReplyArea::show(
|
|||
_controls->clear();
|
||||
}
|
||||
return;
|
||||
} else if (const auto peer = _data.peer) {
|
||||
using Flag = Data::PeerUpdate::Flag;
|
||||
_starsForMessage = peer->session().changes().peerFlagsValue(
|
||||
peer,
|
||||
Flag::StarsPerMessage | Flag::FullInfo
|
||||
) | rpl::map([=] {
|
||||
return peer->starsPerMessageChecked();
|
||||
});
|
||||
} else {
|
||||
_starsForMessage = 0;
|
||||
}
|
||||
invalidate_weak_ptrs(&_shownPeerGuard);
|
||||
const auto peer = data.peer;
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "base/weak_ptr.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
|
||||
class History;
|
||||
enum class SendMediaType;
|
||||
|
@ -44,6 +45,7 @@ struct Details;
|
|||
|
||||
namespace Ui {
|
||||
struct PreparedList;
|
||||
struct PreparedBundle;
|
||||
class SendFilesWay;
|
||||
class RpWidget;
|
||||
} // namespace Ui
|
||||
|
@ -90,9 +92,13 @@ private:
|
|||
|
||||
bool send(
|
||||
Api::MessageToSend message,
|
||||
Api::SendOptions options,
|
||||
bool skipToast = false);
|
||||
|
||||
[[nodiscard]] bool checkSendPayment(
|
||||
int messagesCount,
|
||||
int starsApproved,
|
||||
Fn<void(int)> withPaymentApproved);
|
||||
|
||||
void uploadFile(const QByteArray &fileContent, SendMediaType type);
|
||||
bool confirmSendingFiles(
|
||||
QImage &&image,
|
||||
|
@ -116,6 +122,9 @@ private:
|
|||
TextWithTags &&caption,
|
||||
Api::SendOptions options,
|
||||
bool ctrlShiftEnter);
|
||||
void sendingFilesConfirmed(
|
||||
std::shared_ptr<Ui::PreparedBundle> bundle,
|
||||
Api::SendOptions options);
|
||||
void finishSending(bool skipToast = false);
|
||||
|
||||
bool sendExistingDocument(
|
||||
|
@ -141,7 +150,7 @@ private:
|
|||
[[nodiscard]] Api::SendAction prepareSendAction(
|
||||
Api::SendOptions options) const;
|
||||
void send(Api::SendOptions options);
|
||||
void sendVoice(VoiceToSend &&data);
|
||||
void sendVoice(const VoiceToSend &data);
|
||||
void chooseAttach(std::optional<bool> overrideSendImagesAsPhotos);
|
||||
|
||||
[[nodiscard]] Fn<SendMenu::Details()> sendMenuDetails() const;
|
||||
|
@ -151,6 +160,7 @@ private:
|
|||
|
||||
const not_null<Controller*> _controller;
|
||||
rpl::variable<bool> _isComment;
|
||||
rpl::variable<int> _starsForMessage;
|
||||
|
||||
const std::unique_ptr<HistoryView::ComposeControls> _controls;
|
||||
std::unique_ptr<Cant> _cant;
|
||||
|
@ -160,6 +170,8 @@ private:
|
|||
bool _chooseAttachRequest = false;
|
||||
rpl::variable<bool> _choosingAttach;
|
||||
|
||||
SendPaymentHelper _sendPayment;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
|
|
@ -266,6 +266,27 @@ bool PreparedList::hasSpoilerMenu(bool compress) const {
|
|||
return allAreVideo || (allAreMedia && compress);
|
||||
}
|
||||
|
||||
std::shared_ptr<PreparedBundle> PrepareFilesBundle(
|
||||
std::vector<PreparedGroup> groups,
|
||||
SendFilesWay way,
|
||||
TextWithTags caption,
|
||||
bool ctrlShiftEnter) {
|
||||
auto totalCount = 0;
|
||||
for (const auto &group : groups) {
|
||||
totalCount += group.list.files.size();
|
||||
}
|
||||
const auto sendComment = !caption.text.isEmpty()
|
||||
&& (groups.size() != 1 || !groups.front().sentWithCaption());
|
||||
return std::make_shared<PreparedBundle>(PreparedBundle{
|
||||
.groups = std::move(groups),
|
||||
.way = way,
|
||||
.caption = std::move(caption),
|
||||
.totalCount = totalCount + (sendComment ? 1 : 0),
|
||||
.sendComment = sendComment,
|
||||
.ctrlShiftEnter = ctrlShiftEnter,
|
||||
});
|
||||
}
|
||||
|
||||
int MaxAlbumItems() {
|
||||
return kMaxAlbumCount;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "editor/photo_editor_common.h"
|
||||
#include "ui/chat/attach/attach_send_files_way.h"
|
||||
#include "ui/rect_part.h"
|
||||
|
||||
#include <QtCore/QSemaphore>
|
||||
|
@ -153,6 +154,20 @@ struct PreparedGroup {
|
|||
SendFilesWay way,
|
||||
bool slowmode);
|
||||
|
||||
struct PreparedBundle {
|
||||
std::vector<PreparedGroup> groups;
|
||||
SendFilesWay way;
|
||||
TextWithTags caption;
|
||||
int totalCount = 0;
|
||||
bool sendComment = false;
|
||||
bool ctrlShiftEnter = false;
|
||||
};
|
||||
[[nodiscard]] std::shared_ptr<PreparedBundle> PrepareFilesBundle(
|
||||
std::vector<PreparedGroup> groups,
|
||||
SendFilesWay way,
|
||||
TextWithTags caption,
|
||||
bool ctrlShiftEnter);
|
||||
|
||||
[[nodiscard]] int MaxAlbumItems();
|
||||
[[nodiscard]] bool ValidateThumbDimensions(int width, int height);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue