1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #include "td/telegram/NotificationSettings.h"
8
9 #include "td/telegram/Global.h"
10 #include "td/telegram/misc.h"
11
12 #include "td/utils/common.h"
13
14 #include <limits>
15
16 namespace td {
17
operator <<(StringBuilder & string_builder,const DialogNotificationSettings & notification_settings)18 StringBuilder &operator<<(StringBuilder &string_builder, const DialogNotificationSettings ¬ification_settings) {
19 return string_builder << "[" << notification_settings.mute_until << ", " << notification_settings.sound << ", "
20 << notification_settings.show_preview << ", " << notification_settings.silent_send_message
21 << ", " << notification_settings.disable_pinned_message_notifications << ", "
22 << notification_settings.disable_mention_notifications << ", "
23 << notification_settings.use_default_mute_until << ", "
24 << notification_settings.use_default_sound << ", "
25 << notification_settings.use_default_show_preview << ", "
26 << notification_settings.use_default_disable_pinned_message_notifications << ", "
27 << notification_settings.use_default_disable_mention_notifications << ", "
28 << notification_settings.is_synchronized << "]";
29 }
30
operator <<(StringBuilder & string_builder,NotificationSettingsScope scope)31 StringBuilder &operator<<(StringBuilder &string_builder, NotificationSettingsScope scope) {
32 switch (scope) {
33 case NotificationSettingsScope::Private:
34 return string_builder << "notification settings for private chats";
35 case NotificationSettingsScope::Group:
36 return string_builder << "notification settings for group chats";
37 case NotificationSettingsScope::Channel:
38 return string_builder << "notification settings for channel chats";
39 default:
40 UNREACHABLE();
41 return string_builder;
42 }
43 }
44
operator <<(StringBuilder & string_builder,const ScopeNotificationSettings & notification_settings)45 StringBuilder &operator<<(StringBuilder &string_builder, const ScopeNotificationSettings ¬ification_settings) {
46 return string_builder << "[" << notification_settings.mute_until << ", " << notification_settings.sound << ", "
47 << notification_settings.show_preview << ", " << notification_settings.is_synchronized << ", "
48 << notification_settings.disable_pinned_message_notifications << ", "
49 << notification_settings.disable_mention_notifications << "]";
50 }
51
get_notification_settings_scope_object(NotificationSettingsScope scope)52 td_api::object_ptr<td_api::NotificationSettingsScope> get_notification_settings_scope_object(
53 NotificationSettingsScope scope) {
54 switch (scope) {
55 case NotificationSettingsScope::Private:
56 return td_api::make_object<td_api::notificationSettingsScopePrivateChats>();
57 case NotificationSettingsScope::Group:
58 return td_api::make_object<td_api::notificationSettingsScopeGroupChats>();
59 case NotificationSettingsScope::Channel:
60 return td_api::make_object<td_api::notificationSettingsScopeChannelChats>();
61 default:
62 UNREACHABLE();
63 return nullptr;
64 }
65 }
66
get_chat_notification_settings_object(const DialogNotificationSettings * notification_settings)67 td_api::object_ptr<td_api::chatNotificationSettings> get_chat_notification_settings_object(
68 const DialogNotificationSettings *notification_settings) {
69 CHECK(notification_settings != nullptr);
70 return td_api::make_object<td_api::chatNotificationSettings>(
71 notification_settings->use_default_mute_until, max(0, notification_settings->mute_until - G()->unix_time()),
72 notification_settings->use_default_sound, notification_settings->sound,
73 notification_settings->use_default_show_preview, notification_settings->show_preview,
74 notification_settings->use_default_disable_pinned_message_notifications,
75 notification_settings->disable_pinned_message_notifications,
76 notification_settings->use_default_disable_mention_notifications,
77 notification_settings->disable_mention_notifications);
78 }
79
get_scope_notification_settings_object(const ScopeNotificationSettings * notification_settings)80 td_api::object_ptr<td_api::scopeNotificationSettings> get_scope_notification_settings_object(
81 const ScopeNotificationSettings *notification_settings) {
82 CHECK(notification_settings != nullptr);
83 return td_api::make_object<td_api::scopeNotificationSettings>(
84 max(0, notification_settings->mute_until - G()->unix_time()), notification_settings->sound,
85 notification_settings->show_preview, notification_settings->disable_pinned_message_notifications,
86 notification_settings->disable_mention_notifications);
87 }
88
get_input_notify_peer(NotificationSettingsScope scope)89 telegram_api::object_ptr<telegram_api::InputNotifyPeer> get_input_notify_peer(NotificationSettingsScope scope) {
90 switch (scope) {
91 case NotificationSettingsScope::Private:
92 return telegram_api::make_object<telegram_api::inputNotifyUsers>();
93 case NotificationSettingsScope::Group:
94 return telegram_api::make_object<telegram_api::inputNotifyChats>();
95 case NotificationSettingsScope::Channel:
96 return telegram_api::make_object<telegram_api::inputNotifyBroadcasts>();
97 default:
98 return nullptr;
99 }
100 }
101
get_notification_settings_scope(const td_api::object_ptr<td_api::NotificationSettingsScope> & scope)102 NotificationSettingsScope get_notification_settings_scope(
103 const td_api::object_ptr<td_api::NotificationSettingsScope> &scope) {
104 CHECK(scope != nullptr);
105 switch (scope->get_id()) {
106 case td_api::notificationSettingsScopePrivateChats::ID:
107 return NotificationSettingsScope::Private;
108 case td_api::notificationSettingsScopeGroupChats::ID:
109 return NotificationSettingsScope::Group;
110 case td_api::notificationSettingsScopeChannelChats::ID:
111 return NotificationSettingsScope::Channel;
112 default:
113 UNREACHABLE();
114 return NotificationSettingsScope::Private;
115 }
116 }
117
get_mute_until(int32 mute_for)118 static int32 get_mute_until(int32 mute_for) {
119 if (mute_for <= 0) {
120 return 0;
121 }
122
123 const int32 MAX_PRECISE_MUTE_FOR = 7 * 86400;
124 int32 current_time = G()->unix_time();
125 if (mute_for > MAX_PRECISE_MUTE_FOR || mute_for >= std::numeric_limits<int32>::max() - current_time) {
126 return std::numeric_limits<int32>::max();
127 }
128 return mute_for + current_time;
129 }
130
get_dialog_notification_settings(td_api::object_ptr<td_api::chatNotificationSettings> && notification_settings,bool old_silent_send_message)131 Result<DialogNotificationSettings> get_dialog_notification_settings(
132 td_api::object_ptr<td_api::chatNotificationSettings> &¬ification_settings, bool old_silent_send_message) {
133 if (notification_settings == nullptr) {
134 return Status::Error(400, "New notification settings must be non-empty");
135 }
136 if (!clean_input_string(notification_settings->sound_)) {
137 return Status::Error(400, "Notification settings sound must be encoded in UTF-8");
138 }
139 if (notification_settings->sound_.empty()) {
140 notification_settings->sound_ = "default";
141 }
142
143 int32 mute_until =
144 notification_settings->use_default_mute_for_ ? 0 : get_mute_until(notification_settings->mute_for_);
145 return DialogNotificationSettings(notification_settings->use_default_mute_for_, mute_until,
146 notification_settings->use_default_sound_, std::move(notification_settings->sound_),
147 notification_settings->use_default_show_preview_,
148 notification_settings->show_preview_, old_silent_send_message,
149 notification_settings->use_default_disable_pinned_message_notifications_,
150 notification_settings->disable_pinned_message_notifications_,
151 notification_settings->use_default_disable_mention_notifications_,
152 notification_settings->disable_mention_notifications_);
153 }
154
get_scope_notification_settings(td_api::object_ptr<td_api::scopeNotificationSettings> && notification_settings)155 Result<ScopeNotificationSettings> get_scope_notification_settings(
156 td_api::object_ptr<td_api::scopeNotificationSettings> &¬ification_settings) {
157 if (notification_settings == nullptr) {
158 return Status::Error(400, "New notification settings must be non-empty");
159 }
160 if (!clean_input_string(notification_settings->sound_)) {
161 return Status::Error(400, "Notification settings sound must be encoded in UTF-8");
162 }
163 if (notification_settings->sound_.empty()) {
164 notification_settings->sound_ = "default";
165 }
166
167 auto mute_until = get_mute_until(notification_settings->mute_for_);
168 return ScopeNotificationSettings(mute_until, std::move(notification_settings->sound_),
169 notification_settings->show_preview_,
170 notification_settings->disable_pinned_message_notifications_,
171 notification_settings->disable_mention_notifications_);
172 }
173
get_dialog_notification_settings(tl_object_ptr<telegram_api::peerNotifySettings> && settings,bool old_use_default_disable_pinned_message_notifications,bool old_disable_pinned_message_notifications,bool old_use_default_disable_mention_notifications,bool old_disable_mention_notifications)174 DialogNotificationSettings get_dialog_notification_settings(tl_object_ptr<telegram_api::peerNotifySettings> &&settings,
175 bool old_use_default_disable_pinned_message_notifications,
176 bool old_disable_pinned_message_notifications,
177 bool old_use_default_disable_mention_notifications,
178 bool old_disable_mention_notifications) {
179 bool use_default_mute_until = (settings->flags_ & telegram_api::peerNotifySettings::MUTE_UNTIL_MASK) == 0;
180 bool use_default_sound = (settings->flags_ & telegram_api::peerNotifySettings::SOUND_MASK) == 0;
181 bool use_default_show_preview = (settings->flags_ & telegram_api::peerNotifySettings::SHOW_PREVIEWS_MASK) == 0;
182 auto mute_until = use_default_mute_until || settings->mute_until_ <= G()->unix_time() ? 0 : settings->mute_until_;
183 auto sound = std::move(settings->sound_);
184 if (sound.empty()) {
185 sound = "default";
186 }
187 bool silent_send_message =
188 (settings->flags_ & telegram_api::peerNotifySettings::SILENT_MASK) == 0 ? false : settings->silent_;
189 return {use_default_mute_until,
190 mute_until,
191 use_default_sound,
192 std::move(sound),
193 use_default_show_preview,
194 settings->show_previews_,
195 silent_send_message,
196 old_use_default_disable_pinned_message_notifications,
197 old_disable_pinned_message_notifications,
198 old_use_default_disable_mention_notifications,
199 old_disable_mention_notifications};
200 }
201
get_scope_notification_settings(tl_object_ptr<telegram_api::peerNotifySettings> && settings,bool old_disable_pinned_message_notifications,bool old_disable_mention_notifications)202 ScopeNotificationSettings get_scope_notification_settings(tl_object_ptr<telegram_api::peerNotifySettings> &&settings,
203 bool old_disable_pinned_message_notifications,
204 bool old_disable_mention_notifications) {
205 auto mute_until = (settings->flags_ & telegram_api::peerNotifySettings::MUTE_UNTIL_MASK) == 0 ||
206 settings->mute_until_ <= G()->unix_time()
207 ? 0
208 : settings->mute_until_;
209 auto sound = std::move(settings->sound_);
210 if (sound.empty()) {
211 sound = "default";
212 }
213 auto show_preview =
214 (settings->flags_ & telegram_api::peerNotifySettings::SHOW_PREVIEWS_MASK) == 0 ? false : settings->show_previews_;
215 return {mute_until, std::move(sound), show_preview, old_disable_pinned_message_notifications,
216 old_disable_mention_notifications};
217 }
218
are_default_dialog_notification_settings(const DialogNotificationSettings & settings,bool compare_sound)219 bool are_default_dialog_notification_settings(const DialogNotificationSettings &settings, bool compare_sound) {
220 return settings.use_default_mute_until && (!compare_sound || settings.use_default_sound) &&
221 settings.use_default_show_preview && settings.use_default_disable_pinned_message_notifications &&
222 settings.use_default_disable_mention_notifications;
223 }
224
225 } // namespace td
226