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
 |