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 schedule = [=] {
sendAction(SendMenu::ActionType::Schedule, _sendMenuDetails());
sendAction(
{ .type = SendMenu::ActionType::Schedule },
_sendMenuDetails());
};
const auto submit = addButton(
(isNormal

View file

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

View file

@ -523,12 +523,19 @@ void ShareBox::showMenu(not_null<Ui::RpWidget*> parent) {
using namespace SendMenu;
const auto sendAction = crl::guard(this, [=](Action action, Details) {
const auto options = std::get_if<Api::SendOptions>(&action);
if (options || v::get<ActionType>(action) == ActionType::Send) {
submit(options ? *options : Api::SendOptions());
} else {
submitScheduled();
if (action.type == ActionType::Send) {
submit(action.options);
return;
}
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);
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 {
if (const auto onstack = _descriptor.copyCallback) {
onstack();

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -7,14 +7,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "api/api_common.h"
namespace style {
struct ComposeIcons;
} // namespace style
namespace Api {
struct SendOptions;
} // namespace Api
namespace ChatHelpers {
class Show;
} // namespace ChatHelpers
@ -54,7 +52,12 @@ enum class ActionType {
Send,
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(
std::shared_ptr<ChatHelpers::Show> show,
Fn<void(Api::SendOptions)> send);