179 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| This file is part of Telegram Desktop,
 | |
| the official desktop application for the Telegram messaging service.
 | |
| 
 | |
| For license and copyright information please follow this link:
 | |
| https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | |
| */
 | |
| #include "settings/settings_power_saving.h"
 | |
| 
 | |
| #include "base/battery_saving.h"
 | |
| #include "boxes/peers/edit_peer_permissions_box.h"
 | |
| #include "core/application.h"
 | |
| #include "core/core_settings.h"
 | |
| #include "lang/lang_keys.h"
 | |
| #include "settings/settings_common.h"
 | |
| #include "ui/layers/generic_box.h"
 | |
| #include "ui/widgets/buttons.h"
 | |
| #include "ui/power_saving.h"
 | |
| #include "styles/style_menu_icons.h"
 | |
| #include "styles/style_layers.h"
 | |
| #include "styles/style_settings.h"
 | |
| 
 | |
| namespace Settings {
 | |
| namespace {
 | |
| 
 | |
| constexpr auto kForceDisableTooltipDuration = 3 * crl::time(1000);
 | |
| 
 | |
| } // namespace
 | |
| 
 | |
| void PowerSavingBox(not_null<Ui::GenericBox*> box) {
 | |
| 	box->setStyle(st::layerBox);
 | |
| 	box->setTitle(tr::lng_settings_power_title());
 | |
| 	box->setWidth(st::boxWideWidth);
 | |
| 
 | |
| 	const auto container = box->verticalLayout();
 | |
| 	const auto ignore = Core::App().settings().ignoreBatterySaving();
 | |
| 	const auto batterySaving = Core::App().batterySaving().enabled();
 | |
| 
 | |
| 	// Force top shadow visibility.
 | |
| 	box->setPinnedToTopContent(
 | |
| 		object_ptr<Ui::FixedHeightWidget>(box, st::lineWidth));
 | |
| 
 | |
| 	const auto subtitle = AddSubsectionTitle(
 | |
| 		container,
 | |
| 		tr::lng_settings_power_subtitle(),
 | |
| 		st::powerSavingSubtitlePadding);
 | |
| 
 | |
| 	struct State {
 | |
| 		rpl::variable<QString> forceDisabledMessage;
 | |
| 	};
 | |
| 	const auto state = container->lifetime().make_state<State>();
 | |
| 	state->forceDisabledMessage = (batterySaving.value_or(false) && !ignore)
 | |
| 		? tr::lng_settings_power_turn_off(tr::now)
 | |
| 		: QString();
 | |
| 
 | |
| 	auto [checkboxes, getResult, changes] = CreateEditPowerSaving(
 | |
| 		box,
 | |
| 		PowerSaving::kAll & ~PowerSaving::Current(),
 | |
| 		state->forceDisabledMessage.value());
 | |
| 
 | |
| 	const auto controlsRaw = checkboxes.data();
 | |
| 	box->addRow(std::move(checkboxes), {});
 | |
| 
 | |
| 	auto automatic = (Ui::SettingsButton*)nullptr;
 | |
| 	if (batterySaving.has_value()) {
 | |
| 		AddSkip(container);
 | |
| 		AddDivider(container);
 | |
| 		AddSkip(container);
 | |
| 		automatic = AddButton(
 | |
| 			container,
 | |
| 			tr::lng_settings_power_auto(),
 | |
| 			st::powerSavingButtonNoIcon
 | |
| 		)->toggleOn(rpl::single(!ignore));
 | |
| 		AddSkip(container);
 | |
| 		AddDividerText(container, tr::lng_settings_power_auto_about());
 | |
| 
 | |
| 		state->forceDisabledMessage = rpl::combine(
 | |
| 			automatic->toggledValue(),
 | |
| 			Core::App().batterySaving().value()
 | |
| 		) | rpl::map([=](bool dontIgnore, bool saving) {
 | |
| 			return (saving && dontIgnore)
 | |
| 				? tr::lng_settings_power_turn_off()
 | |
| 				: rpl::single(QString());
 | |
| 		}) | rpl::flatten_latest();
 | |
| 
 | |
| 		const auto show = box->uiShow();
 | |
| 		const auto disabler = Ui::CreateChild<Ui::AbstractButton>(
 | |
| 			container.get());
 | |
| 		disabler->setClickedCallback([=] {
 | |
| 			show->showToast(
 | |
| 				tr::lng_settings_power_turn_off(tr::now),
 | |
| 				kForceDisableTooltipDuration);
 | |
| 		});
 | |
| 		disabler->paintRequest() | rpl::start_with_next([=](QRect clip) {
 | |
| 			auto color = st::boxBg->c;
 | |
| 			color.setAlpha(96);
 | |
| 			QPainter(disabler).fillRect(clip, color);
 | |
| 		}, disabler->lifetime());
 | |
| 		rpl::combine(
 | |
| 			subtitle->geometryValue(),
 | |
| 			controlsRaw->geometryValue()
 | |
| 		) | rpl::start_with_next([=](QRect subtitle, QRect controls) {
 | |
| 			disabler->setGeometry(subtitle.united(controls));
 | |
| 		}, disabler->lifetime());
 | |
| 		disabler->showOn(state->forceDisabledMessage.value(
 | |
| 		) | rpl::map([=](const QString &value) {
 | |
| 			return !value.isEmpty();
 | |
| 		}));
 | |
| 	}
 | |
| 
 | |
| 	box->addButton(tr::lng_settings_save(), [=, collect = getResult] {
 | |
| 		const auto ignore = automatic
 | |
| 			? !automatic->toggled()
 | |
| 			: Core::App().settings().ignoreBatterySaving();
 | |
| 		const auto batterySaving = Core::App().batterySaving().enabled();
 | |
| 		if (ignore || !batterySaving.value_or(false)) {
 | |
| 			Set(PowerSaving::kAll & ~collect());
 | |
| 		}
 | |
| 		Core::App().settings().setIgnoreBatterySavingValue(ignore);
 | |
| 		Core::App().saveSettingsDelayed();
 | |
| 		box->closeBox();
 | |
| 	});
 | |
| 	box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
 | |
| }
 | |
| 
 | |
| EditFlagsDescriptor<PowerSaving::Flags> PowerSavingLabels() {
 | |
| 	using namespace PowerSaving;
 | |
| 	using Label = EditFlagsLabel<Flags>;
 | |
| 
 | |
| 	auto stickers = std::vector<Label>{
 | |
| 		{
 | |
| 			kStickersPanel,
 | |
| 			tr::lng_settings_power_stickers_panel(tr::now),
 | |
| 			&st::menuIconStickers,
 | |
| 		},
 | |
| 		{ kStickersChat, tr::lng_settings_power_stickers_chat(tr::now) },
 | |
| 	};
 | |
| 	auto emoji = std::vector<Label>{
 | |
| 		{
 | |
| 			kEmojiPanel,
 | |
| 			tr::lng_settings_power_emoji_panel(tr::now),
 | |
| 			&st::menuIconEmoji,
 | |
| 		},
 | |
| 		{ kEmojiReactions, tr::lng_settings_power_emoji_reactions(tr::now) },
 | |
| 		{ kEmojiChat, tr::lng_settings_power_emoji_chat(tr::now) },
 | |
| 		{ kEmojiStatus, tr::lng_settings_power_emoji_status(tr::now) },
 | |
| 	};
 | |
| 	auto chat = std::vector<Label>{
 | |
| 		{
 | |
| 			kChatBackground,
 | |
| 			tr::lng_settings_power_chat_background(tr::now),
 | |
| 			&st::menuIconChatBubble,
 | |
| 		},
 | |
| 		{ kChatSpoiler, tr::lng_settings_power_chat_spoiler(tr::now) },
 | |
| 	};
 | |
| 	auto calls = std::vector<Label>{
 | |
| 		{
 | |
| 			kCalls,
 | |
| 			tr::lng_settings_power_calls(tr::now),
 | |
| 			&st::menuIconPhone,
 | |
| 		},
 | |
| 	};
 | |
| 	auto animations = std::vector<Label>{
 | |
| 		{
 | |
| 			kAnimations,
 | |
| 			tr::lng_settings_power_ui(tr::now),
 | |
| 			&st::menuIconStartStream,
 | |
| 		},
 | |
| 	};
 | |
| 	return { .labels = {
 | |
| 		{ tr::lng_settings_power_stickers(), std::move(stickers) },
 | |
| 		{ tr::lng_settings_power_emoji(), std::move(emoji) },
 | |
| 		{ tr::lng_settings_power_chat(), std::move(chat) },
 | |
| 		{ std::nullopt, std::move(calls) },
 | |
| 		{ std::nullopt, std::move(animations),  },
 | |
| 	}, .st = &st::powerSavingButton };
 | |
| }
 | |
| 
 | |
| } // namespace Settings
 | 
