Fix sending scheduled effects.

This commit is contained in:
John Preston 2024-05-14 14:47:34 +04:00
parent 487fa9728a
commit a011a7c316
11 changed files with 86 additions and 69 deletions

View file

@ -1304,7 +1304,9 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
const auto isNormal = (_sendType == Api::SendType::Normal); const auto isNormal = (_sendType == Api::SendType::Normal);
const auto schedule = [=] { const auto schedule = [=] {
sendAction(SendMenu::ActionType::Schedule, _sendMenuDetails()); sendAction(
{ .type = SendMenu::ActionType::Schedule },
_sendMenuDetails());
}; };
const auto submit = addButton( const auto submit = addButton(
(isNormal (isNormal

View file

@ -1427,7 +1427,7 @@ void SendFilesBox::send(
|| _sendType == Api::SendType::ScheduledToUser) || _sendType == Api::SendType::ScheduledToUser)
&& !options.scheduled) { && !options.scheduled) {
return SendMenu::DefaultCallback(_show, sendCallback())( return SendMenu::DefaultCallback(_show, sendCallback())(
SendMenu::ActionType::Schedule, { .type = SendMenu::ActionType::Schedule },
_sendMenuDetails()); _sendMenuDetails());
} }
if (_preparing) { if (_preparing) {

View file

@ -523,12 +523,19 @@ void ShareBox::showMenu(not_null<Ui::RpWidget*> parent) {
using namespace SendMenu; using namespace SendMenu;
const auto sendAction = crl::guard(this, [=](Action action, Details) { const auto sendAction = crl::guard(this, [=](Action action, Details) {
const auto options = std::get_if<Api::SendOptions>(&action); if (action.type == ActionType::Send) {
if (options || v::get<ActionType>(action) == ActionType::Send) { submit(action.options);
submit(options ? *options : Api::SendOptions()); return;
} else {
submitScheduled();
} }
uiShow()->showBox(
HistoryView::PrepareScheduleBox(
this,
nullptr, // ChatHelpers::Show for effect attachment.
sendMenuDetails(),
[=](Api::SendOptions options) { submit(options); },
action.options,
HistoryView::DefaultScheduleTime(),
_descriptor.scheduleBoxStyle));
}); });
_menu->setForcedVerticalOrigin(Ui::PopupMenu::VerticalOrigin::Bottom); _menu->setForcedVerticalOrigin(Ui::PopupMenu::VerticalOrigin::Bottom);
const auto result = FillSendMenu( const auto result = FillSendMenu(
@ -620,18 +627,6 @@ void ShareBox::submit(Api::SendOptions options) {
} }
} }
void ShareBox::submitScheduled() {
const auto callback = [=](Api::SendOptions options) { submit(options); };
uiShow()->showBox(
HistoryView::PrepareScheduleBox(
this,
nullptr, // ChatHelpers::Show for effect attachment.
sendMenuDetails(),
callback,
HistoryView::DefaultScheduleTime(),
_descriptor.scheduleBoxStyle));
}
void ShareBox::copyLink() const { void ShareBox::copyLink() const {
if (const auto onstack = _descriptor.copyCallback) { if (const auto onstack = _descriptor.copyCallback) {
onstack(); onstack();

View file

@ -130,7 +130,6 @@ private:
void scrollAnimationCallback(); void scrollAnimationCallback();
void submit(Api::SendOptions options); void submit(Api::SendOptions options);
void submitScheduled();
void copyLink() const; void copyLink() const;
bool searchByUsername(bool useCache = false); bool searchByUsername(bool useCache = false);

View file

@ -324,11 +324,10 @@ HistoryWidget::HistoryWidget(
{ {
using namespace SendMenu; using namespace SendMenu;
const auto sendAction = [=](Action action, Details) { const auto sendAction = [=](Action action, Details) {
const auto options = std::get_if<Api::SendOptions>(&action); if (action.type == ActionType::Send) {
if (options || v::get<ActionType>(action) == ActionType::Send) { send(action.options);
send(options ? *options : Api::SendOptions());
} else { } else {
sendScheduled(); sendScheduled(action.options);
} }
}; };
SetupMenuAndShortcuts( SetupMenuAndShortcuts(
@ -4192,7 +4191,7 @@ void HistoryWidget::sendWithModifiers(Qt::KeyboardModifiers modifiers) {
send({ .handleSupportSwitch = Support::HandleSwitch(modifiers) }); send({ .handleSupportSwitch = Support::HandleSwitch(modifiers) });
} }
void HistoryWidget::sendScheduled() { void HistoryWidget::sendScheduled(Api::SendOptions initialOptions) {
if (!_list) { if (!_list) {
return; return;
} }
@ -4202,13 +4201,13 @@ void HistoryWidget::sendScheduled() {
ignoreSlowmodeCountdown)) { ignoreSlowmodeCountdown)) {
return; return;
} }
const auto callback = [=](Api::SendOptions options) { send(options); };
controller()->show( controller()->show(
HistoryView::PrepareScheduleBox( HistoryView::PrepareScheduleBox(
_list, _list,
controller()->uiShow(), controller()->uiShow(),
sendMenuDetails(), sendMenuDetails(),
callback)); [=](Api::SendOptions options) { send(options); },
initialOptions));
} }
SendMenu::Details HistoryWidget::sendMenuDetails() const { SendMenu::Details HistoryWidget::sendMenuDetails() const {

View file

@ -395,7 +395,7 @@ private:
Api::SendOptions options) const; Api::SendOptions options) const;
void send(Api::SendOptions options); void send(Api::SendOptions options);
void sendWithModifiers(Qt::KeyboardModifiers modifiers); void sendWithModifiers(Qt::KeyboardModifiers modifiers);
void sendScheduled(); void sendScheduled(Api::SendOptions initialOptions);
[[nodiscard]] SendMenu::Details sendButtonMenuDetails() const; [[nodiscard]] SendMenu::Details sendButtonMenuDetails() const;
void handlePendingHistoryUpdate(); void handlePendingHistoryUpdate();
void fullInfoUpdated(); void fullInfoUpdated();

View file

@ -592,6 +592,7 @@ bool AddRescheduleAction(
request.navigation->uiShow(), request.navigation->uiShow(),
{ .type = sendMenuType, .effectAllowed = false }, { .type = sendMenuType, .effectAllowed = false },
callback, callback,
{}, // initial options
date)); date));
owner->itemRemoved( owner->itemRemoved(

View file

@ -70,28 +70,34 @@ bool CanScheduleUntilOnline(not_null<PeerData*> peer) {
void ScheduleBox( void ScheduleBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
std::shared_ptr<ChatHelpers::Show> show, std::shared_ptr<ChatHelpers::Show> show,
const Api::SendOptions &initialOptions,
const SendMenu::Details &details, const SendMenu::Details &details,
Fn<void(Api::SendOptions)> done, Fn<void(Api::SendOptions)> done,
TimeId time, TimeId time,
ScheduleBoxStyleArgs style) { ScheduleBoxStyleArgs style) {
const auto save = [=](bool silent, TimeId scheduleDate) { const auto submit = [=](Api::SendOptions options) {
if (!scheduleDate) { if (!options.scheduled) {
return; return;
} }
auto result = Api::SendOptions();
// Pro tip: Hold Ctrl key to send a silent scheduled message! // Pro tip: Hold Ctrl key to send a silent scheduled message!
result.silent = silent || base::IsCtrlPressed(); if (base::IsCtrlPressed()) {
result.scheduled = scheduleDate; options.silent = true;
}
const auto copy = done; const auto copy = done;
box->closeBox(); box->closeBox();
copy(result); copy(options);
};
const auto with = [=](TimeId scheduled) {
auto result = initialOptions;
result.scheduled = scheduled;
return result;
}; };
auto descriptor = Ui::ChooseDateTimeBox(box, { auto descriptor = Ui::ChooseDateTimeBox(box, {
.title = (details.type == SendMenu::Type::Reminder .title = (details.type == SendMenu::Type::Reminder
? tr::lng_remind_title() ? tr::lng_remind_title()
: tr::lng_schedule_title()), : tr::lng_schedule_title()),
.submit = tr::lng_schedule_button(), .submit = tr::lng_schedule_button(),
.done = [=](TimeId result) { save(false, result); }, .done = [=](TimeId result) { submit(with(result)); },
.time = time, .time = time,
.style = style.chooseDateTimeArgs, .style = style.chooseDateTimeArgs,
}); });
@ -105,9 +111,16 @@ void ScheduleBox(
.effectAllowed = details.effectAllowed, .effectAllowed = details.effectAllowed,
}; };
const auto sendAction = crl::guard(box, [=](Action action, Details) { const auto sendAction = crl::guard(box, [=](Action action, Details) {
save( Expects(action.type == ActionType::Send);
v::get<Api::SendOptions>(action).silent,
descriptor.collect()); auto options = with(descriptor.collect());
if (action.options.silent) {
options.silent = action.options.silent;
}
if (action.options.effectId) {
options.effectId = action.options.effectId;
}
submit(options);
}); });
SetupMenuAndShortcuts( SetupMenuAndShortcuts(
descriptor.submit.data(), descriptor.submit.data(),
@ -120,7 +133,7 @@ void ScheduleBox(
const auto timestamp = Api::kScheduledUntilOnlineTimestamp; const auto timestamp = Api::kScheduledUntilOnlineTimestamp;
FillSendUntilOnlineMenu( FillSendUntilOnlineMenu(
sendUntilOnline.data(), sendUntilOnline.data(),
[=] { save(false, timestamp); }, [=] { submit(with(timestamp)); },
style); style);
} }
} }

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
#include "api/api_common.h"
#include "ui/boxes/choose_date_time.h" #include "ui/boxes/choose_date_time.h"
namespace style { namespace style {
@ -14,10 +15,6 @@ struct IconButton;
struct PopupMenu; struct PopupMenu;
} // namespace style } // namespace style
namespace Api {
struct SendOptions;
} // namespace Api
namespace ChatHelpers { namespace ChatHelpers {
class Show; class Show;
} // namespace ChatHelpers } // namespace ChatHelpers
@ -41,6 +38,7 @@ struct ScheduleBoxStyleArgs {
void ScheduleBox( void ScheduleBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
std::shared_ptr<ChatHelpers::Show> show, std::shared_ptr<ChatHelpers::Show> show,
const Api::SendOptions &initialOptions,
const SendMenu::Details &details, const SendMenu::Details &details,
Fn<void(Api::SendOptions)> done, Fn<void(Api::SendOptions)> done,
TimeId time, TimeId time,
@ -52,11 +50,13 @@ template <typename Guard, typename Submit>
std::shared_ptr<ChatHelpers::Show> show, std::shared_ptr<ChatHelpers::Show> show,
const SendMenu::Details &details, const SendMenu::Details &details,
Submit &&submit, Submit &&submit,
const Api::SendOptions &initialOptions = {},
TimeId scheduleTime = DefaultScheduleTime(), TimeId scheduleTime = DefaultScheduleTime(),
ScheduleBoxStyleArgs style = ScheduleBoxStyleArgs()) { ScheduleBoxStyleArgs style = ScheduleBoxStyleArgs()) {
return Box( return Box(
ScheduleBox, ScheduleBox,
std::move(show), std::move(show),
initialOptions,
details, details,
crl::guard(std::forward<Guard>(guard), std::forward<Submit>(submit)), crl::guard(std::forward<Guard>(guard), std::forward<Submit>(submit)),
scheduleTime, scheduleTime,

View file

@ -214,9 +214,8 @@ void BottomRounded::paintEvent(QPaintEvent *e) {
EffectId id, EffectId id,
Fn<void()> done) { Fn<void()> done) {
return [=](Action action, Details details) { return [=](Action action, Details details) {
if (const auto options = std::get_if<Api::SendOptions>(&action)) { action.options.effectId = id;
options->effectId = id;
}
const auto onstack = done; const auto onstack = done;
sendAction(action, details); sendAction(action, details);
if (onstack) { if (onstack) {
@ -511,7 +510,7 @@ bool EffectPreview::canSend() const {
void EffectPreview::setupSend(Details details) { void EffectPreview::setupSend(Details details) {
if (_send) { if (_send) {
_send->setClickedCallback([=] { _send->setClickedCallback([=] {
_actionWithEffect(Api::SendOptions(), details); _actionWithEffect({}, details);
}); });
const auto type = details.type; const auto type = details.type;
SetupMenuAndShortcuts(_send.get(), _show, [=] { SetupMenuAndShortcuts(_send.get(), _show, [=] {
@ -588,18 +587,20 @@ Fn<void(Action, Details)> DefaultCallback(
Fn<void(Api::SendOptions)> send) { Fn<void(Api::SendOptions)> send) {
const auto guard = Ui::MakeWeak(show->toastParent()); const auto guard = Ui::MakeWeak(show->toastParent());
return [=](Action action, Details details) { return [=](Action action, Details details) {
if (const auto options = std::get_if<Api::SendOptions>(&action)) { if (action.type == ActionType::Send) {
send(*options); send(action.options);
} else if (v::get<ActionType>(action) == ActionType::Send) { return;
send({}); }
} else { auto box = HistoryView::PrepareScheduleBox(
using namespace HistoryView; guard,
auto box = PrepareScheduleBox(guard, show, details, send); show,
const auto weak = Ui::MakeWeak(box.data()); details,
show->showBox(std::move(box)); send,
if (const auto strong = weak.data()) { action.options);
strong->setCloseByOutsideClick(false); const auto weak = Ui::MakeWeak(box.data());
} show->showBox(std::move(box));
if (const auto strong = weak.data()) {
strong->setCloseByOutsideClick(false);
} }
}; };
} }
@ -622,7 +623,9 @@ FillMenuResult FillSendMenu(
if (type != Type::Reminder) { if (type != Type::Reminder) {
menu->addAction( menu->addAction(
tr::lng_send_silent_message(tr::now), tr::lng_send_silent_message(tr::now),
[=] { action(Api::SendOptions{ .silent = true }, details); }, [=] { action(
{ Api::SendOptions{ .silent = true } },
details); },
&icons.menuMute); &icons.menuMute);
} }
if (type != Type::SilentOnly) { if (type != Type::SilentOnly) {
@ -630,13 +633,15 @@ FillMenuResult FillSendMenu(
(type == Type::Reminder (type == Type::Reminder
? tr::lng_reminder_message(tr::now) ? tr::lng_reminder_message(tr::now)
: tr::lng_schedule_message(tr::now)), : tr::lng_schedule_message(tr::now)),
[=] { action(ActionType::Schedule, details); }, [=] { action({ .type = ActionType::Schedule }, details); },
&icons.menuSchedule); &icons.menuSchedule);
} }
if (type == Type::ScheduledToUser) { if (type == Type::ScheduledToUser) {
menu->addAction( menu->addAction(
tr::lng_scheduled_send_until_online(tr::now), tr::lng_scheduled_send_until_online(tr::now),
[=] { action(Api::DefaultSendWhenOnlineOptions(), details); }, [=] { action(
{ Api::DefaultSendWhenOnlineOptions() },
details); },
&icons.menuWhenOnline); &icons.menuWhenOnline);
} }
@ -730,14 +735,14 @@ void SetupMenuAndShortcuts(
((now != Type::Reminder) ((now != Type::Reminder)
&& request->check(Command::SendSilentMessage) && request->check(Command::SendSilentMessage)
&& request->handle([=] { && request->handle([=] {
action(Api::SendOptions{ .silent = true }, details()); action({ Api::SendOptions{ .silent = true } }, details());
return true; return true;
})) }))
|| ||
((now != Type::SilentOnly) ((now != Type::SilentOnly)
&& request->check(Command::ScheduleMessage) && request->check(Command::ScheduleMessage)
&& request->handle([=] { && request->handle([=] {
action(ActionType::Schedule, details()); action({ .type = ActionType::Schedule }, details());
return true; return true;
})) }))
|| ||

View file

@ -7,14 +7,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
#include "api/api_common.h"
namespace style { namespace style {
struct ComposeIcons; struct ComposeIcons;
} // namespace style } // namespace style
namespace Api {
struct SendOptions;
} // namespace Api
namespace ChatHelpers { namespace ChatHelpers {
class Show; class Show;
} // namespace ChatHelpers } // namespace ChatHelpers
@ -54,7 +52,12 @@ enum class ActionType {
Send, Send,
Schedule, Schedule,
}; };
using Action = std::variant<Api::SendOptions, ActionType>; struct Action {
using Type = ActionType;
Api::SendOptions options;
Type type = Type::Send;
};
[[nodiscard]] Fn<void(Action, Details)> DefaultCallback( [[nodiscard]] Fn<void(Action, Details)> DefaultCallback(
std::shared_ptr<ChatHelpers::Show> show, std::shared_ptr<ChatHelpers::Show> show,
Fn<void(Api::SendOptions)> send); Fn<void(Api::SendOptions)> send);