data_peer_notify_settings.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "data/notify/data_peer_notify_settings.h"
  8. #include "base/unixtime.h"
  9. namespace Data {
  10. namespace {
  11. [[nodiscard]] MTPinputPeerNotifySettings DefaultSettings() {
  12. return MTP_inputPeerNotifySettings(
  13. MTP_flags(0),
  14. MTPBool(),
  15. MTPBool(),
  16. MTPint(),
  17. MTPNotificationSound(),
  18. MTPBool(),
  19. MTPBool(),
  20. MTPNotificationSound());
  21. }
  22. [[nodiscard]] NotifySound ParseSound(const MTPNotificationSound &sound) {
  23. return sound.match([&](const MTPDnotificationSoundDefault &data) {
  24. return NotifySound();
  25. }, [&](const MTPDnotificationSoundNone &data) {
  26. return NotifySound{ .none = true };
  27. }, [&](const MTPDnotificationSoundLocal &data) {
  28. return NotifySound{
  29. .title = qs(data.vtitle()),
  30. .data = qs(data.vdata()),
  31. };
  32. }, [&](const MTPDnotificationSoundRingtone &data) {
  33. return NotifySound{ .id = data.vid().v };
  34. });
  35. }
  36. [[nodiscard]] MTPNotificationSound SerializeSound(
  37. const std::optional<NotifySound> &sound) {
  38. return !sound
  39. ? MTPNotificationSound()
  40. : sound->none
  41. ? MTP_notificationSoundNone()
  42. : sound->id
  43. ? MTP_notificationSoundRingtone(MTP_long(sound->id))
  44. : !sound->title.isEmpty()
  45. ? MTP_notificationSoundLocal(
  46. MTP_string(sound->title),
  47. MTP_string(sound->data))
  48. : MTP_notificationSoundDefault();
  49. }
  50. } // namespace
  51. int MuteValue::until() const {
  52. constexpr auto kMax = std::numeric_limits<int>::max();
  53. return forever
  54. ? kMax
  55. : (period > 0)
  56. ? int(std::min(int64(base::unixtime::now()) + period, int64(kMax)))
  57. : unmute
  58. ? 0
  59. : -1;
  60. }
  61. class NotifyPeerSettingsValue {
  62. public:
  63. NotifyPeerSettingsValue(const MTPDpeerNotifySettings &data);
  64. bool change(const MTPDpeerNotifySettings &data);
  65. bool change(
  66. MuteValue muteForSeconds,
  67. std::optional<bool> silentPosts,
  68. std::optional<NotifySound> sound,
  69. std::optional<bool> storiesMuted);
  70. std::optional<TimeId> muteUntil() const;
  71. std::optional<bool> silentPosts() const;
  72. std::optional<NotifySound> sound() const;
  73. MTPinputPeerNotifySettings serialize() const;
  74. private:
  75. bool change(
  76. std::optional<int> mute,
  77. std::optional<NotifySound> sound,
  78. std::optional<bool> showPreviews,
  79. std::optional<bool> silentPosts,
  80. std::optional<bool> storiesMuted);
  81. std::optional<TimeId> _mute;
  82. std::optional<NotifySound> _sound;
  83. std::optional<bool> _silent;
  84. std::optional<bool> _showPreviews;
  85. std::optional<bool> _storiesMuted;
  86. };
  87. NotifyPeerSettingsValue::NotifyPeerSettingsValue(
  88. const MTPDpeerNotifySettings &data) {
  89. change(data);
  90. }
  91. bool NotifyPeerSettingsValue::change(const MTPDpeerNotifySettings &data) {
  92. const auto mute = data.vmute_until();
  93. const auto sound = data.vother_sound();
  94. const auto showPreviews = data.vshow_previews();
  95. const auto silent = data.vsilent();
  96. const auto storiesMuted = data.vstories_muted();
  97. return change(
  98. mute ? std::make_optional(mute->v) : std::nullopt,
  99. sound ? std::make_optional(ParseSound(*sound)) : std::nullopt,
  100. (showPreviews
  101. ? std::make_optional(mtpIsTrue(*showPreviews))
  102. : std::nullopt),
  103. silent ? std::make_optional(mtpIsTrue(*silent)) : std::nullopt,
  104. (storiesMuted
  105. ? std::make_optional(mtpIsTrue(*storiesMuted))
  106. : std::nullopt));
  107. }
  108. bool NotifyPeerSettingsValue::change(
  109. MuteValue muteForSeconds,
  110. std::optional<bool> silentPosts,
  111. std::optional<NotifySound> sound,
  112. std::optional<bool> storiesMuted) {
  113. const auto newMute = muteForSeconds
  114. ? base::make_optional(muteForSeconds.until())
  115. : _mute;
  116. const auto newSilentPosts = silentPosts
  117. ? base::make_optional(*silentPosts)
  118. : _silent;
  119. const auto newSound = sound
  120. ? base::make_optional(*sound)
  121. : _sound;
  122. const auto newStoriesMuted = storiesMuted
  123. ? base::make_optional(*storiesMuted)
  124. : _storiesMuted;
  125. return change(
  126. newMute,
  127. newSound,
  128. _showPreviews,
  129. newSilentPosts,
  130. newStoriesMuted);
  131. }
  132. bool NotifyPeerSettingsValue::change(
  133. std::optional<int> mute,
  134. std::optional<NotifySound> sound,
  135. std::optional<bool> showPreviews,
  136. std::optional<bool> silentPosts,
  137. std::optional<bool> storiesMuted) {
  138. if (_mute == mute
  139. && _sound == sound
  140. && _showPreviews == showPreviews
  141. && _silent == silentPosts
  142. && _storiesMuted == storiesMuted) {
  143. return false;
  144. }
  145. _mute = mute;
  146. _sound = sound;
  147. _showPreviews = showPreviews;
  148. _silent = silentPosts;
  149. _storiesMuted = storiesMuted;
  150. return true;
  151. }
  152. std::optional<TimeId> NotifyPeerSettingsValue::muteUntil() const {
  153. return _mute;
  154. }
  155. std::optional<bool> NotifyPeerSettingsValue::silentPosts() const {
  156. return _silent;
  157. }
  158. std::optional<NotifySound> NotifyPeerSettingsValue::sound() const {
  159. return _sound;
  160. }
  161. MTPinputPeerNotifySettings NotifyPeerSettingsValue::serialize() const {
  162. using Flag = MTPDinputPeerNotifySettings::Flag;
  163. const auto flag = [](auto &&optional, Flag flag) {
  164. return optional.has_value() ? flag : Flag(0);
  165. };
  166. return MTP_inputPeerNotifySettings(
  167. MTP_flags(flag(_mute, Flag::f_mute_until)
  168. | flag(_sound, Flag::f_sound)
  169. | flag(_silent, Flag::f_silent)
  170. | flag(_showPreviews, Flag::f_show_previews)
  171. | flag(_storiesMuted, Flag::f_stories_muted)),
  172. MTP_bool(_showPreviews.value_or(true)),
  173. MTP_bool(_silent.value_or(false)),
  174. MTP_int(_mute.value_or(false)),
  175. SerializeSound(_sound),
  176. MTP_bool(_storiesMuted.value_or(false)),
  177. MTP_bool(false), // stories_hide_sender
  178. SerializeSound(std::nullopt)); // stories_sound
  179. }
  180. PeerNotifySettings::PeerNotifySettings() = default;
  181. bool PeerNotifySettings::change(const MTPPeerNotifySettings &settings) {
  182. auto &data = settings.data();
  183. const auto empty = !data.vflags().v;
  184. if (empty) {
  185. if (!_known || _value) {
  186. _known = true;
  187. _value = nullptr;
  188. return true;
  189. }
  190. return false;
  191. }
  192. if (_value) {
  193. return _value->change(data);
  194. }
  195. _known = true;
  196. _value = std::make_unique<NotifyPeerSettingsValue>(data);
  197. return true;
  198. }
  199. bool PeerNotifySettings::change(
  200. MuteValue muteForSeconds,
  201. std::optional<bool> silentPosts,
  202. std::optional<NotifySound> sound,
  203. std::optional<bool> storiesMuted) {
  204. if (!muteForSeconds && !silentPosts && !sound && !storiesMuted) {
  205. return false;
  206. } else if (_value) {
  207. return _value->change(
  208. muteForSeconds,
  209. silentPosts,
  210. sound,
  211. storiesMuted);
  212. }
  213. using Flag = MTPDpeerNotifySettings::Flag;
  214. const auto flags = (muteForSeconds ? Flag::f_mute_until : Flag(0))
  215. | (silentPosts ? Flag::f_silent : Flag(0))
  216. | (sound ? Flag::f_other_sound : Flag(0))
  217. | (storiesMuted ? Flag::f_stories_muted : Flag(0));
  218. return change(MTP_peerNotifySettings(
  219. MTP_flags(flags),
  220. MTPBool(),
  221. silentPosts ? MTP_bool(*silentPosts) : MTPBool(),
  222. MTP_int(muteForSeconds.until()),
  223. MTPNotificationSound(),
  224. MTPNotificationSound(),
  225. SerializeSound(sound),
  226. storiesMuted ? MTP_bool(*storiesMuted) : MTPBool(),
  227. MTPBool(), // stories_hide_sender
  228. MTPNotificationSound(),
  229. MTPNotificationSound(),
  230. SerializeSound(std::nullopt))); // stories_sound
  231. }
  232. bool PeerNotifySettings::resetToDefault() {
  233. if (_known && !_value) {
  234. return false;
  235. }
  236. _known = true;
  237. _value = nullptr;
  238. return true;
  239. }
  240. std::optional<TimeId> PeerNotifySettings::muteUntil() const {
  241. return _value
  242. ? _value->muteUntil()
  243. : std::nullopt;
  244. }
  245. bool PeerNotifySettings::settingsUnknown() const {
  246. return !_known;
  247. }
  248. std::optional<bool> PeerNotifySettings::silentPosts() const {
  249. return _value
  250. ? _value->silentPosts()
  251. : std::nullopt;
  252. }
  253. std::optional<NotifySound> PeerNotifySettings::sound() const {
  254. return _value
  255. ? _value->sound()
  256. : std::nullopt;
  257. }
  258. MTPinputPeerNotifySettings PeerNotifySettings::serialize() const {
  259. return _value
  260. ? _value->serialize()
  261. : DefaultSettings();
  262. }
  263. PeerNotifySettings::~PeerNotifySettings() = default;
  264. } // namespace Data