dialogs_quick_action.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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 "dialogs/dialogs_quick_action.h"
  8. #include "dialogs/ui/dialogs_quick_action_context.h"
  9. #include "apiwrap.h"
  10. #include "data/data_histories.h"
  11. #include "data/data_peer.h"
  12. #include "data/data_session.h"
  13. #include "dialogs/dialogs_entry.h"
  14. #include "history/history.h"
  15. #include "lang/lang_instance.h"
  16. #include "lang/lang_keys.h"
  17. #include "lottie/lottie_icon.h"
  18. #include "main/main_session.h"
  19. #include "menu/menu_mute.h"
  20. #include "window/window_peer_menu.h"
  21. #include "window/window_session_controller.h"
  22. #include "styles/style_dialogs.h"
  23. namespace Dialogs {
  24. namespace {
  25. const style::font &SwipeActionFont(
  26. Dialogs::Ui::QuickDialogActionLabel action,
  27. int availableWidth) {
  28. struct Entry final {
  29. Dialogs::Ui::QuickDialogActionLabel action;
  30. QString langId;
  31. style::font font;
  32. };
  33. static auto Fonts = std::vector<Entry>();
  34. for (auto &entry : Fonts) {
  35. if (entry.action == action) {
  36. if (entry.langId == Lang::GetInstance().id()) {
  37. return entry.font;
  38. }
  39. }
  40. }
  41. constexpr auto kNormalFontSize = 13;
  42. constexpr auto kMinFontSize = 5;
  43. for (auto i = kNormalFontSize; i >= kMinFontSize; --i) {
  44. auto font = style::font(
  45. style::ConvertScale(i, style::Scale()),
  46. st::semiboldFont->flags(),
  47. st::semiboldFont->family());
  48. if (font->width(ResolveQuickDialogLabel(action)) <= availableWidth
  49. || i == kMinFontSize) {
  50. Fonts.emplace_back(Entry{
  51. .action = action,
  52. .langId = Lang::GetInstance().id(),
  53. .font = std::move(font),
  54. });
  55. return Fonts.back().font;
  56. }
  57. }
  58. Unexpected("SwipeActionFont: can't find font.");
  59. }
  60. } // namespace
  61. void PerformQuickDialogAction(
  62. not_null<Window::SessionController*> controller,
  63. not_null<PeerData*> peer,
  64. Ui::QuickDialogAction action,
  65. FilterId filterId) {
  66. const auto history = peer->owner().history(peer);
  67. if (action == Dialogs::Ui::QuickDialogAction::Mute) {
  68. const auto isMuted = rpl::variable<bool>(
  69. MuteMenu::ThreadDescriptor(history).isMutedValue()).current();
  70. MuteMenu::ThreadDescriptor(history).updateMutePeriod(isMuted
  71. ? 0
  72. : std::numeric_limits<TimeId>::max());
  73. } else if (action == Dialogs::Ui::QuickDialogAction::Pin) {
  74. const auto entry = (Dialogs::Entry*)(history);
  75. Window::TogglePinnedThread(controller, entry, filterId);
  76. } else if (action == Dialogs::Ui::QuickDialogAction::Read) {
  77. if (Window::IsUnreadThread(history)) {
  78. Window::MarkAsReadThread(history);
  79. } else if (history) {
  80. peer->owner().histories().changeDialogUnreadMark(history, true);
  81. }
  82. } else if (action == Dialogs::Ui::QuickDialogAction::Archive) {
  83. history->session().api().toggleHistoryArchived(
  84. history,
  85. !Window::IsArchived(history),
  86. [] {});
  87. } else if (action == Dialogs::Ui::QuickDialogAction::Delete) {
  88. Window::DeleteAndLeaveHandler(controller, peer)();
  89. }
  90. }
  91. QString ResolveQuickDialogLottieIconName(
  92. not_null<PeerData*> peer,
  93. Ui::QuickDialogAction action,
  94. FilterId filterId) {
  95. if (action == Dialogs::Ui::QuickDialogAction::Mute) {
  96. const auto history = peer->owner().history(peer);
  97. const auto isMuted = rpl::variable<bool>(
  98. MuteMenu::ThreadDescriptor(history).isMutedValue()).current();
  99. return isMuted ? u"swipe_unmute"_q : u"swipe_mute"_q;
  100. } else if (action == Dialogs::Ui::QuickDialogAction::Pin) {
  101. const auto history = peer->owner().history(peer);
  102. const auto entry = (Dialogs::Entry*)(history);
  103. return entry->isPinnedDialog(filterId)
  104. ? u"swipe_unpin"_q
  105. : u"swipe_pin"_q;
  106. } else if (action == Dialogs::Ui::QuickDialogAction::Read) {
  107. const auto history = peer->owner().history(peer);
  108. return Window::IsUnreadThread(history)
  109. ? u"swipe_read"_q
  110. : u"swipe_unread"_q;
  111. } else if (action == Dialogs::Ui::QuickDialogAction::Archive) {
  112. const auto history = peer->owner().history(peer);
  113. return Window::IsArchived(history)
  114. ? u"swipe_unarchive"_q
  115. : u"swipe_archive"_q;
  116. } else if (action == Dialogs::Ui::QuickDialogAction::Delete) {
  117. return u"swipe_delete"_q;
  118. }
  119. return u"swipe_disabled"_q;
  120. }
  121. Ui::QuickDialogActionLabel ResolveQuickDialogLabel(
  122. not_null<History*> history,
  123. Ui::QuickDialogAction action,
  124. FilterId filterId) {
  125. if (action == Dialogs::Ui::QuickDialogAction::Mute) {
  126. const auto isMuted = rpl::variable<bool>(
  127. MuteMenu::ThreadDescriptor(history).isMutedValue()).current();
  128. return isMuted
  129. ? Ui::QuickDialogActionLabel::Unmute
  130. : Ui::QuickDialogActionLabel::Mute;
  131. } else if (action == Dialogs::Ui::QuickDialogAction::Pin) {
  132. const auto entry = (Dialogs::Entry*)(history);
  133. return entry->isPinnedDialog(filterId)
  134. ? Ui::QuickDialogActionLabel::Unpin
  135. : Ui::QuickDialogActionLabel::Pin;
  136. } else if (action == Dialogs::Ui::QuickDialogAction::Read) {
  137. return Window::IsUnreadThread(history)
  138. ? Ui::QuickDialogActionLabel::Read
  139. : Ui::QuickDialogActionLabel::Unread;
  140. } else if (action == Dialogs::Ui::QuickDialogAction::Archive) {
  141. return Window::IsArchived(history)
  142. ? Ui::QuickDialogActionLabel::Unarchive
  143. : Ui::QuickDialogActionLabel::Archive;
  144. } else if (action == Dialogs::Ui::QuickDialogAction::Delete) {
  145. return Ui::QuickDialogActionLabel::Delete;
  146. }
  147. return Ui::QuickDialogActionLabel::Disabled;
  148. }
  149. QString ResolveQuickDialogLabel(Ui::QuickDialogActionLabel action) {
  150. switch (action) {
  151. case Ui::QuickDialogActionLabel::Mute:
  152. return tr::lng_settings_quick_dialog_action_mute(tr::now);
  153. case Ui::QuickDialogActionLabel::Unmute:
  154. return tr::lng_settings_quick_dialog_action_unmute(tr::now);
  155. case Ui::QuickDialogActionLabel::Pin:
  156. return tr::lng_settings_quick_dialog_action_pin(tr::now);
  157. case Ui::QuickDialogActionLabel::Unpin:
  158. return tr::lng_settings_quick_dialog_action_unpin(tr::now);
  159. case Ui::QuickDialogActionLabel::Read:
  160. return tr::lng_settings_quick_dialog_action_read(tr::now);
  161. case Ui::QuickDialogActionLabel::Unread:
  162. return tr::lng_settings_quick_dialog_action_unread(tr::now);
  163. case Ui::QuickDialogActionLabel::Archive:
  164. return tr::lng_settings_quick_dialog_action_archive(tr::now);
  165. case Ui::QuickDialogActionLabel::Unarchive:
  166. return tr::lng_settings_quick_dialog_action_unarchive(tr::now);
  167. case Ui::QuickDialogActionLabel::Delete:
  168. return tr::lng_settings_quick_dialog_action_delete(tr::now);
  169. default:
  170. return tr::lng_settings_quick_dialog_action_disabled(tr::now);
  171. };
  172. }
  173. const style::color &ResolveQuickActionBg(
  174. Ui::QuickDialogActionLabel action) {
  175. switch (action) {
  176. case Ui::QuickDialogActionLabel::Delete:
  177. return st::attentionButtonFg;
  178. case Ui::QuickDialogActionLabel::Disabled:
  179. return st::windowSubTextFgOver;
  180. case Ui::QuickDialogActionLabel::Mute:
  181. case Ui::QuickDialogActionLabel::Unmute:
  182. case Ui::QuickDialogActionLabel::Pin:
  183. case Ui::QuickDialogActionLabel::Unpin:
  184. case Ui::QuickDialogActionLabel::Read:
  185. case Ui::QuickDialogActionLabel::Unread:
  186. case Ui::QuickDialogActionLabel::Archive:
  187. case Ui::QuickDialogActionLabel::Unarchive:
  188. default:
  189. return st::windowBgActive;
  190. };
  191. }
  192. const style::color &ResolveQuickActionBgActive(
  193. Ui::QuickDialogActionLabel action) {
  194. return st::windowSubTextFgOver;
  195. }
  196. void DrawQuickAction(
  197. QPainter &p,
  198. const QRect &rect,
  199. not_null<Lottie::Icon*> icon,
  200. Ui::QuickDialogActionLabel label) {
  201. const auto iconSize = st::dialogsQuickActionSize;
  202. const auto innerHeight = iconSize * 2;
  203. const auto top = (rect.height() - innerHeight) / 2;
  204. icon->paint(p, rect.x() + (rect.width() - iconSize) / 2, top);
  205. p.setPen(st::premiumButtonFg);
  206. p.setBrush(Qt::NoBrush);
  207. const auto availableWidth = rect.width();
  208. p.setFont(SwipeActionFont(label, availableWidth));
  209. p.drawText(
  210. QRect(rect.x(), top, availableWidth, innerHeight),
  211. ResolveQuickDialogLabel(label),
  212. style::al_bottom);
  213. }
  214. } // namespace Dialogs