menu_ttl.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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 "menu/menu_ttl.h"
  8. #include "lang/lang_keys.h"
  9. #include "ui/boxes/confirm_box.h"
  10. #include "ui/boxes/time_picker_box.h"
  11. #include "ui/layers/generic_box.h"
  12. #include "ui/text/format_values.h"
  13. #include "ui/ui_utility.h"
  14. #include "ui/widgets/labels.h"
  15. #if 0
  16. #include "ui/boxes/choose_time.h"
  17. #include "ui/widgets/menu/menu_action.h"
  18. #include "ui/widgets/popup_menu.h"
  19. #include "styles/style_dialogs.h" // dialogsScamFont
  20. #include "styles/style_menu_icons.h"
  21. #endif
  22. #include "styles/style_layers.h"
  23. namespace TTLMenu {
  24. namespace {
  25. #if 0
  26. constexpr auto kTTLDurHours1 = crl::time(1);
  27. constexpr auto kTTLDurSeconds1 = kTTLDurHours1 * 3600;
  28. constexpr auto kTTLDurHours2 = crl::time(24);
  29. constexpr auto kTTLDurSeconds2 = kTTLDurHours2 * 3600;
  30. constexpr auto kTTLDurHours3 = crl::time(24 * 7);
  31. constexpr auto kTTLDurSeconds3 = kTTLDurHours3 * 3600;
  32. constexpr auto kTTLDurHours4 = crl::time(24 * 30);
  33. constexpr auto kTTLDurSeconds4 = kTTLDurHours4 * 3600;
  34. // See menu_mute.cpp.
  35. class IconWithText final : public Ui::Menu::Action {
  36. public:
  37. using Ui::Menu::Action::Action;
  38. void setData(const QString &text, const QPoint &iconPosition);
  39. protected:
  40. void paintEvent(QPaintEvent *e) override;
  41. private:
  42. QPoint _iconPosition;
  43. QString _text;
  44. };
  45. void IconWithText::setData(const QString &text, const QPoint &iconPosition) {
  46. _iconPosition = iconPosition;
  47. _text = text;
  48. }
  49. void IconWithText::paintEvent(QPaintEvent *e) {
  50. Ui::Menu::Action::paintEvent(e);
  51. Painter p(this);
  52. p.setFont(st::dialogsScamFont);
  53. p.setPen(st::menuIconColor);
  54. p.drawText(_iconPosition, _text);
  55. }
  56. class TextItem final : public Ui::Menu::ItemBase {
  57. public:
  58. TextItem(
  59. not_null<RpWidget*> parent,
  60. const style::Menu &st,
  61. rpl::producer<QString> &&text);
  62. not_null<QAction*> action() const override;
  63. bool isEnabled() const override;
  64. protected:
  65. int contentHeight() const override;
  66. private:
  67. const base::unique_qptr<Ui::FlatLabel> _label;
  68. const not_null<QAction*> _dummyAction;
  69. };
  70. TextItem::TextItem(
  71. not_null<RpWidget*> parent,
  72. const style::Menu &st,
  73. rpl::producer<QString> &&text)
  74. : ItemBase(parent, st)
  75. , _label(base::make_unique_q<Ui::FlatLabel>(
  76. this,
  77. std::move(text),
  78. st::historyMessagesTTLLabel))
  79. , _dummyAction(Ui::CreateChild<QAction>(parent.get())) {
  80. setAttribute(Qt::WA_TransparentForMouseEvents);
  81. setMinWidth(st::historyMessagesTTLLabel.minWidth
  82. + st.itemIconPosition.x());
  83. sizeValue(
  84. ) | rpl::start_with_next([=](const QSize &s) {
  85. _label->moveToLeft(
  86. st.itemIconPosition.x(),
  87. (s.height() - _label->height()) / 2);
  88. }, lifetime());
  89. initResizeHook(parent->sizeValue());
  90. }
  91. not_null<QAction*> TextItem::action() const {
  92. return _dummyAction;
  93. }
  94. bool TextItem::isEnabled() const {
  95. return false;
  96. }
  97. int TextItem::contentHeight() const {
  98. return _label->height();
  99. }
  100. void TTLBoxOld(
  101. not_null<Ui::GenericBox*> box,
  102. Fn<void(TimeId)> callback,
  103. TimeId startTtlPeriod) {
  104. struct State {
  105. int lastSeconds = 0;
  106. };
  107. const auto startTtl = startTtlPeriod ? startTtlPeriod : kTTLDurSeconds2;
  108. auto chooseTimeResult = ChooseTimeWidget(box, startTtl);
  109. box->addRow(std::move(chooseTimeResult.widget));
  110. const auto state = box->lifetime().make_state<State>();
  111. box->setTitle(tr::lng_manage_messages_ttl_title());
  112. auto confirmText = std::move(
  113. chooseTimeResult.secondsValue
  114. ) | rpl::map([=](int seconds) {
  115. state->lastSeconds = seconds;
  116. return !seconds
  117. ? tr::lng_manage_messages_ttl_disable()
  118. : tr::lng_enable_auto_delete();
  119. }) | rpl::flatten_latest();
  120. const auto confirm = box->addButton(std::move(confirmText), [=] {
  121. callback(state->lastSeconds);
  122. box->closeBox();
  123. });
  124. box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
  125. }
  126. #endif
  127. } // namespace
  128. void TTLBox(not_null<Ui::GenericBox*> box, Args args) {
  129. if (args.about) {
  130. box->addRow(object_ptr<Ui::FlatLabel>(
  131. box,
  132. std::move(args.about),
  133. st::boxLabel));
  134. }
  135. const auto ttls = std::vector<TimeId>{
  136. (86400 * 1),
  137. (86400 * 2),
  138. (86400 * 3),
  139. (86400 * 4),
  140. (86400 * 5),
  141. (86400 * 6),
  142. (86400 * 7 * 1),
  143. (86400 * 7 * 2),
  144. (86400 * 7 * 3),
  145. (86400 * 31 * 1),
  146. (86400 * 31 * 2),
  147. (86400 * 31 * 3),
  148. (86400 * 31 * 4),
  149. (86400 * 31 * 5),
  150. (86400 * 31 * 6),
  151. (86400 * 365),
  152. };
  153. const auto phrases = ranges::views::all(
  154. ttls
  155. ) | ranges::views::transform(Ui::FormatTTL) | ranges::to_vector;
  156. const auto pickerTtl = TimePickerBox(box, ttls, phrases, args.startTtl);
  157. Ui::ConfirmBox(box, {
  158. .confirmed = [=](Fn<void()> close) {
  159. args.callback(pickerTtl(), std::move(close));
  160. },
  161. .confirmText = tr::lng_settings_save(),
  162. .cancelText = tr::lng_cancel(),
  163. });
  164. box->setTitle(tr::lng_manage_messages_ttl_title());
  165. if (args.startTtl && !args.hideDisable) {
  166. box->addLeftButton(tr::lng_manage_messages_ttl_disable(), [=] {
  167. args.callback(0, [=] { box->closeBox(); });
  168. });
  169. }
  170. }
  171. #if 0
  172. void FillTTLMenu(not_null<Ui::PopupMenu*> menu, Args args) {
  173. const auto &st = menu->st().menu;
  174. const auto iconTextPosition = st.itemIconPosition
  175. + st::menuIconTTLAnyTextPosition;
  176. const auto addAction = [&](const QString &text, TimeId ttl) {
  177. auto item = base::make_unique_q<IconWithText>(
  178. menu,
  179. st,
  180. Ui::Menu::CreateAction(
  181. menu->menu().get(),
  182. text,
  183. [=] { args.callback(ttl); }),
  184. &st::menuIconTTLAny,
  185. &st::menuIconTTLAny);
  186. item->setData(Ui::FormatTTLTiny(ttl), iconTextPosition);
  187. menu->addAction(std::move(item));
  188. };
  189. addAction(tr::lng_manage_messages_ttl_after1(tr::now), kTTLDurSeconds1);
  190. addAction(tr::lng_manage_messages_ttl_after2(tr::now), kTTLDurSeconds2);
  191. addAction(tr::lng_manage_messages_ttl_after3(tr::now), kTTLDurSeconds3);
  192. addAction(tr::lng_manage_messages_ttl_after4(tr::now), kTTLDurSeconds4);
  193. menu->addAction(
  194. tr::lng_manage_messages_ttl_after_custom(tr::now),
  195. [a = args] { a.show->showBox(Box(TTLBox, a)); },
  196. &st::menuIconCustomize);
  197. if (args.startTtl) {
  198. menu->addAction({
  199. .text = tr::lng_manage_messages_ttl_disable(tr::now),
  200. .handler = [=] { args.callback(0); },
  201. .icon = &st::menuIconDisableAttention,
  202. .isAttention = true,
  203. });
  204. }
  205. menu->addSeparator();
  206. menu->addAction(base::make_unique_q<TextItem>(
  207. menu,
  208. menu->st().menu,
  209. std::move(args.about)));
  210. }
  211. void SetupTTLMenu(
  212. not_null<Ui::RpWidget*> parent,
  213. rpl::producer<> triggers,
  214. Args args) {
  215. struct State {
  216. base::unique_qptr<Ui::PopupMenu> menu;
  217. };
  218. const auto state = parent->lifetime().make_state<State>();
  219. std::move(
  220. triggers
  221. ) | rpl::start_with_next([=] {
  222. if (state->menu) {
  223. return;
  224. }
  225. state->menu = base::make_unique_q<Ui::PopupMenu>(
  226. parent,
  227. st::popupMenuExpandedSeparator);
  228. FillTTLMenu(state->menu.get(), args);
  229. state->menu->popup(QCursor::pos());
  230. }, parent->lifetime());
  231. }
  232. #endif
  233. } // namespace TTLMenu