mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Support paid files-with-comment and polls.
This commit is contained in:
parent
3633c19208
commit
101d626d4f
5 changed files with 136 additions and 27 deletions
|
@ -577,6 +577,11 @@ void ApiWrap::sendMessageFail(
|
||||||
if (show) {
|
if (show) {
|
||||||
show->showToast(tr::lng_error_schedule_limit(tr::now));
|
show->showToast(tr::lng_error_schedule_limit(tr::now));
|
||||||
}
|
}
|
||||||
|
} else if (error.startsWith(u"ALLOW_PAYMENT_REQUIRED_"_q)) {
|
||||||
|
if (show) {
|
||||||
|
show->showToast(
|
||||||
|
u"Payment requirements changed. Please, try again."_q);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (const auto item = _session->data().message(itemId)) {
|
if (const auto item = _session->data().message(itemId)) {
|
||||||
Assert(randomId != 0);
|
Assert(randomId != 0);
|
||||||
|
|
|
@ -258,7 +258,7 @@ void ShowSendPaidConfirm(
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowSendPaidConfirm(
|
void ShowSendPaidConfirm(
|
||||||
std::shared_ptr<ChatHelpers::Show> show,
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
SendPaymentDetails details,
|
SendPaymentDetails details,
|
||||||
Fn<void()> confirmed) {
|
Fn<void()> confirmed) {
|
||||||
|
@ -330,6 +330,61 @@ void ShowSendPaidConfirm(
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SendPaymentHelper::check(
|
||||||
|
not_null<Window::SessionNavigation*> navigation,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
int messagesCount,
|
||||||
|
int starsApproved,
|
||||||
|
Fn<void(int)> resend) {
|
||||||
|
return check(
|
||||||
|
navigation->uiShow(),
|
||||||
|
peer,
|
||||||
|
messagesCount,
|
||||||
|
starsApproved,
|
||||||
|
std::move(resend));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SendPaymentHelper::check(
|
||||||
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
int messagesCount,
|
||||||
|
int starsApproved,
|
||||||
|
Fn<void(int)> resend) {
|
||||||
|
_lifetime.destroy();
|
||||||
|
const auto details = ComputePaymentDetails(peer, messagesCount);
|
||||||
|
if (!details) {
|
||||||
|
_resend = [=] { resend(starsApproved); };
|
||||||
|
|
||||||
|
if (!peer->session().credits().loaded()) {
|
||||||
|
peer->session().credits().loadedValue(
|
||||||
|
) | rpl::filter(
|
||||||
|
rpl::mappers::_1
|
||||||
|
) | rpl::take(1) | rpl::start_with_next([=] {
|
||||||
|
if (const auto callback = base::take(_resend)) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
peer->session().changes().peerUpdates(
|
||||||
|
peer,
|
||||||
|
Data::PeerUpdate::Flag::FullInfo
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
if (const auto callback = base::take(_resend)) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} else if (const auto stars = details->stars; stars > starsApproved) {
|
||||||
|
ShowSendPaidConfirm(show, peer, *details, [=] {
|
||||||
|
resend(stars);
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void RequestDependentMessageItem(
|
void RequestDependentMessageItem(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct SendErrorWithThread;
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
class Session;
|
class Session;
|
||||||
|
class SessionShow;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -149,11 +150,32 @@ void ShowSendPaidConfirm(
|
||||||
SendPaymentDetails details,
|
SendPaymentDetails details,
|
||||||
Fn<void()> confirmed);
|
Fn<void()> confirmed);
|
||||||
void ShowSendPaidConfirm(
|
void ShowSendPaidConfirm(
|
||||||
std::shared_ptr<ChatHelpers::Show> show,
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
SendPaymentDetails details,
|
SendPaymentDetails details,
|
||||||
Fn<void()> confirmed);
|
Fn<void()> confirmed);
|
||||||
|
|
||||||
|
class SendPaymentHelper final {
|
||||||
|
public:
|
||||||
|
[[nodiscard]] bool check(
|
||||||
|
not_null<Window::SessionNavigation*> navigation,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
int messagesCount,
|
||||||
|
int starsApproved,
|
||||||
|
Fn<void(int)> resend);
|
||||||
|
[[nodiscard]] bool check(
|
||||||
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
int messagesCount,
|
||||||
|
int starsApproved,
|
||||||
|
Fn<void(int)> resend);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Fn<void()> _resend;
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] Data::SendErrorWithThread GetErrorForSending(
|
[[nodiscard]] Data::SendErrorWithThread GetErrorForSending(
|
||||||
const std::vector<not_null<Data::Thread*>> &threads,
|
const std::vector<not_null<Data::Thread*>> &threads,
|
||||||
SendingErrorRequest request);
|
SendingErrorRequest request);
|
||||||
|
|
|
@ -226,10 +226,12 @@ const auto kPsaAboutPrefix = "cloud_lng_about_psa_";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct HistoryWidget::SendingFiles {
|
struct HistoryWidget::SendingFiles {
|
||||||
Ui::PreparedList list;
|
std::vector<Ui::PreparedGroup> groups;
|
||||||
Ui::SendFilesWay way;
|
Ui::SendFilesWay way;
|
||||||
TextWithTags caption;
|
TextWithTags caption;
|
||||||
Api::SendOptions options;
|
Api::SendOptions options;
|
||||||
|
int totalCount = 0;
|
||||||
|
bool sendComment = false;
|
||||||
bool ctrlShiftEnter = false;
|
bool ctrlShiftEnter = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -895,14 +897,16 @@ HistoryWidget::HistoryWidget(
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
session().credits().loadedValue(
|
if (!session().credits().loaded()) {
|
||||||
) | rpl::filter(
|
session().credits().loadedValue(
|
||||||
rpl::mappers::_1
|
) | rpl::filter(
|
||||||
) | rpl::take(1) | rpl::start_with_next([=] {
|
rpl::mappers::_1
|
||||||
if (const auto callback = base::take(_resendOnFullUpdated)) {
|
) | rpl::take(1) | rpl::start_with_next([=] {
|
||||||
callback();
|
if (const auto callback = base::take(_resendOnFullUpdated)) {
|
||||||
}
|
callback();
|
||||||
}, lifetime());
|
}
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
using Type = Data::DefaultNotify;
|
using Type = Data::DefaultNotify;
|
||||||
rpl::merge(
|
rpl::merge(
|
||||||
|
@ -6037,11 +6041,20 @@ void HistoryWidget::sendingFilesConfirmed(
|
||||||
return;
|
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{
|
sendingFilesConfirmed(std::make_shared<SendingFiles>(SendingFiles{
|
||||||
.list = std::move(list),
|
.groups = std::move(groups),
|
||||||
.way = way,
|
.way = way,
|
||||||
.caption = std::move(caption),
|
.caption = std::move(caption),
|
||||||
.options = options,
|
.options = options,
|
||||||
|
.totalCount = filesCount + (sendComment ? 1 : 0),
|
||||||
|
.sendComment = sendComment,
|
||||||
.ctrlShiftEnter = ctrlShiftEnter,
|
.ctrlShiftEnter = ctrlShiftEnter,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -6053,28 +6066,23 @@ void HistoryWidget::sendingFilesConfirmed(
|
||||||
sendingFilesConfirmed(args);
|
sendingFilesConfirmed(args);
|
||||||
};
|
};
|
||||||
const auto checked = checkSendPayment(
|
const auto checked = checkSendPayment(
|
||||||
args->list.files.size(),
|
args->totalCount,
|
||||||
args->options.starsApproved,
|
args->options.starsApproved,
|
||||||
withPaymentApproved);
|
withPaymentApproved);
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto groups = DivideByGroups(
|
|
||||||
std::move(args->list),
|
|
||||||
args->way,
|
|
||||||
_peer->slowmodeApplied());
|
|
||||||
const auto compress = args->way.sendImagesAsPhotos();
|
const auto compress = args->way.sendImagesAsPhotos();
|
||||||
const auto type = compress ? SendMediaType::Photo : SendMediaType::File;
|
const auto type = compress ? SendMediaType::Photo : SendMediaType::File;
|
||||||
auto action = prepareSendAction(args->options);
|
auto action = prepareSendAction(args->options);
|
||||||
action.clearDraft = false;
|
action.clearDraft = false;
|
||||||
if ((groups.size() != 1 || !groups.front().sentWithCaption())
|
if (args->sendComment) {
|
||||||
&& !args->caption.text.isEmpty()) {
|
|
||||||
auto message = Api::MessageToSend(action);
|
auto message = Api::MessageToSend(action);
|
||||||
message.textWithTags = base::take(args->caption);
|
message.textWithTags = base::take(args->caption);
|
||||||
session().api().sendMessage(std::move(message));
|
session().api().sendMessage(std::move(message));
|
||||||
}
|
}
|
||||||
for (auto &group : groups) {
|
for (auto &group : args->groups) {
|
||||||
const auto album = (group.type != Ui::AlbumType::None)
|
const auto album = (group.type != Ui::AlbumType::None)
|
||||||
? std::make_shared<SendingAlbum>()
|
? std::make_shared<SendingAlbum>()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
|
|
@ -1737,11 +1737,27 @@ void PeerMenuCreatePoll(
|
||||||
disabled,
|
disabled,
|
||||||
sendType,
|
sendType,
|
||||||
sendMenuDetails);
|
sendMenuDetails);
|
||||||
const auto weak = Ui::MakeWeak(box.data());
|
struct State {
|
||||||
const auto lock = box->lifetime().make_state<bool>(false);
|
QPointer<CreatePollBox> weak;
|
||||||
box->submitRequests(
|
Fn<void(const CreatePollBox::Result &)> create;
|
||||||
) | rpl::start_with_next([=](const CreatePollBox::Result &result) {
|
SendPaymentHelper sendPayment;
|
||||||
if (std::exchange(*lock, true)) {
|
bool lock = false;
|
||||||
|
};
|
||||||
|
const auto state = std::make_shared<State>();
|
||||||
|
state->weak = box;
|
||||||
|
state->create = [=](const CreatePollBox::Result &result) {
|
||||||
|
const auto withPaymentApproved = [=](int stars) {
|
||||||
|
auto copy = result;
|
||||||
|
copy.options.starsApproved = stars;
|
||||||
|
state->create(copy);
|
||||||
|
};
|
||||||
|
const auto checked = state->sendPayment.check(
|
||||||
|
controller,
|
||||||
|
peer,
|
||||||
|
1,
|
||||||
|
result.options.starsApproved,
|
||||||
|
withPaymentApproved);
|
||||||
|
if (!checked || std::exchange(state->lock, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto action = Api::SendAction(
|
auto action = Api::SendAction(
|
||||||
|
@ -1755,13 +1771,16 @@ void PeerMenuCreatePoll(
|
||||||
action.clearDraft = false;
|
action.clearDraft = false;
|
||||||
}
|
}
|
||||||
const auto api = &peer->session().api();
|
const auto api = &peer->session().api();
|
||||||
|
const auto weak = state->weak;
|
||||||
api->polls().create(result.poll, action, crl::guard(weak, [=] {
|
api->polls().create(result.poll, action, crl::guard(weak, [=] {
|
||||||
weak->closeBox();
|
weak->closeBox();
|
||||||
}), crl::guard(weak, [=] {
|
}), crl::guard(weak, [=] {
|
||||||
*lock = false;
|
state->lock = false;
|
||||||
weak->submitFailed(tr::lng_attach_failed(tr::now));
|
weak->submitFailed(tr::lng_attach_failed(tr::now));
|
||||||
}));
|
}));
|
||||||
}, box->lifetime());
|
};
|
||||||
|
box->submitRequests(
|
||||||
|
) | rpl::start_with_next(state->create, box->lifetime());
|
||||||
controller->show(std::move(box), Ui::LayerOption::CloseOther);
|
controller->show(std::move(box), Ui::LayerOption::CloseOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue