mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 08:31:13 +00:00
Merge commit 'c6e520e5c17b229b44dca62b5894b77062988b79'
This commit is contained in:
commit
e7775a881a
@ -4,7 +4,7 @@ import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
|
||||
private let separatorHeight: CGFloat = 1.0 / UIScreen.main.scale
|
||||
private func tabBarItemImage(_ image: UIImage?, title: String, backgroundColor: UIColor, tintColor: UIColor, horizontal: Bool, imageMode: Bool) -> (UIImage, CGFloat) {
|
||||
private func tabBarItemImage(_ image: UIImage?, title: String, backgroundColor: UIColor, tintColor: UIColor, horizontal: Bool, imageMode: Bool, centered: Bool = false) -> (UIImage, CGFloat) {
|
||||
let font = horizontal ? Font.regular(13.0) : Font.medium(10.0)
|
||||
let titleSize = (title as NSString).boundingRect(with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin], attributes: [NSAttributedString.Key.font: font], context: nil).size
|
||||
|
||||
@ -25,10 +25,12 @@ private func tabBarItemImage(_ image: UIImage?, title: String, backgroundColor:
|
||||
let size: CGSize
|
||||
let contentWidth: CGFloat
|
||||
if horizontal {
|
||||
size = CGSize(width: max(1.0, ceil(titleSize.width) + horizontalSpacing + imageSize.width), height: 34.0)
|
||||
let width = max(1.0, centered ? imageSize.width : ceil(titleSize.width) + horizontalSpacing + imageSize.width)
|
||||
size = CGSize(width: width, height: 34.0)
|
||||
contentWidth = size.width
|
||||
} else {
|
||||
size = CGSize(width: max(1.0, max(ceil(titleSize.width), imageSize.width), 1.0), height: 45.0)
|
||||
let width = max(1.0, centered ? imageSize.width : max(ceil(titleSize.width), imageSize.width), 1.0)
|
||||
size = CGSize(width: width, height: 45.0)
|
||||
contentWidth = imageSize.width
|
||||
}
|
||||
|
||||
@ -53,7 +55,7 @@ private func tabBarItemImage(_ image: UIImage?, title: String, backgroundColor:
|
||||
}
|
||||
context.restoreGState()
|
||||
} else {
|
||||
let imageRect = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - imageSize.width) / 2.0), y: 0.0), size: imageSize)
|
||||
let imageRect = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - imageSize.width) / 2.0), y: centered ? floor((size.height - imageSize.height) / 2.0) : 0.0), size: imageSize)
|
||||
context.saveGState()
|
||||
context.translateBy(x: imageRect.midX, y: imageRect.midY)
|
||||
context.scaleBy(x: 1.0, y: -1.0)
|
||||
@ -215,6 +217,7 @@ class TabBarNode: ASDisplayNode {
|
||||
private var theme: TabBarControllerTheme
|
||||
private var validLayout: (CGSize, CGFloat, CGFloat, CGFloat)?
|
||||
private var horizontal: Bool = false
|
||||
private var centered: Bool = false
|
||||
|
||||
private var badgeImage: UIImage
|
||||
|
||||
@ -289,6 +292,8 @@ class TabBarNode: ASDisplayNode {
|
||||
node.badgeContainerNode.removeFromSupernode()
|
||||
}
|
||||
|
||||
self.centered = self.theme.tabBarTextColor == .clear
|
||||
|
||||
var tabBarNodeContainers: [TabBarNodeContainer] = []
|
||||
for i in 0 ..< self.tabBarItems.count {
|
||||
let item = self.tabBarItems[i]
|
||||
@ -304,15 +309,15 @@ class TabBarNode: ASDisplayNode {
|
||||
self?.updateNodeImage(i, layout: true)
|
||||
})
|
||||
if let selectedIndex = self.selectedIndex, selectedIndex == i {
|
||||
let (textImage, contentWidth) = tabBarItemImage(item.selectedImage, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarSelectedTextColor, horizontal: self.horizontal, imageMode: false)
|
||||
let (image, imageContentWidth) = tabBarItemImage(item.selectedImage, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarSelectedTextColor, horizontal: self.horizontal, imageMode: true)
|
||||
let (textImage, contentWidth) = tabBarItemImage(item.selectedImage, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarSelectedTextColor, horizontal: self.horizontal, imageMode: false, centered: self.centered)
|
||||
let (image, imageContentWidth) = tabBarItemImage(item.selectedImage, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarSelectedTextColor, horizontal: self.horizontal, imageMode: true, centered: self.centered)
|
||||
node.textImageNode.image = textImage
|
||||
node.imageNode.image = image
|
||||
node.accessibilityLabel = item.title
|
||||
node.contentWidth = max(contentWidth, imageContentWidth)
|
||||
} else {
|
||||
let (textImage, contentWidth) = tabBarItemImage(item.image, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarTextColor, horizontal: self.horizontal, imageMode: false)
|
||||
let (image, imageContentWidth) = tabBarItemImage(item.image, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarTextColor, horizontal: self.horizontal, imageMode: true)
|
||||
let (textImage, contentWidth) = tabBarItemImage(item.image, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarTextColor, horizontal: self.horizontal, imageMode: false, centered: self.centered)
|
||||
let (image, imageContentWidth) = tabBarItemImage(item.image, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarIconColor, horizontal: self.horizontal, imageMode: true, centered: self.centered)
|
||||
node.textImageNode.image = textImage
|
||||
node.accessibilityLabel = item.title
|
||||
node.imageNode.image = image
|
||||
@ -337,18 +342,20 @@ class TabBarNode: ASDisplayNode {
|
||||
let node = self.tabBarNodeContainers[index].imageNode
|
||||
let item = self.tabBarItems[index]
|
||||
|
||||
self.centered = self.theme.tabBarTextColor == .clear
|
||||
|
||||
let previousImageSize = node.imageNode.image?.size ?? CGSize()
|
||||
let previousTextImageSize = node.textImageNode.image?.size ?? CGSize()
|
||||
if let selectedIndex = self.selectedIndex, selectedIndex == index {
|
||||
let (textImage, contentWidth) = tabBarItemImage(item.selectedImage, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarSelectedTextColor, horizontal: self.horizontal, imageMode: false)
|
||||
let (image, imageContentWidth) = tabBarItemImage(item.selectedImage, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarSelectedIconColor, horizontal: self.horizontal, imageMode: true)
|
||||
let (textImage, contentWidth) = tabBarItemImage(item.selectedImage, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarSelectedTextColor, horizontal: self.horizontal, imageMode: false, centered: self.centered)
|
||||
let (image, imageContentWidth) = tabBarItemImage(item.selectedImage, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarSelectedIconColor, horizontal: self.horizontal, imageMode: true, centered: self.centered)
|
||||
node.textImageNode.image = textImage
|
||||
node.accessibilityLabel = item.title
|
||||
node.imageNode.image = image
|
||||
node.contentWidth = max(contentWidth, imageContentWidth)
|
||||
} else {
|
||||
let (textImage, contentWidth) = tabBarItemImage(item.image, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarTextColor, horizontal: self.horizontal, imageMode: false)
|
||||
let (image, imageContentWidth) = tabBarItemImage(item.image, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarIconColor, horizontal: self.horizontal, imageMode: true)
|
||||
let (textImage, contentWidth) = tabBarItemImage(item.image, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarTextColor, horizontal: self.horizontal, imageMode: false, centered: self.centered)
|
||||
let (image, imageContentWidth) = tabBarItemImage(item.image, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarIconColor, horizontal: self.horizontal, imageMode: true, centered: self.centered)
|
||||
node.textImageNode.image = textImage
|
||||
node.accessibilityLabel = item.title
|
||||
node.imageNode.image = image
|
||||
@ -433,10 +440,10 @@ class TabBarNode: ASDisplayNode {
|
||||
let backgroundSize = CGSize(width: hasSingleLetterValue ? 18.0 : max(18.0, badgeSize.width + 10.0 + 1.0), height: 18.0)
|
||||
let backgroundFrame: CGRect
|
||||
if horizontal {
|
||||
backgroundFrame = CGRect(origin: CGPoint(x: originX + 10.0, y: 2.0), size: backgroundSize)
|
||||
backgroundFrame = CGRect(origin: CGPoint(x: originX + 15.0, y: 3.0), size: backgroundSize)
|
||||
} else {
|
||||
let contentWidth = node.contentWidth ?? node.frame.width
|
||||
backgroundFrame = CGRect(origin: CGPoint(x: floor(originX + node.frame.width / 2.0) + contentWidth - backgroundSize.width - 5.0, y: 2.0), size: backgroundSize)
|
||||
backgroundFrame = CGRect(origin: CGPoint(x: floor(originX + node.frame.width / 2.0) + contentWidth - backgroundSize.width - 5.0, y: self.centered ? 9.0 : 2.0), size: backgroundSize)
|
||||
}
|
||||
transition.updateFrame(node: container.badgeContainerNode, frame: backgroundFrame)
|
||||
container.badgeBackgroundNode.frame = CGRect(origin: CGPoint(), size: backgroundFrame.size)
|
||||
|
@ -282,6 +282,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
||||
initialState = EditThemeControllerState(mode: mode, title: generateThemeName(accentColor: theme.rootController.navigationBar.buttonColor), slug: "", updatedTheme: nil, updating: false)
|
||||
previewThemePromise.set(.single(theme.withUpdated(name: "", defaultWallpaper: wallpaper)))
|
||||
case let .edit(info):
|
||||
settingsPromise.set(.single(info.theme.settings))
|
||||
if let file = info.theme.file, let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path)), let theme = makePresentationTheme(data: data, resolvedWallpaper: info.resolvedWallpaper) {
|
||||
if case let .file(file) = theme.chat.defaultWallpaper, file.id == 0 {
|
||||
previewThemePromise.set(cachedWallpaper(account: context.account, slug: file.slug, settings: file.settings)
|
||||
@ -295,7 +296,6 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
||||
} else {
|
||||
previewThemePromise.set(.single(theme.withUpdated(name: nil, defaultWallpaper: info.resolvedWallpaper)))
|
||||
}
|
||||
settingsPromise.set(.single(info.theme.settings))
|
||||
} else {
|
||||
previewThemePromise.set(.single(presentationData.theme.withUpdated(name: "", defaultWallpaper: presentationData.chatWallpaper)))
|
||||
|
||||
@ -320,7 +320,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
||||
let _ = (combineLatest(queue: Queue.mainQueue(), previewThemePromise.get(), settingsPromise.get())
|
||||
|> take(1)).start(next: { theme, previousSettings in
|
||||
var controllerDismissImpl: (() -> Void)?
|
||||
let controller = ThemeAccentColorController(context: context, mode: .edit(theme: theme, wallpaper: nil, defaultThemeReference: nil, create: false, completion: { updatedTheme, settings in
|
||||
let controller = ThemeAccentColorController(context: context, mode: .edit(theme: theme, wallpaper: nil, generalThemeReference: nil, defaultThemeReference: nil, create: false, completion: { updatedTheme, settings in
|
||||
updateState { current in
|
||||
var state = current
|
||||
previewThemePromise.set(.single(updatedTheme))
|
||||
@ -515,7 +515,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
||||
|
||||
return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
}) |> deliverOnMainQueue).start(completed: {
|
||||
if !hasCustomFile {
|
||||
saveThemeTemplateFile(state.title, themeResource, {
|
||||
@ -549,7 +549,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
||||
|
||||
return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
}) |> deliverOnMainQueue).start(completed: {
|
||||
if let themeResource = themeResource, !hasCustomFile {
|
||||
saveThemeTemplateFile(state.title, themeResource, {
|
||||
|
@ -17,13 +17,13 @@ private let randomBackgroundColors: [Int32] = [0x007aff, 0x00c2ed, 0x29b327, 0xe
|
||||
enum ThemeAccentColorControllerMode {
|
||||
case colors(themeReference: PresentationThemeReference, create: Bool)
|
||||
case background(themeReference: PresentationThemeReference)
|
||||
case edit(theme: PresentationTheme, wallpaper: TelegramWallpaper?, defaultThemeReference: PresentationThemeReference?, create: Bool, completion: (PresentationTheme, TelegramThemeSettings?) -> Void)
|
||||
case edit(theme: PresentationTheme, wallpaper: TelegramWallpaper?, generalThemeReference: PresentationThemeReference?, defaultThemeReference: PresentationThemeReference?, create: Bool, completion: (PresentationTheme, TelegramThemeSettings?) -> Void)
|
||||
|
||||
var themeReference: PresentationThemeReference? {
|
||||
switch self {
|
||||
case let .colors(themeReference, _), let .background(themeReference):
|
||||
return themeReference
|
||||
case let .edit(_, _, defaultThemeReference, _, _):
|
||||
case let .edit(_, _, _, defaultThemeReference, _, _):
|
||||
return defaultThemeReference
|
||||
default:
|
||||
return nil
|
||||
@ -119,7 +119,7 @@ final class ThemeAccentColorController: ViewController {
|
||||
|
||||
let theme: PresentationTheme
|
||||
let wallpaper: TelegramWallpaper
|
||||
if case let .edit(editedTheme, walpaper, _, _, _) = self.mode {
|
||||
if case let .edit(editedTheme, walpaper, _, _, _, _) = self.mode {
|
||||
theme = editedTheme
|
||||
wallpaper = walpaper ?? editedTheme.chat.defaultWallpaper
|
||||
} else {
|
||||
@ -178,28 +178,38 @@ final class ThemeAccentColorController: ViewController {
|
||||
prepare = .complete()
|
||||
}
|
||||
|
||||
if case let .edit(theme, _, themeReference, _, completion) = strongSelf.mode {
|
||||
if case let .edit(theme, _, generalThemeReference, themeReference, _, completion) = strongSelf.mode {
|
||||
let _ = (prepare
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
let updatedTheme: PresentationTheme
|
||||
|
||||
var settings: TelegramThemeSettings?
|
||||
var hasSettings = false
|
||||
var baseTheme: TelegramBaseTheme?
|
||||
|
||||
if case let .cloud(theme) = generalThemeReference, let settings = theme.theme.settings {
|
||||
hasSettings = true
|
||||
baseTheme = settings.baseTheme
|
||||
} else if case let .builtin(theme) = generalThemeReference {
|
||||
hasSettings = true
|
||||
baseTheme = theme.baseTheme
|
||||
}
|
||||
|
||||
if let themeReference = themeReference {
|
||||
updatedTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: state.accentColor, backgroundColors: state.backgroundColors, bubbleColors: state.messagesColors, wallpaper: state.initialWallpaper ?? coloredWallpaper, serviceBackgroundColor: serviceBackgroundColor) ?? defaultPresentationTheme
|
||||
|
||||
if case let .builtin(theme) = themeReference {
|
||||
var messageColors: (Int32, Int32)?
|
||||
if let colors = state.messagesColors {
|
||||
messageColors = (Int32(bitPattern: colors.0.rgb), Int32(bitPattern: colors.1?.rgb ?? colors.0.rgb))
|
||||
}
|
||||
|
||||
settings = TelegramThemeSettings(baseTheme: theme.baseTheme, accentColor: Int32(bitPattern: state.accentColor.rgb), messageColors: messageColors, wallpaper: coloredWallpaper)
|
||||
}
|
||||
} else {
|
||||
updatedTheme = customizePresentationTheme(theme, editing: false, accentColor: state.accentColor, backgroundColors: state.backgroundColors, bubbleColors: state.messagesColors, wallpaper: state.initialWallpaper ?? coloredWallpaper)
|
||||
}
|
||||
|
||||
|
||||
if hasSettings, let baseTheme = baseTheme {
|
||||
var messageColors: (Int32, Int32)?
|
||||
if let colors = state.messagesColors {
|
||||
messageColors = (Int32(bitPattern: colors.0.rgb), Int32(bitPattern: colors.1?.rgb ?? colors.0.rgb))
|
||||
}
|
||||
|
||||
settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: Int32(bitPattern: state.accentColor.rgb), messageColors: messageColors, wallpaper: coloredWallpaper)
|
||||
}
|
||||
|
||||
completion(updatedTheme, settings)
|
||||
})
|
||||
} else if case let .colors(theme, create) = strongSelf.mode {
|
||||
@ -208,6 +218,8 @@ final class ThemeAccentColorController: ViewController {
|
||||
if case let .cloud(theme) = theme, let settings = theme.theme.settings {
|
||||
telegramTheme = theme.theme
|
||||
baseTheme = settings.baseTheme
|
||||
} else if case let .builtin(theme) = theme {
|
||||
baseTheme = theme.baseTheme
|
||||
} else {
|
||||
baseTheme = .classic
|
||||
}
|
||||
@ -228,6 +240,7 @@ final class ThemeAccentColorController: ViewController {
|
||||
}
|
||||
|
||||
let settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: accentColor, messageColors: bubbleColors, wallpaper: wallpaper)
|
||||
let baseThemeReference = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: baseTheme))
|
||||
|
||||
let save: Signal<Void, NoError>
|
||||
|
||||
@ -246,7 +259,10 @@ final class ThemeAccentColorController: ViewController {
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
||||
|
||||
return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
var themeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
themeSpecificAccentColors[baseThemeReference.index] = PresentationThemeAccentColor(themeIndex: themeReference.index)
|
||||
|
||||
return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
}) |> deliverOnMainQueue).start(completed: {
|
||||
if let strongSelf = self {
|
||||
strongSelf.completion?()
|
||||
@ -272,7 +288,10 @@ final class ThemeAccentColorController: ViewController {
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
||||
|
||||
return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
var themeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
themeSpecificAccentColors[baseThemeReference.index] = PresentationThemeAccentColor(themeIndex: themeReference.index)
|
||||
|
||||
return PresentationThemeSettings(theme: themeReference, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
}) |> deliverOnMainQueue).start(completed: {
|
||||
if let strongSelf = self {
|
||||
strongSelf.completion?()
|
||||
@ -283,35 +302,6 @@ final class ThemeAccentColorController: ViewController {
|
||||
}, error: { error in
|
||||
})
|
||||
}
|
||||
|
||||
// let _ = (prepare
|
||||
// |> then(updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
// let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
|
||||
// var currentTheme = current.theme
|
||||
// if autoNightModeTriggered {
|
||||
// currentTheme = current.automaticThemeSwitchSetting.theme
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// if create {
|
||||
//
|
||||
// } else {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
//
|
||||
//
|
||||
// themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: nil)] = wallpaper
|
||||
//
|
||||
// return PresentationThemeSettings(theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
// })) |> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
// if let strongSelf = self {
|
||||
// strongSelf.completion?()
|
||||
// strongSelf.dismiss()
|
||||
// }
|
||||
// })
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -387,9 +377,9 @@ final class ThemeAccentColorController: ViewController {
|
||||
} else if let customWallpaper = settings.themeSpecificChatWallpapers[themeReference.index] {
|
||||
wallpaper = customWallpaper
|
||||
} else {
|
||||
let theme = makePresentationTheme(mediaBox: strongSelf.context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: nil) ?? defaultPresentationTheme
|
||||
let theme = makePresentationTheme(mediaBox: strongSelf.context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: nil, wallpaper: themeSpecificAccentColor?.wallpaper) ?? defaultPresentationTheme
|
||||
if case let .builtin(themeName) = themeReference {
|
||||
if case .dayClassic = themeName, settings.themeSpecificAccentColors[themeReference.index] != nil {
|
||||
if case .dayClassic = themeName, settings.themeSpecificAccentColors[coloredThemeIndex(reference: themeReference, accentColor: themeSpecificAccentColor)] != nil {
|
||||
ignoreDefaultWallpaper = true
|
||||
} else if case .nightAccent = themeName {
|
||||
ignoreDefaultWallpaper = true
|
||||
@ -488,7 +478,7 @@ final class ThemeAccentColorController: ViewController {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if case let .edit(theme, wallpaper, _, _, _) = strongSelf.mode {
|
||||
} else if case let .edit(theme, wallpaper, _, _, _, _) = strongSelf.mode {
|
||||
accentColor = theme.rootController.navigationBar.accentTextColor
|
||||
|
||||
let wallpaper = wallpaper ?? theme.chat.defaultWallpaper
|
||||
|
@ -258,7 +258,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
self.patternPanelNode = WallpaperPatternPanelNode(context: self.context, theme: self.theme, strings: self.presentationData.strings)
|
||||
|
||||
let doneButtonType: WallpaperGalleryToolbarDoneButtonType
|
||||
if case .edit(_, _, _, true, _) = self.mode {
|
||||
if case .edit(_, _, _, _, true, _) = self.mode {
|
||||
doneButtonType = .proceed
|
||||
} else {
|
||||
doneButtonType = .set
|
||||
@ -469,7 +469,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
if !updateOnlyWallpaper {
|
||||
if let themeReference = mode.themeReference {
|
||||
updatedTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: messagesColors, serviceBackgroundColor: serviceBackgroundColor, preview: true) ?? defaultPresentationTheme
|
||||
} else if case let .edit(theme, _, _, _, _) = mode {
|
||||
} else if case let .edit(theme, _, _, _, _, _) = mode {
|
||||
updatedTheme = customizePresentationTheme(theme, editing: false, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: messagesColors)
|
||||
} else {
|
||||
updatedTheme = theme
|
||||
@ -700,7 +700,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
doneButtonType = .apply
|
||||
cancelButtonType = .discard
|
||||
} else {
|
||||
if case .edit(_, _, _, true, _) = self.mode {
|
||||
if case .edit(_, _, _, _, true, _) = self.mode {
|
||||
doneButtonType = .proceed
|
||||
} else {
|
||||
doneButtonType = .set
|
||||
|
@ -68,7 +68,7 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry {
|
||||
case settingInfo(PresentationTheme, String)
|
||||
|
||||
case themeHeader(PresentationTheme, String)
|
||||
case themeItem(PresentationTheme, PresentationStrings, [PresentationThemeReference], PresentationThemeReference, [Int64: PresentationThemeAccentColor], [Int64: TelegramWallpaper])
|
||||
case themeItem(PresentationTheme, PresentationStrings, [PresentationThemeReference], [PresentationThemeReference], PresentationThemeReference, [Int64: PresentationThemeAccentColor], [Int64: TelegramWallpaper])
|
||||
|
||||
var section: ItemListSectionId {
|
||||
switch self {
|
||||
@ -186,8 +186,8 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeChatWallpapers):
|
||||
if case let .themeItem(rhsTheme, rhsStrings, rhsThemes, rhsCurrentTheme, rhsThemeAccentColors, rhsThemeChatWallpapers) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsThemes == rhsThemes, lhsCurrentTheme == rhsCurrentTheme, lhsThemeAccentColors == rhsThemeAccentColors, lhsThemeChatWallpapers == rhsThemeChatWallpapers {
|
||||
case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsAllThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeChatWallpapers):
|
||||
if case let .themeItem(rhsTheme, rhsStrings, rhsThemes, rhsAllThemes, rhsCurrentTheme, rhsThemeAccentColors, rhsThemeChatWallpapers) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsThemes == rhsThemes, lhsAllThemes == rhsAllThemes, lhsCurrentTheme == rhsCurrentTheme, lhsThemeAccentColors == rhsThemeAccentColors, lhsThemeChatWallpapers == rhsThemeChatWallpapers {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -244,8 +244,8 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry {
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||
case let .themeHeader(theme, title):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section)
|
||||
case let .themeItem(theme, strings, themes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers):
|
||||
return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, displayUnsupported: false, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in
|
||||
case let .themeItem(theme, strings, themes, allThemes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers):
|
||||
return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, allThemes: allThemes, displayUnsupported: false, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in
|
||||
arguments.updateTheme(theme)
|
||||
}, contextAction: nil)
|
||||
}
|
||||
@ -313,7 +313,16 @@ private func themeAutoNightSettingsControllerEntries(theme: PresentationTheme, s
|
||||
break
|
||||
case .system, .timeBased, .brightness:
|
||||
entries.append(.themeHeader(theme, strings.AutoNightTheme_PreferredTheme))
|
||||
entries.append(.themeItem(theme, strings, availableThemes, switchSetting.theme, settings.themeSpecificAccentColors, settings.themeSpecificChatWallpapers))
|
||||
|
||||
let generalThemes: [PresentationThemeReference] = availableThemes.filter { reference in
|
||||
if case let .cloud(theme) = reference {
|
||||
return theme.theme.settings == nil
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
entries.append(.themeItem(theme, strings, generalThemes, availableThemes, switchSetting.theme, settings.themeSpecificAccentColors, settings.themeSpecificChatWallpapers))
|
||||
}
|
||||
|
||||
return entries
|
||||
|
@ -143,6 +143,15 @@ enum ThemeSettingsColorOption: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
var wallpaper: TelegramWallpaper? {
|
||||
switch self {
|
||||
case let .accentColor(color):
|
||||
return color.wallpaper
|
||||
case .theme:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var index: Int64 {
|
||||
switch self {
|
||||
case let .accentColor(color):
|
||||
@ -341,7 +350,7 @@ private final class ThemeSettingsAccentColorIconItemNode : ListViewItemNode {
|
||||
var updatedAccentColor = false
|
||||
var updatedSelected = false
|
||||
|
||||
if currentItem == nil || currentItem?.color != item.color {
|
||||
if currentItem == nil || currentItem?.color != item.color || currentItem?.themeReference != item.themeReference {
|
||||
updatedAccentColor = true
|
||||
}
|
||||
if currentItem?.selected != item.selected {
|
||||
@ -418,7 +427,7 @@ private final class ThemeSettingsAccentColorIconItemNode : ListViewItemNode {
|
||||
strongSelf.dotsNode.bounds = bounds
|
||||
|
||||
if updatedSelected {
|
||||
strongSelf.setSelected(item.selected, animated: currentItem != nil && !animated)
|
||||
strongSelf.setSelected(item.selected, animated: !updatedAccentColor && currentItem != nil)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -663,17 +672,17 @@ private struct ThemeSettingsAccentColorItemNodeTransition {
|
||||
let deletions: [ListViewDeleteItem]
|
||||
let insertions: [ListViewInsertItem]
|
||||
let updates: [ListViewUpdateItem]
|
||||
let crossfade: Bool
|
||||
let updatePosition: Bool
|
||||
}
|
||||
|
||||
private func preparedTransition(action: @escaping (ThemeSettingsColorOption?, Bool) -> Void, contextAction: ((ThemeSettingsColorOption?, Bool, ASDisplayNode, ContextGesture?) -> Void)?, openColorPicker: @escaping (Bool) -> Void, from fromEntries: [ThemeSettingsColorEntry], to toEntries: [ThemeSettingsColorEntry], crossfade: Bool) -> ThemeSettingsAccentColorItemNodeTransition {
|
||||
private func preparedTransition(action: @escaping (ThemeSettingsColorOption?, Bool) -> Void, contextAction: ((ThemeSettingsColorOption?, Bool, ASDisplayNode, ContextGesture?) -> Void)?, openColorPicker: @escaping (Bool) -> Void, from fromEntries: [ThemeSettingsColorEntry], to toEntries: [ThemeSettingsColorEntry], updatePosition: Bool) -> ThemeSettingsAccentColorItemNodeTransition {
|
||||
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
||||
|
||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
||||
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(action: action, contextAction: contextAction, openColorPicker: openColorPicker), directionHint: .Down) }
|
||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(action: action, contextAction: contextAction, openColorPicker: openColorPicker), directionHint: nil) }
|
||||
|
||||
return ThemeSettingsAccentColorItemNodeTransition(deletions: deletions, insertions: insertions, updates: updates, crossfade: crossfade)
|
||||
return ThemeSettingsAccentColorItemNodeTransition(deletions: deletions, insertions: insertions, updates: updates, updatePosition: updatePosition)
|
||||
}
|
||||
|
||||
private func ensureColorVisible(listNode: ListView, accentColor: ThemeSettingsColorOption?, animated: Bool) -> Bool {
|
||||
@ -758,19 +767,15 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
|
||||
self.enqueuedTransitions.remove(at: 0)
|
||||
|
||||
var options = ListViewDeleteAndInsertOptions()
|
||||
if self.initialized && transition.crossfade {
|
||||
options.insert(.AnimateCrossfade)
|
||||
}
|
||||
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
if !self.initialized || transition.crossfade {
|
||||
if !self.initialized || transition.updatePosition {
|
||||
if let index = item.colors.firstIndex(where: { $0.index == item.currentColor?.index }) {
|
||||
scrollToItem = ListViewScrollToItem(index: index, position: .bottom(-56.0), animated: false, curve: .Default(duration: 0.0), directionHint: .Down)
|
||||
self.initialized = true
|
||||
}
|
||||
}
|
||||
|
||||
self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, scrollToItem: scrollToItem, updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { _ in
|
||||
|
||||
self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, scrollToItem: scrollToItem, updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { [weak self] _ in
|
||||
})
|
||||
}
|
||||
|
||||
@ -922,7 +927,7 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
|
||||
}
|
||||
let contextAction: ((ThemeSettingsColorOption?, Bool, ASDisplayNode, ContextGesture?) -> Void)? = { [weak item] color, selected, node, gesture in
|
||||
if let strongSelf = self, let item = strongSelf.item {
|
||||
item.contextAction?(selected, item.themeReference, color, node, gesture)
|
||||
item.contextAction?(selected, item.generalThemeReference, color, node, gesture)
|
||||
}
|
||||
}
|
||||
let openColorPicker: (Bool) -> Void = { [weak self] create in
|
||||
@ -932,8 +937,8 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
|
||||
}
|
||||
|
||||
let previousEntries = strongSelf.entries ?? []
|
||||
let crossfade = previousEntries.count != entries.count || (currentItem != nil && (currentItem?.generalThemeReference.index != item.generalThemeReference.index))
|
||||
let transition = preparedTransition(action: action, contextAction: contextAction, openColorPicker: openColorPicker, from: previousEntries, to: entries, crossfade: crossfade)
|
||||
let updatePosition = currentItem != nil && (previousEntries.count != entries.count || (currentItem?.generalThemeReference.index != item.generalThemeReference.index))
|
||||
let transition = preparedTransition(action: action, contextAction: contextAction, openColorPicker: openColorPicker, from: previousEntries, to: entries, updatePosition: updatePosition)
|
||||
strongSelf.enqueueTransition(transition)
|
||||
|
||||
strongSelf.entries = entries
|
||||
|
@ -133,10 +133,10 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
case fontSize(PresentationTheme, PresentationFontSize)
|
||||
case chatPreview(PresentationTheme, PresentationTheme, TelegramWallpaper, PresentationFontSize, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, [ChatPreviewMessageItem])
|
||||
case wallpaper(PresentationTheme, String)
|
||||
case accentColor(PresentationTheme, PresentationThemeReference, PresentationThemeReference, PresentationThemeCustomColors?, [PresentationThemeReference], ThemeSettingsColorOption?)
|
||||
case accentColor(PresentationTheme, PresentationThemeReference, PresentationThemeReference, [PresentationThemeReference], ThemeSettingsColorOption?)
|
||||
case autoNightTheme(PresentationTheme, String, String)
|
||||
case textSize(PresentationTheme, String, String)
|
||||
case themeItem(PresentationTheme, PresentationStrings, [PresentationThemeReference], PresentationThemeReference, [Int64: PresentationThemeAccentColor], [Int64: TelegramWallpaper], PresentationThemeAccentColor?)
|
||||
case themeItem(PresentationTheme, PresentationStrings, [PresentationThemeReference], [PresentationThemeReference], PresentationThemeReference, [Int64: PresentationThemeAccentColor], [Int64: TelegramWallpaper], PresentationThemeAccentColor?)
|
||||
case iconHeader(PresentationTheme, String)
|
||||
case iconItem(PresentationTheme, PresentationStrings, [PresentationAppIcon], String?)
|
||||
case otherHeader(PresentationTheme, String)
|
||||
@ -208,8 +208,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .accentColor(lhsTheme, lhsGeneralTheme, lhsCurrentTheme, lhsCustomColors, lhsThemes, lhsColor):
|
||||
if case let .accentColor(rhsTheme, rhsGeneralTheme, rhsCurrentTheme, rhsCustomColors, rhsThemes, rhsColor) = rhs, lhsTheme === rhsTheme, lhsCurrentTheme == rhsCurrentTheme, lhsCustomColors == rhsCustomColors, lhsThemes == rhsThemes, lhsColor == rhsColor {
|
||||
case let .accentColor(lhsTheme, lhsGeneralTheme, lhsCurrentTheme, lhsThemes, lhsColor):
|
||||
if case let .accentColor(rhsTheme, rhsGeneralTheme, rhsCurrentTheme, rhsThemes, rhsColor) = rhs, lhsTheme === rhsTheme, lhsCurrentTheme == rhsCurrentTheme, lhsThemes == rhsThemes, lhsColor == rhsColor {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -232,8 +232,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeSpecificChatWallpapers, lhsCurrentColor):
|
||||
if case let .themeItem(rhsTheme, rhsStrings, rhsThemes, rhsCurrentTheme, rhsThemeAccentColors, rhsThemeSpecificChatWallpapers, rhsCurrentColor) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsThemes == rhsThemes, lhsCurrentTheme == rhsCurrentTheme, lhsThemeAccentColors == rhsThemeAccentColors, lhsThemeSpecificChatWallpapers == rhsThemeSpecificChatWallpapers, lhsCurrentColor == rhsCurrentColor {
|
||||
case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsAllThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeSpecificChatWallpapers, lhsCurrentColor):
|
||||
if case let .themeItem(rhsTheme, rhsStrings, rhsThemes, rhsAllThemes, rhsCurrentTheme, rhsThemeAccentColors, rhsThemeSpecificChatWallpapers, rhsCurrentColor) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsThemes == rhsThemes, lhsAllThemes == rhsAllThemes, lhsCurrentTheme == rhsCurrentTheme, lhsThemeAccentColors == rhsThemeAccentColors, lhsThemeSpecificChatWallpapers == rhsThemeSpecificChatWallpapers, lhsCurrentColor == rhsCurrentColor {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -308,7 +308,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openWallpaperSettings()
|
||||
})
|
||||
case let .accentColor(theme, generalThemeReference, currentTheme, customColors, themes, color):
|
||||
case let .accentColor(theme, generalThemeReference, currentTheme, themes, color):
|
||||
var colorItems: [ThemeSettingsAccentColor] = []
|
||||
|
||||
for theme in themes {
|
||||
@ -317,7 +317,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
|
||||
var defaultColor: PresentationThemeAccentColor? = PresentationThemeAccentColor(baseColor: .blue)
|
||||
var colors = PresentationThemeBaseColor.allCases
|
||||
colors = colors.filter { $0 != .custom && $0 != .preset }
|
||||
colors = colors.filter { $0 != .custom && $0 != .preset && $0 != .theme }
|
||||
if case let .builtin(name) = generalThemeReference {
|
||||
if name == .dayClassic {
|
||||
colorItems.append(.default)
|
||||
@ -358,14 +358,6 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
let currentColor = color ?? defaultColor.flatMap { .accentColor($0) }
|
||||
colorItems.append(contentsOf: colors.map { .color($0) })
|
||||
|
||||
if let customColors = customColors {
|
||||
// colorItems.insert(contentsOf: customColors.colors.reversed().map { .custom($0) }, at: 0)
|
||||
} else {
|
||||
// if let currentColor = currentColor, currentColor.baseColor == .custom {
|
||||
// colorItems.insert(.custom(currentColor), at: 0)
|
||||
// }
|
||||
}
|
||||
|
||||
return ThemeSettingsAccentColorItem(theme: theme, sectionId: self.section, generalThemeReference: generalThemeReference, themeReference: currentTheme, colors: colorItems, currentColor: currentColor, updated: { color in
|
||||
if let color = color {
|
||||
switch color {
|
||||
@ -392,9 +384,9 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
||||
})
|
||||
case let .themeListHeader(theme, text):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||
case let .themeItem(theme, strings, themes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers, _):
|
||||
return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, displayUnsupported: true, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in
|
||||
if case let .cloud(theme) = theme, theme.theme.file == nil {
|
||||
case let .themeItem(theme, strings, themes, allThemes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers, _):
|
||||
return ThemeSettingsThemeItem(context: arguments.context, theme: theme, strings: strings, sectionId: self.section, themes: themes, allThemes: allThemes, displayUnsupported: true, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, currentTheme: currentTheme, updatedTheme: { theme in
|
||||
if case let .cloud(theme) = theme, theme.theme.file == nil && theme.theme.settings == nil {
|
||||
if theme.theme.isCreator {
|
||||
arguments.editTheme(theme)
|
||||
}
|
||||
@ -448,8 +440,8 @@ private func themeSettingsControllerEntries(presentationData: PresentationData,
|
||||
} else {
|
||||
generalThemeReference = themeReference
|
||||
}
|
||||
|
||||
entries.append(.themeItem(presentationData.theme, presentationData.strings, generalThemes, generalThemeReference, presentationThemeSettings.themeSpecificAccentColors, presentationThemeSettings.themeSpecificChatWallpapers, presentationThemeSettings.themeSpecificAccentColors[themeReference.index]))
|
||||
|
||||
entries.append(.themeItem(presentationData.theme, presentationData.strings, generalThemes, availableThemes, themeReference, presentationThemeSettings.themeSpecificAccentColors, presentationThemeSettings.themeSpecificChatWallpapers, presentationThemeSettings.themeSpecificAccentColors[themeReference.index]))
|
||||
|
||||
if case let .builtin(builtinTheme) = generalThemeReference {
|
||||
let colorThemes = availableThemes.filter { reference in
|
||||
@ -467,7 +459,7 @@ private func themeSettingsControllerEntries(presentationData: PresentationData,
|
||||
colorOption = .theme(themeReference)
|
||||
}
|
||||
|
||||
entries.append(.accentColor(presentationData.theme, generalThemeReference, themeReference, presentationThemeSettings.themeSpecificCustomColors[generalThemeReference.index], colorThemes, colorOption))
|
||||
entries.append(.accentColor(presentationData.theme, generalThemeReference, themeReference, colorThemes, colorOption))
|
||||
}
|
||||
|
||||
entries.append(.wallpaper(presentationData.theme, strings.Settings_ChatBackground))
|
||||
@ -526,6 +518,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
var presentCrossfadeControllerImpl: ((Bool) -> Void)?
|
||||
|
||||
var selectThemeImpl: ((PresentationThemeReference) -> Void)?
|
||||
var selectAccentColorImpl: ((PresentationThemeAccentColor?) -> Void)?
|
||||
var moreImpl: (() -> Void)?
|
||||
|
||||
let _ = telegramWallpapers(postbox: context.account.postbox, network: context.account.network).start()
|
||||
@ -555,87 +548,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
}, openWallpaperSettings: {
|
||||
pushControllerImpl?(ThemeGridController(context: context))
|
||||
}, selectAccentColor: { accentColor in
|
||||
var wallpaperSignal: Signal<TelegramWallpaper?, NoError> = .single(nil)
|
||||
if let colorWallpaper = accentColor?.wallpaper, case let .file(file) = colorWallpaper {
|
||||
wallpaperSignal = cachedWallpaper(account: context.account, slug: file.slug, settings: colorWallpaper.settings)
|
||||
|> mapToSignal { cachedWallpaper in
|
||||
if let wallpaper = cachedWallpaper?.wallpaper, case let .file(file) = wallpaper {
|
||||
let resource = file.file.resource
|
||||
let representation = CachedPatternWallpaperRepresentation(color: file.settings.color ?? 0xd6e2ee, bottomColor: file.settings.bottomColor, intensity: file.settings.intensity ?? 50, rotation: file.settings.rotation)
|
||||
|
||||
var data: Data?
|
||||
if let path = context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
|
||||
data = maybeData
|
||||
} else if let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
|
||||
data = maybeData
|
||||
}
|
||||
|
||||
if let data = data {
|
||||
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||
return (context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true)
|
||||
|> filter({ $0.complete })
|
||||
|> take(1)
|
||||
|> mapToSignal { _ -> Signal<TelegramWallpaper?, NoError> in
|
||||
return .single(wallpaper)
|
||||
})
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let _ = (wallpaperSignal
|
||||
|> deliverOnMainQueue).start(next: { presetWallpaper in
|
||||
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
|
||||
var currentTheme = current.theme
|
||||
if autoNightModeTriggered {
|
||||
currentTheme = current.automaticThemeSwitchSetting.theme
|
||||
}
|
||||
|
||||
let generalThemeReference: PresentationThemeReference
|
||||
if case let .cloud(theme) = currentTheme, let settings = theme.theme.settings {
|
||||
generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme))
|
||||
} else {
|
||||
generalThemeReference = currentTheme
|
||||
}
|
||||
|
||||
currentTheme = generalThemeReference
|
||||
var updatedTheme = current.theme
|
||||
var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting
|
||||
|
||||
if autoNightModeTriggered {
|
||||
var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting
|
||||
updatedAutomaticThemeSwitchSetting.theme = generalThemeReference
|
||||
} else {
|
||||
updatedTheme = generalThemeReference
|
||||
}
|
||||
|
||||
guard let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.color, wallpaper: presetWallpaper) else {
|
||||
return current
|
||||
}
|
||||
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
var themeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
themeSpecificAccentColors[generalThemeReference.index] = accentColor?.withUpdatedWallpaper(presetWallpaper)
|
||||
|
||||
if case let .builtin(theme) = generalThemeReference {
|
||||
if let wallpaper = current.themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)], wallpaper.isColorOrGradient || wallpaper.isPattern || wallpaper.isBuiltin {
|
||||
themeSpecificChatWallpapers[currentTheme.index] = nil
|
||||
if let accentColor = accentColor {
|
||||
themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PresentationThemeSettings(theme: updatedTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
}).start()
|
||||
|
||||
presentCrossfadeControllerImpl?(true)
|
||||
})
|
||||
selectAccentColorImpl?(accentColor)
|
||||
}, openAccentColorPicker: { themeReference, create in
|
||||
let controller = ThemeAccentColorController(context: context, mode: .colors(themeReference: themeReference, create: create))
|
||||
pushControllerImpl?(controller)
|
||||
@ -685,7 +598,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
if let wallpaper = wallpaper {
|
||||
effectiveWallpaper = wallpaper
|
||||
} else {
|
||||
let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: reference, accentColor: accentColor?.color, bubbleColors: accentColor?.customBubbleColors)
|
||||
let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: reference, accentColor: accentColor?.color, bubbleColors: accentColor?.customBubbleColors, wallpaper: accentColor?.wallpaper)
|
||||
effectiveWallpaper = theme?.chat.defaultWallpaper ?? .builtin(WallpaperSettings())
|
||||
}
|
||||
return (accentColor, effectiveWallpaper)
|
||||
@ -750,7 +663,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
|
||||
let _ = (resolvedWallpaper
|
||||
|> deliverOnMainQueue).start(next: { wallpaper in
|
||||
let controller = ThemeAccentColorController(context: context, mode: .edit(theme: theme, wallpaper: wallpaper, defaultThemeReference: nil, create: true, completion: { result, settings in
|
||||
let controller = ThemeAccentColorController(context: context, mode: .edit(theme: theme, wallpaper: wallpaper, generalThemeReference: reference.generalThemeReference, defaultThemeReference: nil, create: true, completion: { result, settings in
|
||||
let controller = editThemeController(context: context, mode: .create(result, nil), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
@ -791,14 +704,19 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { themes in
|
||||
if isCurrent, let currentThemeIndex = themes.firstIndex(where: { $0.id == theme.theme.id }) {
|
||||
let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil })
|
||||
let newTheme: PresentationThemeReference
|
||||
if let previousThemeIndex = previousThemeIndex {
|
||||
newTheme = .cloud(PresentationCloudTheme(theme: themes[themes.index(before: previousThemeIndex.base)], resolvedWallpaper: nil))
|
||||
if let settings = theme.theme.settings {
|
||||
selectAccentColorImpl?(nil)
|
||||
} else {
|
||||
newTheme = .builtin(.nightAccent)
|
||||
let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil })
|
||||
let newTheme: PresentationThemeReference
|
||||
if let previousThemeIndex = previousThemeIndex {
|
||||
newTheme = .cloud(PresentationCloudTheme(theme: themes[themes.index(before: previousThemeIndex.base)], resolvedWallpaper: nil))
|
||||
} else {
|
||||
newTheme = .builtin(.nightAccent)
|
||||
}
|
||||
selectThemeImpl?(newTheme)
|
||||
}
|
||||
selectThemeImpl?(newTheme)
|
||||
|
||||
}
|
||||
|
||||
let _ = deleteThemeInteractively(account: context.account, accountManager: context.sharedContext.accountManager, theme: theme.theme).start()
|
||||
@ -845,7 +763,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
}
|
||||
}
|
||||
return (accentColor, wallpaper)
|
||||
} |> mapToSignal { accentColor, wallpaper -> Signal<(PresentationTheme?, TelegramWallpaper?), NoError> in
|
||||
} |> mapToSignal { accentColor, wallpaper -> Signal<(PresentationTheme?, PresentationThemeReference, TelegramWallpaper?), NoError> in
|
||||
let generalThemeReference: PresentationThemeReference
|
||||
if let accentColor = accentColor, case let .cloud(theme) = reference, let settings = theme.theme.settings {
|
||||
generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme))
|
||||
@ -854,6 +772,13 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
}
|
||||
|
||||
let effectiveWallpaper: TelegramWallpaper
|
||||
let effectiveThemeReference: PresentationThemeReference
|
||||
if let accentColor = accentColor, case let .theme(themeReference) = accentColor {
|
||||
effectiveThemeReference = themeReference
|
||||
} else {
|
||||
effectiveThemeReference = reference
|
||||
}
|
||||
|
||||
if let wallpaper = wallpaper {
|
||||
effectiveWallpaper = wallpaper
|
||||
} else {
|
||||
@ -861,7 +786,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
if let accentColor = accentColor, case let .theme(themeReference) = accentColor {
|
||||
theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference)
|
||||
} else {
|
||||
theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.accentColor, bubbleColors: accentColor?.customBubbleColors)
|
||||
theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.accentColor, bubbleColors: accentColor?.customBubbleColors, wallpaper: accentColor?.wallpaper)
|
||||
}
|
||||
effectiveWallpaper = theme?.chat.defaultWallpaper ?? .builtin(WallpaperSettings())
|
||||
}
|
||||
@ -879,23 +804,26 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
return wallpaperSignal
|
||||
|> mapToSignal { wallpaper in
|
||||
return chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: context.sharedContext.accountManager.mediaBox)
|
||||
|> map { serviceBackgroundColor in
|
||||
return (wallpaper, serviceBackgroundColor)
|
||||
}
|
||||
}
|
||||
|> map { serviceBackgroundColor in
|
||||
|> map { wallpaper, serviceBackgroundColor in
|
||||
if let accentColor = accentColor, case let .theme(themeReference) = accentColor {
|
||||
return (makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, serviceBackgroundColor: serviceBackgroundColor), wallpaper)
|
||||
return (makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, serviceBackgroundColor: serviceBackgroundColor), effectiveThemeReference, wallpaper)
|
||||
} else {
|
||||
return (makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.accentColor, bubbleColors: accentColor?.customBubbleColors, serviceBackgroundColor: serviceBackgroundColor), wallpaper)
|
||||
return (makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.accentColor, bubbleColors: accentColor?.customBubbleColors, serviceBackgroundColor: serviceBackgroundColor), effectiveThemeReference, wallpaper)
|
||||
}
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { theme, wallpaper in
|
||||
|> deliverOnMainQueue).start(next: { theme, effectiveThemeReference, wallpaper in
|
||||
guard let theme = theme else {
|
||||
return
|
||||
}
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let strings = presentationData.strings
|
||||
let themeController = ThemePreviewController(context: context, previewTheme: theme, source: .settings(reference, wallpaper))
|
||||
let themeController = ThemePreviewController(context: context, previewTheme: theme, source: .settings(effectiveThemeReference, wallpaper))
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
if let accentColor = accentColor {
|
||||
@ -931,7 +859,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
|
||||
let _ = (resolvedWallpaper
|
||||
|> deliverOnMainQueue).start(next: { wallpaper in
|
||||
let controller = ThemeAccentColorController(context: context, mode: .edit(theme: theme, wallpaper: wallpaper, defaultThemeReference: nil, create: true, completion: { result, settings in
|
||||
let controller = ThemeAccentColorController(context: context, mode: .edit(theme: theme, wallpaper: wallpaper, generalThemeReference: reference.generalThemeReference, defaultThemeReference: nil, create: true, completion: { result, settings in
|
||||
let controller = editThemeController(context: context, mode: .create(result, nil), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
@ -971,15 +899,24 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
let _ = (cloudThemes.get() |> delay(0.5, queue: Queue.mainQueue())
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { themes in
|
||||
if isCurrent, let currentThemeIndex = themes.firstIndex(where: { $0.id == cloudTheme.theme.id }) {
|
||||
let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil })
|
||||
let newTheme: PresentationThemeReference
|
||||
if let previousThemeIndex = previousThemeIndex {
|
||||
newTheme = .cloud(PresentationCloudTheme(theme: themes[themes.index(before: previousThemeIndex.base)], resolvedWallpaper: nil))
|
||||
} else {
|
||||
newTheme = .builtin(.nightAccent)
|
||||
if isCurrent, let settings = cloudTheme.theme.settings {
|
||||
let colorThemes = themes.filter { theme in
|
||||
if let settings = theme.settings {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if let currentThemeIndex = colorThemes.firstIndex(where: { $0.id == cloudTheme.theme.id }) {
|
||||
let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil })
|
||||
let newTheme: PresentationThemeReference
|
||||
if let previousThemeIndex = previousThemeIndex {
|
||||
selectThemeImpl?(.cloud(PresentationCloudTheme(theme: themes[themes.index(before: previousThemeIndex.base)], resolvedWallpaper: nil)))
|
||||
} else {
|
||||
selectAccentColorImpl?(nil)
|
||||
}
|
||||
}
|
||||
selectThemeImpl?(newTheme)
|
||||
}
|
||||
|
||||
let _ = deleteThemeInteractively(account: context.account, accountManager: context.sharedContext.accountManager, theme: cloudTheme.theme).start()
|
||||
@ -993,67 +930,6 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
presentControllerImpl?(actionSheet, nil)
|
||||
})
|
||||
})))
|
||||
} else {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_ShareThemeColor, textColor: .primary, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Share"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { c, f in
|
||||
c.dismiss(completion: {
|
||||
|
||||
})
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Appearance_RemoveThemeColor, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor)
|
||||
}, action: { c, f in
|
||||
c.dismiss(completion: {
|
||||
let actionSheet = ActionSheetController(presentationData: presentationData)
|
||||
var items: [ActionSheetItem] = []
|
||||
items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_RemoveThemeColorConfirmation, color: .destructive, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
|
||||
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
let themeReference: PresentationThemeReference
|
||||
if presentationData.autoNightModeTriggered {
|
||||
themeReference = current.automaticThemeSwitchSetting.theme
|
||||
} else {
|
||||
themeReference = current.theme
|
||||
}
|
||||
|
||||
var themeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
var themeSpecificCustomColors = current.themeSpecificCustomColors
|
||||
var customColors = themeSpecificCustomColors[themeReference.index]?.colors ?? []
|
||||
|
||||
var updatedAccentColor: PresentationThemeAccentColor?
|
||||
if let index = customColors.firstIndex(where: { $0.index == accentColor.index }) {
|
||||
if index > 0 {
|
||||
updatedAccentColor = customColors[index - 1]
|
||||
} else {
|
||||
if case let .builtin(theme) = themeReference {
|
||||
switch theme {
|
||||
case .dayClassic:
|
||||
updatedAccentColor = nil
|
||||
case .day, .night, .nightAccent:
|
||||
updatedAccentColor = PresentationThemeAccentColor(baseColor: .blue)
|
||||
}
|
||||
} else {
|
||||
updatedAccentColor = PresentationThemeAccentColor(baseColor: .blue)
|
||||
}
|
||||
}
|
||||
customColors.remove(at: index)
|
||||
} else {
|
||||
updatedAccentColor = PresentationThemeAccentColor(baseColor: .blue)
|
||||
}
|
||||
|
||||
themeSpecificAccentColors[themeReference.index] = updatedAccentColor
|
||||
themeSpecificCustomColors[themeReference.index] = PresentationThemeCustomColors(colors: customColors)
|
||||
return current.withUpdatedThemeSpecificCustomColors(themeSpecificCustomColors).withUpdatedThemeSpecificAccentColors(themeSpecificAccentColors)
|
||||
}).start()
|
||||
}))
|
||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
})
|
||||
])])
|
||||
presentControllerImpl?(actionSheet, nil)
|
||||
})
|
||||
})))
|
||||
}
|
||||
}
|
||||
let contextController = ContextController(account: context.account, presentationData: presentationData, source: .controller(ContextControllerContentSourceImpl(controller: themeController, sourceNode: node)), items: .single(items), reactionItems: [], gesture: gesture)
|
||||
@ -1212,24 +1088,140 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
}
|
||||
let _ = applyTheme(accountManager: context.sharedContext.accountManager, account: context.account, theme: cloudTheme).start()
|
||||
|
||||
let _ = (resolvedWallpaper
|
||||
|> mapToSignal { resolvedWallpaper -> Signal<Void, NoError> in
|
||||
let currentTheme = context.sharedContext.accountManager.transaction { transaction -> (PresentationThemeReference) in
|
||||
let settings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.presentationThemeSettings) as? PresentationThemeSettings ?? PresentationThemeSettings.defaultSettings
|
||||
if autoNightModeTriggered {
|
||||
return settings.automaticThemeSwitchSetting.theme
|
||||
} else {
|
||||
return settings.theme
|
||||
}
|
||||
}
|
||||
|
||||
let _ = (combineLatest(resolvedWallpaper, currentTheme)
|
||||
|> map { resolvedWallpaper, currentTheme -> Bool in
|
||||
var updatedTheme = theme
|
||||
var currentThemeBaseIndex: Int64?
|
||||
if case let .cloud(info) = currentTheme, let settings = info.theme.settings {
|
||||
currentThemeBaseIndex = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)).index
|
||||
} else {
|
||||
currentThemeBaseIndex = currentTheme.index
|
||||
}
|
||||
|
||||
var baseThemeIndex: Int64?
|
||||
var updatedThemeBaseIndex: Int64?
|
||||
if case let .cloud(info) = theme {
|
||||
updatedTheme = .cloud(PresentationCloudTheme(theme: info.theme, resolvedWallpaper: resolvedWallpaper))
|
||||
if let settings = info.theme.settings {
|
||||
baseThemeIndex = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)).index
|
||||
updatedThemeBaseIndex = baseThemeIndex
|
||||
}
|
||||
} else {
|
||||
updatedThemeBaseIndex = theme.index
|
||||
}
|
||||
return updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
|
||||
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
var updatedThemeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
if let baseThemeIndex = baseThemeIndex {
|
||||
updatedThemeSpecificAccentColors[baseThemeIndex] = PresentationThemeAccentColor(themeIndex: updatedTheme.index)
|
||||
}
|
||||
|
||||
if autoNightModeTriggered {
|
||||
var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting
|
||||
updatedAutomaticThemeSwitchSetting.theme = updatedTheme
|
||||
return current.withUpdatedAutomaticThemeSwitchSetting(updatedAutomaticThemeSwitchSetting)
|
||||
|
||||
return current.withUpdatedAutomaticThemeSwitchSetting(updatedAutomaticThemeSwitchSetting).withUpdatedThemeSpecificAccentColors(updatedThemeSpecificAccentColors)
|
||||
} else {
|
||||
return current.withUpdatedTheme(updatedTheme)
|
||||
return current.withUpdatedTheme(updatedTheme).withUpdatedThemeSpecificAccentColors(updatedThemeSpecificAccentColors)
|
||||
}
|
||||
})
|
||||
}).start()
|
||||
}).start()
|
||||
|
||||
return currentThemeBaseIndex != updatedThemeBaseIndex
|
||||
} |> deliverOnMainQueue).start(next: { crossfadeAccentColors in
|
||||
presentCrossfadeControllerImpl?((cloudTheme == nil || cloudTheme?.settings != nil) && !crossfadeAccentColors)
|
||||
})
|
||||
}
|
||||
selectAccentColorImpl = { accentColor in
|
||||
var wallpaperSignal: Signal<TelegramWallpaper?, NoError> = .single(nil)
|
||||
if let colorWallpaper = accentColor?.wallpaper, case let .file(file) = colorWallpaper {
|
||||
wallpaperSignal = cachedWallpaper(account: context.account, slug: file.slug, settings: colorWallpaper.settings)
|
||||
|> mapToSignal { cachedWallpaper in
|
||||
if let wallpaper = cachedWallpaper?.wallpaper, case let .file(file) = wallpaper {
|
||||
let resource = file.file.resource
|
||||
let representation = CachedPatternWallpaperRepresentation(color: file.settings.color ?? 0xd6e2ee, bottomColor: file.settings.bottomColor, intensity: file.settings.intensity ?? 50, rotation: file.settings.rotation)
|
||||
|
||||
var data: Data?
|
||||
if let path = context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
|
||||
data = maybeData
|
||||
} else if let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
|
||||
data = maybeData
|
||||
}
|
||||
|
||||
if let data = data {
|
||||
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||
return (context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true)
|
||||
|> filter({ $0.complete })
|
||||
|> take(1)
|
||||
|> mapToSignal { _ -> Signal<TelegramWallpaper?, NoError> in
|
||||
return .single(wallpaper)
|
||||
})
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
presentCrossfadeControllerImpl?(cloudTheme == nil || cloudTheme?.settings != nil)
|
||||
let _ = (wallpaperSignal
|
||||
|> deliverOnMainQueue).start(next: { presetWallpaper in
|
||||
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
|
||||
var currentTheme = current.theme
|
||||
if autoNightModeTriggered {
|
||||
currentTheme = current.automaticThemeSwitchSetting.theme
|
||||
}
|
||||
|
||||
let generalThemeReference: PresentationThemeReference
|
||||
if case let .cloud(theme) = currentTheme, let settings = theme.theme.settings {
|
||||
generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme))
|
||||
} else {
|
||||
generalThemeReference = currentTheme
|
||||
}
|
||||
|
||||
currentTheme = generalThemeReference
|
||||
var updatedTheme = current.theme
|
||||
var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting
|
||||
|
||||
if autoNightModeTriggered {
|
||||
var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting
|
||||
updatedAutomaticThemeSwitchSetting.theme = generalThemeReference
|
||||
} else {
|
||||
updatedTheme = generalThemeReference
|
||||
}
|
||||
|
||||
guard let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: generalThemeReference, accentColor: accentColor?.color, wallpaper: presetWallpaper) else {
|
||||
return current
|
||||
}
|
||||
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
var themeSpecificAccentColors = current.themeSpecificAccentColors
|
||||
themeSpecificAccentColors[generalThemeReference.index] = accentColor?.withUpdatedWallpaper(presetWallpaper)
|
||||
|
||||
if case let .builtin(theme) = generalThemeReference {
|
||||
if let wallpaper = current.themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)], wallpaper.isColorOrGradient || wallpaper.isPattern || wallpaper.isBuiltin {
|
||||
themeSpecificChatWallpapers[currentTheme.index] = nil
|
||||
if let accentColor = accentColor {
|
||||
themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PresentationThemeSettings(theme: updatedTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
}).start()
|
||||
|
||||
presentCrossfadeControllerImpl?(true)
|
||||
})
|
||||
}
|
||||
moreImpl = {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
@ -1238,10 +1230,10 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_CreateTheme, color: .accent, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
|
||||
let _ = (context.sharedContext.accountManager.transaction { transaction -> PresentationThemeReference? in
|
||||
let _ = (context.sharedContext.accountManager.transaction { transaction -> PresentationThemeReference in
|
||||
let settings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.presentationThemeSettings) as? PresentationThemeSettings ?? PresentationThemeSettings.defaultSettings
|
||||
|
||||
var themeReference: PresentationThemeReference?
|
||||
let themeReference: PresentationThemeReference
|
||||
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
|
||||
if autoNightModeTriggered {
|
||||
themeReference = settings.automaticThemeSwitchSetting.theme
|
||||
@ -1249,14 +1241,15 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
||||
themeReference = settings.theme
|
||||
}
|
||||
|
||||
if let themeReference = themeReference, case .builtin = themeReference {
|
||||
} else {
|
||||
themeReference = nil
|
||||
}
|
||||
return themeReference
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { themeReference in
|
||||
let controller = ThemeAccentColorController(context: context, mode: .edit(theme: presentationData.theme, wallpaper: presentationData.chatWallpaper, defaultThemeReference: themeReference, create: true, completion: { result, settings in
|
||||
let defaultThemeReference: PresentationThemeReference?
|
||||
if case .builtin = themeReference {
|
||||
defaultThemeReference = themeReference
|
||||
}
|
||||
|
||||
let controller = ThemeAccentColorController(context: context, mode: .edit(theme: presentationData.theme, wallpaper: presentationData.chatWallpaper, generalThemeReference: themeReference.generalThemeReference, defaultThemeReference: themeReference, create: true, completion: { result, settings in
|
||||
let controller = editThemeController(context: context, mode: .create(result, settings), navigateToChat: { peerId in
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||
|
@ -273,7 +273,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
if let strongSelf = self {
|
||||
strongSelf.item = item
|
||||
|
||||
if case let .cloud(theme) = item.themeReference, theme.theme.file == nil {
|
||||
if case let .cloud(theme) = item.themeReference, theme.theme.file == nil && theme.theme.settings == nil {
|
||||
if updatedTheme {
|
||||
strongSelf.imageNode.setSignal(createThemeImage(theme: item.theme))
|
||||
}
|
||||
@ -305,7 +305,9 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
}
|
||||
|
||||
func prepareCrossfadeTransition() {
|
||||
self.snapshotView?.removeFromSuperview()
|
||||
guard self.snapshotView == nil else {
|
||||
return
|
||||
}
|
||||
|
||||
if let snapshotView = self.containerNode.view.snapshotView(afterScreenUpdates: false) {
|
||||
self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view)
|
||||
@ -314,8 +316,13 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
||||
}
|
||||
|
||||
func animateCrossfadeTransition() {
|
||||
guard self.snapshotView?.layer.animationKeys()?.isEmpty ?? true else {
|
||||
return
|
||||
}
|
||||
|
||||
self.snapshotView?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak self] _ in
|
||||
self?.snapshotView?.removeFromSuperview()
|
||||
self?.snapshotView = nil
|
||||
})
|
||||
}
|
||||
|
||||
@ -345,6 +352,7 @@ class ThemeSettingsThemeItem: ListViewItem, ItemListItem {
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let themes: [PresentationThemeReference]
|
||||
let allThemes: [PresentationThemeReference]
|
||||
let displayUnsupported: Bool
|
||||
let themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
||||
let themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
|
||||
@ -353,11 +361,12 @@ class ThemeSettingsThemeItem: ListViewItem, ItemListItem {
|
||||
let contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?
|
||||
let tag: ItemListItemTag?
|
||||
|
||||
init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, themes: [PresentationThemeReference], displayUnsupported: Bool, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], currentTheme: PresentationThemeReference, updatedTheme: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, tag: ItemListItemTag? = nil) {
|
||||
init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, sectionId: ItemListSectionId, themes: [PresentationThemeReference], allThemes: [PresentationThemeReference], displayUnsupported: Bool, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], themeSpecificChatWallpapers: [Int64: TelegramWallpaper], currentTheme: PresentationThemeReference, updatedTheme: @escaping (PresentationThemeReference) -> Void, contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?, tag: ItemListItemTag? = nil) {
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.themes = themes
|
||||
self.allThemes = allThemes
|
||||
self.displayUnsupported = displayUnsupported
|
||||
self.themeSpecificAccentColors = themeSpecificAccentColors
|
||||
self.themeSpecificChatWallpapers = themeSpecificChatWallpapers
|
||||
@ -594,14 +603,26 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
strongSelf.listNode.position = CGPoint(x: contentSize.width / 2.0, y: contentSize.height / 2.0 + 2.0)
|
||||
strongSelf.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: CGSize(width: contentSize.height, height: contentSize.width), insets: listInsets, duration: 0.0, curve: .Default(duration: nil)), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
|
||||
var themes: [Int64: PresentationThemeReference] = [:]
|
||||
for theme in item.allThemes {
|
||||
themes[theme.index] = theme
|
||||
}
|
||||
|
||||
var entries: [ThemeSettingsThemeEntry] = []
|
||||
var index: Int = 0
|
||||
for theme in item.themes {
|
||||
for var theme in item.themes.prefix(1) {
|
||||
if !item.displayUnsupported, case let .cloud(theme) = theme, theme.theme.file == nil {
|
||||
continue
|
||||
}
|
||||
let title = themeDisplayName(strings: item.strings, reference: theme)
|
||||
let accentColor = item.themeSpecificAccentColors[theme.index]
|
||||
var accentColor = item.themeSpecificAccentColors[theme.index]
|
||||
if let customThemeIndex = accentColor?.themeIndex {
|
||||
if let customTheme = themes[customThemeIndex] {
|
||||
theme = customTheme
|
||||
}
|
||||
accentColor = nil
|
||||
}
|
||||
|
||||
let wallpaper = accentColor?.wallpaper
|
||||
entries.append(ThemeSettingsThemeEntry(index: index, themeReference: theme, title: title, accentColor: accentColor, selected: item.currentTheme.index == theme.index, theme: item.theme, wallpaper: wallpaper))
|
||||
index += 1
|
||||
@ -633,7 +654,9 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
}
|
||||
|
||||
func prepareCrossfadeTransition() {
|
||||
self.snapshotView?.removeFromSuperview()
|
||||
guard self.snapshotView == nil else {
|
||||
return
|
||||
}
|
||||
|
||||
if let snapshotView = self.containerNode.view.snapshotView(afterScreenUpdates: false) {
|
||||
self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view)
|
||||
@ -648,8 +671,13 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
|
||||
}
|
||||
|
||||
func animateCrossfadeTransition() {
|
||||
guard self.snapshotView?.layer.animationKeys()?.isEmpty ?? true else {
|
||||
return
|
||||
}
|
||||
|
||||
self.snapshotView?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak self] _ in
|
||||
self?.snapshotView?.removeFromSuperview()
|
||||
self?.snapshotView = nil
|
||||
})
|
||||
|
||||
self.listNode.forEachVisibleItemNode { node in
|
||||
|
@ -143,7 +143,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
|
||||
selectedFileId = file.id
|
||||
}
|
||||
|
||||
for wallpaper in wallpapers {
|
||||
for wallpaper in self.wallpapers {
|
||||
let node = SettingsThemeWallpaperNode(overlayBackgroundColor: self.serviceBackgroundColor.withAlphaComponent(0.4))
|
||||
node.clipsToBounds = true
|
||||
node.cornerRadius = 5.0
|
||||
@ -251,7 +251,16 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
|
||||
let frame = node.frame.insetBy(dx: -48.0, dy: 0.0)
|
||||
|
||||
if frame.minX < bounds.minX || frame.maxX > bounds.maxX {
|
||||
self.scrollNode.view.scrollRectToVisible(frame, animated: animated)
|
||||
let transition: ContainedViewLayoutTransition = animated ? .animated(duration: 0.3, curve: .easeInOut) : .immediate
|
||||
|
||||
var origin = CGPoint()
|
||||
if frame.minX < bounds.minX {
|
||||
origin.x = max(0.0, frame.minX)
|
||||
} else if frame.maxX > bounds.maxX {
|
||||
origin.x = min(self.scrollNode.view.contentSize.width - bounds.width, frame.maxX - bounds.width)
|
||||
}
|
||||
|
||||
transition.updateBounds(node: self.scrollNode, bounds: CGRect(origin: origin, size: self.scrollNode.frame.size))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,10 +25,10 @@ func apiWallpaperSettings(_ wallpaperSettings: WallpaperSettings) -> Api.WallPap
|
||||
if wallpaperSettings.motion {
|
||||
flags |= (1 << 2)
|
||||
}
|
||||
if let _ = wallpaperSettings.bottomColor {
|
||||
flags |= (1 << 4)
|
||||
if let _ = wallpaperSettings.intensity {
|
||||
flags |= (1 << 3)
|
||||
}
|
||||
if let _ = wallpaperSettings.rotation {
|
||||
if let _ = wallpaperSettings.bottomColor {
|
||||
flags |= (1 << 4)
|
||||
}
|
||||
return .wallPaperSettings(flags: flags, backgroundColor: wallpaperSettings.color, secondBackgroundColor: wallpaperSettings.bottomColor, intensity: wallpaperSettings.intensity, rotation: wallpaperSettings.rotation)
|
||||
|
@ -221,7 +221,7 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
|
||||
)
|
||||
}
|
||||
|
||||
public func makeDefaultDarkPresentationTheme(preview: Bool) -> PresentationTheme {
|
||||
public func makeDefaultDarkPresentationTheme(extendingThemeReference: PresentationThemeReference? = nil, preview: Bool) -> PresentationTheme {
|
||||
let rootTabBar = PresentationThemeRootTabBar(
|
||||
backgroundColor: UIColor(rgb: 0x1c1c1d),
|
||||
separatorColor: UIColor(rgb: 0x3d3d40),
|
||||
@ -531,8 +531,8 @@ public func makeDefaultDarkPresentationTheme(preview: Bool) -> PresentationTheme
|
||||
)
|
||||
|
||||
return PresentationTheme(
|
||||
name: .builtin(.night),
|
||||
index: PresentationThemeReference.builtin(.night).index,
|
||||
name: extendingThemeReference?.name ?? .builtin(.night),
|
||||
index: extendingThemeReference?.index ?? PresentationThemeReference.builtin(.night).index,
|
||||
referenceTheme: .night,
|
||||
overallDarkAppearance: true,
|
||||
intro: intro,
|
||||
|
@ -441,7 +441,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
)
|
||||
}
|
||||
|
||||
public func makeDefaultDarkTintedPresentationTheme(preview: Bool) -> PresentationTheme {
|
||||
public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: PresentationThemeReference? = nil, preview: Bool) -> PresentationTheme {
|
||||
let accentColor = defaultDarkTintedAccentColor
|
||||
|
||||
let secondaryBadgeTextColor: UIColor
|
||||
@ -787,8 +787,8 @@ public func makeDefaultDarkTintedPresentationTheme(preview: Bool) -> Presentatio
|
||||
)
|
||||
|
||||
return PresentationTheme(
|
||||
name: .builtin(.nightAccent),
|
||||
index: PresentationThemeReference.builtin(.nightAccent).index,
|
||||
name: extendingThemeReference?.name ?? .builtin(.nightAccent),
|
||||
index: extendingThemeReference?.index ?? PresentationThemeReference.builtin(.nightAccent).index,
|
||||
referenceTheme: .nightAccent,
|
||||
overallDarkAppearance: true,
|
||||
intro: intro,
|
||||
|
@ -311,7 +311,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ac
|
||||
)
|
||||
}
|
||||
|
||||
public func makeDefaultDayPresentationTheme(serviceBackgroundColor: UIColor?, day: Bool, preview: Bool) -> PresentationTheme {
|
||||
public func makeDefaultDayPresentationTheme(extendingThemeReference: PresentationThemeReference? = nil, serviceBackgroundColor: UIColor?, day: Bool, preview: Bool) -> PresentationTheme {
|
||||
var serviceBackgroundColor = serviceBackgroundColor ?? defaultServiceBackgroundColor
|
||||
|
||||
let intro = PresentationThemeIntro(
|
||||
@ -740,8 +740,8 @@ public func makeDefaultDayPresentationTheme(serviceBackgroundColor: UIColor?, da
|
||||
)
|
||||
|
||||
return PresentationTheme(
|
||||
name: .builtin(day ? .day : .dayClassic),
|
||||
index: PresentationThemeReference.builtin(day ? .day : .dayClassic).index,
|
||||
name: extendingThemeReference?.name ?? .builtin(day ? .day : .dayClassic),
|
||||
index: extendingThemeReference?.index ?? PresentationThemeReference.builtin(day ? .day : .dayClassic).index,
|
||||
referenceTheme: day ? .day : .dayClassic,
|
||||
overallDarkAppearance: false,
|
||||
intro: intro,
|
||||
|
@ -4,23 +4,23 @@ import Postbox
|
||||
import SyncCore
|
||||
import TelegramUIPreferences
|
||||
|
||||
public func makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference, serviceBackgroundColor: UIColor?, preview: Bool = false) -> PresentationTheme {
|
||||
public func makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference, extendingThemeReference: PresentationThemeReference? = nil, serviceBackgroundColor: UIColor?, preview: Bool = false) -> PresentationTheme {
|
||||
let theme: PresentationTheme
|
||||
switch reference {
|
||||
case .dayClassic:
|
||||
theme = makeDefaultDayPresentationTheme(serviceBackgroundColor: serviceBackgroundColor, day: false, preview: preview)
|
||||
theme = makeDefaultDayPresentationTheme(extendingThemeReference: extendingThemeReference, serviceBackgroundColor: serviceBackgroundColor, day: false, preview: preview)
|
||||
case .day:
|
||||
theme = makeDefaultDayPresentationTheme(serviceBackgroundColor: serviceBackgroundColor, day: true, preview: preview)
|
||||
theme = makeDefaultDayPresentationTheme(extendingThemeReference: extendingThemeReference, serviceBackgroundColor: serviceBackgroundColor, day: true, preview: preview)
|
||||
case .night:
|
||||
theme = makeDefaultDarkPresentationTheme(preview: preview)
|
||||
theme = makeDefaultDarkPresentationTheme(extendingThemeReference: extendingThemeReference, preview: preview)
|
||||
case .nightAccent:
|
||||
theme = makeDefaultDarkTintedPresentationTheme(preview: preview)
|
||||
theme = makeDefaultDarkTintedPresentationTheme(extendingThemeReference: extendingThemeReference, preview: preview)
|
||||
}
|
||||
return theme
|
||||
}
|
||||
|
||||
public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper: TelegramWallpaper? = nil) -> PresentationTheme {
|
||||
if accentColor == nil && bubbleColors == nil && backgroundColors == nil {
|
||||
if accentColor == nil && bubbleColors == nil && backgroundColors == nil && wallpaper == nil {
|
||||
return theme
|
||||
}
|
||||
switch theme.referenceTheme {
|
||||
@ -35,11 +35,11 @@ public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool
|
||||
return theme
|
||||
}
|
||||
|
||||
public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, accentColor: UIColor? = nil, backgroundColors: (UIColor, UIColor?)? = nil, bubbleColors: (UIColor, UIColor?)? = nil, wallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor? = nil, preview: Bool = false) -> PresentationTheme? {
|
||||
public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, extendingThemeReference: PresentationThemeReference? = nil, accentColor: UIColor? = nil, backgroundColors: (UIColor, UIColor?)? = nil, bubbleColors: (UIColor, UIColor?)? = nil, wallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor? = nil, preview: Bool = false) -> PresentationTheme? {
|
||||
let theme: PresentationTheme
|
||||
switch themeReference {
|
||||
case let .builtin(reference):
|
||||
let defaultTheme = makeDefaultPresentationTheme(reference: reference, serviceBackgroundColor: serviceBackgroundColor, preview: preview)
|
||||
let defaultTheme = makeDefaultPresentationTheme(reference: reference, extendingThemeReference: extendingThemeReference, serviceBackgroundColor: serviceBackgroundColor, preview: preview)
|
||||
theme = customizePresentationTheme(defaultTheme, editing: true, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper)
|
||||
case let .local(info):
|
||||
if let path = mediaBox.completedResourcePath(info.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead), let loadedTheme = makePresentationTheme(data: data, themeReference: themeReference, resolvedWallpaper: info.resolvedWallpaper) {
|
||||
@ -49,7 +49,7 @@ public func makePresentationTheme(mediaBox: MediaBox, themeReference: Presentati
|
||||
}
|
||||
case let .cloud(info):
|
||||
if let settings = info.theme.settings {
|
||||
if let loadedTheme = makePresentationTheme(mediaBox: mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: accentColor ?? UIColor(rgb: UInt32(bitPattern: settings.accentColor)), backgroundColors: nil, bubbleColors: bubbleColors ?? settings.messageColors.flatMap { (UIColor(rgb: UInt32(bitPattern: $0.top)), UIColor(rgb: UInt32(bitPattern: $0.bottom))) }, wallpaper: wallpaper ?? settings.wallpaper, serviceBackgroundColor: serviceBackgroundColor, preview: preview) {
|
||||
if let loadedTheme = makePresentationTheme(mediaBox: mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), extendingThemeReference: themeReference, accentColor: accentColor ?? UIColor(rgb: UInt32(bitPattern: settings.accentColor)), backgroundColors: nil, bubbleColors: bubbleColors ?? settings.messageColors.flatMap { (UIColor(rgb: UInt32(bitPattern: $0.top)), UIColor(rgb: UInt32(bitPattern: $0.bottom))) }, wallpaper: wallpaper ?? settings.wallpaper, serviceBackgroundColor: serviceBackgroundColor, preview: preview) {
|
||||
theme = loadedTheme
|
||||
} else {
|
||||
return nil
|
||||
|
@ -1105,6 +1105,28 @@ public enum PresentationThemeName: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public extension PresentationThemeReference {
|
||||
public var name: PresentationThemeName {
|
||||
switch self {
|
||||
case let .builtin(theme):
|
||||
switch theme {
|
||||
case .day:
|
||||
return .builtin(.day)
|
||||
case .dayClassic:
|
||||
return .builtin(.dayClassic)
|
||||
case .night:
|
||||
return .builtin(.night)
|
||||
case .nightAccent:
|
||||
return .builtin(.nightAccent)
|
||||
}
|
||||
case let .cloud(info):
|
||||
return .custom(info.theme.title)
|
||||
default:
|
||||
return .custom("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final class PresentationTheme: Equatable {
|
||||
public let name: PresentationThemeName
|
||||
public let index: Int64
|
||||
|
@ -139,7 +139,7 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager {
|
||||
theme = updatedTheme
|
||||
}
|
||||
|
||||
return PresentationThemeSettings(theme: theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
return PresentationThemeSettings(theme: theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: current.themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
})
|
||||
}).start()
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager {
|
||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||
themeSpecificChatWallpapers[themeReference.index] = updatedWallpaper
|
||||
themeSpecificChatWallpapers[coloredThemeIndex(reference: themeReference, accentColor: current.themeSpecificAccentColors[themeReference.index])] = updatedWallpaper
|
||||
return PresentationThemeSettings(theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificCustomColors: current.themeSpecificCustomColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
return PresentationThemeSettings(theme: current.theme, themeSpecificAccentColors: current.themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: current.automaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations)
|
||||
})).start()
|
||||
}
|
||||
}
|
||||
|
@ -220,6 +220,16 @@ public enum PresentationThemeReference: PostboxCoding, Equatable {
|
||||
|
||||
return (Int64(namespace) << 32) | Int64(bitPattern: UInt64(UInt32(bitPattern: id)))
|
||||
}
|
||||
|
||||
public var generalThemeReference: PresentationThemeReference {
|
||||
let generalThemeReference: PresentationThemeReference
|
||||
if case let .cloud(theme) = self, let settings = theme.theme.settings {
|
||||
generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme))
|
||||
} else {
|
||||
generalThemeReference = self
|
||||
}
|
||||
return generalThemeReference
|
||||
}
|
||||
}
|
||||
|
||||
public func coloredThemeIndex(reference: PresentationThemeReference, accentColor: PresentationThemeAccentColor?) -> Int64 {
|
||||
@ -353,6 +363,7 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable {
|
||||
case white
|
||||
case custom
|
||||
case preset
|
||||
case theme
|
||||
|
||||
public var color: UIColor {
|
||||
let value: UInt32
|
||||
@ -379,39 +390,13 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable {
|
||||
value = 0x000000
|
||||
case .white:
|
||||
value = 0xffffff
|
||||
case .custom, .preset:
|
||||
case .custom, .preset, .theme:
|
||||
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
|
||||
@ -422,6 +407,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
public var accentColor: Int32?
|
||||
public var bubbleColors: (Int32, Int32?)?
|
||||
public var wallpaper: TelegramWallpaper?
|
||||
public var themeIndex: Int64?
|
||||
|
||||
public init(baseColor: PresentationThemeBaseColor) {
|
||||
if baseColor != .preset && baseColor != .custom {
|
||||
@ -443,6 +429,15 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
self.wallpaper = wallpaper
|
||||
}
|
||||
|
||||
public init(themeIndex: Int64) {
|
||||
self.index = -1
|
||||
self.baseColor = .theme
|
||||
self.accentColor = nil
|
||||
self.bubbleColors = nil
|
||||
self.wallpaper = nil
|
||||
self.themeIndex = themeIndex
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.index = decoder.decodeInt32ForKey("i", orElse: -1)
|
||||
self.baseColor = PresentationThemeBaseColor(rawValue: decoder.decodeInt32ForKey("b", orElse: 0)) ?? .blue
|
||||
@ -457,6 +452,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
self.bubbleColors = nil
|
||||
}
|
||||
self.wallpaper = decoder.decodeObjectForKey("w", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
|
||||
self.themeIndex = decoder.decodeOptionalInt64ForKey("t")
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
@ -483,6 +479,11 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "w")
|
||||
}
|
||||
if let themeIndex = self.themeIndex {
|
||||
encoder.encodeInt64(themeIndex, forKey: "t")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "t")
|
||||
}
|
||||
}
|
||||
|
||||
public var color: UIColor {
|
||||
@ -525,7 +526,6 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||
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
|
||||
@ -565,24 +565,16 @@ public struct PresentationThemeSettings: PreferencesEntry {
|
||||
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)
|
||||
return PresentationThemeSettings(theme: .builtin(.dayClassic), themeSpecificAccentColors: [:], 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) {
|
||||
public init(theme: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], 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
|
||||
@ -600,12 +592,6 @@ public struct PresentationThemeSettings: PreferencesEntry {
|
||||
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
|
||||
@ -624,9 +610,6 @@ public struct PresentationThemeSettings: PreferencesEntry {
|
||||
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")
|
||||
})
|
||||
@ -646,43 +629,39 @@ public struct PresentationThemeSettings: PreferencesEntry {
|
||||
}
|
||||
|
||||
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
|
||||
return lhs.theme == rhs.theme && lhs.themeSpecificAccentColors == rhs.themeSpecificAccentColors && 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)
|
||||
return PresentationThemeSettings(theme: theme, themeSpecificAccentColors: self.themeSpecificAccentColors, 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)
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: themeSpecificAccentColors, 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)
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, 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)
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, 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)
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, 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)
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, 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)
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, 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)
|
||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: disableAnimations)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1164,78 +1164,101 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
} else if case let .cloud(theme) = theme, let resource = theme.theme.file?.resource {
|
||||
reference = .theme(theme: .slug(theme.theme.slug), resource: resource)
|
||||
}
|
||||
|
||||
let themeSignal: Signal<PresentationTheme?, NoError>
|
||||
if let reference = reference {
|
||||
colorsSignal = telegramThemeData(account: account, accountManager: accountManager, reference: reference, synchronousLoad: false)
|
||||
|> mapToSignal { data -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in
|
||||
themeSignal = telegramThemeData(account: account, accountManager: accountManager, reference: reference, synchronousLoad: false)
|
||||
|> map { data -> PresentationTheme? in
|
||||
if let data = data, let theme = makePresentationTheme(data: data) {
|
||||
var wallpaperSignal: Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> = .complete()
|
||||
var rotation: Int32?
|
||||
let backgroundColor: (UIColor, UIColor?)
|
||||
let incomingColor = (theme.chat.message.incoming.bubble.withoutWallpaper.fill, theme.chat.message.incoming.bubble.withoutWallpaper.gradientFill)
|
||||
let outgoingColor = (theme.chat.message.outgoing.bubble.withoutWallpaper.fill, theme.chat.message.outgoing.bubble.withoutWallpaper.gradientFill)
|
||||
switch theme.chat.defaultWallpaper {
|
||||
case .builtin:
|
||||
backgroundColor = (UIColor(rgb: 0xd6e2ee), nil)
|
||||
case let .color(color):
|
||||
backgroundColor = (UIColor(rgb: UInt32(bitPattern: color)), nil)
|
||||
case let .gradient(topColor, bottomColor, settings):
|
||||
backgroundColor = (UIColor(rgb: UInt32(bitPattern: topColor)), UIColor(rgb: UInt32(bitPattern: bottomColor)))
|
||||
rotation = settings.rotation
|
||||
case .image:
|
||||
backgroundColor = (.black, nil)
|
||||
case let .file(file):
|
||||
rotation = file.settings.rotation
|
||||
if file.isPattern, let color = file.settings.color {
|
||||
backgroundColor = (UIColor(rgb: UInt32(bitPattern: color)), file.settings.bottomColor.flatMap { UIColor(rgb: UInt32(bitPattern: $0)) })
|
||||
} else {
|
||||
backgroundColor = (theme.chatList.backgroundColor, nil)
|
||||
}
|
||||
wallpaperSignal = cachedWallpaper(account: account, slug: file.slug, settings: file.settings)
|
||||
|> mapToSignal { wallpaper in
|
||||
if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper {
|
||||
var convertedRepresentations: [ImageRepresentationWithReference] = []
|
||||
convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .media(media: .standalone(media: file.file), resource: file.file.resource)))
|
||||
return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false)
|
||||
|> mapToSignal { _, fullSizeData, complete -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in
|
||||
guard complete, let fullSizeData = fullSizeData else {
|
||||
return .complete()
|
||||
}
|
||||
accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData)
|
||||
let _ = accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start()
|
||||
|
||||
if file.isPattern, let color = file.settings.color, let intensity = file.settings.intensity {
|
||||
return theme
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else if case let .cloud(theme) = theme, let settings = theme.theme.settings {
|
||||
themeSignal = Signal { subscriber in
|
||||
let theme = makePresentationTheme(mediaBox: accountManager.mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: UIColor(rgb: UInt32(bitPattern: settings.accentColor)), backgroundColors: nil, bubbleColors: settings.messageColors.flatMap { (UIColor(rgb: UInt32(bitPattern: $0.top)), UIColor(rgb: UInt32(bitPattern: $0.bottom))) }, wallpaper: settings.wallpaper, serviceBackgroundColor: nil, preview: false)
|
||||
subscriber.putNext(theme)
|
||||
subscriber.putCompletion()
|
||||
|
||||
return EmptyDisposable
|
||||
}
|
||||
} else {
|
||||
themeSignal = .never()
|
||||
}
|
||||
|
||||
colorsSignal = themeSignal
|
||||
|> mapToSignal { theme -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in
|
||||
if let theme = theme {
|
||||
var wallpaperSignal: Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> = .complete()
|
||||
var rotation: Int32?
|
||||
let backgroundColor: (UIColor, UIColor?)
|
||||
let incomingColor = (theme.chat.message.incoming.bubble.withoutWallpaper.fill, theme.chat.message.incoming.bubble.withoutWallpaper.gradientFill)
|
||||
let outgoingColor = (theme.chat.message.outgoing.bubble.withoutWallpaper.fill, theme.chat.message.outgoing.bubble.withoutWallpaper.gradientFill)
|
||||
switch theme.chat.defaultWallpaper {
|
||||
case .builtin:
|
||||
backgroundColor = (UIColor(rgb: 0xd6e2ee), nil)
|
||||
case let .color(color):
|
||||
backgroundColor = (UIColor(rgb: UInt32(bitPattern: color)), nil)
|
||||
case let .gradient(topColor, bottomColor, settings):
|
||||
backgroundColor = (UIColor(rgb: UInt32(bitPattern: topColor)), UIColor(rgb: UInt32(bitPattern: bottomColor)))
|
||||
rotation = settings.rotation
|
||||
case .image:
|
||||
backgroundColor = (.black, nil)
|
||||
case let .file(file):
|
||||
rotation = file.settings.rotation
|
||||
if file.isPattern, let color = file.settings.color {
|
||||
backgroundColor = (UIColor(rgb: UInt32(bitPattern: color)), file.settings.bottomColor.flatMap { UIColor(rgb: UInt32(bitPattern: $0)) })
|
||||
} else {
|
||||
backgroundColor = (theme.chatList.backgroundColor, nil)
|
||||
}
|
||||
wallpaperSignal = cachedWallpaper(account: account, slug: file.slug, settings: file.settings)
|
||||
|> mapToSignal { wallpaper in
|
||||
if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper {
|
||||
var convertedRepresentations: [ImageRepresentationWithReference] = []
|
||||
convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .media(media: .standalone(media: file.file), resource: file.file.resource)))
|
||||
return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false)
|
||||
|> mapToSignal { _, fullSizeData, complete -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in
|
||||
guard complete, let fullSizeData = fullSizeData else {
|
||||
return .complete()
|
||||
}
|
||||
accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData)
|
||||
let _ = accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedScaledImageRepresentation(size: CGSize(width: 720.0, height: 720.0), mode: .aspectFit), complete: true, fetch: true).start()
|
||||
|
||||
if file.isPattern {
|
||||
if let color = file.settings.color, let intensity = file.settings.intensity {
|
||||
return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedPatternWallpaperRepresentation(color: color, bottomColor: file.settings.bottomColor, intensity: intensity, rotation: file.settings.rotation), complete: true, fetch: true)
|
||||
|> mapToSignal { _ in
|
||||
return .complete()
|
||||
}
|
||||
} else if file.settings.blur {
|
||||
return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true)
|
||||
|> mapToSignal { _ in
|
||||
if let image = UIImage(data: fullSizeData) {
|
||||
return .single((backgroundColor, incomingColor, outgoingColor, image, rotation))
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
} else if let image = UIImage(data: fullSizeData) {
|
||||
return .single((backgroundColor, incomingColor, outgoingColor, image, rotation))
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
} else if file.settings.blur {
|
||||
return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true)
|
||||
|> mapToSignal { _ in
|
||||
if let image = UIImage(data: fullSizeData) {
|
||||
return .single((backgroundColor, incomingColor, outgoingColor, image, rotation))
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
} else if let image = UIImage(data: fullSizeData) {
|
||||
return .single((backgroundColor, incomingColor, outgoingColor, image, rotation))
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
return .single((backgroundColor, incomingColor, outgoingColor, nil, rotation))
|
||||
|> then(wallpaperSignal)
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
return .single((backgroundColor, incomingColor, outgoingColor, nil, rotation))
|
||||
|> then(wallpaperSignal)
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
} else {
|
||||
colorsSignal = .never()
|
||||
}
|
||||
}
|
||||
return colorsSignal
|
||||
|
Loading…
x
Reference in New Issue
Block a user