mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
554 lines
22 KiB
Swift
554 lines
22 KiB
Swift
import Foundation
|
|
import Postbox
|
|
import TelegramCore
|
|
import SwiftSignalKit
|
|
import Display
|
|
|
|
public enum PresentationBuiltinThemeReference: Int32 {
|
|
case dayClassic = 0
|
|
case night = 1
|
|
case day = 2
|
|
case nightAccent = 3
|
|
}
|
|
|
|
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 enum PresentationFontSize: Int32 {
|
|
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 none
|
|
case timeBased(setting: AutomaticThemeSwitchTimeBasedSetting)
|
|
case brightness(threshold: Double)
|
|
|
|
public init(decoder: PostboxDecoder) {
|
|
switch decoder.decodeInt32ForKey("_t", orElse: 0) {
|
|
case 0:
|
|
self = .none
|
|
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))
|
|
default:
|
|
assertionFailure()
|
|
self = .none
|
|
}
|
|
}
|
|
|
|
public func encode(_ encoder: PostboxEncoder) {
|
|
switch self {
|
|
case .none:
|
|
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")
|
|
}
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
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:
|
|
return .clear
|
|
}
|
|
return UIColor(rgb: value)
|
|
}
|
|
|
|
public var outgoingGradientColors: (UIColor, UIColor) {
|
|
switch self {
|
|
case .blue:
|
|
return (UIColor(rgb: 0x63BFFB), UIColor(rgb: 0x007AFF))
|
|
case .cyan:
|
|
return (UIColor(rgb: 0x5CE0E9), UIColor(rgb: 0x00C2ED))
|
|
case .green:
|
|
return (UIColor(rgb: 0x93D374), UIColor(rgb: 0x29B327))
|
|
case .pink:
|
|
return (UIColor(rgb: 0xE296C1), UIColor(rgb: 0xEB6CA4))
|
|
case .orange:
|
|
return (UIColor(rgb: 0xF2A451), UIColor(rgb: 0xF08200))
|
|
case .purple:
|
|
return (UIColor(rgb: 0xAC98E6), UIColor(rgb: 0x9472EE))
|
|
case .red:
|
|
return (UIColor(rgb: 0xE06D54), UIColor(rgb: 0xD33213))
|
|
case .yellow:
|
|
return (UIColor(rgb: 0xF7DA6B), UIColor(rgb: 0xEDB400))
|
|
case .gray:
|
|
return (UIColor(rgb: 0x7D8E9A), UIColor(rgb: 0x6D839E))
|
|
case .black:
|
|
return (UIColor(rgb: 0x000000), UIColor(rgb: 0x000000))
|
|
case .white:
|
|
return (UIColor(rgb: 0xffffff), UIColor(rgb: 0xffffff))
|
|
case .custom:
|
|
return (UIColor(rgb: 0x000000), UIColor(rgb: 0x000000))
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
|
public var baseColor: PresentationThemeBaseColor
|
|
public var value: Int32?
|
|
|
|
public init(baseColor: PresentationThemeBaseColor, value: Int32? = nil) {
|
|
self.baseColor = baseColor
|
|
self.value = value
|
|
}
|
|
|
|
public init(decoder: PostboxDecoder) {
|
|
self.baseColor = PresentationThemeBaseColor(rawValue: decoder.decodeInt32ForKey("b", orElse: 0)) ?? .blue
|
|
self.value = decoder.decodeOptionalInt32ForKey("c")
|
|
}
|
|
|
|
public func encode(_ encoder: PostboxEncoder) {
|
|
encoder.encodeInt32(self.baseColor.rawValue, forKey: "b")
|
|
if let value = self.value {
|
|
encoder.encodeInt32(value, forKey: "c")
|
|
} else {
|
|
encoder.encodeNil(forKey: "c")
|
|
}
|
|
}
|
|
|
|
public var color: UIColor {
|
|
if let value = self.value {
|
|
return UIColor(rgb: UInt32(bitPattern: value))
|
|
} else {
|
|
return self.baseColor.color
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct PresentationThemeSettings: PreferencesEntry {
|
|
public var chatWallpaper: TelegramWallpaper
|
|
public var theme: PresentationThemeReference
|
|
public var themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
|
public var themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
|
|
public var fontSize: PresentationFontSize
|
|
public var automaticThemeSwitchSetting: AutomaticThemeSwitchSetting
|
|
public var largeEmoji: Bool
|
|
public var disableAnimations: Bool
|
|
|
|
private func wallpaperResources(_ wallpaper: TelegramWallpaper) -> [MediaResourceId] {
|
|
switch self.chatWallpaper {
|
|
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] = []
|
|
resources.append(contentsOf: wallpaperResources(self.chatWallpaper))
|
|
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))
|
|
}
|
|
}
|
|
return resources
|
|
}
|
|
|
|
public static var defaultSettings: PresentationThemeSettings {
|
|
return PresentationThemeSettings(chatWallpaper: .builtin(WallpaperSettings()), theme: .builtin(.dayClassic), themeSpecificAccentColors: [:], themeSpecificChatWallpapers: [:], fontSize: .regular, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting(trigger: .none, theme: .builtin(.nightAccent)), largeEmoji: true, disableAnimations: true)
|
|
}
|
|
|
|
public init(chatWallpaper: TelegramWallpaper, theme: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], fontSize: PresentationFontSize, automaticThemeSwitchSetting: AutomaticThemeSwitchSetting, largeEmoji: Bool, disableAnimations: Bool) {
|
|
self.chatWallpaper = chatWallpaper
|
|
self.theme = theme
|
|
self.themeSpecificAccentColors = themeSpecificAccentColors
|
|
self.themeSpecificChatWallpapers = themeSpecificChatWallpapers
|
|
self.fontSize = fontSize
|
|
self.automaticThemeSwitchSetting = automaticThemeSwitchSetting
|
|
self.largeEmoji = largeEmoji
|
|
self.disableAnimations = disableAnimations
|
|
}
|
|
|
|
public init(decoder: PostboxDecoder) {
|
|
self.chatWallpaper = (decoder.decodeObjectForKey("w", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper) ?? .builtin(WallpaperSettings())
|
|
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.themeSpecificAccentColors = decoder.decodeObjectDictionaryForKey("themeSpecificAccentColors", keyDecoder: { decoder in
|
|
return decoder.decodeInt64ForKey("k", orElse: 0)
|
|
}, valueDecoder: { decoder in
|
|
return PresentationThemeAccentColor(decoder: decoder)
|
|
})
|
|
|
|
if self.themeSpecificAccentColors[PresentationThemeReference.builtin(.day).index] == nil, let themeAccentColor = decoder.decodeOptionalInt32ForKey("themeAccentColor") {
|
|
let baseColor: PresentationThemeBaseColor
|
|
switch themeAccentColor {
|
|
case 0xf83b4c:
|
|
baseColor = .red
|
|
case 0xff7519:
|
|
baseColor = .orange
|
|
case 0xeba239:
|
|
baseColor = .yellow
|
|
case 0x29b327:
|
|
baseColor = .green
|
|
case 0x00c2ed:
|
|
baseColor = .cyan
|
|
case 0x007ee5:
|
|
baseColor = .blue
|
|
case 0x7748ff:
|
|
baseColor = .purple
|
|
case 0xff5da2:
|
|
baseColor = .pink
|
|
default:
|
|
baseColor = .blue
|
|
}
|
|
self.themeSpecificAccentColors[PresentationThemeReference.builtin(.day).index] = PresentationThemeAccentColor(baseColor: baseColor)
|
|
}
|
|
|
|
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: .none, theme: .builtin(.nightAccent))
|
|
self.largeEmoji = decoder.decodeBoolForKey("largeEmoji", orElse: true)
|
|
self.disableAnimations = decoder.decodeBoolForKey("disableAnimations", orElse: true)
|
|
}
|
|
|
|
public func encode(_ encoder: PostboxEncoder) {
|
|
encoder.encodeObject(self.chatWallpaper, forKey: "w")
|
|
encoder.encodeObject(self.theme, forKey: "t")
|
|
encoder.encodeObjectDictionary(self.themeSpecificAccentColors, forKey: "themeSpecificAccentColors", 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.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.chatWallpaper == rhs.chatWallpaper && lhs.theme == rhs.theme && lhs.themeSpecificAccentColors == rhs.themeSpecificAccentColors && lhs.themeSpecificChatWallpapers == rhs.themeSpecificChatWallpapers && lhs.fontSize == rhs.fontSize && lhs.automaticThemeSwitchSetting == rhs.automaticThemeSwitchSetting && lhs.largeEmoji == rhs.largeEmoji && lhs.disableAnimations == rhs.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)
|
|
})
|
|
}
|
|
}
|