mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
[WIP] Energy settings
This commit is contained in:
@@ -16,6 +16,7 @@ public class ItemListSwitchItem: ListViewItem, ItemListItem {
|
||||
let presentationData: ItemListPresentationData
|
||||
let icon: UIImage?
|
||||
let title: String
|
||||
let text: String?
|
||||
let value: Bool
|
||||
let type: ItemListSwitchItemNodeType
|
||||
let enableInteractiveChanges: Bool
|
||||
@@ -30,10 +31,11 @@ public class ItemListSwitchItem: ListViewItem, ItemListItem {
|
||||
let activatedWhileDisabled: () -> Void
|
||||
public let tag: ItemListItemTag?
|
||||
|
||||
public init(presentationData: ItemListPresentationData, icon: UIImage? = nil, title: String, value: Bool, type: ItemListSwitchItemNodeType = .regular, enableInteractiveChanges: Bool = true, enabled: Bool = true, displayLocked: Bool = false, disableLeadingInset: Bool = false, maximumNumberOfLines: Int = 1, noCorners: Bool = false, sectionId: ItemListSectionId, style: ItemListStyle, updated: @escaping (Bool) -> Void, activatedWhileDisabled: @escaping () -> Void = {}, tag: ItemListItemTag? = nil) {
|
||||
public init(presentationData: ItemListPresentationData, icon: UIImage? = nil, title: String, text: String? = nil, value: Bool, type: ItemListSwitchItemNodeType = .regular, enableInteractiveChanges: Bool = true, enabled: Bool = true, displayLocked: Bool = false, disableLeadingInset: Bool = false, maximumNumberOfLines: Int = 1, noCorners: Bool = false, sectionId: ItemListSectionId, style: ItemListStyle, updated: @escaping (Bool) -> Void, activatedWhileDisabled: @escaping () -> Void = {}, tag: ItemListItemTag? = nil) {
|
||||
self.presentationData = presentationData
|
||||
self.icon = icon
|
||||
self.title = title
|
||||
self.text = text
|
||||
self.value = value
|
||||
self.type = type
|
||||
self.enableInteractiveChanges = enableInteractiveChanges
|
||||
@@ -127,6 +129,7 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
private let iconNode: ASImageNode
|
||||
private let titleNode: TextNode
|
||||
private let textNode: TextNode
|
||||
private var switchNode: ASDisplayNode & ItemListSwitchNodeImpl
|
||||
private let switchGestureNode: ASDisplayNode
|
||||
private var disabledOverlayNode: ASDisplayNode?
|
||||
@@ -161,6 +164,10 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
self.titleNode = TextNode()
|
||||
self.titleNode.isUserInteractionEnabled = false
|
||||
|
||||
self.textNode = TextNode()
|
||||
self.textNode.isUserInteractionEnabled = false
|
||||
|
||||
switch type {
|
||||
case .regular:
|
||||
self.switchNode = SwitchNode()
|
||||
@@ -178,6 +185,7 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
self.addSubnode(self.titleNode)
|
||||
self.addSubnode(self.textNode)
|
||||
self.addSubnode(self.switchNode)
|
||||
self.addSubnode(self.switchGestureNode)
|
||||
self.addSubnode(self.activateArea)
|
||||
@@ -204,6 +212,7 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
func asyncLayout() -> (_ item: ItemListSwitchItem, _ params: ListViewItemLayoutParams, _ insets: ItemListNeighbors) -> (ListViewItemNodeLayout, (Bool) -> Void) {
|
||||
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
|
||||
let makeTextLayout = TextNode.asyncLayout(self.textNode)
|
||||
|
||||
let currentItem = self.item
|
||||
var currentDisabledOverlayNode = self.disabledOverlayNode
|
||||
@@ -216,6 +225,7 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
|
||||
let itemSeparatorColor: UIColor
|
||||
|
||||
let titleFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize)
|
||||
let textFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize * 14.0 / 17.0)
|
||||
|
||||
var updatedTheme: PresentationTheme?
|
||||
if currentItem?.presentationData.theme !== item.presentationData.theme {
|
||||
@@ -252,7 +262,12 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.title, font: titleFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: item.maximumNumberOfLines, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - params.rightInset - 64.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.text ?? "", font: textFont, textColor: item.presentationData.theme.list.itemSecondaryTextColor), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - params.rightInset - 64.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
contentSize.height = max(contentSize.height, titleLayout.size.height + 22.0)
|
||||
if item.text != nil {
|
||||
contentSize.height += 2.0 + textLayout.size.height
|
||||
}
|
||||
|
||||
if !item.enabled {
|
||||
if currentDisabledOverlayNode == nil {
|
||||
@@ -288,7 +303,12 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
|
||||
if updateIcon {
|
||||
strongSelf.iconNode.image = icon
|
||||
}
|
||||
let iconY = floor((layout.contentSize.height - icon.size.height) / 2.0)
|
||||
let iconY: CGFloat
|
||||
if item.text == nil {
|
||||
iconY = floor((layout.contentSize.height - icon.size.height) / 2.0)
|
||||
} else {
|
||||
iconY = max(0.0, floor(11.0 + titleLayout.size.height + 1.0 - icon.size.height * 0.5))
|
||||
}
|
||||
strongSelf.iconNode.frame = CGRect(origin: CGPoint(x: params.leftInset + floor((leftInset - params.leftInset - icon.size.width) / 2.0), y: iconY), size: icon.size)
|
||||
} else if strongSelf.iconNode.supernode != nil {
|
||||
strongSelf.iconNode.image = nil
|
||||
@@ -335,6 +355,7 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
|
||||
}
|
||||
|
||||
let _ = titleApply()
|
||||
let _ = textApply()
|
||||
|
||||
switch item.style {
|
||||
case .plain:
|
||||
@@ -394,7 +415,10 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||
}
|
||||
|
||||
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: floorToScreenPixels((contentSize.height - titleLayout.size.height) / 2.0)), size: titleLayout.size)
|
||||
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 11.0), size: titleLayout.size)
|
||||
|
||||
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: strongSelf.titleNode.frame.maxY + 2.0), size: textLayout.size)
|
||||
|
||||
if let switchView = strongSelf.switchNode.view as? UISwitch {
|
||||
if strongSelf.switchNode.bounds.size.width.isZero {
|
||||
switchView.sizeToFit()
|
||||
|
||||
@@ -33,13 +33,12 @@ private final class DataAndStorageControllerArguments {
|
||||
let toggleRaiseToListen: (Bool) -> Void
|
||||
let toggleAutoplayGifs: (Bool) -> Void
|
||||
let toggleAutoplayVideos: (Bool) -> Void
|
||||
let openEnergySavingSettings: () -> Void
|
||||
let toggleDownloadInBackground: (Bool) -> Void
|
||||
let openBrowserSelection: () -> Void
|
||||
let openIntents: () -> Void
|
||||
let toggleEnableSensitiveContent: (Bool) -> Void
|
||||
|
||||
init(openStorageUsage: @escaping () -> Void, openNetworkUsage: @escaping () -> Void, openProxy: @escaping () -> Void, openAutomaticDownloadConnectionType: @escaping (AutomaticDownloadConnectionType) -> Void, resetAutomaticDownload: @escaping () -> Void, toggleVoiceUseLessData: @escaping (Bool) -> Void, openSaveIncoming: @escaping (AutomaticSaveIncomingPeerType) -> Void, toggleSaveEditedPhotos: @escaping (Bool) -> Void, togglePauseMusicOnRecording: @escaping (Bool) -> Void, toggleRaiseToListen: @escaping (Bool) -> Void, toggleAutoplayGifs: @escaping (Bool) -> Void, toggleAutoplayVideos: @escaping (Bool) -> Void, openEnergySavingSettings: @escaping () -> Void, toggleDownloadInBackground: @escaping (Bool) -> Void, openBrowserSelection: @escaping () -> Void, openIntents: @escaping () -> Void, toggleEnableSensitiveContent: @escaping (Bool) -> Void) {
|
||||
init(openStorageUsage: @escaping () -> Void, openNetworkUsage: @escaping () -> Void, openProxy: @escaping () -> Void, openAutomaticDownloadConnectionType: @escaping (AutomaticDownloadConnectionType) -> Void, resetAutomaticDownload: @escaping () -> Void, toggleVoiceUseLessData: @escaping (Bool) -> Void, openSaveIncoming: @escaping (AutomaticSaveIncomingPeerType) -> Void, toggleSaveEditedPhotos: @escaping (Bool) -> Void, togglePauseMusicOnRecording: @escaping (Bool) -> Void, toggleRaiseToListen: @escaping (Bool) -> Void, toggleAutoplayGifs: @escaping (Bool) -> Void, toggleAutoplayVideos: @escaping (Bool) -> Void, toggleDownloadInBackground: @escaping (Bool) -> Void, openBrowserSelection: @escaping () -> Void, openIntents: @escaping () -> Void, toggleEnableSensitiveContent: @escaping (Bool) -> Void) {
|
||||
self.openStorageUsage = openStorageUsage
|
||||
self.openNetworkUsage = openNetworkUsage
|
||||
self.openProxy = openProxy
|
||||
@@ -52,7 +51,6 @@ private final class DataAndStorageControllerArguments {
|
||||
self.toggleRaiseToListen = toggleRaiseToListen
|
||||
self.toggleAutoplayGifs = toggleAutoplayGifs
|
||||
self.toggleAutoplayVideos = toggleAutoplayVideos
|
||||
self.openEnergySavingSettings = openEnergySavingSettings
|
||||
self.toggleDownloadInBackground = toggleDownloadInBackground
|
||||
self.openBrowserSelection = openBrowserSelection
|
||||
self.openIntents = openIntents
|
||||
@@ -66,7 +64,6 @@ private enum DataAndStorageSection: Int32 {
|
||||
case autoSave
|
||||
case backgroundDownload
|
||||
case autoPlay
|
||||
case energySaving
|
||||
case voiceCalls
|
||||
case other
|
||||
case connection
|
||||
@@ -111,8 +108,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
|
||||
case autoplayGifs(PresentationTheme, String, Bool)
|
||||
case autoplayVideos(PresentationTheme, String, Bool)
|
||||
|
||||
case energySaving
|
||||
|
||||
case useLessVoiceData(PresentationTheme, String, Bool)
|
||||
case useLessVoiceDataInfo(PresentationTheme, String)
|
||||
case otherHeader(PresentationTheme, String)
|
||||
@@ -141,8 +136,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
|
||||
return DataAndStorageSection.voiceCalls.rawValue
|
||||
case .autoplayHeader, .autoplayGifs, .autoplayVideos:
|
||||
return DataAndStorageSection.autoPlay.rawValue
|
||||
case .energySaving:
|
||||
return DataAndStorageSection.energySaving.rawValue
|
||||
case .otherHeader, .shareSheet, .saveEditedPhotos, .openLinksIn, .pauseMusicOnRecording, .raiseToListen, .raiseToListenInfo:
|
||||
return DataAndStorageSection.other.rawValue
|
||||
case .connectionHeader, .connectionProxy:
|
||||
@@ -186,8 +179,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
|
||||
return 26
|
||||
case .autoplayVideos:
|
||||
return 27
|
||||
case .energySaving:
|
||||
return 28
|
||||
case .otherHeader:
|
||||
return 29
|
||||
case .shareSheet:
|
||||
@@ -285,12 +276,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .energySaving:
|
||||
if case .energySaving = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .useLessVoiceData(lhsTheme, lhsText, lhsValue):
|
||||
if case let .useLessVoiceData(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
||||
return true
|
||||
@@ -440,11 +425,6 @@ private enum DataAndStorageEntry: ItemListNodeEntry {
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.toggleAutoplayVideos(value)
|
||||
}, tag: DataAndStorageEntryTag.autoplayVideos)
|
||||
case .energySaving:
|
||||
//TODO:localize
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: "Energy Saving", label: "", sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openEnergySavingSettings()
|
||||
})
|
||||
case let .useLessVoiceData(_, text, value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.toggleVoiceUseLessData(value)
|
||||
@@ -688,8 +668,6 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat
|
||||
entries.append(.autoplayGifs(presentationData.theme, presentationData.strings.ChatSettings_AutoPlayGifs, data.automaticMediaDownloadSettings.autoplayGifs))
|
||||
entries.append(.autoplayVideos(presentationData.theme, presentationData.strings.ChatSettings_AutoPlayVideos, data.automaticMediaDownloadSettings.autoplayVideos))
|
||||
|
||||
entries.append(.energySaving)
|
||||
|
||||
entries.append(.otherHeader(presentationData.theme, presentationData.strings.ChatSettings_Other))
|
||||
if #available(iOSApplicationExtension 13.2, iOS 13.2, *) {
|
||||
entries.append(.shareSheet(presentationData.theme, presentationData.strings.ChatSettings_IntentsSettings))
|
||||
@@ -945,8 +923,6 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da
|
||||
settings.autoplayVideos = value
|
||||
return settings
|
||||
}).start()
|
||||
}, openEnergySavingSettings: {
|
||||
pushControllerImpl?(energySavingSettingsScreen(context: context))
|
||||
}, toggleDownloadInBackground: { value in
|
||||
let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
|
||||
var settings = settings
|
||||
|
||||
@@ -11,6 +11,9 @@ import PresentationDataUtils
|
||||
import AccountContext
|
||||
|
||||
enum ItemType: CaseIterable {
|
||||
case autoplayVideo
|
||||
case autoplayGif
|
||||
case loopStickers
|
||||
case loopEmoji
|
||||
case playVideoAvatars
|
||||
case fullTranslucency
|
||||
@@ -20,6 +23,12 @@ enum ItemType: CaseIterable {
|
||||
|
||||
var settingsKeyPath: WritableKeyPath<EnergyUsageSettings, Bool> {
|
||||
switch self {
|
||||
case .autoplayVideo:
|
||||
return \.autoplayVideo
|
||||
case .autoplayGif:
|
||||
return \.autoplayGif
|
||||
case .loopStickers:
|
||||
return \.loopStickers
|
||||
case .loopEmoji:
|
||||
return \.loopEmoji
|
||||
case .playVideoAvatars:
|
||||
@@ -35,21 +44,63 @@ enum ItemType: CaseIterable {
|
||||
}
|
||||
}
|
||||
|
||||
func title(strings: PresentationStrings) -> String {
|
||||
func title(strings: PresentationStrings) -> (String, String, String) {
|
||||
//TODO:localize
|
||||
switch self {
|
||||
case .autoplayVideo:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Autoplay Videos",
|
||||
"Autoplay and loop videos and video messages in chats."
|
||||
)
|
||||
case .autoplayGif:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Autoplay GIFs",
|
||||
"Autoplay and loop GIFs in chats and in the keyboard."
|
||||
)
|
||||
case .loopStickers:
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Sticker Animations",
|
||||
"Autoplay and loop GIFs in chats and in the keyboard."
|
||||
)
|
||||
case .loopEmoji:
|
||||
return "Loop Animated Emoji"
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Emoli Animations",
|
||||
"Loop animated emoji in messages, reactions, statuses."
|
||||
)
|
||||
case .playVideoAvatars:
|
||||
return "Play Video Avatars"
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Autoplay Video Avatars",
|
||||
"Autoplay and loop video avatars in chats"
|
||||
)
|
||||
case .fullTranslucency:
|
||||
return "Translucency Effects"
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Interface Effects",
|
||||
"Various effects and animations that make Telegram look amazing."
|
||||
)
|
||||
case .extendBackgroundWork:
|
||||
return "Extended Background Time"
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Extended Background Time",
|
||||
"Extended Background Time Description"
|
||||
)
|
||||
case .synchronizeInBackground:
|
||||
return "Background Sync"
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Background Sync",
|
||||
"Background Sync Description"
|
||||
)
|
||||
case .autodownloadInBackground:
|
||||
return "Preload Media in Chats"
|
||||
return (
|
||||
"Settings/Menu/Reactions",
|
||||
"Preload Media in Chats",
|
||||
"Preload Media in Chats Description"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,17 +123,21 @@ private enum EnergeSavingSettingsScreenSection: Int32 {
|
||||
private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
|
||||
enum StableId: Hashable {
|
||||
case all
|
||||
case allFooter
|
||||
case itemsHeader
|
||||
case item(ItemType)
|
||||
}
|
||||
|
||||
case all(Bool)
|
||||
case item(index: Int, type: ItemType, value: Bool)
|
||||
case allFooter
|
||||
case item(index: Int, type: ItemType, value: Bool, enabled: Bool)
|
||||
case itemsHeader
|
||||
|
||||
var section: ItemListSectionId {
|
||||
switch self {
|
||||
case .all:
|
||||
case .all, .allFooter:
|
||||
return EnergeSavingSettingsScreenSection.all.rawValue
|
||||
case .item:
|
||||
case .item, .itemsHeader:
|
||||
return EnergeSavingSettingsScreenSection.items.rawValue
|
||||
}
|
||||
}
|
||||
@@ -90,8 +145,12 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
|
||||
var sortIndex: Int {
|
||||
switch self {
|
||||
case .all:
|
||||
return -3
|
||||
case .allFooter:
|
||||
return -2
|
||||
case .itemsHeader:
|
||||
return -1
|
||||
case let .item(index, _, _):
|
||||
case let .item(index, _, _, _):
|
||||
return index
|
||||
}
|
||||
}
|
||||
@@ -100,7 +159,11 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
|
||||
switch self {
|
||||
case .all:
|
||||
return .all
|
||||
case let .item(_, type, _):
|
||||
case .allFooter:
|
||||
return .allFooter
|
||||
case .itemsHeader:
|
||||
return .itemsHeader
|
||||
case let .item(_, type, _, _):
|
||||
return .item(type)
|
||||
}
|
||||
}
|
||||
@@ -114,11 +177,17 @@ private enum EnergeSavingSettingsScreenEntry: ItemListNodeEntry {
|
||||
switch self {
|
||||
case let .all(value):
|
||||
//TODO:localize
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Enable All", value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in
|
||||
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 let .item(_, type, value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: type.title(strings: presentationData.strings), value: value, enableInteractiveChanges: true, enabled: true, sectionId: self.section, style: .blocks, updated: { value in
|
||||
case .allFooter:
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain("Reduce all resource-intensive animations and background activity."), sectionId: self.section)
|
||||
case .itemsHeader:
|
||||
//TODO:localize
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "RESOURCE-INTENSIVE PROCESSES", sectionId: self.section)
|
||||
case let .item(_, type, value, enabled):
|
||||
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)
|
||||
})
|
||||
}
|
||||
@@ -131,10 +200,13 @@ private func energeSavingSettingsScreenEntries(
|
||||
) -> [EnergeSavingSettingsScreenEntry] {
|
||||
var entries: [EnergeSavingSettingsScreenEntry] = []
|
||||
|
||||
entries.append(.all(ItemType.allCases.allSatisfy({ item in settings.energyUsageSettings[keyPath: item.settingsKeyPath] })))
|
||||
let powerSavingOn = ItemType.allCases.allSatisfy({ item in !settings.energyUsageSettings[keyPath: item.settingsKeyPath] })
|
||||
entries.append(.all(powerSavingOn))
|
||||
entries.append(.allFooter)
|
||||
|
||||
entries.append(.itemsHeader)
|
||||
for type in ItemType.allCases {
|
||||
entries.append(.item(index: entries.count, type: type, value: settings.energyUsageSettings[keyPath: type.settingsKeyPath]))
|
||||
entries.append(.item(index: entries.count, type: type, value: settings.energyUsageSettings[keyPath: type.settingsKeyPath], enabled: !powerSavingOn))
|
||||
}
|
||||
|
||||
return entries
|
||||
@@ -149,7 +221,7 @@ func energySavingSettingsScreen(context: AccountContext) -> ViewController {
|
||||
let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
|
||||
var settings = settings
|
||||
for type in ItemType.allCases {
|
||||
settings.energyUsageSettings[keyPath: type.settingsKeyPath] = value
|
||||
settings.energyUsageSettings[keyPath: type.settingsKeyPath] = !value
|
||||
}
|
||||
return settings
|
||||
}).start()
|
||||
|
||||
@@ -56,6 +56,7 @@ private final class ThemeSettingsControllerArguments {
|
||||
let openAutoNightTheme: () -> Void
|
||||
let openTextSize: () -> Void
|
||||
let openBubbleSettings: () -> Void
|
||||
let openPowerSavingSettings: () -> Void
|
||||
let toggleLargeEmoji: (Bool) -> Void
|
||||
let disableAnimations: (Bool) -> Void
|
||||
let selectAppIcon: (PresentationAppIcon) -> Void
|
||||
@@ -63,7 +64,7 @@ private final class ThemeSettingsControllerArguments {
|
||||
let themeContextAction: (Bool, PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void
|
||||
let colorContextAction: (Bool, PresentationThemeReference, ThemeSettingsColorOption?, ASDisplayNode, ContextGesture?) -> Void
|
||||
|
||||
init(context: AccountContext, selectTheme: @escaping (PresentationThemeReference) -> Void, openThemeSettings: @escaping () -> Void, openWallpaperSettings: @escaping () -> Void, selectAccentColor: @escaping (PresentationThemeAccentColor?) -> Void, openAccentColorPicker: @escaping (PresentationThemeReference, Bool) -> Void, toggleNightTheme: @escaping (Bool) -> Void, openAutoNightTheme: @escaping () -> Void, openTextSize: @escaping () -> Void, openBubbleSettings: @escaping () -> Void, toggleLargeEmoji: @escaping (Bool) -> Void, disableAnimations: @escaping (Bool) -> Void, selectAppIcon: @escaping (PresentationAppIcon) -> Void, editTheme: @escaping (PresentationCloudTheme) -> Void, themeContextAction: @escaping (Bool, PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void, colorContextAction: @escaping (Bool, PresentationThemeReference, ThemeSettingsColorOption?, ASDisplayNode, ContextGesture?) -> Void) {
|
||||
init(context: AccountContext, selectTheme: @escaping (PresentationThemeReference) -> Void, openThemeSettings: @escaping () -> Void, openWallpaperSettings: @escaping () -> Void, selectAccentColor: @escaping (PresentationThemeAccentColor?) -> Void, openAccentColorPicker: @escaping (PresentationThemeReference, Bool) -> Void, toggleNightTheme: @escaping (Bool) -> Void, openAutoNightTheme: @escaping () -> Void, openTextSize: @escaping () -> Void, openBubbleSettings: @escaping () -> Void, openPowerSavingSettings: @escaping () -> Void, toggleLargeEmoji: @escaping (Bool) -> Void, disableAnimations: @escaping (Bool) -> Void, selectAppIcon: @escaping (PresentationAppIcon) -> Void, editTheme: @escaping (PresentationCloudTheme) -> Void, themeContextAction: @escaping (Bool, PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void, colorContextAction: @escaping (Bool, PresentationThemeReference, ThemeSettingsColorOption?, ASDisplayNode, ContextGesture?) -> Void) {
|
||||
self.context = context
|
||||
self.selectTheme = selectTheme
|
||||
self.openThemeSettings = openThemeSettings
|
||||
@@ -74,6 +75,7 @@ private final class ThemeSettingsControllerArguments {
|
||||
self.openAutoNightTheme = openAutoNightTheme
|
||||
self.openTextSize = openTextSize
|
||||
self.openBubbleSettings = openBubbleSettings
|
||||
self.openPowerSavingSettings = openPowerSavingSettings
|
||||
self.toggleLargeEmoji = toggleLargeEmoji
|
||||
self.disableAnimations = disableAnimations
|
||||
self.selectAppIcon = selectAppIcon
|
||||
@@ -88,6 +90,7 @@ private enum ThemeSettingsControllerSection: Int32 {
|
||||
case nightMode
|
||||
case message
|
||||
case icon
|
||||
case powerSaving
|
||||
case other
|
||||
}
|
||||
|
||||
@@ -97,6 +100,7 @@ public enum ThemeSettingsEntryTag: ItemListItemTag {
|
||||
case tint
|
||||
case accentColor
|
||||
case icon
|
||||
case powerSaving
|
||||
case largeEmoji
|
||||
case animations
|
||||
|
||||
@@ -121,6 +125,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
case bubbleSettings(PresentationTheme, String, String)
|
||||
case iconHeader(PresentationTheme, String)
|
||||
case iconItem(PresentationTheme, PresentationStrings, [PresentationAppIcon], Bool, String?)
|
||||
case powerSaving
|
||||
case otherHeader(PresentationTheme, String)
|
||||
case largeEmoji(PresentationTheme, String, Bool)
|
||||
case animations(PresentationTheme, String, Bool)
|
||||
@@ -136,6 +141,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
return ThemeSettingsControllerSection.message.rawValue
|
||||
case .iconHeader, .iconItem:
|
||||
return ThemeSettingsControllerSection.icon.rawValue
|
||||
case .powerSaving:
|
||||
return ThemeSettingsControllerSection.powerSaving.rawValue
|
||||
case .otherHeader, .largeEmoji, .animations, .animationsInfo:
|
||||
return ThemeSettingsControllerSection.other.rawValue
|
||||
}
|
||||
@@ -165,14 +172,16 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
return 9
|
||||
case .iconItem:
|
||||
return 10
|
||||
case .otherHeader:
|
||||
case .powerSaving:
|
||||
return 11
|
||||
case .largeEmoji:
|
||||
case .otherHeader:
|
||||
return 12
|
||||
case .animations:
|
||||
case .largeEmoji:
|
||||
return 13
|
||||
case .animationsInfo:
|
||||
case .animations:
|
||||
return 14
|
||||
case .animationsInfo:
|
||||
return 15
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,6 +253,12 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .powerSaving:
|
||||
if case .powerSaving = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .otherHeader(lhsTheme, lhsText):
|
||||
if case let .otherHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||
return true
|
||||
@@ -318,6 +333,11 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
return ThemeSettingsAppIconItem(theme: theme, strings: strings, sectionId: self.section, icons: icons, isPremium: isPremium, currentIconName: value, updated: { icon in
|
||||
arguments.selectAppIcon(icon)
|
||||
})
|
||||
case .powerSaving:
|
||||
//TODO:localize
|
||||
return ItemListDisclosureItem(presentationData: presentationData, icon: nil, title: "Power Saving", label: "", labelStyle: .text, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
arguments.openPowerSavingSettings()
|
||||
})
|
||||
case let .otherHeader(_, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .largeEmoji(_, title, value):
|
||||
@@ -382,6 +402,8 @@ private func themeSettingsControllerEntries(presentationData: PresentationData,
|
||||
entries.append(.iconItem(presentationData.theme, presentationData.strings, availableAppIcons, isPremium, currentAppIconName))
|
||||
}
|
||||
|
||||
entries.append(.powerSaving)
|
||||
|
||||
entries.append(.otherHeader(presentationData.theme, strings.Appearance_Other.uppercased()))
|
||||
entries.append(.largeEmoji(presentationData.theme, strings.Appearance_LargeEmoji, presentationData.largeEmoji))
|
||||
entries.append(.animations(presentationData.theme, strings.Appearance_ReduceMotion, presentationData.reduceMotion))
|
||||
@@ -492,6 +514,8 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
let settings = view.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings]?.get(PresentationThemeSettings.self) ?? PresentationThemeSettings.defaultSettings
|
||||
pushControllerImpl?(BubbleSettingsController(context: context, presentationThemeSettings: settings))
|
||||
})
|
||||
}, openPowerSavingSettings: {
|
||||
pushControllerImpl?(energySavingSettingsScreen(context: context))
|
||||
}, toggleLargeEmoji: { largeEmoji in
|
||||
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
return current.withUpdatedLargeEmoji(largeEmoji)
|
||||
|
||||
@@ -260,6 +260,9 @@ public struct MediaAutoSaveSettings: Codable, Equatable {
|
||||
|
||||
public struct EnergyUsageSettings: Codable, Equatable {
|
||||
private enum CodingKeys: CodingKey {
|
||||
case autoplayVideo
|
||||
case autoplayGif
|
||||
case loopStickers
|
||||
case loopEmoji
|
||||
case playVideoAvatars
|
||||
case fullTranslucency
|
||||
@@ -270,6 +273,9 @@ public struct EnergyUsageSettings: Codable, Equatable {
|
||||
|
||||
public static var `default`: EnergyUsageSettings {
|
||||
return EnergyUsageSettings(
|
||||
autoplayVideo: true,
|
||||
autoplayGif: true,
|
||||
loopStickers: true,
|
||||
loopEmoji: true,
|
||||
playVideoAvatars: true,
|
||||
fullTranslucency: true,
|
||||
@@ -279,6 +285,9 @@ public struct EnergyUsageSettings: Codable, Equatable {
|
||||
)
|
||||
}
|
||||
|
||||
public var autoplayVideo: Bool
|
||||
public var autoplayGif: Bool
|
||||
public var loopStickers: Bool
|
||||
public var loopEmoji: Bool
|
||||
public var playVideoAvatars: Bool
|
||||
public var fullTranslucency: Bool
|
||||
@@ -287,6 +296,9 @@ public struct EnergyUsageSettings: Codable, Equatable {
|
||||
public var autodownloadInBackground: Bool
|
||||
|
||||
public init(
|
||||
autoplayVideo: Bool,
|
||||
autoplayGif: Bool,
|
||||
loopStickers: Bool,
|
||||
loopEmoji: Bool,
|
||||
playVideoAvatars: Bool,
|
||||
fullTranslucency: Bool,
|
||||
@@ -294,6 +306,9 @@ public struct EnergyUsageSettings: Codable, Equatable {
|
||||
synchronizeInBackground: Bool,
|
||||
autodownloadInBackground: Bool
|
||||
) {
|
||||
self.autoplayVideo = autoplayVideo
|
||||
self.autoplayGif = autoplayGif
|
||||
self.loopStickers = loopStickers
|
||||
self.loopEmoji = loopEmoji
|
||||
self.playVideoAvatars = playVideoAvatars
|
||||
self.fullTranslucency = fullTranslucency
|
||||
@@ -305,6 +320,9 @@ public struct EnergyUsageSettings: Codable, Equatable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.autoplayVideo = try container.decodeIfPresent(Bool.self, forKey: .autoplayVideo) ?? EnergyUsageSettings.default.autoplayVideo
|
||||
self.autoplayGif = try container.decodeIfPresent(Bool.self, forKey: .autoplayGif) ?? EnergyUsageSettings.default.autoplayGif
|
||||
self.loopStickers = try container.decodeIfPresent(Bool.self, forKey: .loopStickers) ?? EnergyUsageSettings.default.loopStickers
|
||||
self.loopEmoji = try container.decodeIfPresent(Bool.self, forKey: .loopEmoji) ?? EnergyUsageSettings.default.loopEmoji
|
||||
self.playVideoAvatars = try container.decodeIfPresent(Bool.self, forKey: .playVideoAvatars) ?? EnergyUsageSettings.default.playVideoAvatars
|
||||
self.fullTranslucency = try container.decodeIfPresent(Bool.self, forKey: .fullTranslucency) ?? EnergyUsageSettings.default.fullTranslucency
|
||||
@@ -316,7 +334,10 @@ public struct EnergyUsageSettings: Codable, Equatable {
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(self.autoplayVideo, forKey: .autoplayVideo)
|
||||
try container.encode(self.autoplayGif, forKey: .autoplayGif)
|
||||
try container.encode(self.loopEmoji, forKey: .loopEmoji)
|
||||
try container.encode(self.loopStickers, forKey: .loopStickers)
|
||||
try container.encode(self.playVideoAvatars, forKey: .playVideoAvatars)
|
||||
try container.encode(self.fullTranslucency, forKey: .fullTranslucency)
|
||||
try container.encode(self.extendBackgroundWork, forKey: .extendBackgroundWork)
|
||||
|
||||
Reference in New Issue
Block a user