1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4 
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #include "history/view/history_view_schedule_box.h"
9 
10 #include "api/api_common.h"
11 #include "data/data_peer.h"
12 #include "data/data_user.h"
13 #include "data/data_scheduled_messages.h" // kScheduledUntilOnlineTimestamp
14 #include "lang/lang_keys.h"
15 #include "base/event_filter.h"
16 #include "base/unixtime.h"
17 #include "ui/widgets/input_fields.h"
18 #include "ui/widgets/labels.h"
19 #include "ui/widgets/buttons.h"
20 #include "ui/widgets/popup_menu.h"
21 #include "ui/wrap/padding_wrap.h"
22 #include "ui/boxes/choose_date_time.h"
23 #include "chat_helpers/send_context_menu.h"
24 #include "styles/style_info.h"
25 #include "styles/style_layers.h"
26 #include "styles/style_chat.h"
27 
28 #include <QGuiApplication>
29 
30 namespace HistoryView {
31 namespace {
32 
FillSendUntilOnlineMenu(not_null<Ui::IconButton * > button,Fn<void ()> callback)33 void FillSendUntilOnlineMenu(
34 		not_null<Ui::IconButton*> button,
35 		Fn<void()> callback) {
36 	const auto menu = std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
37 	button->setClickedCallback([=] {
38 		*menu = base::make_unique_q<Ui::PopupMenu>(button);
39 		(*menu)->addAction(
40 			tr::lng_scheduled_send_until_online(tr::now),
41 			std::move(callback));
42 		(*menu)->popup(QCursor::pos());
43 		return true;
44 	});
45 }
46 
47 } // namespace
48 
DefaultScheduleTime()49 TimeId DefaultScheduleTime() {
50 	return base::unixtime::now() + 600;
51 }
52 
CanScheduleUntilOnline(not_null<PeerData * > peer)53 bool CanScheduleUntilOnline(not_null<PeerData*> peer) {
54 	return !peer->isSelf()
55 		&& peer->isUser()
56 		&& !peer->asUser()->isBot()
57 		&& (peer->asUser()->onlineTill > 0);
58 }
59 
ScheduleBox(not_null<Ui::GenericBox * > box,SendMenu::Type type,Fn<void (Api::SendOptions)> done,TimeId time)60 void ScheduleBox(
61 		not_null<Ui::GenericBox*> box,
62 		SendMenu::Type type,
63 		Fn<void(Api::SendOptions)> done,
64 		TimeId time) {
65 	const auto save = [=](bool silent, TimeId scheduleDate) {
66 		if (!scheduleDate) {
67 			return;
68 		}
69 		// Pro tip: Hold Ctrl key to send a silent scheduled message!
70 		auto ctrl =
71 			(QGuiApplication::keyboardModifiers() == Qt::ControlModifier);
72 		auto result = Api::SendOptions();
73 		result.silent = silent || ctrl;
74 		result.scheduled = scheduleDate;
75 		const auto copy = done;
76 		box->closeBox();
77 		copy(result);
78 	};
79 	auto descriptor = Ui::ChooseDateTimeBox(box, {
80 		.title = (type == SendMenu::Type::Reminder
81 			? tr::lng_remind_title()
82 			: tr::lng_schedule_title()),
83 		.submit = tr::lng_schedule_button(),
84 		.done = [=](TimeId result) { save(false, result); },
85 		.time = time,
86 	});
87 
88 	SendMenu::SetupMenuAndShortcuts(
89 		descriptor.submit.data(),
90 		[=] { return SendMenu::Type::SilentOnly; },
91 		[=] { save(true, descriptor.collect()); },
92 		nullptr);
93 
94 	if (type == SendMenu::Type::ScheduledToUser) {
95 		const auto sendUntilOnline = box->addTopButton(st::infoTopBarMenu);
96 		const auto timestamp
97 			= Data::ScheduledMessages::kScheduledUntilOnlineTimestamp;
98 		FillSendUntilOnlineMenu(
99 			sendUntilOnline.data(),
100 			[=] { save(false, timestamp); });
101 	}
102 }
103 
104 } // namespace HistoryView
105