settings_power_saving.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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 "settings/settings_power_saving.h"
  8. #include "base/battery_saving.h"
  9. #include "boxes/peers/edit_peer_permissions_box.h"
  10. #include "core/application.h"
  11. #include "core/core_settings.h"
  12. #include "lang/lang_keys.h"
  13. #include "ui/layers/generic_box.h"
  14. #include "ui/widgets/buttons.h"
  15. #include "ui/power_saving.h"
  16. #include "ui/vertical_list.h"
  17. #include "styles/style_menu_icons.h"
  18. #include "styles/style_layers.h"
  19. #include "styles/style_settings.h"
  20. namespace Settings {
  21. namespace {
  22. constexpr auto kForceDisableTooltipDuration = 3 * crl::time(1000);
  23. } // namespace
  24. void PowerSavingBox(not_null<Ui::GenericBox*> box) {
  25. box->setStyle(st::layerBox);
  26. box->setTitle(tr::lng_settings_power_title());
  27. box->setWidth(st::boxWideWidth);
  28. const auto container = box->verticalLayout();
  29. const auto ignore = Core::App().settings().ignoreBatterySaving();
  30. const auto batterySaving = Core::App().batterySaving().enabled();
  31. // Force top shadow visibility.
  32. box->setPinnedToTopContent(
  33. object_ptr<Ui::FixedHeightWidget>(box, st::lineWidth));
  34. const auto subtitle = Ui::AddSubsectionTitle(
  35. container,
  36. tr::lng_settings_power_subtitle(),
  37. st::powerSavingSubtitlePadding);
  38. struct State {
  39. rpl::variable<QString> forceDisabledMessage;
  40. };
  41. const auto state = container->lifetime().make_state<State>();
  42. state->forceDisabledMessage = (batterySaving.value_or(false) && !ignore)
  43. ? tr::lng_settings_power_turn_off(tr::now)
  44. : QString();
  45. auto [checkboxes, getResult, changes] = CreateEditPowerSaving(
  46. box,
  47. PowerSaving::kAll & ~PowerSaving::Current(),
  48. state->forceDisabledMessage.value());
  49. const auto controlsRaw = checkboxes.data();
  50. box->addRow(std::move(checkboxes), {});
  51. auto automatic = (Ui::SettingsButton*)nullptr;
  52. if (batterySaving.has_value()) {
  53. Ui::AddSkip(container);
  54. Ui::AddDivider(container);
  55. Ui::AddSkip(container);
  56. automatic = container->add(object_ptr<Ui::SettingsButton>(
  57. container,
  58. tr::lng_settings_power_auto(),
  59. st::powerSavingButtonNoIcon
  60. ))->toggleOn(rpl::single(!ignore));
  61. Ui::AddSkip(container);
  62. Ui::AddDividerText(container, tr::lng_settings_power_auto_about());
  63. state->forceDisabledMessage = rpl::combine(
  64. automatic->toggledValue(),
  65. Core::App().batterySaving().value()
  66. ) | rpl::map([=](bool dontIgnore, bool saving) {
  67. return (saving && dontIgnore)
  68. ? tr::lng_settings_power_turn_off()
  69. : rpl::single(QString());
  70. }) | rpl::flatten_latest();
  71. const auto show = box->uiShow();
  72. const auto disabler = Ui::CreateChild<Ui::AbstractButton>(
  73. container.get());
  74. disabler->setClickedCallback([=] {
  75. show->showToast(
  76. tr::lng_settings_power_turn_off(tr::now),
  77. kForceDisableTooltipDuration);
  78. });
  79. disabler->paintRequest() | rpl::start_with_next([=](QRect clip) {
  80. auto color = st::boxBg->c;
  81. color.setAlpha(96);
  82. QPainter(disabler).fillRect(clip, color);
  83. }, disabler->lifetime());
  84. rpl::combine(
  85. subtitle->geometryValue(),
  86. controlsRaw->geometryValue()
  87. ) | rpl::start_with_next([=](QRect subtitle, QRect controls) {
  88. disabler->setGeometry(subtitle.united(controls));
  89. }, disabler->lifetime());
  90. disabler->showOn(state->forceDisabledMessage.value(
  91. ) | rpl::map([=](const QString &value) {
  92. return !value.isEmpty();
  93. }));
  94. }
  95. box->addButton(tr::lng_settings_save(), [=, collect = getResult] {
  96. const auto ignore = automatic
  97. ? !automatic->toggled()
  98. : Core::App().settings().ignoreBatterySaving();
  99. const auto batterySaving = Core::App().batterySaving().enabled();
  100. if (ignore || !batterySaving.value_or(false)) {
  101. Set(PowerSaving::kAll & ~collect());
  102. }
  103. Core::App().settings().setIgnoreBatterySavingValue(ignore);
  104. Core::App().saveSettingsDelayed();
  105. box->closeBox();
  106. });
  107. box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
  108. }
  109. EditFlagsDescriptor<PowerSaving::Flags> PowerSavingLabels() {
  110. using namespace PowerSaving;
  111. using Label = EditFlagsLabel<Flags>;
  112. auto stickers = std::vector<Label>{
  113. {
  114. kStickersPanel,
  115. tr::lng_settings_power_stickers_panel(tr::now),
  116. &st::menuIconStickers,
  117. },
  118. { kStickersChat, tr::lng_settings_power_stickers_chat(tr::now) },
  119. };
  120. auto emoji = std::vector<Label>{
  121. {
  122. kEmojiPanel,
  123. tr::lng_settings_power_emoji_panel(tr::now),
  124. &st::menuIconEmoji,
  125. },
  126. { kEmojiReactions, tr::lng_settings_power_emoji_reactions(tr::now) },
  127. { kEmojiChat, tr::lng_settings_power_emoji_chat(tr::now) },
  128. { kEmojiStatus, tr::lng_settings_power_emoji_status(tr::now) },
  129. };
  130. auto chat = std::vector<Label>{
  131. {
  132. kChatBackground,
  133. tr::lng_settings_power_chat_background(tr::now),
  134. &st::menuIconChatBubble,
  135. },
  136. { kChatSpoiler, tr::lng_settings_power_chat_spoiler(tr::now) },
  137. { kChatEffects, tr::lng_settings_power_chat_effects(tr::now) },
  138. };
  139. auto calls = std::vector<Label>{
  140. {
  141. kCalls,
  142. tr::lng_settings_power_calls(tr::now),
  143. &st::menuIconPhone,
  144. },
  145. };
  146. auto animations = std::vector<Label>{
  147. {
  148. kAnimations,
  149. tr::lng_settings_power_ui(tr::now),
  150. &st::menuIconStartStream,
  151. },
  152. };
  153. return { .labels = {
  154. { tr::lng_settings_power_stickers(), std::move(stickers) },
  155. { tr::lng_settings_power_emoji(), std::move(emoji) },
  156. { tr::lng_settings_power_chat(), std::move(chat) },
  157. { std::nullopt, std::move(calls) },
  158. { std::nullopt, std::move(animations) },
  159. }, .st = &st::powerSavingButton };
  160. }
  161. } // namespace Settings