Add "Send when online" to the send button context menu.

This commit is contained in:
John Preston 2023-04-22 22:26:09 +04:00
parent 4201a0193c
commit e285b22398
24 changed files with 80 additions and 31 deletions

View File

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "api/api_common.h" #include "api/api_common.h"
#include "base/qt/qt_key_modifiers.h"
#include "data/data_thread.h" #include "data/data_thread.h"
namespace Api { namespace Api {
@ -20,4 +21,11 @@ SendAction::SendAction(
, topicRootId(replyTo) { , topicRootId(replyTo) {
} }
SendOptions DefaultSendWhenOnlineOptions() {
return {
.scheduled = kScheduledUntilOnlineTimestamp,
.silent = base::IsCtrlPressed(),
};
}
} // namespace Api } // namespace Api

View File

@ -15,6 +15,8 @@ class Thread;
namespace Api { namespace Api {
inline constexpr auto kScheduledUntilOnlineTimestamp = TimeId(0x7FFFFFFE);
struct SendOptions { struct SendOptions {
PeerData *sendAs = nullptr; PeerData *sendAs = nullptr;
TimeId scheduled = 0; TimeId scheduled = 0;
@ -23,6 +25,7 @@ struct SendOptions {
bool removeWebPageId = false; bool removeWebPageId = false;
bool hideViaBot = false; bool hideViaBot = false;
}; };
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();
enum class SendType { enum class SendType {
Normal, Normal,

View File

@ -1102,6 +1102,9 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
send), send),
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
}; };
const auto sendWhenOnline = [=] {
send(Api::DefaultSendWhenOnlineOptions());
};
options->scrollToWidget( options->scrollToWidget(
) | rpl::start_with_next([=](not_null<QWidget*> widget) { ) | rpl::start_with_next([=](not_null<QWidget*> widget) {
@ -1130,7 +1133,8 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
submit.data(), submit.data(),
sendMenuType, sendMenuType,
sendSilent, sendSilent,
sendScheduled); sendScheduled,
sendWhenOnline);
addButton(tr::lng_cancel(), [=] { closeBox(); }); addButton(tr::lng_cancel(), [=] { closeBox(); });
return result; return result;

View File

@ -508,7 +508,8 @@ void SendFilesBox::refreshButtons() {
_send, _send,
[=] { return _sendMenuType; }, [=] { return _sendMenuType; },
[=] { sendSilent(); }, [=] { sendSilent(); },
[=] { sendScheduled(); }); [=] { sendScheduled(); },
[=] { sendWhenOnline(); });
} }
addButton(tr::lng_cancel(), [=] { closeBox(); }); addButton(tr::lng_cancel(), [=] { closeBox(); });
_addFile = addLeftButton( _addFile = addLeftButton(
@ -584,7 +585,8 @@ void SendFilesBox::addMenuButton() {
_menu.get(), _menu.get(),
_sendMenuType, _sendMenuType,
[=] { sendSilent(); }, [=] { sendSilent(); },
[=] { sendScheduled(); }); [=] { sendScheduled(); },
[=] { sendWhenOnline(); });
} }
_menu->popup(QCursor::pos()); _menu->popup(QCursor::pos());
return true; return true;
@ -1390,4 +1392,8 @@ void SendFilesBox::sendScheduled() {
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
} }
void SendFilesBox::sendWhenOnline() {
send(Api::DefaultSendWhenOnlineOptions());
}
SendFilesBox::~SendFilesBox() = default; SendFilesBox::~SendFilesBox() = default;

View File

@ -179,6 +179,7 @@ private:
void send(Api::SendOptions options, bool ctrlShiftEnter = false); void send(Api::SendOptions options, bool ctrlShiftEnter = false);
void sendSilent(); void sendSilent();
void sendScheduled(); void sendScheduled();
void sendWhenOnline();
void captionResized(); void captionResized();
void saveSendWaySettings(); void saveSendWaySettings();

View File

@ -502,7 +502,8 @@ void ShareBox::showMenu(not_null<Ui::RpWidget*> parent) {
_menu.get(), _menu.get(),
sendMenuType(), sendMenuType(),
[=] { submitSilent(); }, [=] { submitSilent(); },
[=] { submitScheduled(); }); [=] { submitScheduled(); },
[=] { submitWhenOnline(); });
const auto success = (result == SendMenu::FillMenuResult::Success); const auto success = (result == SendMenu::FillMenuResult::Success);
if (_descriptor.forwardOptions.show || success) { if (_descriptor.forwardOptions.show || success) {
_menu->setForcedVerticalOrigin(Ui::PopupMenu::VerticalOrigin::Bottom); _menu->setForcedVerticalOrigin(Ui::PopupMenu::VerticalOrigin::Bottom);
@ -599,6 +600,10 @@ void ShareBox::submitScheduled() {
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
} }
void ShareBox::submitWhenOnline() {
submit(Api::DefaultSendWhenOnlineOptions());
}
void ShareBox::copyLink() { void ShareBox::copyLink() {
if (const auto onstack = _descriptor.copyCallback) { if (const auto onstack = _descriptor.copyCallback) {
onstack(); onstack();

View File

@ -118,6 +118,7 @@ private:
void submit(Api::SendOptions options); void submit(Api::SendOptions options);
void submitSilent(); void submitSilent();
void submitScheduled(); void submitScheduled();
void submitWhenOnline();
void copyLink(); void copyLink();
bool searchByUsername(bool useCache = false); bool searchByUsername(bool useCache = false);

View File

@ -1023,7 +1023,8 @@ void StickerSetBox::Inner::contextMenuEvent(QContextMenuEvent *e) {
_menu.get(), _menu.get(),
type, type,
SendMenu::DefaultSilentCallback(sendSelected), SendMenu::DefaultSilentCallback(sendSelected),
SendMenu::DefaultScheduleCallback(this, type, sendSelected)); SendMenu::DefaultScheduleCallback(this, type, sendSelected),
SendMenu::DefaultWhenOnlineCallback(sendSelected));
const auto controller = _controller; const auto controller = _controller;
const auto toggleFavedSticker = [=] { const auto toggleFavedSticker = [=] {

View File

@ -1283,7 +1283,8 @@ void FieldAutocomplete::Inner::contextMenuEvent(QContextMenuEvent *e) {
_menu, _menu,
type, type,
SendMenu::DefaultSilentCallback(send), SendMenu::DefaultSilentCallback(send),
SendMenu::DefaultScheduleCallback(this, type, send)); SendMenu::DefaultScheduleCallback(this, type, send),
SendMenu::DefaultWhenOnlineCallback(send));
if (!_menu->empty()) { if (!_menu->empty()) {
_menu->popup(QCursor::pos()); _menu->popup(QCursor::pos());

View File

@ -381,7 +381,8 @@ base::unique_qptr<Ui::PopupMenu> GifsListWidget::fillContextMenu(
menu, menu,
type, type,
SendMenu::DefaultSilentCallback(send), SendMenu::DefaultSilentCallback(send),
SendMenu::DefaultScheduleCallback(this, type, send)); SendMenu::DefaultScheduleCallback(this, type, send),
SendMenu::DefaultWhenOnlineCallback(send));
if (const auto item = _mosaic.maybeItemAt(_selected)) { if (const auto item = _mosaic.maybeItemAt(_selected)) {
const auto document = item->getDocument() const auto document = item->getDocument()

View File

@ -1608,7 +1608,8 @@ base::unique_qptr<Ui::PopupMenu> StickersListWidget::fillContextMenu(
menu, menu,
type, type,
SendMenu::DefaultSilentCallback(send), SendMenu::DefaultSilentCallback(send),
SendMenu::DefaultScheduleCallback(this, type, send)); SendMenu::DefaultScheduleCallback(this, type, send),
SendMenu::DefaultWhenOnlineCallback(send));
const auto window = _controller; const auto window = _controller;
const auto toggleFavedSticker = [=] { const auto toggleFavedSticker = [=] {

View File

@ -40,7 +40,7 @@ constexpr auto kRequestTimeLimit = 60 * crl::time(1000);
} }
[[nodiscard]] bool HasScheduledDate(not_null<HistoryItem*> item) { [[nodiscard]] bool HasScheduledDate(not_null<HistoryItem*> item) {
return (item->date() != ScheduledMessages::kScheduledUntilOnlineTimestamp) return (item->date() != Api::kScheduledUntilOnlineTimestamp)
&& (item->date() > base::unixtime::now()); && (item->date() > base::unixtime::now());
} }

View File

@ -53,8 +53,6 @@ public:
[[nodiscard]] rpl::producer<> updates(not_null<History*> history); [[nodiscard]] rpl::producer<> updates(not_null<History*> history);
[[nodiscard]] Data::MessagesSlice list(not_null<History*> history); [[nodiscard]] Data::MessagesSlice list(not_null<History*> history);
static constexpr auto kScheduledUntilOnlineTimestamp = TimeId(0x7FFFFFFE);
private: private:
using OwnedItem = std::unique_ptr<HistoryItem, HistoryItem::Destroyer>; using OwnedItem = std::unique_ptr<HistoryItem, HistoryItem::Destroyer>;
struct List { struct List {

View File

@ -50,7 +50,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/ui/dialogs_message_view.h" #include "dialogs/ui/dialogs_message_view.h"
#include "data/notify/data_notify_settings.h" #include "data/notify/data_notify_settings.h"
#include "data/data_bot_app.h" #include "data/data_bot_app.h"
#include "data/data_scheduled_messages.h" // kScheduledUntilOnlineTimestamp #include "data/data_scheduled_messages.h"
#include "data/data_changes.h" #include "data/data_changes.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_message_reactions.h" #include "data/data_message_reactions.h"

View File

@ -18,7 +18,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_forum_topic.h" #include "data/data_forum_topic.h"
#include "data/data_media_types.h" #include "data/data_media_types.h"
#include "data/data_message_reactions.h" #include "data/data_message_reactions.h"
#include "data/data_scheduled_messages.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "history/history.h" #include "history/history.h"
@ -230,8 +229,7 @@ QString ItemDateText(not_null<const HistoryItem*> item, bool isUntilOnline) {
bool IsItemScheduledUntilOnline(not_null<const HistoryItem*> item) { bool IsItemScheduledUntilOnline(not_null<const HistoryItem*> item) {
return item->isScheduled() return item->isScheduled()
&& (item->date() == && (item->date() == Api::kScheduledUntilOnlineTimestamp);
Data::ScheduledMessages::kScheduledUntilOnlineTimestamp);
} }
ClickHandlerPtr JumpToMessageClickHandler( ClickHandlerPtr JumpToMessageClickHandler(

View File

@ -305,7 +305,8 @@ HistoryWidget::HistoryWidget(
_send.get(), _send.get(),
[=] { return sendButtonMenuType(); }, [=] { return sendButtonMenuType(); },
[=] { sendSilent(); }, [=] { sendSilent(); },
[=] { sendScheduled(); }); [=] { sendScheduled(); },
[=] { sendWhenOnline(); });
_unblock->addClickHandler([=] { unblockUser(); }); _unblock->addClickHandler([=] { unblockUser(); });
_botStart->addClickHandler([=] { sendBotStartCommand(); }); _botStart->addClickHandler([=] { sendBotStartCommand(); });
@ -3934,6 +3935,10 @@ void HistoryWidget::sendScheduled() {
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
} }
void HistoryWidget::sendWhenOnline() {
send(Api::DefaultSendWhenOnlineOptions());
}
SendMenu::Type HistoryWidget::sendMenuType() const { SendMenu::Type HistoryWidget::sendMenuType() const {
return !_peer return !_peer
? SendMenu::Type::Disabled ? SendMenu::Type::Disabled

View File

@ -379,6 +379,7 @@ private:
void sendWithModifiers(Qt::KeyboardModifiers modifiers); void sendWithModifiers(Qt::KeyboardModifiers modifiers);
void sendSilent(); void sendSilent();
void sendScheduled(); void sendScheduled();
void sendWhenOnline();
[[nodiscard]] SendMenu::Type sendButtonMenuType() const; [[nodiscard]] SendMenu::Type sendButtonMenuType() const;
void handlePendingHistoryUpdate(); void handlePendingHistoryUpdate();
void fullInfoUpdated(); void fullInfoUpdated();

View File

@ -2075,7 +2075,8 @@ void ComposeControls::initSendButton() {
_send.get(), _send.get(),
[=] { return sendButtonMenuType(); }, [=] { return sendButtonMenuType(); },
SendMenu::DefaultSilentCallback(send), SendMenu::DefaultSilentCallback(send),
SendMenu::DefaultScheduleCallback(_wrap.get(), sendMenuType(), send)); SendMenu::DefaultScheduleCallback(_wrap.get(), sendMenuType(), send),
SendMenu::DefaultWhenOnlineCallback(send));
} }
void ComposeControls::initSendAsButton(not_null<PeerData*> peer) { void ComposeControls::initSendAsButton(not_null<PeerData*> peer) {

View File

@ -52,7 +52,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_file_click_handler.h" #include "data/data_file_click_handler.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "data/data_scheduled_messages.h"
#include "data/data_message_reactions.h" #include "data/data_message_reactions.h"
#include "data/stickers/data_custom_emoji.h" #include "data/stickers/data_custom_emoji.h"
#include "core/file_utilities.h" #include "core/file_utilities.h"
@ -555,9 +554,8 @@ bool AddRescheduleAction(
? SendMenu::Type::ScheduledToUser ? SendMenu::Type::ScheduledToUser
: SendMenu::Type::Scheduled; : SendMenu::Type::Scheduled;
using S = Data::ScheduledMessages;
const auto itemDate = firstItem->date(); const auto itemDate = firstItem->date();
const auto date = (itemDate == S::kScheduledUntilOnlineTimestamp) const auto date = (itemDate == Api::kScheduledUntilOnlineTimestamp)
? HistoryView::DefaultScheduleTime() ? HistoryView::DefaultScheduleTime()
: itemDate + 600; : itemDate + 600;

View File

@ -10,7 +10,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_common.h" #include "api/api_common.h"
#include "data/data_peer.h" #include "data/data_peer.h"
#include "data/data_user.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/event_filter.h" #include "base/event_filter.h"
#include "base/qt/qt_key_modifiers.h" #include "base/qt/qt_key_modifiers.h"
@ -98,12 +97,12 @@ void ScheduleBox(
descriptor.submit.data(), descriptor.submit.data(),
[=] { return SendMenu::Type::SilentOnly; }, [=] { return SendMenu::Type::SilentOnly; },
[=] { save(true, descriptor.collect()); }, [=] { save(true, descriptor.collect()); },
nullptr,
nullptr); nullptr);
if (type == SendMenu::Type::ScheduledToUser) { if (type == SendMenu::Type::ScheduledToUser) {
const auto sendUntilOnline = box->addTopButton(*style.topButtonStyle); const auto sendUntilOnline = box->addTopButton(*style.topButtonStyle);
const auto timestamp const auto timestamp = Api::kScheduledUntilOnlineTimestamp;
= Data::ScheduledMessages::kScheduledUntilOnlineTimestamp;
FillSendUntilOnlineMenu( FillSendUntilOnlineMenu(
sendUntilOnline.data(), sendUntilOnline.data(),
[=] { save(false, timestamp); }, [=] { save(false, timestamp); },

View File

@ -344,7 +344,8 @@ void Inner::contextMenuEvent(QContextMenuEvent *e) {
_menu, _menu,
type, type,
SendMenu::DefaultSilentCallback(send), SendMenu::DefaultSilentCallback(send),
SendMenu::DefaultScheduleCallback(this, type, send)); SendMenu::DefaultScheduleCallback(this, type, send),
SendMenu::DefaultWhenOnlineCallback(send));
const auto item = _mosaic.itemAt(_selected); const auto item = _mosaic.itemAt(_selected);
if (const auto previewDocument = item->getPreviewDocument()) { if (const auto previewDocument = item->getPreviewDocument()) {

View File

@ -47,11 +47,16 @@ Fn<void()> DefaultScheduleCallback(
}; };
} }
Fn<void()> DefaultWhenOnlineCallback(Fn<void(Api::SendOptions)> send) {
return [=] { send(Api::DefaultSendWhenOnlineOptions()); };
}
FillMenuResult FillSendMenu( FillMenuResult FillSendMenu(
not_null<Ui::PopupMenu*> menu, not_null<Ui::PopupMenu*> menu,
Type type, Type type,
Fn<void()> silent, Fn<void()> silent,
Fn<void()> schedule) { Fn<void()> schedule,
Fn<void()> whenOnline) {
if (!silent && !schedule) { if (!silent && !schedule) {
return FillMenuResult::None; return FillMenuResult::None;
} }
@ -75,6 +80,12 @@ FillMenuResult FillSendMenu(
schedule, schedule,
&st::menuIconSchedule); &st::menuIconSchedule);
} }
if (whenOnline && now == Type::ScheduledToUser) {
menu->addAction(
tr::lng_scheduled_send_until_online(tr::now),
whenOnline,
&st::menuIconWhenOnline);
}
return FillMenuResult::Success; return FillMenuResult::Success;
} }
@ -82,8 +93,9 @@ void SetupMenuAndShortcuts(
not_null<Ui::RpWidget*> button, not_null<Ui::RpWidget*> button,
Fn<Type()> type, Fn<Type()> type,
Fn<void()> silent, Fn<void()> silent,
Fn<void()> schedule) { Fn<void()> schedule,
if (!silent && !schedule) { Fn<void()> whenOnline) {
if (!silent && !schedule && !whenOnline) {
return; return;
} }
const auto menu = std::make_shared<base::unique_qptr<Ui::PopupMenu>>(); const auto menu = std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
@ -91,7 +103,7 @@ void SetupMenuAndShortcuts(
*menu = base::make_unique_q<Ui::PopupMenu>( *menu = base::make_unique_q<Ui::PopupMenu>(
button, button,
st::popupMenuWithIcons); st::popupMenuWithIcons);
const auto result = FillSendMenu(*menu, type(), silent, schedule); const auto result = FillSendMenu(*menu, type(), silent, schedule, whenOnline);
const auto success = (result == FillMenuResult::Success); const auto success = (result == FillMenuResult::Success);
if (success) { if (success) {
(*menu)->popup(QCursor::pos()); (*menu)->popup(QCursor::pos());

View File

@ -40,18 +40,21 @@ Fn<void()> DefaultScheduleCallback(
not_null<Ui::RpWidget*> parent, not_null<Ui::RpWidget*> parent,
Type type, Type type,
Fn<void(Api::SendOptions)> send); Fn<void(Api::SendOptions)> send);
Fn<void()> DefaultWhenOnlineCallback(Fn<void(Api::SendOptions)> send);
FillMenuResult FillSendMenu( FillMenuResult FillSendMenu(
not_null<Ui::PopupMenu*> menu, not_null<Ui::PopupMenu*> menu,
Type type, Type type,
Fn<void()> silent, Fn<void()> silent,
Fn<void()> schedule); Fn<void()> schedule,
Fn<void()> whenOnline);
void SetupMenuAndShortcuts( void SetupMenuAndShortcuts(
not_null<Ui::RpWidget*> button, not_null<Ui::RpWidget*> button,
Fn<Type()> type, Fn<Type()> type,
Fn<void()> silent, Fn<void()> silent,
Fn<void()> schedule); Fn<void()> schedule,
Fn<void()> whenOnline);
void SetupUnreadMentionsMenu( void SetupUnreadMentionsMenu(
not_null<Ui::RpWidget*> button, not_null<Ui::RpWidget*> button,

View File

@ -1885,7 +1885,8 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
state->menu.get(), state->menu.get(),
type, type,
SendMenu::DefaultSilentCallback(submit), SendMenu::DefaultSilentCallback(submit),
SendMenu::DefaultScheduleCallback(state->box, type, submit)); SendMenu::DefaultScheduleCallback(state->box, type, submit),
SendMenu::DefaultWhenOnlineCallback(submit));
const auto success = (result == SendMenu::FillMenuResult::Success); const auto success = (result == SendMenu::FillMenuResult::Success);
if (showForwardOptions || success) { if (showForwardOptions || success) {
state->menu->setForcedVerticalOrigin( state->menu->setForcedVerticalOrigin(