Added ability to schedule messages to be sent when user comes online.

Pro tip: Hold Ctrl key to send a silent scheduled message!
This commit is contained in:
23rd 2020-01-15 05:31:28 +03:00 committed by John Preston
parent 8ebbeb5274
commit c08b2ae3df
10 changed files with 68 additions and 13 deletions

View File

@ -1296,6 +1296,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_reminder_messages" = "Reminders"; "lng_reminder_messages" = "Reminders";
"lng_scheduled_date" = "Scheduled for {date}"; "lng_scheduled_date" = "Scheduled for {date}";
"lng_scheduled_date_until_online" = "Scheduled until online"; "lng_scheduled_date_until_online" = "Scheduled until online";
"lng_scheduled_send_until_online" = "Send when online";
"lng_scheduled_send_now" = "Send message now?"; "lng_scheduled_send_now" = "Send message now?";
"lng_scheduled_send_now_many#one" = "Send {count} message now?"; "lng_scheduled_send_now_many#one" = "Send {count} message now?";
"lng_scheduled_send_now_many#other" = "Send {count} messages now?"; "lng_scheduled_send_now_many#other" = "Send {count} messages now?";

View File

@ -21,6 +21,7 @@ struct SendOptions {
enum class SendType { enum class SendType {
Normal, Normal,
Scheduled, Scheduled,
ScheduledToUser, // For "Send when online".
}; };
struct SendAction { struct SendAction {

View File

@ -1937,7 +1937,9 @@ void SendFilesBox::setInnerFocus() {
void SendFilesBox::send( void SendFilesBox::send(
Api::SendOptions options, Api::SendOptions options,
bool ctrlShiftEnter) { bool ctrlShiftEnter) {
if (_sendType == Api::SendType::Scheduled && !options.scheduled) { if ((_sendType == Api::SendType::Scheduled
|| _sendType == Api::SendType::ScheduledToUser)
&& !options.scheduled) {
return sendScheduled(); return sendScheduled();
} }
@ -1982,9 +1984,12 @@ void SendFilesBox::sendSilent() {
} }
void SendFilesBox::sendScheduled() { void SendFilesBox::sendScheduled() {
const auto type = (_sendType == Api::SendType::ScheduledToUser)
? SendMenuType::ScheduledToUser
: _sendMenuType;
const auto callback = [=](Api::SendOptions options) { send(options); }; const auto callback = [=](Api::SendOptions options) { send(options); };
Ui::show( Ui::show(
HistoryView::PrepareScheduleBox(this, _sendMenuType, callback), HistoryView::PrepareScheduleBox(this, type, callback),
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
} }

View File

@ -413,7 +413,9 @@ void ShareBox::keyPressEvent(QKeyEvent *e) {
SendMenuType ShareBox::sendMenuType() const { SendMenuType ShareBox::sendMenuType() const {
const auto selected = _inner->selected(); const auto selected = _inner->selected();
return (selected.size() == 1 && selected.front()->isSelf()) return ranges::all_of(selected, HistoryView::CanScheduleUntilOnline)
? SendMenuType::ScheduledToUser
: (selected.size() == 1 && selected.front()->isSelf())
? SendMenuType::Reminder ? SendMenuType::Reminder
: SendMenuType::Scheduled; : SendMenuType::Scheduled;
} }

View File

@ -688,9 +688,9 @@ void SetupSendMenu(
} }
if (schedule && now != SendMenuType::SilentOnly) { if (schedule && now != SendMenuType::SilentOnly) {
(*menu)->addAction( (*menu)->addAction(
(now == SendMenuType::Scheduled (now == SendMenuType::Reminder
? tr::lng_schedule_message(tr::now) ? tr::lng_reminder_message(tr::now)
: tr::lng_reminder_message(tr::now)), : tr::lng_schedule_message(tr::now)),
schedule); schedule);
} }
(*menu)->popup(QCursor::pos()); (*menu)->popup(QCursor::pos());

View File

@ -99,6 +99,7 @@ enum class SendMenuType {
Disabled, Disabled,
SilentOnly, SilentOnly,
Scheduled, Scheduled,
ScheduledToUser, // For "Send when online".
Reminder, Reminder,
}; };

View File

@ -3019,6 +3019,8 @@ SendMenuType HistoryWidget::sendMenuType() const {
? SendMenuType::Disabled ? SendMenuType::Disabled
: _peer->isSelf() : _peer->isSelf()
? SendMenuType::Reminder ? SendMenuType::Reminder
: HistoryView::CanScheduleUntilOnline(_peer)
? SendMenuType::ScheduledToUser
: SendMenuType::Scheduled; : SendMenuType::Scheduled;
} }

View File

@ -8,17 +8,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_schedule_box.h" #include "history/view/history_view_schedule_box.h"
#include "api/api_common.h" #include "api/api_common.h"
#include "data/data_peer.h"
#include "data/data_user.h"
#include "data/data_scheduled_messages.h" // kScheduledUntilOnlineTimestamp
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "base/unixtime.h" #include "base/unixtime.h"
#include "boxes/calendar_box.h" #include "boxes/calendar_box.h"
#include "ui/widgets/input_fields.h" #include "ui/widgets/input_fields.h"
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/popup_menu.h"
#include "ui/wrap/padding_wrap.h" #include "ui/wrap/padding_wrap.h"
#include "chat_helpers/message_field.h" #include "chat_helpers/message_field.h"
#include "styles/style_info.h"
#include "styles/style_layers.h" #include "styles/style_layers.h"
#include "styles/style_history.h" #include "styles/style_history.h"
#include <QGuiApplication>
namespace HistoryView { namespace HistoryView {
namespace { namespace {
@ -535,20 +542,38 @@ void TimeInput::startBorderAnimation() {
} }
} }
void FillSendUntilOnlineMenu(
not_null<Ui::IconButton*> button,
Fn<void()> callback) {
const auto menu = std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
button->setClickedCallback([=] {
*menu = base::make_unique_q<Ui::PopupMenu>(button);
(*menu)->addAction(
tr::lng_scheduled_send_until_online(tr::now),
std::move(callback));
(*menu)->popup(QCursor::pos());
return true;
});
}
} // namespace } // namespace
TimeId DefaultScheduleTime() { TimeId DefaultScheduleTime() {
return base::unixtime::now() + 600; return base::unixtime::now() + 600;
} }
bool CanScheduleUntilOnline(not_null<PeerData*> peer) {
return !peer->isSelf() && peer->isUser() && !peer->asUser()->isBot();
}
void ScheduleBox( void ScheduleBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
SendMenuType type, SendMenuType type,
FnMut<void(Api::SendOptions)> done, FnMut<void(Api::SendOptions)> done,
TimeId time) { TimeId time) {
box->setTitle((type == SendMenuType::Scheduled) box->setTitle((type == SendMenuType::Reminder)
? tr::lng_schedule_title() ? tr::lng_remind_title()
: tr::lng_remind_title()); : tr::lng_schedule_title());
box->setWidth(st::boxWideWidth); box->setWidth(st::boxWideWidth);
const auto date = Ui::CreateChild<rpl::variable<QDate>>( const auto date = Ui::CreateChild<rpl::variable<QDate>>(
@ -637,10 +662,15 @@ void ScheduleBox(
} }
return result; return result;
}; };
const auto save = [=](bool silent) { const auto save = [=](bool silent, bool untilOnline = false) {
// Pro tip: Hold Ctrl key to send a silent scheduled message!
auto ctrl =
(QGuiApplication::keyboardModifiers() == Qt::ControlModifier);
auto result = Api::SendOptions(); auto result = Api::SendOptions();
result.silent = silent; result.silent = silent || ctrl;
result.scheduled = collect(); result.scheduled = untilOnline
? Data::ScheduledMessages::kScheduledUntilOnlineTimestamp
: collect();
if (!result.scheduled) { if (!result.scheduled) {
return; return;
} }
@ -664,6 +694,14 @@ void ScheduleBox(
[=] { save(true); }, [=] { save(true); },
nullptr); nullptr);
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
if (type == SendMenuType::ScheduledToUser) {
const auto sendUntilOnline = box->addTopButton(st::infoTopBarMenu);
FillSendUntilOnlineMenu(
sendUntilOnline.data(),
[=] { save(false, true); });
}
} }
} // namespace HistoryView } // namespace HistoryView

View File

@ -18,6 +18,7 @@ enum class SendMenuType;
namespace HistoryView { namespace HistoryView {
[[nodiscard]] TimeId DefaultScheduleTime(); [[nodiscard]] TimeId DefaultScheduleTime();
[[nodiscard]] bool CanScheduleUntilOnline(not_null<PeerData*> peer);
void ScheduleBox( void ScheduleBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
SendMenuType type, SendMenuType type,

View File

@ -240,7 +240,9 @@ bool ScheduledWidget::confirmSendingFiles(
text, text,
boxCompressConfirm, boxCompressConfirm,
_history->peer->slowmodeApplied() ? SendLimit::One : SendLimit::Many, _history->peer->slowmodeApplied() ? SendLimit::One : SendLimit::Many,
Api::SendType::Scheduled, CanScheduleUntilOnline(_history->peer)
? Api::SendType::ScheduledToUser
: Api::SendType::Scheduled,
SendMenuType::Disabled); SendMenuType::Disabled);
//_field->setTextWithTags({}); //_field->setTextWithTags({});
@ -545,6 +547,8 @@ void ScheduledWidget::sendInlineResult(
SendMenuType ScheduledWidget::sendMenuType() const { SendMenuType ScheduledWidget::sendMenuType() const {
return _history->peer->isSelf() return _history->peer->isSelf()
? SendMenuType::Reminder ? SendMenuType::Reminder
: HistoryView::CanScheduleUntilOnline(_history->peer)
? SendMenuType::ScheduledToUser
: SendMenuType::Scheduled; : SendMenuType::Scheduled;
} }