Swiftgram/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift
Ilya Laktyushin efacf13a9e Update themes
2019-12-23 15:13:21 +03:00

692 lines
31 KiB
Swift

import Foundation
import Postbox
import TelegramCore
import SyncCore
import SwiftSignalKit
import Display
public enum PresentationBuiltinThemeReference: Int32 {
case dayClassic = 0
case night = 1
case day = 2
case nightAccent = 3
public init(baseTheme: TelegramBaseTheme) {
switch baseTheme {
case .classic:
self = .dayClassic
case .day:
self = .day
case .night:
self = .night
case .tinted:
self = .nightAccent
}
}
public var baseTheme: TelegramBaseTheme {
switch self {
case .dayClassic:
return .classic
case .day:
return .day
case .night:
return .night
case .nightAccent:
return .tinted
}
}
}
public struct WallpaperPresentationOptions: OptionSet {
public var rawValue: Int32
public init(rawValue: Int32) {
self.rawValue = rawValue
}
public init() {
self.rawValue = 0
}
public static let motion = WallpaperPresentationOptions(rawValue: 1 << 0)
public static let blur = WallpaperPresentationOptions(rawValue: 1 << 1)
}
public struct PresentationLocalTheme: PostboxCoding, Equatable {
public let title: String
public let resource: LocalFileMediaResource
public let resolvedWallpaper: TelegramWallpaper?
public init(title: String, resource: LocalFileMediaResource, resolvedWallpaper: TelegramWallpaper?) {
self.title = title
self.resource = resource
self.resolvedWallpaper = resolvedWallpaper
}
public init(decoder: PostboxDecoder) {
self.title = decoder.decodeStringForKey("title", orElse: "")
self.resource = decoder.decodeObjectForKey("resource", decoder: { LocalFileMediaResource(decoder: $0) }) as! LocalFileMediaResource
self.resolvedWallpaper = decoder.decodeObjectForKey("wallpaper", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeString(self.title, forKey: "title")
encoder.encodeObject(self.resource, forKey: "resource")
if let resolvedWallpaper = self.resolvedWallpaper {
encoder.encodeObject(resolvedWallpaper, forKey: "wallpaper")
} else {
encoder.encodeNil(forKey: "wallpaper")
}
}
public static func ==(lhs: PresentationLocalTheme, rhs: PresentationLocalTheme) -> Bool {
if lhs.title != rhs.title {
return false
}
if !lhs.resource.isEqual(to: rhs.resource) {
return false
}
if lhs.resolvedWallpaper != rhs.resolvedWallpaper {
return false
}
return true
}
}
public struct PresentationCloudTheme: PostboxCoding, Equatable {
public let theme: TelegramTheme
public let resolvedWallpaper: TelegramWallpaper?
public init(theme: TelegramTheme, resolvedWallpaper: TelegramWallpaper?) {
self.theme = theme
self.resolvedWallpaper = resolvedWallpaper
}
public init(decoder: PostboxDecoder) {
self.theme = decoder.decodeObjectForKey("theme", decoder: { TelegramTheme(decoder: $0) }) as! TelegramTheme
self.resolvedWallpaper = decoder.decodeObjectForKey("wallpaper", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(self.theme, forKey: "theme")
if let resolvedWallpaper = self.resolvedWallpaper {
encoder.encodeObject(resolvedWallpaper, forKey: "wallpaper")
} else {
encoder.encodeNil(forKey: "wallpaper")
}
}
public static func ==(lhs: PresentationCloudTheme, rhs: PresentationCloudTheme) -> Bool {
if lhs.theme != rhs.theme {
return false
}
if lhs.resolvedWallpaper != rhs.resolvedWallpaper {
return false
}
return true
}
}
public enum PresentationThemeReference: PostboxCoding, Equatable {
case builtin(PresentationBuiltinThemeReference)
case local(PresentationLocalTheme)
case cloud(PresentationCloudTheme)
public init(decoder: PostboxDecoder) {
switch decoder.decodeInt32ForKey("v", orElse: 0) {
case 0:
self = .builtin(PresentationBuiltinThemeReference(rawValue: decoder.decodeInt32ForKey("t", orElse: 0))!)
case 1:
if let localTheme = decoder.decodeObjectForKey("localTheme", decoder: { PresentationLocalTheme(decoder: $0) }) as? PresentationLocalTheme {
self = .local(localTheme)
} else {
self = .builtin(.dayClassic)
}
case 2:
if let cloudTheme = decoder.decodeObjectForKey("cloudTheme", decoder: { PresentationCloudTheme(decoder: $0) }) as? PresentationCloudTheme {
self = .cloud(cloudTheme)
} else {
self = .builtin(.dayClassic)
}
default:
assertionFailure()
self = .builtin(.dayClassic)
}
}
public func encode(_ encoder: PostboxEncoder) {
switch self {
case let .builtin(reference):
encoder.encodeInt32(0, forKey: "v")
encoder.encodeInt32(reference.rawValue, forKey: "t")
case let .local(theme):
encoder.encodeInt32(1, forKey: "v")
encoder.encodeObject(theme, forKey: "localTheme")
case let .cloud(theme):
encoder.encodeInt32(2, forKey: "v")
encoder.encodeObject(theme, forKey: "cloudTheme")
}
}
public static func ==(lhs: PresentationThemeReference, rhs: PresentationThemeReference) -> Bool {
switch lhs {
case let .builtin(reference):
if case .builtin(reference) = rhs {
return true
} else {
return false
}
case let .local(lhsTheme):
if case let .local(rhsTheme) = rhs, lhsTheme == rhsTheme {
return true
} else {
return false
}
case let .cloud(lhsTheme):
if case let .cloud(rhsTheme) = rhs, lhsTheme == rhsTheme {
return true
} else {
return false
}
}
}
public var index: Int64 {
let namespace: Int32
let id: Int32
func themeId(for id: Int64) -> Int32 {
var acc: UInt32 = 0
let low = UInt32(UInt64(bitPattern: id) & (0xffffffff as UInt64))
let high = UInt32((UInt64(bitPattern: id) >> 32) & (0xffffffff as UInt64))
acc = (acc &* 20261) &+ high
acc = (acc &* 20261) &+ low
return Int32(bitPattern: acc & UInt32(0x7fffffff))
}
switch self {
case let .builtin(reference):
namespace = 0
id = reference.rawValue
case let .local(theme):
namespace = 1
id = themeId(for: theme.resource.fileId)
case let .cloud(theme):
namespace = 2
id = themeId(for: theme.theme.id)
}
return (Int64(namespace) << 32) | Int64(bitPattern: UInt64(UInt32(bitPattern: id)))
}
}
public func coloredThemeIndex(reference: PresentationThemeReference, accentColor: PresentationThemeAccentColor?) -> Int64 {
if let accentColor = accentColor {
if case let .builtin(theme) = reference {
return reference.index * 1000 &+ Int64(accentColor.index)
} else {
return reference.index &+ Int64(accentColor.index)
}
} else {
return reference.index
}
}
public enum PresentationFontSize: Int32, CaseIterable {
case extraSmall = 0
case small = 1
case regular = 2
case large = 3
case extraLarge = 4
case extraLargeX2 = 5
case medium = 6
}
public enum AutomaticThemeSwitchTimeBasedSetting: PostboxCoding, Equatable {
case manual(fromSeconds: Int32, toSeconds: Int32)
case automatic(latitude: Double, longitude: Double, localizedName: String)
public init(decoder: PostboxDecoder) {
switch decoder.decodeInt32ForKey("_t", orElse: 0) {
case 0:
self = .manual(fromSeconds: decoder.decodeInt32ForKey("fromSeconds", orElse: 0), toSeconds: decoder.decodeInt32ForKey("toSeconds", orElse: 0))
case 1:
self = .automatic(latitude: decoder.decodeDoubleForKey("latitude", orElse: 0.0), longitude: decoder.decodeDoubleForKey("longitude", orElse: 0.0), localizedName: decoder.decodeStringForKey("localizedName", orElse: ""))
default:
assertionFailure()
self = .manual(fromSeconds: 0, toSeconds: 1)
}
}
public func encode(_ encoder: PostboxEncoder) {
switch self {
case let .manual(fromSeconds, toSeconds):
encoder.encodeInt32(0, forKey: "_t")
encoder.encodeInt32(fromSeconds, forKey: "fromSeconds")
encoder.encodeInt32(toSeconds, forKey: "toSeconds")
case let .automatic(latitude, longitude, localizedName):
encoder.encodeInt32(1, forKey: "_t")
encoder.encodeDouble(latitude, forKey: "latitude")
encoder.encodeDouble(longitude, forKey: "longitude")
encoder.encodeString(localizedName, forKey: "localizedName")
}
}
}
public enum AutomaticThemeSwitchTrigger: PostboxCoding, Equatable {
case system
case explicitNone
case timeBased(setting: AutomaticThemeSwitchTimeBasedSetting)
case brightness(threshold: Double)
public init(decoder: PostboxDecoder) {
switch decoder.decodeInt32ForKey("_t", orElse: 0) {
case 0:
self = .system
case 1:
self = .timeBased(setting: decoder.decodeObjectForKey("setting", decoder: { AutomaticThemeSwitchTimeBasedSetting(decoder: $0) }) as! AutomaticThemeSwitchTimeBasedSetting)
case 2:
self = .brightness(threshold: decoder.decodeDoubleForKey("threshold", orElse: 0.2))
case 3:
self = .explicitNone
default:
assertionFailure()
self = .system
}
}
public func encode(_ encoder: PostboxEncoder) {
switch self {
case .system:
encoder.encodeInt32(0, forKey: "_t")
case let .timeBased(setting):
encoder.encodeInt32(1, forKey: "_t")
encoder.encodeObject(setting, forKey: "setting")
case let .brightness(threshold):
encoder.encodeInt32(2, forKey: "_t")
encoder.encodeDouble(threshold, forKey: "threshold")
case .explicitNone:
encoder.encodeInt32(3, forKey: "_t")
}
}
}
public struct AutomaticThemeSwitchSetting: PostboxCoding, Equatable {
public var trigger: AutomaticThemeSwitchTrigger
public var theme: PresentationThemeReference
public init(trigger: AutomaticThemeSwitchTrigger, theme: PresentationThemeReference) {
self.trigger = trigger
self.theme = theme
}
public init(decoder: PostboxDecoder) {
self.trigger = decoder.decodeObjectForKey("trigger", decoder: { AutomaticThemeSwitchTrigger(decoder: $0) }) as! AutomaticThemeSwitchTrigger
if let theme = decoder.decodeObjectForKey("theme_v2", decoder: { PresentationThemeReference(decoder: $0) }) as? PresentationThemeReference {
self.theme = theme
} else if let legacyValue = decoder.decodeOptionalInt32ForKey("theme") {
self.theme = .builtin(PresentationBuiltinThemeReference(rawValue: legacyValue) ?? .nightAccent)
} else {
self.theme = .builtin(.nightAccent)
}
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(self.trigger, forKey: "trigger")
encoder.encodeObject(self.theme, forKey: "theme_v2")
}
}
public enum PresentationThemeBaseColor: Int32, CaseIterable {
case blue
case cyan
case green
case pink
case orange
case purple
case red
case yellow
case gray
case black
case white
case custom
case preset
public var color: UIColor {
let value: UInt32
switch self {
case .blue:
value = 0x007aff
case .cyan:
value = 0x00c2ed
case .green:
value = 0x29b327
case .pink:
value = 0xeb6ca4
case .orange:
value = 0xf08200
case .purple:
value = 0x9472ee
case .red:
value = 0xd33213
case .yellow:
value = 0xedb400
case .gray:
value = 0x6d839e
case .black:
value = 0x000000
case .white:
value = 0xffffff
case .custom, .preset:
return .clear
}
return UIColor(rgb: value)
}
}
public struct PresentationThemeCustomColors: PostboxCoding, Equatable {
public static func == (lhs: PresentationThemeCustomColors, rhs: PresentationThemeCustomColors) -> Bool {
return lhs.colors == rhs.colors
}
public let colors: [PresentationThemeAccentColor]
public init(colors: [PresentationThemeAccentColor]) {
self.colors = colors
}
public init(decoder: PostboxDecoder) {
if let colors = try? decoder.decodeObjectArrayWithCustomDecoderForKey("v", decoder: { decoder in
return PresentationThemeAccentColor(decoder: decoder)
}) {
self.colors = colors
} else {
self.colors = []
}
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObjectArray(self.colors, forKey: "v")
}
}
public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
public static func == (lhs: PresentationThemeAccentColor, rhs: PresentationThemeAccentColor) -> Bool {
return lhs.index == rhs.index && lhs.baseColor == rhs.baseColor && lhs.accentColor == rhs.accentColor && lhs.bubbleColors?.0 == rhs.bubbleColors?.0 && lhs.bubbleColors?.1 == rhs.bubbleColors?.1
}
public var index: Int32
public var baseColor: PresentationThemeBaseColor
public var accentColor: Int32?
public var bubbleColors: (Int32, Int32?)?
public var wallpaper: TelegramWallpaper?
public init(baseColor: PresentationThemeBaseColor) {
if baseColor != .preset && baseColor != .custom {
self.index = baseColor.rawValue + 10
} else {
self.index = -1
}
self.baseColor = baseColor
self.accentColor = nil
self.bubbleColors = nil
self.wallpaper = nil
}
public init(index: Int32, baseColor: PresentationThemeBaseColor, accentColor: Int32? = nil, bubbleColors: (Int32, Int32?)? = nil, wallpaper: TelegramWallpaper? = nil) {
self.index = index
self.baseColor = baseColor
self.accentColor = accentColor
self.bubbleColors = bubbleColors
self.wallpaper = wallpaper
}
public init(decoder: PostboxDecoder) {
self.index = decoder.decodeInt32ForKey("i", orElse: -1)
self.baseColor = PresentationThemeBaseColor(rawValue: decoder.decodeInt32ForKey("b", orElse: 0)) ?? .blue
self.accentColor = decoder.decodeOptionalInt32ForKey("c")
if let bubbleTopColor = decoder.decodeOptionalInt32ForKey("bt") {
if let bubbleBottomColor = decoder.decodeOptionalInt32ForKey("bb") {
self.bubbleColors = (bubbleTopColor, bubbleBottomColor)
} else {
self.bubbleColors = (bubbleTopColor, nil)
}
} else {
self.bubbleColors = nil
}
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.index, forKey: "i")
encoder.encodeInt32(self.baseColor.rawValue, forKey: "b")
if let value = self.accentColor {
encoder.encodeInt32(value, forKey: "c")
} else {
encoder.encodeNil(forKey: "c")
}
if let bubbleColors = self.bubbleColors {
encoder.encodeInt32(bubbleColors.0, forKey: "bt")
if let bubbleBottomColor = bubbleColors.1 {
encoder.encodeInt32(bubbleBottomColor, forKey: "bb")
} else {
encoder.encodeNil(forKey: "bb")
}
} else {
encoder.encodeNil(forKey: "bt")
encoder.encodeNil(forKey: "bb")
}
}
public var color: UIColor {
if let value = self.accentColor {
return UIColor(rgb: UInt32(bitPattern: value))
} else {
return self.baseColor.color
}
}
public var customBubbleColors: (UIColor, UIColor?)? {
if let bubbleColors = self.bubbleColors {
if let bottomColor = bubbleColors.1 {
return (UIColor(rgb: UInt32(bitPattern: bubbleColors.0)), UIColor(rgb: UInt32(bitPattern: bottomColor)))
} else {
return (UIColor(rgb: UInt32(bitPattern: bubbleColors.0)), nil)
}
} else {
return nil
}
}
public var plainBubbleColors: (UIColor, UIColor)? {
if let bubbleColors = self.bubbleColors {
if let bottomColor = bubbleColors.1 {
return (UIColor(rgb: UInt32(bitPattern: bubbleColors.0)), UIColor(rgb: UInt32(bitPattern: bottomColor)))
} else {
return (UIColor(rgb: UInt32(bitPattern: bubbleColors.0)), UIColor(rgb: UInt32(bitPattern: bubbleColors.0)))
}
} else {
return nil
}
}
}
public struct PresentationThemeSettings: PreferencesEntry {
public var theme: PresentationThemeReference
public var themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
public var themeSpecificCustomColors: [Int64: PresentationThemeCustomColors]
public var themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
public var useSystemFont: Bool
public var fontSize: PresentationFontSize
public var automaticThemeSwitchSetting: AutomaticThemeSwitchSetting
public var largeEmoji: Bool
public var disableAnimations: Bool
private func wallpaperResources(_ wallpaper: TelegramWallpaper) -> [MediaResourceId] {
switch wallpaper {
case let .image(representations, _):
return representations.map { $0.resource.id }
case let .file(_, _, _, _, _, _, _, file, _):
var resources: [MediaResourceId] = []
resources.append(file.resource.id)
resources.append(contentsOf: file.previewRepresentations.map { $0.resource.id })
return resources
default:
return []
}
}
public var relatedResources: [MediaResourceId] {
var resources: [MediaResourceId] = []
for (_, chatWallpaper) in self.themeSpecificChatWallpapers {
resources.append(contentsOf: wallpaperResources(chatWallpaper))
}
switch self.theme {
case .builtin:
break
case let .local(theme):
resources.append(theme.resource.id)
case let .cloud(theme):
if let file = theme.theme.file {
resources.append(file.resource.id)
}
if let chatWallpaper = theme.resolvedWallpaper {
resources.append(contentsOf: wallpaperResources(chatWallpaper))
}
}
for (_, colors) in self.themeSpecificCustomColors {
for color in colors.colors {
if let wallpaper = color.wallpaper {
resources.append(contentsOf: wallpaperResources(wallpaper))
}
}
}
return resources
}
public static var defaultSettings: PresentationThemeSettings {
return PresentationThemeSettings(theme: .builtin(.dayClassic), themeSpecificAccentColors: [:], themeSpecificCustomColors: [:], themeSpecificChatWallpapers: [:], useSystemFont: true, fontSize: .regular, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting(trigger: .system, theme: .builtin(.night)), largeEmoji: true, disableAnimations: true)
}
public init(theme: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificCustomColors: [Int64: PresentationThemeCustomColors], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], useSystemFont: Bool, fontSize: PresentationFontSize, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting, largeEmoji: Bool, disableAnimations: Bool) {
self.theme = theme
self.themeSpecificAccentColors = themeSpecificAccentColors
self.themeSpecificCustomColors = themeSpecificCustomColors
self.themeSpecificChatWallpapers = themeSpecificChatWallpapers
self.useSystemFont = useSystemFont
self.fontSize = fontSize
self.automaticThemeSwitchSetting = automaticThemeSwitchSetting
self.largeEmoji = largeEmoji
self.disableAnimations = disableAnimations
}
public init(decoder: PostboxDecoder) {
self.theme = decoder.decodeObjectForKey("t", decoder: { PresentationThemeReference(decoder: $0) }) as? PresentationThemeReference ?? .builtin(.dayClassic)
self.themeSpecificChatWallpapers = decoder.decodeObjectDictionaryForKey("themeSpecificChatWallpapers", keyDecoder: { decoder in
return decoder.decodeInt64ForKey("k", orElse: 0)
}, valueDecoder: { decoder in
return TelegramWallpaper(decoder: decoder)
})
self.themeSpecificCustomColors = decoder.decodeObjectDictionaryForKey("themeSpecificCustomColors", keyDecoder: { decoder in
return decoder.decodeInt64ForKey("k", orElse: 0)
}, valueDecoder: { decoder in
return PresentationThemeCustomColors(decoder: decoder)
})
self.themeSpecificAccentColors = decoder.decodeObjectDictionaryForKey("themeSpecificAccentColors", keyDecoder: { decoder in
return decoder.decodeInt64ForKey("k", orElse: 0)
}, valueDecoder: { decoder in
return PresentationThemeAccentColor(decoder: decoder)
})
self.useSystemFont = decoder.decodeInt32ForKey("useSystemFont", orElse: 1) != 0
self.fontSize = PresentationFontSize(rawValue: decoder.decodeInt32ForKey("f", orElse: PresentationFontSize.regular.rawValue)) ?? .regular
self.automaticThemeSwitchSetting = (decoder.decodeObjectForKey("automaticThemeSwitchSetting", decoder: { AutomaticThemeSwitchSetting(decoder: $0) }) as? AutomaticThemeSwitchSetting) ?? AutomaticThemeSwitchSetting(trigger: .system, theme: .builtin(.night))
self.largeEmoji = decoder.decodeBoolForKey("largeEmoji", orElse: true)
self.disableAnimations = decoder.decodeBoolForKey("disableAnimations", orElse: true)
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(self.theme, forKey: "t")
encoder.encodeObjectDictionary(self.themeSpecificAccentColors, forKey: "themeSpecificAccentColors", keyEncoder: { key, encoder in
encoder.encodeInt64(key, forKey: "k")
})
encoder.encodeObjectDictionary(self.themeSpecificCustomColors, forKey: "themeSpecificCustomColors", keyEncoder: { key, encoder in
encoder.encodeInt64(key, forKey: "k")
})
encoder.encodeObjectDictionary(self.themeSpecificChatWallpapers, forKey: "themeSpecificChatWallpapers", keyEncoder: { key, encoder in
encoder.encodeInt64(key, forKey: "k")
})
encoder.encodeInt32(self.useSystemFont ? 1 : 0, forKey: "useSystemFont")
encoder.encodeInt32(self.fontSize.rawValue, forKey: "f")
encoder.encodeObject(self.automaticThemeSwitchSetting, forKey: "automaticThemeSwitchSetting")
encoder.encodeBool(self.largeEmoji, forKey: "largeEmoji")
encoder.encodeBool(self.disableAnimations, forKey: "disableAnimations")
}
public func isEqual(to: PreferencesEntry) -> Bool {
if let to = to as? PresentationThemeSettings {
return self == to
} else {
return false
}
}
public static func ==(lhs: PresentationThemeSettings, rhs: PresentationThemeSettings) -> Bool {
return lhs.theme == rhs.theme && lhs.themeSpecificAccentColors == rhs.themeSpecificAccentColors && lhs.themeSpecificCustomColors == rhs.themeSpecificCustomColors && lhs.themeSpecificChatWallpapers == rhs.themeSpecificChatWallpapers && lhs.useSystemFont == rhs.useSystemFont && lhs.fontSize == rhs.fontSize && lhs.automaticThemeSwitchSetting == rhs.automaticThemeSwitchSetting && lhs.largeEmoji == rhs.largeEmoji && lhs.disableAnimations == rhs.disableAnimations
}
public func withUpdatedTheme(_ theme: PresentationThemeReference) -> PresentationThemeSettings {
return PresentationThemeSettings(theme: theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations)
}
public func withUpdatedThemeSpecificAccentColors(_ themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]) -> PresentationThemeSettings {
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations)
}
public func withUpdatedThemeSpecificCustomColors(_ themeSpecificCustomColors: [Int64: PresentationThemeCustomColors]) -> PresentationThemeSettings {
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations)
}
public func withUpdatedThemeSpecificChatWallpapers(_ themeSpecificChatWallpapers: [Int64: TelegramWallpaper]) -> PresentationThemeSettings {
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations)
}
public func withUpdatedUseSystemFont(_ useSystemFont: Bool) -> PresentationThemeSettings {
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations)
}
public func withUpdatedFontSize(_ fontSize: PresentationFontSize) -> PresentationThemeSettings {
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations)
}
public func withUpdatedAutomaticThemeSwitchSetting(_ automaticThemeSwitchSetting: AutomaticThemeSwitchSetting) -> PresentationThemeSettings {
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations)
}
public func withUpdatedLargeEmoji(_ largeEmoji: Bool) -> PresentationThemeSettings {
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: largeEmoji, disableAnimations: self.disableAnimations)
}
public func withUpdatedDisableAnimations(_ disableAnimations: Bool) -> PresentationThemeSettings {
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: self.themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: disableAnimations)
}
}
public func updatePresentationThemeSettingsInteractively(accountManager: AccountManager, _ f: @escaping (PresentationThemeSettings) -> PresentationThemeSettings) -> Signal<Void, NoError> {
return accountManager.transaction { transaction -> Void in
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.presentationThemeSettings, { entry in
let currentSettings: PresentationThemeSettings
if let entry = entry as? PresentationThemeSettings {
currentSettings = entry
} else {
currentSettings = PresentationThemeSettings.defaultSettings
}
return f(currentSettings)
})
}
}