mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Power saving improvements
This commit is contained in:
@@ -9,16 +9,15 @@ import TelegramUIPreferences
|
||||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import AccountContext
|
||||
import UndoUI
|
||||
|
||||
enum ItemType: CaseIterable {
|
||||
case autoplayVideo
|
||||
case autoplayGif
|
||||
case loopStickers
|
||||
case loopEmoji
|
||||
case playVideoAvatars
|
||||
case fullTranslucency
|
||||
case extendBackgroundWork
|
||||
case synchronizeInBackground
|
||||
case autodownloadInBackground
|
||||
|
||||
var settingsKeyPath: WritableKeyPath<EnergyUsageSettings, Bool> {
|
||||
@@ -31,14 +30,10 @@ enum ItemType: CaseIterable {
|
||||
return \.loopStickers
|
||||
case .loopEmoji:
|
||||
return \.loopEmoji
|
||||
case .playVideoAvatars:
|
||||
return \.playVideoAvatars
|
||||
case .fullTranslucency:
|
||||
return \.fullTranslucency
|
||||
case .extendBackgroundWork:
|
||||
return \.extendBackgroundWork
|
||||
case .synchronizeInBackground:
|
||||
return \.synchronizeInBackground
|
||||
case .autodownloadInBackground:
|
||||
return \.autodownloadInBackground
|
||||
}
|
||||
@@ -49,69 +44,59 @@ enum ItemType: CaseIterable {
|
||||
switch self {
|
||||
case .autoplayVideo:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Settings/Power/PowerIconVideo",
|
||||
"Autoplay Videos",
|
||||
"Autoplay and loop videos and video messages in chats."
|
||||
)
|
||||
case .autoplayGif:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Settings/Power/PowerIconGif",
|
||||
"Autoplay GIFs",
|
||||
"Autoplay and loop GIFs in chats and in the keyboard."
|
||||
)
|
||||
case .loopStickers:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Settings/Power/PowerIconStickers",
|
||||
"Sticker Animations",
|
||||
"Autoplay and loop GIFs in chats and in the keyboard."
|
||||
"Loop animated stickers, play full-screen premium effects."
|
||||
)
|
||||
case .loopEmoji:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Settings/Power/PowerIconEmoji",
|
||||
"Emoli Animations",
|
||||
"Loop animated emoji in messages, reactions, statuses."
|
||||
)
|
||||
case .playVideoAvatars:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Autoplay Video Avatars",
|
||||
"Autoplay and loop video avatars in chats"
|
||||
)
|
||||
case .fullTranslucency:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Settings/Power/PowerIconEffects",
|
||||
"Interface Effects",
|
||||
"Various effects and animations that make Telegram look amazing."
|
||||
)
|
||||
case .extendBackgroundWork:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Settings/Power/PowerIconBackgroundTime",
|
||||
"Extended Background Time",
|
||||
"Extended Background Time Description"
|
||||
)
|
||||
case .synchronizeInBackground:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Background Sync",
|
||||
"Background Sync Description"
|
||||
"Update chats faster when switching between apps."
|
||||
)
|
||||
case .autodownloadInBackground:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Preload Media in Chats",
|
||||
"Preload Media in Chats Description"
|
||||
"Settings/Power/PowerIconMedia",
|
||||
"Preload Media",
|
||||
"Start loading media while in the chat list for faster access."
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class EnergeSavingSettingsScreenArguments {
|
||||
let toggleAll: (Bool) -> Void
|
||||
let updateThreshold: (Int32) -> Void
|
||||
let toggleItem: (ItemType) -> Void
|
||||
let displayDisabledTooltip: () -> Void
|
||||
|
||||
init(toggleAll: @escaping (Bool) -> Void, toggleItem: @escaping (ItemType) -> Void) {
|
||||
self.toggleAll = toggleAll
|
||||
init(updateThreshold: @escaping (Int32) -> Void, toggleItem: @escaping (ItemType) -> Void, displayDisabledTooltip: @escaping () -> Void) {
|
||||
self.updateThreshold = updateThreshold
|
||||
self.toggleItem = toggleItem
|
||||
self.displayDisabledTooltip = displayDisabledTooltip
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,20 +107,22 @@ private enum EnergeSavingSettingsScreenSection: Int32 {
|
||||
|
||||
private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
|
||||
enum StableId: Hashable {
|
||||
case allHeader
|
||||
case all
|
||||
case allFooter
|
||||
case itemsHeader
|
||||
case item(ItemType)
|
||||
}
|
||||
|
||||
case all(Bool)
|
||||
case allFooter
|
||||
case allHeader(Bool?)
|
||||
case all(Int32)
|
||||
case allFooter(String)
|
||||
case item(index: Int, type: ItemType, value: Bool, enabled: Bool)
|
||||
case itemsHeader
|
||||
|
||||
var section: ItemListSectionId {
|
||||
switch self {
|
||||
case .all, .allFooter:
|
||||
case .allHeader, .all, .allFooter:
|
||||
return EnergeSavingSettingsScreenSection.all.rawValue
|
||||
case .item, .itemsHeader:
|
||||
return EnergeSavingSettingsScreenSection.items.rawValue
|
||||
@@ -144,6 +131,8 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
|
||||
|
||||
var sortIndex: Int {
|
||||
switch self {
|
||||
case .allHeader:
|
||||
return -4
|
||||
case .all:
|
||||
return -3
|
||||
case .allFooter:
|
||||
@@ -157,6 +146,8 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
|
||||
|
||||
var stableId: StableId {
|
||||
switch self {
|
||||
case .allHeader:
|
||||
return .allHeader
|
||||
case .all:
|
||||
return .all
|
||||
case .allFooter:
|
||||
@@ -175,13 +166,28 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
|
||||
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
|
||||
let arguments = arguments as! EnergeSavingSettingsScreenArguments
|
||||
switch self {
|
||||
case let .all(value):
|
||||
case let .allHeader(value):
|
||||
//TODO:localize
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Power-Saving Mode", value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.toggleAll(value)
|
||||
})
|
||||
case .allFooter:
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain("Reduce all resource-intensive animations and background activity."), sectionId: self.section)
|
||||
let text: String
|
||||
if let value {
|
||||
let modeValue = value ? "ON" : "OFF"
|
||||
text = "POWER SAVING MODE (\(modeValue))"
|
||||
} else {
|
||||
text = "POWER SAVING MODE"
|
||||
}
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .all(value):
|
||||
return EnergyUsageBatteryLevelItem(
|
||||
theme: presentationData.theme,
|
||||
strings: presentationData.strings,
|
||||
value: value,
|
||||
sectionId: self.section,
|
||||
updated: { value in
|
||||
arguments.updateThreshold(value)
|
||||
}
|
||||
)
|
||||
case let .allFooter(text):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||
case .itemsHeader:
|
||||
//TODO:localize
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "RESOURCE-INTENSIVE PROCESSES", sectionId: self.section)
|
||||
@@ -189,6 +195,8 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
|
||||
let (iconName, title, text) = type.title(strings: presentationData.strings)
|
||||
return ItemListSwitchItem(presentationData: presentationData, icon: UIImage(bundleImageName: iconName)?.precomposed(), title: title, text: text, value: value, enableInteractiveChanges: true, enabled: enabled, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.toggleItem(type)
|
||||
}, activatedWhileDisabled: {
|
||||
arguments.displayDisabledTooltip()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -200,29 +208,57 @@ private func energeSavingSettingsScreenEntries(
|
||||
) -> [EnergeSavingSettingsScreenEntry] {
|
||||
var entries: [EnergeSavingSettingsScreenEntry] = []
|
||||
|
||||
let powerSavingOn = ItemType.allCases.allSatisfy({ item in !settings.energyUsageSettings[keyPath: item.settingsKeyPath] })
|
||||
entries.append(.all(powerSavingOn))
|
||||
entries.append(.allFooter)
|
||||
let isOn = automaticEnergyUsageShouldBeOnNow(settings: settings)
|
||||
|
||||
let allIsOn: Bool?
|
||||
if settings.energyUsageSettings.activationThreshold == 0 || settings.energyUsageSettings.activationThreshold == 100 {
|
||||
allIsOn = nil
|
||||
} else {
|
||||
allIsOn = isOn
|
||||
}
|
||||
entries.append(.allHeader(allIsOn))
|
||||
entries.append(.all(settings.energyUsageSettings.activationThreshold))
|
||||
|
||||
let allText: String
|
||||
if settings.energyUsageSettings.activationThreshold == 0 {
|
||||
allText = "Don’t disable all resource-intensive processes even when the battery is low."
|
||||
} else if settings.energyUsageSettings.activationThreshold >= 100 {
|
||||
allText = "Always disable all resource-intensive processes, regardless of the battery charge level."
|
||||
} else {
|
||||
allText = "Automatically disable all resource-intensive processes when your battery is below \(settings.energyUsageSettings.activationThreshold)%."
|
||||
}
|
||||
entries.append(.allFooter(allText))
|
||||
|
||||
let itemsEnabled: Bool
|
||||
if settings.energyUsageSettings.activationThreshold == 0 {
|
||||
itemsEnabled = false
|
||||
} else if settings.energyUsageSettings.activationThreshold == 100 {
|
||||
itemsEnabled = true
|
||||
} else if isOn {
|
||||
itemsEnabled = false
|
||||
} else {
|
||||
itemsEnabled = true
|
||||
}
|
||||
|
||||
entries.append(.itemsHeader)
|
||||
for type in ItemType.allCases {
|
||||
entries.append(.item(index: entries.count, type: type, value: settings.energyUsageSettings[keyPath: type.settingsKeyPath], enabled: !powerSavingOn))
|
||||
entries.append(.item(index: entries.count, type: type, value: settings.energyUsageSettings[keyPath: type.settingsKeyPath], enabled: itemsEnabled))
|
||||
}
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
func energySavingSettingsScreen(context: AccountContext) -> ViewController {
|
||||
public func energySavingSettingsScreen(context: AccountContext) -> ViewController {
|
||||
var pushControllerImpl: ((ViewController) -> Void)?
|
||||
let _ = pushControllerImpl
|
||||
|
||||
var displayTooltipImpl: ((UndoOverlayContent) -> Void)?
|
||||
|
||||
let arguments = EnergeSavingSettingsScreenArguments(
|
||||
toggleAll: { value in
|
||||
updateThreshold: { value in
|
||||
let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
|
||||
var settings = settings
|
||||
for type in ItemType.allCases {
|
||||
settings.energyUsageSettings[keyPath: type.settingsKeyPath] = !value
|
||||
}
|
||||
settings.energyUsageSettings.activationThreshold = max(0, min(100, value))
|
||||
return settings
|
||||
}).start()
|
||||
},
|
||||
@@ -232,6 +268,16 @@ func energySavingSettingsScreen(context: AccountContext) -> ViewController {
|
||||
settings.energyUsageSettings[keyPath: type.settingsKeyPath] = !settings.energyUsageSettings[keyPath: type.settingsKeyPath]
|
||||
return settings
|
||||
}).start()
|
||||
},
|
||||
displayDisabledTooltip: {
|
||||
//TODO:localize
|
||||
let text: String
|
||||
if context.sharedContext.currentAutomaticMediaDownloadSettings.energyUsageSettings.activationThreshold == 100 {
|
||||
text = "Turn off Power Saving Mode to change these settings."
|
||||
} else {
|
||||
text = "Turn off Power Saving Mode or charge your phone to change these settings."
|
||||
}
|
||||
displayTooltipImpl?(.info(title: nil, text: text))
|
||||
}
|
||||
)
|
||||
|
||||
@@ -267,5 +313,11 @@ func energySavingSettingsScreen(context: AccountContext) -> ViewController {
|
||||
(controller.navigationController as? NavigationController)?.pushViewController(c)
|
||||
}
|
||||
}
|
||||
displayTooltipImpl = { [weak controller] c in
|
||||
if let controller = controller {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with({ $0 })
|
||||
controller.present(UndoOverlayController(presentationData: presentationData, content: c, elevatedLayout: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user