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
|
import SwiftSignalKit
|
||||||
|
|
||||||
private let separatorHeight: CGFloat = 1.0 / UIScreen.main.scale
|
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 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
|
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 size: CGSize
|
||||||
let contentWidth: CGFloat
|
let contentWidth: CGFloat
|
||||||
if horizontal {
|
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
|
contentWidth = size.width
|
||||||
} else {
|
} 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
|
contentWidth = imageSize.width
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +55,7 @@ private func tabBarItemImage(_ image: UIImage?, title: String, backgroundColor:
|
|||||||
}
|
}
|
||||||
context.restoreGState()
|
context.restoreGState()
|
||||||
} else {
|
} 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.saveGState()
|
||||||
context.translateBy(x: imageRect.midX, y: imageRect.midY)
|
context.translateBy(x: imageRect.midX, y: imageRect.midY)
|
||||||
context.scaleBy(x: 1.0, y: -1.0)
|
context.scaleBy(x: 1.0, y: -1.0)
|
||||||
@ -215,6 +217,7 @@ class TabBarNode: ASDisplayNode {
|
|||||||
private var theme: TabBarControllerTheme
|
private var theme: TabBarControllerTheme
|
||||||
private var validLayout: (CGSize, CGFloat, CGFloat, CGFloat)?
|
private var validLayout: (CGSize, CGFloat, CGFloat, CGFloat)?
|
||||||
private var horizontal: Bool = false
|
private var horizontal: Bool = false
|
||||||
|
private var centered: Bool = false
|
||||||
|
|
||||||
private var badgeImage: UIImage
|
private var badgeImage: UIImage
|
||||||
|
|
||||||
@ -289,6 +292,8 @@ class TabBarNode: ASDisplayNode {
|
|||||||
node.badgeContainerNode.removeFromSupernode()
|
node.badgeContainerNode.removeFromSupernode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.centered = self.theme.tabBarTextColor == .clear
|
||||||
|
|
||||||
var tabBarNodeContainers: [TabBarNodeContainer] = []
|
var tabBarNodeContainers: [TabBarNodeContainer] = []
|
||||||
for i in 0 ..< self.tabBarItems.count {
|
for i in 0 ..< self.tabBarItems.count {
|
||||||
let item = self.tabBarItems[i]
|
let item = self.tabBarItems[i]
|
||||||
@ -304,15 +309,15 @@ class TabBarNode: ASDisplayNode {
|
|||||||
self?.updateNodeImage(i, layout: true)
|
self?.updateNodeImage(i, layout: true)
|
||||||
})
|
})
|
||||||
if let selectedIndex = self.selectedIndex, selectedIndex == i {
|
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 (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)
|
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.textImageNode.image = textImage
|
||||||
node.imageNode.image = image
|
node.imageNode.image = image
|
||||||
node.accessibilityLabel = item.title
|
node.accessibilityLabel = item.title
|
||||||
node.contentWidth = max(contentWidth, imageContentWidth)
|
node.contentWidth = max(contentWidth, imageContentWidth)
|
||||||
} else {
|
} else {
|
||||||
let (textImage, contentWidth) = tabBarItemImage(item.image, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarTextColor, horizontal: self.horizontal, imageMode: false)
|
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.tabBarTextColor, horizontal: self.horizontal, imageMode: true)
|
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.textImageNode.image = textImage
|
||||||
node.accessibilityLabel = item.title
|
node.accessibilityLabel = item.title
|
||||||
node.imageNode.image = image
|
node.imageNode.image = image
|
||||||
@ -337,18 +342,20 @@ class TabBarNode: ASDisplayNode {
|
|||||||
let node = self.tabBarNodeContainers[index].imageNode
|
let node = self.tabBarNodeContainers[index].imageNode
|
||||||
let item = self.tabBarItems[index]
|
let item = self.tabBarItems[index]
|
||||||
|
|
||||||
|
self.centered = self.theme.tabBarTextColor == .clear
|
||||||
|
|
||||||
let previousImageSize = node.imageNode.image?.size ?? CGSize()
|
let previousImageSize = node.imageNode.image?.size ?? CGSize()
|
||||||
let previousTextImageSize = node.textImageNode.image?.size ?? CGSize()
|
let previousTextImageSize = node.textImageNode.image?.size ?? CGSize()
|
||||||
if let selectedIndex = self.selectedIndex, selectedIndex == index {
|
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 (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)
|
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.textImageNode.image = textImage
|
||||||
node.accessibilityLabel = item.title
|
node.accessibilityLabel = item.title
|
||||||
node.imageNode.image = image
|
node.imageNode.image = image
|
||||||
node.contentWidth = max(contentWidth, imageContentWidth)
|
node.contentWidth = max(contentWidth, imageContentWidth)
|
||||||
} else {
|
} else {
|
||||||
let (textImage, contentWidth) = tabBarItemImage(item.image, title: item.title ?? "", backgroundColor: .clear, tintColor: self.theme.tabBarTextColor, horizontal: self.horizontal, imageMode: false)
|
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)
|
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.textImageNode.image = textImage
|
||||||
node.accessibilityLabel = item.title
|
node.accessibilityLabel = item.title
|
||||||
node.imageNode.image = image
|
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 backgroundSize = CGSize(width: hasSingleLetterValue ? 18.0 : max(18.0, badgeSize.width + 10.0 + 1.0), height: 18.0)
|
||||||
let backgroundFrame: CGRect
|
let backgroundFrame: CGRect
|
||||||
if horizontal {
|
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 {
|
} else {
|
||||||
let contentWidth = node.contentWidth ?? node.frame.width
|
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)
|
transition.updateFrame(node: container.badgeContainerNode, frame: backgroundFrame)
|
||||||
container.badgeBackgroundNode.frame = CGRect(origin: CGPoint(), size: backgroundFrame.size)
|
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)
|
initialState = EditThemeControllerState(mode: mode, title: generateThemeName(accentColor: theme.rootController.navigationBar.buttonColor), slug: "", updatedTheme: nil, updating: false)
|
||||||
previewThemePromise.set(.single(theme.withUpdated(name: "", defaultWallpaper: wallpaper)))
|
previewThemePromise.set(.single(theme.withUpdated(name: "", defaultWallpaper: wallpaper)))
|
||||||
case let .edit(info):
|
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 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 {
|
if case let .file(file) = theme.chat.defaultWallpaper, file.id == 0 {
|
||||||
previewThemePromise.set(cachedWallpaper(account: context.account, slug: file.slug, settings: file.settings)
|
previewThemePromise.set(cachedWallpaper(account: context.account, slug: file.slug, settings: file.settings)
|
||||||
@ -295,7 +296,6 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
|||||||
} else {
|
} else {
|
||||||
previewThemePromise.set(.single(theme.withUpdated(name: nil, defaultWallpaper: info.resolvedWallpaper)))
|
previewThemePromise.set(.single(theme.withUpdated(name: nil, defaultWallpaper: info.resolvedWallpaper)))
|
||||||
}
|
}
|
||||||
settingsPromise.set(.single(info.theme.settings))
|
|
||||||
} else {
|
} else {
|
||||||
previewThemePromise.set(.single(presentationData.theme.withUpdated(name: "", defaultWallpaper: presentationData.chatWallpaper)))
|
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())
|
let _ = (combineLatest(queue: Queue.mainQueue(), previewThemePromise.get(), settingsPromise.get())
|
||||||
|> take(1)).start(next: { theme, previousSettings in
|
|> take(1)).start(next: { theme, previousSettings in
|
||||||
var controllerDismissImpl: (() -> Void)?
|
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
|
updateState { current in
|
||||||
var state = current
|
var state = current
|
||||||
previewThemePromise.set(.single(updatedTheme))
|
previewThemePromise.set(.single(updatedTheme))
|
||||||
@ -515,7 +515,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
|||||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
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: {
|
}) |> deliverOnMainQueue).start(completed: {
|
||||||
if !hasCustomFile {
|
if !hasCustomFile {
|
||||||
saveThemeTemplateFile(state.title, themeResource, {
|
saveThemeTemplateFile(state.title, themeResource, {
|
||||||
@ -549,7 +549,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|
|||||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
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: {
|
}) |> deliverOnMainQueue).start(completed: {
|
||||||
if let themeResource = themeResource, !hasCustomFile {
|
if let themeResource = themeResource, !hasCustomFile {
|
||||||
saveThemeTemplateFile(state.title, themeResource, {
|
saveThemeTemplateFile(state.title, themeResource, {
|
||||||
|
@ -17,13 +17,13 @@ private let randomBackgroundColors: [Int32] = [0x007aff, 0x00c2ed, 0x29b327, 0xe
|
|||||||
enum ThemeAccentColorControllerMode {
|
enum ThemeAccentColorControllerMode {
|
||||||
case colors(themeReference: PresentationThemeReference, create: Bool)
|
case colors(themeReference: PresentationThemeReference, create: Bool)
|
||||||
case background(themeReference: PresentationThemeReference)
|
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? {
|
var themeReference: PresentationThemeReference? {
|
||||||
switch self {
|
switch self {
|
||||||
case let .colors(themeReference, _), let .background(themeReference):
|
case let .colors(themeReference, _), let .background(themeReference):
|
||||||
return themeReference
|
return themeReference
|
||||||
case let .edit(_, _, defaultThemeReference, _, _):
|
case let .edit(_, _, _, defaultThemeReference, _, _):
|
||||||
return defaultThemeReference
|
return defaultThemeReference
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
@ -119,7 +119,7 @@ final class ThemeAccentColorController: ViewController {
|
|||||||
|
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let wallpaper: TelegramWallpaper
|
let wallpaper: TelegramWallpaper
|
||||||
if case let .edit(editedTheme, walpaper, _, _, _) = self.mode {
|
if case let .edit(editedTheme, walpaper, _, _, _, _) = self.mode {
|
||||||
theme = editedTheme
|
theme = editedTheme
|
||||||
wallpaper = walpaper ?? editedTheme.chat.defaultWallpaper
|
wallpaper = walpaper ?? editedTheme.chat.defaultWallpaper
|
||||||
} else {
|
} else {
|
||||||
@ -178,26 +178,36 @@ final class ThemeAccentColorController: ViewController {
|
|||||||
prepare = .complete()
|
prepare = .complete()
|
||||||
}
|
}
|
||||||
|
|
||||||
if case let .edit(theme, _, themeReference, _, completion) = strongSelf.mode {
|
if case let .edit(theme, _, generalThemeReference, themeReference, _, completion) = strongSelf.mode {
|
||||||
let _ = (prepare
|
let _ = (prepare
|
||||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||||
let updatedTheme: PresentationTheme
|
let updatedTheme: PresentationTheme
|
||||||
|
|
||||||
var settings: TelegramThemeSettings?
|
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 {
|
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
|
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
|
||||||
|
} else {
|
||||||
|
updatedTheme = customizePresentationTheme(theme, editing: false, accentColor: state.accentColor, backgroundColors: state.backgroundColors, bubbleColors: state.messagesColors, wallpaper: state.initialWallpaper ?? coloredWallpaper)
|
||||||
|
}
|
||||||
|
|
||||||
if case let .builtin(theme) = themeReference {
|
if hasSettings, let baseTheme = baseTheme {
|
||||||
var messageColors: (Int32, Int32)?
|
var messageColors: (Int32, Int32)?
|
||||||
if let colors = state.messagesColors {
|
if let colors = state.messagesColors {
|
||||||
messageColors = (Int32(bitPattern: colors.0.rgb), Int32(bitPattern: colors.1?.rgb ?? colors.0.rgb))
|
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)
|
settings = TelegramThemeSettings(baseTheme: 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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
completion(updatedTheme, settings)
|
completion(updatedTheme, settings)
|
||||||
@ -208,6 +218,8 @@ final class ThemeAccentColorController: ViewController {
|
|||||||
if case let .cloud(theme) = theme, let settings = theme.theme.settings {
|
if case let .cloud(theme) = theme, let settings = theme.theme.settings {
|
||||||
telegramTheme = theme.theme
|
telegramTheme = theme.theme
|
||||||
baseTheme = settings.baseTheme
|
baseTheme = settings.baseTheme
|
||||||
|
} else if case let .builtin(theme) = theme {
|
||||||
|
baseTheme = theme.baseTheme
|
||||||
} else {
|
} else {
|
||||||
baseTheme = .classic
|
baseTheme = .classic
|
||||||
}
|
}
|
||||||
@ -228,6 +240,7 @@ final class ThemeAccentColorController: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: accentColor, messageColors: bubbleColors, wallpaper: wallpaper)
|
let settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: accentColor, messageColors: bubbleColors, wallpaper: wallpaper)
|
||||||
|
let baseThemeReference = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: baseTheme))
|
||||||
|
|
||||||
let save: Signal<Void, NoError>
|
let save: Signal<Void, NoError>
|
||||||
|
|
||||||
@ -246,7 +259,10 @@ final class ThemeAccentColorController: ViewController {
|
|||||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
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: {
|
}) |> deliverOnMainQueue).start(completed: {
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.completion?()
|
strongSelf.completion?()
|
||||||
@ -272,7 +288,10 @@ final class ThemeAccentColorController: ViewController {
|
|||||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||||
themeSpecificChatWallpapers[themeReference.index] = nil
|
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: {
|
}) |> deliverOnMainQueue).start(completed: {
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.completion?()
|
strongSelf.completion?()
|
||||||
@ -283,35 +302,6 @@ final class ThemeAccentColorController: ViewController {
|
|||||||
}, error: { error in
|
}, 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] {
|
} else if let customWallpaper = settings.themeSpecificChatWallpapers[themeReference.index] {
|
||||||
wallpaper = customWallpaper
|
wallpaper = customWallpaper
|
||||||
} else {
|
} 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 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
|
ignoreDefaultWallpaper = true
|
||||||
} else if case .nightAccent = themeName {
|
} else if case .nightAccent = themeName {
|
||||||
ignoreDefaultWallpaper = true
|
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
|
accentColor = theme.rootController.navigationBar.accentTextColor
|
||||||
|
|
||||||
let wallpaper = wallpaper ?? theme.chat.defaultWallpaper
|
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)
|
self.patternPanelNode = WallpaperPatternPanelNode(context: self.context, theme: self.theme, strings: self.presentationData.strings)
|
||||||
|
|
||||||
let doneButtonType: WallpaperGalleryToolbarDoneButtonType
|
let doneButtonType: WallpaperGalleryToolbarDoneButtonType
|
||||||
if case .edit(_, _, _, true, _) = self.mode {
|
if case .edit(_, _, _, _, true, _) = self.mode {
|
||||||
doneButtonType = .proceed
|
doneButtonType = .proceed
|
||||||
} else {
|
} else {
|
||||||
doneButtonType = .set
|
doneButtonType = .set
|
||||||
@ -469,7 +469,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
|||||||
if !updateOnlyWallpaper {
|
if !updateOnlyWallpaper {
|
||||||
if let themeReference = mode.themeReference {
|
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
|
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)
|
updatedTheme = customizePresentationTheme(theme, editing: false, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: messagesColors)
|
||||||
} else {
|
} else {
|
||||||
updatedTheme = theme
|
updatedTheme = theme
|
||||||
@ -700,7 +700,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
|||||||
doneButtonType = .apply
|
doneButtonType = .apply
|
||||||
cancelButtonType = .discard
|
cancelButtonType = .discard
|
||||||
} else {
|
} else {
|
||||||
if case .edit(_, _, _, true, _) = self.mode {
|
if case .edit(_, _, _, _, true, _) = self.mode {
|
||||||
doneButtonType = .proceed
|
doneButtonType = .proceed
|
||||||
} else {
|
} else {
|
||||||
doneButtonType = .set
|
doneButtonType = .set
|
||||||
|
@ -68,7 +68,7 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
case settingInfo(PresentationTheme, String)
|
case settingInfo(PresentationTheme, String)
|
||||||
|
|
||||||
case themeHeader(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 {
|
var section: ItemListSectionId {
|
||||||
switch self {
|
switch self {
|
||||||
@ -186,8 +186,8 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeChatWallpapers):
|
case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsAllThemes, 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 {
|
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
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -244,8 +244,8 @@ private enum ThemeAutoNightSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||||
case let .themeHeader(theme, title):
|
case let .themeHeader(theme, title):
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section)
|
return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section)
|
||||||
case let .themeItem(theme, strings, themes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers):
|
case let .themeItem(theme, strings, themes, allThemes, 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
|
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)
|
arguments.updateTheme(theme)
|
||||||
}, contextAction: nil)
|
}, contextAction: nil)
|
||||||
}
|
}
|
||||||
@ -313,7 +313,16 @@ private func themeAutoNightSettingsControllerEntries(theme: PresentationTheme, s
|
|||||||
break
|
break
|
||||||
case .system, .timeBased, .brightness:
|
case .system, .timeBased, .brightness:
|
||||||
entries.append(.themeHeader(theme, strings.AutoNightTheme_PreferredTheme))
|
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
|
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 {
|
var index: Int64 {
|
||||||
switch self {
|
switch self {
|
||||||
case let .accentColor(color):
|
case let .accentColor(color):
|
||||||
@ -341,7 +350,7 @@ private final class ThemeSettingsAccentColorIconItemNode : ListViewItemNode {
|
|||||||
var updatedAccentColor = false
|
var updatedAccentColor = false
|
||||||
var updatedSelected = false
|
var updatedSelected = false
|
||||||
|
|
||||||
if currentItem == nil || currentItem?.color != item.color {
|
if currentItem == nil || currentItem?.color != item.color || currentItem?.themeReference != item.themeReference {
|
||||||
updatedAccentColor = true
|
updatedAccentColor = true
|
||||||
}
|
}
|
||||||
if currentItem?.selected != item.selected {
|
if currentItem?.selected != item.selected {
|
||||||
@ -418,7 +427,7 @@ private final class ThemeSettingsAccentColorIconItemNode : ListViewItemNode {
|
|||||||
strongSelf.dotsNode.bounds = bounds
|
strongSelf.dotsNode.bounds = bounds
|
||||||
|
|
||||||
if updatedSelected {
|
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 deletions: [ListViewDeleteItem]
|
||||||
let insertions: [ListViewInsertItem]
|
let insertions: [ListViewInsertItem]
|
||||||
let updates: [ListViewUpdateItem]
|
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 (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
||||||
|
|
||||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
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 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) }
|
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 {
|
private func ensureColorVisible(listNode: ListView, accentColor: ThemeSettingsColorOption?, animated: Bool) -> Bool {
|
||||||
@ -758,19 +767,15 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
self.enqueuedTransitions.remove(at: 0)
|
self.enqueuedTransitions.remove(at: 0)
|
||||||
|
|
||||||
var options = ListViewDeleteAndInsertOptions()
|
var options = ListViewDeleteAndInsertOptions()
|
||||||
if self.initialized && transition.crossfade {
|
|
||||||
options.insert(.AnimateCrossfade)
|
|
||||||
}
|
|
||||||
|
|
||||||
var scrollToItem: ListViewScrollToItem?
|
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 }) {
|
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)
|
scrollToItem = ListViewScrollToItem(index: index, position: .bottom(-56.0), animated: false, curve: .Default(duration: 0.0), directionHint: .Down)
|
||||||
self.initialized = true
|
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
|
let contextAction: ((ThemeSettingsColorOption?, Bool, ASDisplayNode, ContextGesture?) -> Void)? = { [weak item] color, selected, node, gesture in
|
||||||
if let strongSelf = self, let item = strongSelf.item {
|
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
|
let openColorPicker: (Bool) -> Void = { [weak self] create in
|
||||||
@ -932,8 +937,8 @@ class ThemeSettingsAccentColorItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let previousEntries = strongSelf.entries ?? []
|
let previousEntries = strongSelf.entries ?? []
|
||||||
let crossfade = previousEntries.count != entries.count || (currentItem != nil && (currentItem?.generalThemeReference.index != item.generalThemeReference.index))
|
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, crossfade: crossfade)
|
let transition = preparedTransition(action: action, contextAction: contextAction, openColorPicker: openColorPicker, from: previousEntries, to: entries, updatePosition: updatePosition)
|
||||||
strongSelf.enqueueTransition(transition)
|
strongSelf.enqueueTransition(transition)
|
||||||
|
|
||||||
strongSelf.entries = entries
|
strongSelf.entries = entries
|
||||||
|
@ -133,10 +133,10 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
case fontSize(PresentationTheme, PresentationFontSize)
|
case fontSize(PresentationTheme, PresentationFontSize)
|
||||||
case chatPreview(PresentationTheme, PresentationTheme, TelegramWallpaper, PresentationFontSize, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, [ChatPreviewMessageItem])
|
case chatPreview(PresentationTheme, PresentationTheme, TelegramWallpaper, PresentationFontSize, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, [ChatPreviewMessageItem])
|
||||||
case wallpaper(PresentationTheme, String)
|
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 autoNightTheme(PresentationTheme, String, String)
|
||||||
case textSize(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 iconHeader(PresentationTheme, String)
|
||||||
case iconItem(PresentationTheme, PresentationStrings, [PresentationAppIcon], String?)
|
case iconItem(PresentationTheme, PresentationStrings, [PresentationAppIcon], String?)
|
||||||
case otherHeader(PresentationTheme, String)
|
case otherHeader(PresentationTheme, String)
|
||||||
@ -208,8 +208,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case let .accentColor(lhsTheme, lhsGeneralTheme, lhsCurrentTheme, lhsCustomColors, lhsThemes, lhsColor):
|
case let .accentColor(lhsTheme, lhsGeneralTheme, lhsCurrentTheme, lhsThemes, lhsColor):
|
||||||
if case let .accentColor(rhsTheme, rhsGeneralTheme, rhsCurrentTheme, rhsCustomColors, rhsThemes, rhsColor) = rhs, lhsTheme === rhsTheme, lhsCurrentTheme == rhsCurrentTheme, lhsCustomColors == rhsCustomColors, lhsThemes == rhsThemes, lhsColor == rhsColor {
|
if case let .accentColor(rhsTheme, rhsGeneralTheme, rhsCurrentTheme, rhsThemes, rhsColor) = rhs, lhsTheme === rhsTheme, lhsCurrentTheme == rhsCurrentTheme, lhsThemes == rhsThemes, lhsColor == rhsColor {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -232,8 +232,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsCurrentTheme, lhsThemeAccentColors, lhsThemeSpecificChatWallpapers, lhsCurrentColor):
|
case let .themeItem(lhsTheme, lhsStrings, lhsThemes, lhsAllThemes, 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 {
|
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
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -308,7 +308,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: {
|
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: "", sectionId: self.section, style: .blocks, action: {
|
||||||
arguments.openWallpaperSettings()
|
arguments.openWallpaperSettings()
|
||||||
})
|
})
|
||||||
case let .accentColor(theme, generalThemeReference, currentTheme, customColors, themes, color):
|
case let .accentColor(theme, generalThemeReference, currentTheme, themes, color):
|
||||||
var colorItems: [ThemeSettingsAccentColor] = []
|
var colorItems: [ThemeSettingsAccentColor] = []
|
||||||
|
|
||||||
for theme in themes {
|
for theme in themes {
|
||||||
@ -317,7 +317,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
|
|
||||||
var defaultColor: PresentationThemeAccentColor? = PresentationThemeAccentColor(baseColor: .blue)
|
var defaultColor: PresentationThemeAccentColor? = PresentationThemeAccentColor(baseColor: .blue)
|
||||||
var colors = PresentationThemeBaseColor.allCases
|
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 case let .builtin(name) = generalThemeReference {
|
||||||
if name == .dayClassic {
|
if name == .dayClassic {
|
||||||
colorItems.append(.default)
|
colorItems.append(.default)
|
||||||
@ -358,14 +358,6 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
let currentColor = color ?? defaultColor.flatMap { .accentColor($0) }
|
let currentColor = color ?? defaultColor.flatMap { .accentColor($0) }
|
||||||
colorItems.append(contentsOf: colors.map { .color($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
|
return ThemeSettingsAccentColorItem(theme: theme, sectionId: self.section, generalThemeReference: generalThemeReference, themeReference: currentTheme, colors: colorItems, currentColor: currentColor, updated: { color in
|
||||||
if let color = color {
|
if let color = color {
|
||||||
switch color {
|
switch color {
|
||||||
@ -392,9 +384,9 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
|
|||||||
})
|
})
|
||||||
case let .themeListHeader(theme, text):
|
case let .themeListHeader(theme, text):
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
||||||
case let .themeItem(theme, strings, themes, currentTheme, themeSpecificAccentColors, themeSpecificChatWallpapers, _):
|
case let .themeItem(theme, strings, themes, allThemes, 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
|
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 {
|
if case let .cloud(theme) = theme, theme.theme.file == nil && theme.theme.settings == nil {
|
||||||
if theme.theme.isCreator {
|
if theme.theme.isCreator {
|
||||||
arguments.editTheme(theme)
|
arguments.editTheme(theme)
|
||||||
}
|
}
|
||||||
@ -449,7 +441,7 @@ private func themeSettingsControllerEntries(presentationData: PresentationData,
|
|||||||
generalThemeReference = themeReference
|
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 {
|
if case let .builtin(builtinTheme) = generalThemeReference {
|
||||||
let colorThemes = availableThemes.filter { reference in
|
let colorThemes = availableThemes.filter { reference in
|
||||||
@ -467,7 +459,7 @@ private func themeSettingsControllerEntries(presentationData: PresentationData,
|
|||||||
colorOption = .theme(themeReference)
|
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))
|
entries.append(.wallpaper(presentationData.theme, strings.Settings_ChatBackground))
|
||||||
@ -526,6 +518,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
var presentCrossfadeControllerImpl: ((Bool) -> Void)?
|
var presentCrossfadeControllerImpl: ((Bool) -> Void)?
|
||||||
|
|
||||||
var selectThemeImpl: ((PresentationThemeReference) -> Void)?
|
var selectThemeImpl: ((PresentationThemeReference) -> Void)?
|
||||||
|
var selectAccentColorImpl: ((PresentationThemeAccentColor?) -> Void)?
|
||||||
var moreImpl: (() -> Void)?
|
var moreImpl: (() -> Void)?
|
||||||
|
|
||||||
let _ = telegramWallpapers(postbox: context.account.postbox, network: context.account.network).start()
|
let _ = telegramWallpapers(postbox: context.account.postbox, network: context.account.network).start()
|
||||||
@ -555,87 +548,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
}, openWallpaperSettings: {
|
}, openWallpaperSettings: {
|
||||||
pushControllerImpl?(ThemeGridController(context: context))
|
pushControllerImpl?(ThemeGridController(context: context))
|
||||||
}, selectAccentColor: { accentColor in
|
}, selectAccentColor: { accentColor in
|
||||||
var wallpaperSignal: Signal<TelegramWallpaper?, NoError> = .single(nil)
|
selectAccentColorImpl?(accentColor)
|
||||||
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)
|
|
||||||
})
|
|
||||||
}, openAccentColorPicker: { themeReference, create in
|
}, openAccentColorPicker: { themeReference, create in
|
||||||
let controller = ThemeAccentColorController(context: context, mode: .colors(themeReference: themeReference, create: create))
|
let controller = ThemeAccentColorController(context: context, mode: .colors(themeReference: themeReference, create: create))
|
||||||
pushControllerImpl?(controller)
|
pushControllerImpl?(controller)
|
||||||
@ -685,7 +598,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
if let wallpaper = wallpaper {
|
if let wallpaper = wallpaper {
|
||||||
effectiveWallpaper = wallpaper
|
effectiveWallpaper = wallpaper
|
||||||
} else {
|
} 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())
|
effectiveWallpaper = theme?.chat.defaultWallpaper ?? .builtin(WallpaperSettings())
|
||||||
}
|
}
|
||||||
return (accentColor, effectiveWallpaper)
|
return (accentColor, effectiveWallpaper)
|
||||||
@ -750,7 +663,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
|
|
||||||
let _ = (resolvedWallpaper
|
let _ = (resolvedWallpaper
|
||||||
|> deliverOnMainQueue).start(next: { wallpaper in
|
|> 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
|
let controller = editThemeController(context: context, mode: .create(result, nil), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||||
@ -791,6 +704,9 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
|> take(1)
|
|> take(1)
|
||||||
|> deliverOnMainQueue).start(next: { themes in
|
|> deliverOnMainQueue).start(next: { themes in
|
||||||
if isCurrent, let currentThemeIndex = themes.firstIndex(where: { $0.id == theme.theme.id }) {
|
if isCurrent, let currentThemeIndex = themes.firstIndex(where: { $0.id == theme.theme.id }) {
|
||||||
|
if let settings = theme.theme.settings {
|
||||||
|
selectAccentColorImpl?(nil)
|
||||||
|
} else {
|
||||||
let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil })
|
let previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil })
|
||||||
let newTheme: PresentationThemeReference
|
let newTheme: PresentationThemeReference
|
||||||
if let previousThemeIndex = previousThemeIndex {
|
if let previousThemeIndex = previousThemeIndex {
|
||||||
@ -801,6 +717,8 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
selectThemeImpl?(newTheme)
|
selectThemeImpl?(newTheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
let _ = deleteThemeInteractively(account: context.account, accountManager: context.sharedContext.accountManager, theme: theme.theme).start()
|
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)
|
return (accentColor, wallpaper)
|
||||||
} |> mapToSignal { accentColor, wallpaper -> Signal<(PresentationTheme?, TelegramWallpaper?), NoError> in
|
} |> mapToSignal { accentColor, wallpaper -> Signal<(PresentationTheme?, PresentationThemeReference, TelegramWallpaper?), NoError> in
|
||||||
let generalThemeReference: PresentationThemeReference
|
let generalThemeReference: PresentationThemeReference
|
||||||
if let accentColor = accentColor, case let .cloud(theme) = reference, let settings = theme.theme.settings {
|
if let accentColor = accentColor, case let .cloud(theme) = reference, let settings = theme.theme.settings {
|
||||||
generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme))
|
generalThemeReference = .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme))
|
||||||
@ -854,6 +772,13 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
}
|
}
|
||||||
|
|
||||||
let effectiveWallpaper: TelegramWallpaper
|
let effectiveWallpaper: TelegramWallpaper
|
||||||
|
let effectiveThemeReference: PresentationThemeReference
|
||||||
|
if let accentColor = accentColor, case let .theme(themeReference) = accentColor {
|
||||||
|
effectiveThemeReference = themeReference
|
||||||
|
} else {
|
||||||
|
effectiveThemeReference = reference
|
||||||
|
}
|
||||||
|
|
||||||
if let wallpaper = wallpaper {
|
if let wallpaper = wallpaper {
|
||||||
effectiveWallpaper = wallpaper
|
effectiveWallpaper = wallpaper
|
||||||
} else {
|
} else {
|
||||||
@ -861,7 +786,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
if let accentColor = accentColor, case let .theme(themeReference) = accentColor {
|
if let accentColor = accentColor, case let .theme(themeReference) = accentColor {
|
||||||
theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference)
|
theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference)
|
||||||
} else {
|
} 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())
|
effectiveWallpaper = theme?.chat.defaultWallpaper ?? .builtin(WallpaperSettings())
|
||||||
}
|
}
|
||||||
@ -879,23 +804,26 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
return wallpaperSignal
|
return wallpaperSignal
|
||||||
|> mapToSignal { wallpaper in
|
|> mapToSignal { wallpaper in
|
||||||
return chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: context.sharedContext.accountManager.mediaBox)
|
return chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: context.sharedContext.accountManager.mediaBox)
|
||||||
}
|
|
||||||
|> map { serviceBackgroundColor in
|
|> map { serviceBackgroundColor in
|
||||||
|
return (wallpaper, serviceBackgroundColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> map { wallpaper, serviceBackgroundColor in
|
||||||
if let accentColor = accentColor, case let .theme(themeReference) = accentColor {
|
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 {
|
} 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 {
|
guard let theme = theme else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let strings = presentationData.strings
|
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] = []
|
var items: [ContextMenuItem] = []
|
||||||
|
|
||||||
if let accentColor = accentColor {
|
if let accentColor = accentColor {
|
||||||
@ -931,7 +859,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
|
|
||||||
let _ = (resolvedWallpaper
|
let _ = (resolvedWallpaper
|
||||||
|> deliverOnMainQueue).start(next: { wallpaper in
|
|> 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
|
let controller = editThemeController(context: context, mode: .create(result, nil), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
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())
|
let _ = (cloudThemes.get() |> delay(0.5, queue: Queue.mainQueue())
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> deliverOnMainQueue).start(next: { themes in
|
|> deliverOnMainQueue).start(next: { themes in
|
||||||
if isCurrent, let currentThemeIndex = themes.firstIndex(where: { $0.id == cloudTheme.theme.id }) {
|
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 previousThemeIndex = themes.prefix(upTo: currentThemeIndex).reversed().firstIndex(where: { $0.file != nil })
|
||||||
let newTheme: PresentationThemeReference
|
let newTheme: PresentationThemeReference
|
||||||
if let previousThemeIndex = previousThemeIndex {
|
if let previousThemeIndex = previousThemeIndex {
|
||||||
newTheme = .cloud(PresentationCloudTheme(theme: themes[themes.index(before: previousThemeIndex.base)], resolvedWallpaper: nil))
|
selectThemeImpl?(.cloud(PresentationCloudTheme(theme: themes[themes.index(before: previousThemeIndex.base)], resolvedWallpaper: nil)))
|
||||||
} else {
|
} else {
|
||||||
newTheme = .builtin(.nightAccent)
|
selectAccentColorImpl?(nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
selectThemeImpl?(newTheme)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = deleteThemeInteractively(account: context.account, accountManager: context.sharedContext.accountManager, theme: cloudTheme.theme).start()
|
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)
|
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)
|
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 _ = applyTheme(accountManager: context.sharedContext.accountManager, account: context.account, theme: cloudTheme).start()
|
||||||
|
|
||||||
let _ = (resolvedWallpaper
|
let currentTheme = context.sharedContext.accountManager.transaction { transaction -> (PresentationThemeReference) in
|
||||||
|> mapToSignal { resolvedWallpaper -> Signal<Void, NoError> 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 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 {
|
if case let .cloud(info) = theme {
|
||||||
updatedTheme = .cloud(PresentationCloudTheme(theme: info.theme, resolvedWallpaper: resolvedWallpaper))
|
updatedTheme = .cloud(PresentationCloudTheme(theme: info.theme, resolvedWallpaper: resolvedWallpaper))
|
||||||
|
if let settings = info.theme.settings {
|
||||||
|
baseThemeIndex = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)).index
|
||||||
|
updatedThemeBaseIndex = baseThemeIndex
|
||||||
}
|
}
|
||||||
return updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
} else {
|
||||||
|
updatedThemeBaseIndex = theme.index
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||||
|
var updatedThemeSpecificAccentColors = current.themeSpecificAccentColors
|
||||||
|
if let baseThemeIndex = baseThemeIndex {
|
||||||
|
updatedThemeSpecificAccentColors[baseThemeIndex] = PresentationThemeAccentColor(themeIndex: updatedTheme.index)
|
||||||
|
}
|
||||||
|
|
||||||
if autoNightModeTriggered {
|
if autoNightModeTriggered {
|
||||||
var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting
|
var updatedAutomaticThemeSwitchSetting = current.automaticThemeSwitchSetting
|
||||||
updatedAutomaticThemeSwitchSetting.theme = updatedTheme
|
updatedAutomaticThemeSwitchSetting.theme = updatedTheme
|
||||||
return current.withUpdatedAutomaticThemeSwitchSetting(updatedAutomaticThemeSwitchSetting)
|
|
||||||
|
return current.withUpdatedAutomaticThemeSwitchSetting(updatedAutomaticThemeSwitchSetting).withUpdatedThemeSpecificAccentColors(updatedThemeSpecificAccentColors)
|
||||||
} else {
|
} else {
|
||||||
return current.withUpdatedTheme(updatedTheme)
|
return current.withUpdatedTheme(updatedTheme).withUpdatedThemeSpecificAccentColors(updatedThemeSpecificAccentColors)
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}).start()
|
}).start()
|
||||||
|
|
||||||
presentCrossfadeControllerImpl?(cloudTheme == nil || cloudTheme?.settings != nil)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = {
|
moreImpl = {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
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
|
items.append(ActionSheetButtonItem(title: presentationData.strings.Appearance_CreateTheme, color: .accent, action: { [weak actionSheet] in
|
||||||
actionSheet?.dismissAnimated()
|
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
|
let settings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.presentationThemeSettings) as? PresentationThemeSettings ?? PresentationThemeSettings.defaultSettings
|
||||||
|
|
||||||
var themeReference: PresentationThemeReference?
|
let themeReference: PresentationThemeReference
|
||||||
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
|
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
|
||||||
if autoNightModeTriggered {
|
if autoNightModeTriggered {
|
||||||
themeReference = settings.automaticThemeSwitchSetting.theme
|
themeReference = settings.automaticThemeSwitchSetting.theme
|
||||||
@ -1249,14 +1241,15 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
|
|||||||
themeReference = settings.theme
|
themeReference = settings.theme
|
||||||
}
|
}
|
||||||
|
|
||||||
if let themeReference = themeReference, case .builtin = themeReference {
|
|
||||||
} else {
|
|
||||||
themeReference = nil
|
|
||||||
}
|
|
||||||
return themeReference
|
return themeReference
|
||||||
}
|
}
|
||||||
|> deliverOnMainQueue).start(next: { themeReference in
|
|> 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
|
let controller = editThemeController(context: context, mode: .create(result, settings), navigateToChat: { peerId in
|
||||||
if let navigationController = getNavigationControllerImpl?() {
|
if let navigationController = getNavigationControllerImpl?() {
|
||||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peerId)))
|
||||||
|
@ -273,7 +273,7 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
|||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.item = item
|
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 {
|
if updatedTheme {
|
||||||
strongSelf.imageNode.setSignal(createThemeImage(theme: item.theme))
|
strongSelf.imageNode.setSignal(createThemeImage(theme: item.theme))
|
||||||
}
|
}
|
||||||
@ -305,7 +305,9 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func prepareCrossfadeTransition() {
|
func prepareCrossfadeTransition() {
|
||||||
self.snapshotView?.removeFromSuperview()
|
guard self.snapshotView == nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if let snapshotView = self.containerNode.view.snapshotView(afterScreenUpdates: false) {
|
if let snapshotView = self.containerNode.view.snapshotView(afterScreenUpdates: false) {
|
||||||
self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view)
|
self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view)
|
||||||
@ -314,8 +316,13 @@ private final class ThemeSettingsThemeItemIconNode : ListViewItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func animateCrossfadeTransition() {
|
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?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak self] _ in
|
||||||
self?.snapshotView?.removeFromSuperview()
|
self?.snapshotView?.removeFromSuperview()
|
||||||
|
self?.snapshotView = nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,6 +352,7 @@ class ThemeSettingsThemeItem: ListViewItem, ItemListItem {
|
|||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let strings: PresentationStrings
|
let strings: PresentationStrings
|
||||||
let themes: [PresentationThemeReference]
|
let themes: [PresentationThemeReference]
|
||||||
|
let allThemes: [PresentationThemeReference]
|
||||||
let displayUnsupported: Bool
|
let displayUnsupported: Bool
|
||||||
let themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
let themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
||||||
let themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
|
let themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
|
||||||
@ -353,11 +361,12 @@ class ThemeSettingsThemeItem: ListViewItem, ItemListItem {
|
|||||||
let contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?
|
let contextAction: ((PresentationThemeReference, ASDisplayNode, ContextGesture?) -> Void)?
|
||||||
let tag: ItemListItemTag?
|
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.context = context
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.themes = themes
|
self.themes = themes
|
||||||
|
self.allThemes = allThemes
|
||||||
self.displayUnsupported = displayUnsupported
|
self.displayUnsupported = displayUnsupported
|
||||||
self.themeSpecificAccentColors = themeSpecificAccentColors
|
self.themeSpecificAccentColors = themeSpecificAccentColors
|
||||||
self.themeSpecificChatWallpapers = themeSpecificChatWallpapers
|
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.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 })
|
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 entries: [ThemeSettingsThemeEntry] = []
|
||||||
var index: Int = 0
|
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 {
|
if !item.displayUnsupported, case let .cloud(theme) = theme, theme.theme.file == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let title = themeDisplayName(strings: item.strings, reference: theme)
|
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
|
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))
|
entries.append(ThemeSettingsThemeEntry(index: index, themeReference: theme, title: title, accentColor: accentColor, selected: item.currentTheme.index == theme.index, theme: item.theme, wallpaper: wallpaper))
|
||||||
index += 1
|
index += 1
|
||||||
@ -633,7 +654,9 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func prepareCrossfadeTransition() {
|
func prepareCrossfadeTransition() {
|
||||||
self.snapshotView?.removeFromSuperview()
|
guard self.snapshotView == nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if let snapshotView = self.containerNode.view.snapshotView(afterScreenUpdates: false) {
|
if let snapshotView = self.containerNode.view.snapshotView(afterScreenUpdates: false) {
|
||||||
self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view)
|
self.view.insertSubview(snapshotView, aboveSubview: self.containerNode.view)
|
||||||
@ -648,8 +671,13 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func animateCrossfadeTransition() {
|
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?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak self] _ in
|
||||||
self?.snapshotView?.removeFromSuperview()
|
self?.snapshotView?.removeFromSuperview()
|
||||||
|
self?.snapshotView = nil
|
||||||
})
|
})
|
||||||
|
|
||||||
self.listNode.forEachVisibleItemNode { node in
|
self.listNode.forEachVisibleItemNode { node in
|
||||||
|
@ -143,7 +143,7 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
|
|||||||
selectedFileId = file.id
|
selectedFileId = file.id
|
||||||
}
|
}
|
||||||
|
|
||||||
for wallpaper in wallpapers {
|
for wallpaper in self.wallpapers {
|
||||||
let node = SettingsThemeWallpaperNode(overlayBackgroundColor: self.serviceBackgroundColor.withAlphaComponent(0.4))
|
let node = SettingsThemeWallpaperNode(overlayBackgroundColor: self.serviceBackgroundColor.withAlphaComponent(0.4))
|
||||||
node.clipsToBounds = true
|
node.clipsToBounds = true
|
||||||
node.cornerRadius = 5.0
|
node.cornerRadius = 5.0
|
||||||
@ -251,7 +251,16 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
|
|||||||
let frame = node.frame.insetBy(dx: -48.0, dy: 0.0)
|
let frame = node.frame.insetBy(dx: -48.0, dy: 0.0)
|
||||||
|
|
||||||
if frame.minX < bounds.minX || frame.maxX > bounds.maxX {
|
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 {
|
if wallpaperSettings.motion {
|
||||||
flags |= (1 << 2)
|
flags |= (1 << 2)
|
||||||
}
|
}
|
||||||
if let _ = wallpaperSettings.bottomColor {
|
if let _ = wallpaperSettings.intensity {
|
||||||
flags |= (1 << 4)
|
flags |= (1 << 3)
|
||||||
}
|
}
|
||||||
if let _ = wallpaperSettings.rotation {
|
if let _ = wallpaperSettings.bottomColor {
|
||||||
flags |= (1 << 4)
|
flags |= (1 << 4)
|
||||||
}
|
}
|
||||||
return .wallPaperSettings(flags: flags, backgroundColor: wallpaperSettings.color, secondBackgroundColor: wallpaperSettings.bottomColor, intensity: wallpaperSettings.intensity, rotation: wallpaperSettings.rotation)
|
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(
|
let rootTabBar = PresentationThemeRootTabBar(
|
||||||
backgroundColor: UIColor(rgb: 0x1c1c1d),
|
backgroundColor: UIColor(rgb: 0x1c1c1d),
|
||||||
separatorColor: UIColor(rgb: 0x3d3d40),
|
separatorColor: UIColor(rgb: 0x3d3d40),
|
||||||
@ -531,8 +531,8 @@ public func makeDefaultDarkPresentationTheme(preview: Bool) -> PresentationTheme
|
|||||||
)
|
)
|
||||||
|
|
||||||
return PresentationTheme(
|
return PresentationTheme(
|
||||||
name: .builtin(.night),
|
name: extendingThemeReference?.name ?? .builtin(.night),
|
||||||
index: PresentationThemeReference.builtin(.night).index,
|
index: extendingThemeReference?.index ?? PresentationThemeReference.builtin(.night).index,
|
||||||
referenceTheme: .night,
|
referenceTheme: .night,
|
||||||
overallDarkAppearance: true,
|
overallDarkAppearance: true,
|
||||||
intro: intro,
|
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 accentColor = defaultDarkTintedAccentColor
|
||||||
|
|
||||||
let secondaryBadgeTextColor: UIColor
|
let secondaryBadgeTextColor: UIColor
|
||||||
@ -787,8 +787,8 @@ public func makeDefaultDarkTintedPresentationTheme(preview: Bool) -> Presentatio
|
|||||||
)
|
)
|
||||||
|
|
||||||
return PresentationTheme(
|
return PresentationTheme(
|
||||||
name: .builtin(.nightAccent),
|
name: extendingThemeReference?.name ?? .builtin(.nightAccent),
|
||||||
index: PresentationThemeReference.builtin(.nightAccent).index,
|
index: extendingThemeReference?.index ?? PresentationThemeReference.builtin(.nightAccent).index,
|
||||||
referenceTheme: .nightAccent,
|
referenceTheme: .nightAccent,
|
||||||
overallDarkAppearance: true,
|
overallDarkAppearance: true,
|
||||||
intro: intro,
|
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
|
var serviceBackgroundColor = serviceBackgroundColor ?? defaultServiceBackgroundColor
|
||||||
|
|
||||||
let intro = PresentationThemeIntro(
|
let intro = PresentationThemeIntro(
|
||||||
@ -740,8 +740,8 @@ public func makeDefaultDayPresentationTheme(serviceBackgroundColor: UIColor?, da
|
|||||||
)
|
)
|
||||||
|
|
||||||
return PresentationTheme(
|
return PresentationTheme(
|
||||||
name: .builtin(day ? .day : .dayClassic),
|
name: extendingThemeReference?.name ?? .builtin(day ? .day : .dayClassic),
|
||||||
index: PresentationThemeReference.builtin(day ? .day : .dayClassic).index,
|
index: extendingThemeReference?.index ?? PresentationThemeReference.builtin(day ? .day : .dayClassic).index,
|
||||||
referenceTheme: day ? .day : .dayClassic,
|
referenceTheme: day ? .day : .dayClassic,
|
||||||
overallDarkAppearance: false,
|
overallDarkAppearance: false,
|
||||||
intro: intro,
|
intro: intro,
|
||||||
|
@ -4,23 +4,23 @@ import Postbox
|
|||||||
import SyncCore
|
import SyncCore
|
||||||
import TelegramUIPreferences
|
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
|
let theme: PresentationTheme
|
||||||
switch reference {
|
switch reference {
|
||||||
case .dayClassic:
|
case .dayClassic:
|
||||||
theme = makeDefaultDayPresentationTheme(serviceBackgroundColor: serviceBackgroundColor, day: false, preview: preview)
|
theme = makeDefaultDayPresentationTheme(extendingThemeReference: extendingThemeReference, serviceBackgroundColor: serviceBackgroundColor, day: false, preview: preview)
|
||||||
case .day:
|
case .day:
|
||||||
theme = makeDefaultDayPresentationTheme(serviceBackgroundColor: serviceBackgroundColor, day: true, preview: preview)
|
theme = makeDefaultDayPresentationTheme(extendingThemeReference: extendingThemeReference, serviceBackgroundColor: serviceBackgroundColor, day: true, preview: preview)
|
||||||
case .night:
|
case .night:
|
||||||
theme = makeDefaultDarkPresentationTheme(preview: preview)
|
theme = makeDefaultDarkPresentationTheme(extendingThemeReference: extendingThemeReference, preview: preview)
|
||||||
case .nightAccent:
|
case .nightAccent:
|
||||||
theme = makeDefaultDarkTintedPresentationTheme(preview: preview)
|
theme = makeDefaultDarkTintedPresentationTheme(extendingThemeReference: extendingThemeReference, preview: preview)
|
||||||
}
|
}
|
||||||
return theme
|
return theme
|
||||||
}
|
}
|
||||||
|
|
||||||
public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper: TelegramWallpaper? = nil) -> PresentationTheme {
|
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
|
return theme
|
||||||
}
|
}
|
||||||
switch theme.referenceTheme {
|
switch theme.referenceTheme {
|
||||||
@ -35,11 +35,11 @@ public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool
|
|||||||
return theme
|
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
|
let theme: PresentationTheme
|
||||||
switch themeReference {
|
switch themeReference {
|
||||||
case let .builtin(reference):
|
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)
|
theme = customizePresentationTheme(defaultTheme, editing: true, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper)
|
||||||
case let .local(info):
|
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) {
|
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):
|
case let .cloud(info):
|
||||||
if let settings = info.theme.settings {
|
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
|
theme = loadedTheme
|
||||||
} else {
|
} else {
|
||||||
return nil
|
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 final class PresentationTheme: Equatable {
|
||||||
public let name: PresentationThemeName
|
public let name: PresentationThemeName
|
||||||
public let index: Int64
|
public let index: Int64
|
||||||
|
@ -139,7 +139,7 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager {
|
|||||||
theme = updatedTheme
|
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()
|
}).start()
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager {
|
|||||||
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
var themeSpecificChatWallpapers = current.themeSpecificChatWallpapers
|
||||||
themeSpecificChatWallpapers[themeReference.index] = updatedWallpaper
|
themeSpecificChatWallpapers[themeReference.index] = updatedWallpaper
|
||||||
themeSpecificChatWallpapers[coloredThemeIndex(reference: themeReference, accentColor: current.themeSpecificAccentColors[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()
|
})).start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,6 +220,16 @@ public enum PresentationThemeReference: PostboxCoding, Equatable {
|
|||||||
|
|
||||||
return (Int64(namespace) << 32) | Int64(bitPattern: UInt64(UInt32(bitPattern: id)))
|
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 {
|
public func coloredThemeIndex(reference: PresentationThemeReference, accentColor: PresentationThemeAccentColor?) -> Int64 {
|
||||||
@ -353,6 +363,7 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable {
|
|||||||
case white
|
case white
|
||||||
case custom
|
case custom
|
||||||
case preset
|
case preset
|
||||||
|
case theme
|
||||||
|
|
||||||
public var color: UIColor {
|
public var color: UIColor {
|
||||||
let value: UInt32
|
let value: UInt32
|
||||||
@ -379,39 +390,13 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable {
|
|||||||
value = 0x000000
|
value = 0x000000
|
||||||
case .white:
|
case .white:
|
||||||
value = 0xffffff
|
value = 0xffffff
|
||||||
case .custom, .preset:
|
case .custom, .preset, .theme:
|
||||||
return .clear
|
return .clear
|
||||||
}
|
}
|
||||||
return UIColor(rgb: value)
|
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 struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
||||||
public static func == (lhs: PresentationThemeAccentColor, rhs: PresentationThemeAccentColor) -> Bool {
|
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
|
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 accentColor: Int32?
|
||||||
public var bubbleColors: (Int32, Int32?)?
|
public var bubbleColors: (Int32, Int32?)?
|
||||||
public var wallpaper: TelegramWallpaper?
|
public var wallpaper: TelegramWallpaper?
|
||||||
|
public var themeIndex: Int64?
|
||||||
|
|
||||||
public init(baseColor: PresentationThemeBaseColor) {
|
public init(baseColor: PresentationThemeBaseColor) {
|
||||||
if baseColor != .preset && baseColor != .custom {
|
if baseColor != .preset && baseColor != .custom {
|
||||||
@ -443,6 +429,15 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
|||||||
self.wallpaper = wallpaper
|
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) {
|
public init(decoder: PostboxDecoder) {
|
||||||
self.index = decoder.decodeInt32ForKey("i", orElse: -1)
|
self.index = decoder.decodeInt32ForKey("i", orElse: -1)
|
||||||
self.baseColor = PresentationThemeBaseColor(rawValue: decoder.decodeInt32ForKey("b", orElse: 0)) ?? .blue
|
self.baseColor = PresentationThemeBaseColor(rawValue: decoder.decodeInt32ForKey("b", orElse: 0)) ?? .blue
|
||||||
@ -457,6 +452,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
|||||||
self.bubbleColors = nil
|
self.bubbleColors = nil
|
||||||
}
|
}
|
||||||
self.wallpaper = decoder.decodeObjectForKey("w", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
|
self.wallpaper = decoder.decodeObjectForKey("w", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
|
||||||
|
self.themeIndex = decoder.decodeOptionalInt64ForKey("t")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -483,6 +479,11 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
|||||||
} else {
|
} else {
|
||||||
encoder.encodeNil(forKey: "w")
|
encoder.encodeNil(forKey: "w")
|
||||||
}
|
}
|
||||||
|
if let themeIndex = self.themeIndex {
|
||||||
|
encoder.encodeInt64(themeIndex, forKey: "t")
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: "t")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var color: UIColor {
|
public var color: UIColor {
|
||||||
@ -525,7 +526,6 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
|
|||||||
public struct PresentationThemeSettings: PreferencesEntry {
|
public struct PresentationThemeSettings: PreferencesEntry {
|
||||||
public var theme: PresentationThemeReference
|
public var theme: PresentationThemeReference
|
||||||
public var themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
public var themeSpecificAccentColors: [Int64: PresentationThemeAccentColor]
|
||||||
public var themeSpecificCustomColors: [Int64: PresentationThemeCustomColors]
|
|
||||||
public var themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
|
public var themeSpecificChatWallpapers: [Int64: TelegramWallpaper]
|
||||||
public var useSystemFont: Bool
|
public var useSystemFont: Bool
|
||||||
public var fontSize: PresentationFontSize
|
public var fontSize: PresentationFontSize
|
||||||
@ -565,24 +565,16 @@ public struct PresentationThemeSettings: PreferencesEntry {
|
|||||||
resources.append(contentsOf: wallpaperResources(chatWallpaper))
|
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
|
return resources
|
||||||
}
|
}
|
||||||
|
|
||||||
public static var defaultSettings: PresentationThemeSettings {
|
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.theme = theme
|
||||||
self.themeSpecificAccentColors = themeSpecificAccentColors
|
self.themeSpecificAccentColors = themeSpecificAccentColors
|
||||||
self.themeSpecificCustomColors = themeSpecificCustomColors
|
|
||||||
self.themeSpecificChatWallpapers = themeSpecificChatWallpapers
|
self.themeSpecificChatWallpapers = themeSpecificChatWallpapers
|
||||||
self.useSystemFont = useSystemFont
|
self.useSystemFont = useSystemFont
|
||||||
self.fontSize = fontSize
|
self.fontSize = fontSize
|
||||||
@ -600,12 +592,6 @@ public struct PresentationThemeSettings: PreferencesEntry {
|
|||||||
return TelegramWallpaper(decoder: decoder)
|
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
|
self.themeSpecificAccentColors = decoder.decodeObjectDictionaryForKey("themeSpecificAccentColors", keyDecoder: { decoder in
|
||||||
return decoder.decodeInt64ForKey("k", orElse: 0)
|
return decoder.decodeInt64ForKey("k", orElse: 0)
|
||||||
}, valueDecoder: { decoder in
|
}, valueDecoder: { decoder in
|
||||||
@ -624,9 +610,6 @@ public struct PresentationThemeSettings: PreferencesEntry {
|
|||||||
encoder.encodeObjectDictionary(self.themeSpecificAccentColors, forKey: "themeSpecificAccentColors", keyEncoder: { key, encoder in
|
encoder.encodeObjectDictionary(self.themeSpecificAccentColors, forKey: "themeSpecificAccentColors", keyEncoder: { key, encoder in
|
||||||
encoder.encodeInt64(key, forKey: "k")
|
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.encodeObjectDictionary(self.themeSpecificChatWallpapers, forKey: "themeSpecificChatWallpapers", keyEncoder: { key, encoder in
|
||||||
encoder.encodeInt64(key, forKey: "k")
|
encoder.encodeInt64(key, forKey: "k")
|
||||||
})
|
})
|
||||||
@ -646,43 +629,39 @@ public struct PresentationThemeSettings: PreferencesEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: PresentationThemeSettings, rhs: PresentationThemeSettings) -> Bool {
|
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 {
|
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 {
|
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)
|
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 withUpdatedThemeSpecificCustomColors(_ themeSpecificCustomColors: [Int64: PresentationThemeCustomColors]) -> PresentationThemeSettings {
|
|
||||||
return PresentationThemeSettings(theme: self.theme, themeSpecificAccentColors: self.themeSpecificAccentColors, themeSpecificCustomColors: themeSpecificCustomColors, themeSpecificChatWallpapers: self.themeSpecificChatWallpapers, useSystemFont: self.useSystemFont, fontSize: self.fontSize, automaticThemeSwitchSetting: self.automaticThemeSwitchSetting, largeEmoji: self.largeEmoji, disableAnimations: self.disableAnimations)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func withUpdatedThemeSpecificChatWallpapers(_ themeSpecificChatWallpapers: [Int64: TelegramWallpaper]) -> PresentationThemeSettings {
|
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 {
|
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 {
|
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 {
|
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 {
|
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 {
|
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,10 +1164,32 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
|||||||
} else if case let .cloud(theme) = theme, let resource = theme.theme.file?.resource {
|
} else if case let .cloud(theme) = theme, let resource = theme.theme.file?.resource {
|
||||||
reference = .theme(theme: .slug(theme.theme.slug), resource: resource)
|
reference = .theme(theme: .slug(theme.theme.slug), resource: resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let themeSignal: Signal<PresentationTheme?, NoError>
|
||||||
if let reference = reference {
|
if let reference = reference {
|
||||||
colorsSignal = telegramThemeData(account: account, accountManager: accountManager, reference: reference, synchronousLoad: false)
|
themeSignal = telegramThemeData(account: account, accountManager: accountManager, reference: reference, synchronousLoad: false)
|
||||||
|> mapToSignal { data -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in
|
|> map { data -> PresentationTheme? in
|
||||||
if let data = data, let theme = makePresentationTheme(data: data) {
|
if let data = data, let theme = makePresentationTheme(data: data) {
|
||||||
|
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 wallpaperSignal: Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> = .complete()
|
||||||
var rotation: Int32?
|
var rotation: Int32?
|
||||||
let backgroundColor: (UIColor, UIColor?)
|
let backgroundColor: (UIColor, UIColor?)
|
||||||
@ -1203,11 +1225,15 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
|||||||
accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData)
|
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()
|
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 {
|
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)
|
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
|
|> mapToSignal { _ in
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
} else if file.settings.blur {
|
} else if file.settings.blur {
|
||||||
return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true)
|
return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true)
|
||||||
|> mapToSignal { _ in
|
|> mapToSignal { _ in
|
||||||
@ -1234,9 +1260,6 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
|||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
colorsSignal = .never()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return colorsSignal
|
return colorsSignal
|
||||||
|> map { colors in
|
|> map { colors in
|
||||||
|
Loading…
x
Reference in New Issue
Block a user