Theming fixes

This commit is contained in:
Ilya Laktyushin 2019-12-15 17:37:33 +04:00
parent e4ae7a7a36
commit dece460fcf
13 changed files with 186 additions and 139 deletions

View File

@ -137,43 +137,61 @@ final class ThemeAccentColorController: ViewController {
}, apply: { [weak self] state, serviceBackgroundColor in }, apply: { [weak self] state, serviceBackgroundColor in
if let strongSelf = self { if let strongSelf = self {
let context = strongSelf.context let context = strongSelf.context
if case let .edit(theme, _, themeReference, _, completion) = strongSelf.mode {
let updatedTheme: PresentationTheme var coloredWallpaper: TelegramWallpaper?
if let themeReference = themeReference { if let backgroundColors = state.backgroundColors {
updatedTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: state.accentColor, bubbleColors: state.messagesColors, backgroundColors: state.backgroundColors, serviceBackgroundColor: serviceBackgroundColor) ?? defaultPresentationTheme let color = Int32(bitPattern: backgroundColors.0.rgb)
let bottomColor = backgroundColors.1.flatMap { Int32(bitPattern: $0.rgb) }
if let patternWallpaper = state.patternWallpaper {
coloredWallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(motion: state.motion, color: color, bottomColor: bottomColor, intensity: state.patternIntensity, rotation: state.rotation))
} else if let bottomColor = bottomColor {
coloredWallpaper = .gradient(color, bottomColor, WallpaperSettings(motion: state.motion, rotation: state.rotation))
} else { } else {
updatedTheme = customizePresentationTheme(theme, editing: false, accentColor: state.accentColor, backgroundColors: state.backgroundColors, bubbleColors: state.messagesColors) coloredWallpaper = .color(color)
}
}
let prepare: Signal<Void, NoError>
if let patternWallpaper = state.patternWallpaper, case let .file(file) = patternWallpaper, let backgroundColors = state.backgroundColors {
let resource = file.file.resource
let representation = CachedPatternWallpaperRepresentation(color: Int32(bitPattern: backgroundColors.0.rgb), bottomColor: backgroundColors.1.flatMap { Int32(bitPattern: $0.rgb) }, intensity: state.patternIntensity, rotation: state.rotation)
var data: Data?
if let path = strongSelf.context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
} else if let path = strongSelf.context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
} }
completion(updatedTheme) if let data = data {
} else { strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
let prepare: Signal<Void, NoError> prepare = (strongSelf.context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true)
if let patternWallpaper = state.patternWallpaper, case let .file(file) = patternWallpaper, let backgroundColors = state.backgroundColors { |> filter({ $0.complete })
let resource = file.file.resource |> take(1)
let representation = CachedPatternWallpaperRepresentation(color: Int32(bitPattern: backgroundColors.0.rgb), bottomColor: backgroundColors.1.flatMap { Int32(bitPattern: $0.rgb) }, intensity: state.patternIntensity, rotation: state.rotation) |> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
var data: Data? })
if let path = strongSelf.context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
} else if let path = strongSelf.context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) {
data = maybeData
}
if let data = data {
strongSelf.context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
prepare = (strongSelf.context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true)
|> filter({ $0.complete })
|> take(1)
|> mapToSignal { _ -> Signal<Void, NoError> in
return .complete()
})
} else {
prepare = .complete()
}
} else { } else {
prepare = .complete() prepare = .complete()
} }
} else {
prepare = .complete()
}
if case let .edit(theme, _, themeReference, _, completion) = strongSelf.mode {
let _ = (prepare
|> deliverOnMainQueue).start(completed: { [weak self] in
let updatedTheme: PresentationTheme
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
} else {
updatedTheme = customizePresentationTheme(theme, editing: false, accentColor: state.accentColor, backgroundColors: state.backgroundColors, bubbleColors: state.messagesColors, wallpaper: state.initialWallpaper ?? coloredWallpaper)
}
completion(updatedTheme)
})
} else {
let _ = (prepare let _ = (prepare
|> then(updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in |> then(updatePresentationThemeSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
@ -198,17 +216,8 @@ final class ThemeAccentColorController: ViewController {
themeSpecificAccentColors[currentTheme.index] = color themeSpecificAccentColors[currentTheme.index] = color
var wallpaper = themeSpecificChatWallpapers[currentTheme.index] var wallpaper = themeSpecificChatWallpapers[currentTheme.index]
if let backgroundColors = state.backgroundColors { if let coloredWallpaper = coloredWallpaper {
let color = Int32(bitPattern: backgroundColors.0.rgb) wallpaper = coloredWallpaper
let bottomColor = backgroundColors.1.flatMap { Int32(bitPattern: $0.rgb) }
if let patternWallpaper = state.patternWallpaper {
wallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(motion: state.motion, color: color, bottomColor: bottomColor, intensity: state.patternIntensity, rotation: state.rotation))
} else if let bottomColor = bottomColor {
wallpaper = .gradient(color, bottomColor, WallpaperSettings(motion: state.motion, rotation: state.rotation))
} else {
wallpaper = .color(color)
}
} }
themeSpecificChatWallpapers[currentTheme.index] = wallpaper themeSpecificChatWallpapers[currentTheme.index] = wallpaper
@ -239,7 +248,7 @@ final class ThemeAccentColorController: ViewController {
let accentColor: UIColor let accentColor: UIColor
var initialWallpaper: TelegramWallpaper? var initialWallpaper: TelegramWallpaper?
let backgroundColors: (UIColor, UIColor?)? var backgroundColors: (UIColor, UIColor?)?
var patternWallpaper: TelegramWallpaper? var patternWallpaper: TelegramWallpaper?
var patternIntensity: Int32 = 50 var patternIntensity: Int32 = 50
var motion = false var motion = false
@ -249,13 +258,44 @@ final class ThemeAccentColorController: ViewController {
var ignoreDefaultWallpaper = false var ignoreDefaultWallpaper = false
func extractWallpaperParameters(_ wallpaper: TelegramWallpaper?) {
guard let wallpaper = wallpaper else {
return
}
if case let .file(file) = wallpaper, file.isPattern {
var patternColor = UIColor(rgb: 0xd6e2ee, alpha: 0.5)
var bottomColor: UIColor?
if let color = file.settings.color {
if let intensity = file.settings.intensity {
patternIntensity = intensity
}
patternColor = UIColor(rgb: UInt32(bitPattern: color))
if let bottomColorValue = file.settings.bottomColor {
bottomColor = UIColor(rgb: UInt32(bitPattern: bottomColorValue))
}
}
patternWallpaper = wallpaper
backgroundColors = (patternColor, bottomColor)
motion = file.settings.motion
rotation = file.settings.rotation ?? 0
} else if case let .color(color) = wallpaper {
backgroundColors = (UIColor(rgb: UInt32(bitPattern: color)), nil)
} else if case let .gradient(topColor, bottomColor, settings) = wallpaper {
backgroundColors = (UIColor(rgb: UInt32(bitPattern: topColor)), UIColor(rgb: UInt32(bitPattern: bottomColor)))
motion = settings.motion
rotation = settings.rotation ?? 0
} else {
backgroundColors = nil
}
}
if let themeReference = strongSelf.mode.themeReference { if let themeReference = strongSelf.mode.themeReference {
accentColor = settings.themeSpecificAccentColors[themeReference.index]?.color ?? defaultDayAccentColor accentColor = settings.themeSpecificAccentColors[themeReference.index]?.color ?? defaultDayAccentColor
let wallpaper: TelegramWallpaper let wallpaper: TelegramWallpaper
if let customWallpaper = settings.themeSpecificChatWallpapers[themeReference.index] { 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, bubbleColors: nil) ?? defaultPresentationTheme let theme = makePresentationTheme(mediaBox: strongSelf.context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: nil) ?? 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[themeReference.index] != nil {
ignoreDefaultWallpaper = true ignoreDefaultWallpaper = true
@ -274,31 +314,7 @@ final class ThemeAccentColorController: ViewController {
if let initialBackgroundColor = strongSelf.initialBackgroundColor { if let initialBackgroundColor = strongSelf.initialBackgroundColor {
backgroundColors = (initialBackgroundColor, nil) backgroundColors = (initialBackgroundColor, nil)
} else if !ignoreDefaultWallpaper { } else if !ignoreDefaultWallpaper {
if case let .file(file) = wallpaper, file.isPattern { extractWallpaperParameters(wallpaper)
var patternColor = UIColor(rgb: 0xd6e2ee, alpha: 0.5)
var bottomColor: UIColor?
if let color = file.settings.color {
if let intensity = file.settings.intensity {
patternIntensity = intensity
}
patternColor = UIColor(rgb: UInt32(bitPattern: color))
if let bottomColorValue = file.settings.bottomColor {
bottomColor = UIColor(rgb: UInt32(bitPattern: bottomColorValue))
}
}
patternWallpaper = wallpaper
backgroundColors = (patternColor, bottomColor)
motion = file.settings.motion
rotation = file.settings.rotation ?? 0
} else if case let .color(color) = wallpaper {
backgroundColors = (UIColor(rgb: UInt32(bitPattern: color)), nil)
} else if case let .gradient(topColor, bottomColor, settings) = wallpaper {
backgroundColors = (UIColor(rgb: UInt32(bitPattern: topColor)), UIColor(rgb: UInt32(bitPattern: bottomColor)))
motion = settings.motion
rotation = settings.rotation ?? 0
} else {
backgroundColors = nil
}
} else { } else {
backgroundColors = nil backgroundColors = nil
} }
@ -318,14 +334,10 @@ 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
if case let .color(color) = theme.chat.defaultWallpaper {
backgroundColors = (UIColor(rgb: UInt32(bitPattern: color)), nil) let wallpaper = wallpaper ?? theme.chat.defaultWallpaper
} else if case let .gradient(topColor, bottomColor, settings) = theme.chat.defaultWallpaper { extractWallpaperParameters(wallpaper)
backgroundColors = (UIColor(rgb: UInt32(bitPattern: topColor)), UIColor(rgb: UInt32(bitPattern: bottomColor)))
rotation = settings.rotation ?? 0
} else {
backgroundColors = nil
}
let topMessageColor = theme.chat.message.outgoing.bubble.withWallpaper.fill let topMessageColor = theme.chat.message.outgoing.bubble.withWallpaper.fill
let bottomMessageColor = theme.chat.message.outgoing.bubble.withWallpaper.gradientFill let bottomMessageColor = theme.chat.message.outgoing.bubble.withWallpaper.gradientFill

View File

@ -188,12 +188,12 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
private let serviceBackgroundColorPromise = Promise<UIColor>() private let serviceBackgroundColorPromise = Promise<UIColor>()
private var wallpaperDisposable = MetaDisposable() private var wallpaperDisposable = MetaDisposable()
private var preview = false private var currentBackgroundColors: (UIColor, UIColor?)?
private var currentBackgroundColor: UIColor? private var currentBackgroundPromise = Promise<(UIColor, UIColor?)?>()
private var patternWallpaper: TelegramWallpaper? private var patternWallpaper: TelegramWallpaper?
private var patternArguments: PatternWallpaperArguments? private var patternArguments: PatternWallpaperArguments?
private var patternArgumentsPromise = Promise<TransformImageArguments>()
private var patternArgumentsValue = Promise<TransformImageArguments>()
private var patternArgumentsDisposable: Disposable? private var patternArgumentsDisposable: Disposable?
private var tapGestureRecognizer: UITapGestureRecognizer? private var tapGestureRecognizer: UITapGestureRecognizer?
@ -399,7 +399,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
self.stateDisposable = (self.statePromise.get() self.stateDisposable = (self.statePromise.get()
|> deliverOn(Queue.concurrentDefaultQueue()) |> deliverOn(Queue.concurrentDefaultQueue())
|> map { state -> (PresentationTheme, (TelegramWallpaper, UIImage?, Signal<(TransformImageArguments) -> DrawingContext?, NoError>?), UIColor, UIColor?, [UIColor], Bool) in |> map { state -> (PresentationTheme, (TelegramWallpaper, UIImage?, Signal<(TransformImageArguments) -> DrawingContext?, NoError>?), UIColor, (UIColor, UIColor?)?, [UIColor], Bool) in
let accentColor = state.accentColor let accentColor = state.accentColor
var backgroundColors = state.backgroundColors var backgroundColors = state.backgroundColors
let messagesColors = state.messagesColors let messagesColors = state.messagesColors
@ -439,12 +439,10 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
suggestedWallpaper = .gradient(Int32(bitPattern: topColor.rgb), Int32(bitPattern: bottomColor.rgb), WallpaperSettings()) suggestedWallpaper = .gradient(Int32(bitPattern: topColor.rgb), Int32(bitPattern: bottomColor.rgb), WallpaperSettings())
wallpaperSignal = gradientImage([topColor, bottomColor], rotation: state.rotation) wallpaperSignal = gradientImage([topColor, bottomColor], rotation: state.rotation)
backgroundColors = (topColor, bottomColor) backgroundColors = (topColor, bottomColor)
singleBackgroundColor = bottomColor
case .nightAccent: case .nightAccent:
let color = accentColor.withMultiplied(hue: 1.024, saturation: 0.573, brightness: 0.18) let color = accentColor.withMultiplied(hue: 1.024, saturation: 0.573, brightness: 0.18)
suggestedWallpaper = .color(Int32(bitPattern: color.rgb)) suggestedWallpaper = .color(Int32(bitPattern: color.rgb))
backgroundColors = (color, nil) backgroundColors = (color, nil)
singleBackgroundColor = color
default: default:
suggestedWallpaper = .builtin(WallpaperSettings()) suggestedWallpaper = .builtin(WallpaperSettings())
} }
@ -457,7 +455,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
let serviceBackgroundColor = serviceColor(for: (wallpaper, wallpaperImage)) let serviceBackgroundColor = serviceColor(for: (wallpaper, wallpaperImage))
let updatedTheme: PresentationTheme let updatedTheme: PresentationTheme
if let themeReference = mode.themeReference { if let themeReference = mode.themeReference {
updatedTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: themeReference, accentColor: accentColor, bubbleColors: messagesColors, backgroundColors: backgroundColors, 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 {
@ -468,9 +466,9 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
let patternColors = calcPatternColors(for: state) let patternColors = calcPatternColors(for: state)
return (updatedTheme, (wallpaper, wallpaperImage, wallpaperSignal), serviceBackgroundColor, singleBackgroundColor, patternColors, state.preview) return (updatedTheme, (wallpaper, wallpaperImage, wallpaperSignal), serviceBackgroundColor, backgroundColors, patternColors, state.preview)
} }
|> deliverOnMainQueue).start(next: { [weak self] theme, wallpaperImageAndSignal, serviceBackgroundColor, singleBackgroundColor, patternColors, preview in |> deliverOnMainQueue).start(next: { [weak self] theme, wallpaperImageAndSignal, serviceBackgroundColor, backgroundColors, patternColors, preview in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
@ -495,13 +493,13 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
strongSelf.immediateBackgroundNode.image = nil strongSelf.immediateBackgroundNode.image = nil
strongSelf.immediateBackgroundNode.isHidden = false strongSelf.immediateBackgroundNode.isHidden = false
strongSelf.signalBackgroundNode.isHidden = true strongSelf.signalBackgroundNode.isHidden = true
strongSelf.patternWallpaper = nil strongSelf.patternWallpaper = nil
} else if let wallpaperImage = wallpaperImage { } else if let wallpaperImage = wallpaperImage {
strongSelf.immediateBackgroundNode.image = wallpaperImage strongSelf.immediateBackgroundNode.image = wallpaperImage
strongSelf.immediateBackgroundNode.isHidden = false strongSelf.immediateBackgroundNode.isHidden = false
strongSelf.signalBackgroundNode.isHidden = true strongSelf.signalBackgroundNode.isHidden = true
strongSelf.patternWallpaper = nil strongSelf.patternWallpaper = nil
} else if let wallpaperSignal = wallpaperSignal { } else if let wallpaperSignal = wallpaperSignal {
strongSelf.signalBackgroundNode.contentMode = .scaleToFill strongSelf.signalBackgroundNode.contentMode = .scaleToFill
@ -520,7 +518,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
if dispatch { if dispatch {
if let _ = strongSelf.patternArgumentsDisposable { if let _ = strongSelf.patternArgumentsDisposable {
} else { } else {
let throttledSignal = strongSelf.patternArgumentsValue.get() let throttledSignal = strongSelf.patternArgumentsPromise.get()
|> mapToThrottled { next -> Signal<TransformImageArguments, NoError> in |> mapToThrottled { next -> Signal<TransformImageArguments, NoError> in
return .single(next) |> then(.complete() |> delay(0.016667, queue: Queue.concurrentDefaultQueue())) return .single(next) |> then(.complete() |> delay(0.016667, queue: Queue.concurrentDefaultQueue()))
} }
@ -534,7 +532,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
}) })
} }
strongSelf.patternArgumentsValue.set(.single(TransformImageArguments(corners: ImageCorners(), imageSize: layout.size, boundingSize: layout.size, intrinsicInsets: UIEdgeInsets(), custom: patternArguments))) strongSelf.patternArgumentsPromise.set(.single(TransformImageArguments(corners: ImageCorners(), imageSize: layout.size, boundingSize: layout.size, intrinsicInsets: UIEdgeInsets(), custom: patternArguments)))
} else { } else {
strongSelf.patternArgumentsDisposable?.dispose() strongSelf.patternArgumentsDisposable?.dispose()
strongSelf.patternArgumentsDisposable = nil strongSelf.patternArgumentsDisposable = nil
@ -550,8 +548,12 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
} }
strongSelf.wallpaper = wallpaper strongSelf.wallpaper = wallpaper
strongSelf.patternArguments = patternArguments strongSelf.patternArguments = patternArguments
strongSelf.currentBackgroundColor = singleBackgroundColor
if !preview {
strongSelf.currentBackgroundColors = backgroundColors
strongSelf.patternPanelNode.backgroundColors = backgroundColors
}
if let (layout, navigationBarHeight, messagesBottomInset) = strongSelf.validLayout { if let (layout, navigationBarHeight, messagesBottomInset) = strongSelf.validLayout {
strongSelf.updateChatsLayout(layout: layout, topInset: navigationBarHeight, transition: .immediate) strongSelf.updateChatsLayout(layout: layout, topInset: navigationBarHeight, transition: .immediate)
strongSelf.updateMessagesLayout(layout: layout, bottomInset: messagesBottomInset, transition: .immediate) strongSelf.updateMessagesLayout(layout: layout, bottomInset: messagesBottomInset, transition: .immediate)
@ -1031,7 +1033,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
@objc private func togglePattern() { @objc private func togglePattern() {
let wallpaper = self.state.previousPatternWallpaper ?? self.patternPanelNode.wallpapers.first let wallpaper = self.state.previousPatternWallpaper ?? self.patternPanelNode.wallpapers.first
let backgroundColor = self.currentBackgroundColor let backgroundColors = self.currentBackgroundColors
var appeared = false var appeared = false
self.updateState({ current in self.updateState({ current in
@ -1044,8 +1046,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
updated.displayPatternPanel = true updated.displayPatternPanel = true
if current.patternWallpaper == nil, let wallpaper = wallpaper { if current.patternWallpaper == nil, let wallpaper = wallpaper {
updated.patternWallpaper = wallpaper updated.patternWallpaper = wallpaper
if updated.backgroundColors == nil, let color = backgroundColor { if updated.backgroundColors == nil {
updated.backgroundColors = (color, nil) updated.backgroundColors = backgroundColors
} }
appeared = true appeared = true
} }

View File

@ -523,7 +523,7 @@ public func themeAutoNightSettingsController(context: AccountContext) -> ViewCon
} }
})) }))
}, updateTheme: { theme in }, updateTheme: { theme in
guard let presentationTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: theme, accentColor: nil, bubbleColors: nil, serviceBackgroundColor: .black) else { guard let presentationTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: theme) else {
return return
} }

View File

@ -481,7 +481,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
currentTheme = current.automaticThemeSwitchSetting.theme currentTheme = current.automaticThemeSwitchSetting.theme
} }
guard let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: currentTheme, accentColor: color?.color, bubbleColors: nil) else { guard let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: currentTheme, accentColor: color?.color) else {
return current return current
} }
@ -559,7 +559,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
}))) })))
} else { } else {
items.append(.action(ContextMenuActionItem(text: strings.Theme_Context_ChangeColors, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor) }, action: { c, f in items.append(.action(ContextMenuActionItem(text: strings.Theme_Context_ChangeColors, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor) }, action: { c, f in
guard let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: reference, accentColor: nil, bubbleColors: nil, backgroundColors: nil, preview: false) else { guard let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: reference, preview: false) else {
return return
} }
@ -725,7 +725,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The
return controller?.navigationController as? NavigationController return controller?.navigationController as? NavigationController
} }
selectThemeImpl = { theme in selectThemeImpl = { theme in
guard let presentationTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: theme, accentColor: nil, bubbleColors: nil, serviceBackgroundColor: .black) else { guard let presentationTheme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: theme) else {
return return
} }

View File

@ -284,7 +284,7 @@ private class ColorInputFieldNode: ASDisplayNode, UITextFieldDelegate {
private func updateSelectionLayout(size: CGSize, transition: ContainedViewLayoutTransition) { private func updateSelectionLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
self.measureNode.attributedText = NSAttributedString(string: self.textFieldNode.textField.text ?? "", font: self.textFieldNode.textField.font) self.measureNode.attributedText = NSAttributedString(string: self.textFieldNode.textField.text ?? "", font: self.textFieldNode.textField.font)
let size = self.measureNode.updateLayout(size) let size = self.measureNode.updateLayout(size)
transition.updateFrame(node: self.selectionNode, frame: CGRect(x: self.textFieldNode.frame.minX, y: 6.0, width: max(45.0, size.width), height: 20.0)) transition.updateFrame(node: self.selectionNode, frame: CGRect(x: self.textFieldNode.frame.minX, y: 6.0, width: max(0.0, size.width), height: 20.0))
} }
private func updateSelectionVisibility() { private func updateSelectionVisibility() {

View File

@ -733,7 +733,7 @@ public class WallpaperGalleryController: ViewController {
self.overlayNode?.insertSubnode(patternPanelNode, belowSubnode: self.toolbarNode!) self.overlayNode?.insertSubnode(patternPanelNode, belowSubnode: self.toolbarNode!)
} }
let panelHeight: CGFloat = 190.0 let panelHeight: CGFloat = 235.0
var patternPanelFrame = CGRect(x: 0.0, y: layout.size.height, width: layout.size.width, height: panelHeight) var patternPanelFrame = CGRect(x: 0.0, y: layout.size.height, width: layout.size.width, height: panelHeight)
if self.patternPanelEnabled { if self.patternPanelEnabled {
patternPanelFrame.origin = CGPoint(x: 0.0, y: layout.size.height - bottomInset - panelHeight) patternPanelFrame.origin = CGPoint(x: 0.0, y: layout.size.height - bottomInset - panelHeight)

View File

@ -40,6 +40,12 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
} }
} }
var backgroundColors: (UIColor, UIColor?)? = nil {
didSet {
self.updateWallpapers()
}
}
private var validLayout: CGSize? private var validLayout: CGSize?
var patternChanged: ((TelegramWallpaper?, Int32?, Bool) -> Void)? var patternChanged: ((TelegramWallpaper?, Int32?, Bool) -> Void)?
@ -128,15 +134,17 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
node.removeFromSupernode() node.removeFromSupernode()
} }
let backgroundColors = self.backgroundColors ?? (UIColor(rgb: 0xd6e2ee), nil)
var selected = true var selected = true
for wallpaper in wallpapers { for wallpaper in wallpapers {
let node = SettingsThemeWallpaperNode(overlayBackgroundColor: UIColor(rgb: 0x748698, alpha: 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
var updatedWallpaper = wallpaper var updatedWallpaper = wallpaper
if case let .file(file) = updatedWallpaper { if case let .file(file) = updatedWallpaper {
let settings = WallpaperSettings(blur: false, motion: false, color: 0xd6e2ee, intensity: 100) let settings = WallpaperSettings(blur: false, motion: false, color: Int32(bitPattern: backgroundColors.0.rgb), bottomColor: backgroundColors.1.flatMap { Int32(bitPattern: $0.rgb) }, intensity: 100)
updatedWallpaper = .file(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: file.isPattern, isDark: file.isDark, slug: file.slug, file: file.file, settings: settings) updatedWallpaper = .file(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: file.isPattern, isDark: file.isDark, slug: file.slug, file: file.file, settings: settings)
} }
@ -193,6 +201,11 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
var wallpaper = initialWallpaper ?? self.wallpapers.first var wallpaper = initialWallpaper ?? self.wallpapers.first
if let wallpaper = wallpaper { if let wallpaper = wallpaper {
var selectedFileId: Int64?
if case let .file(file) = wallpaper {
selectedFileId = file.id
}
self.currentWallpaper = wallpaper self.currentWallpaper = wallpaper
self.sliderView?.value = 40.0 self.sliderView?.value = 40.0
@ -200,7 +213,11 @@ final class WallpaperPatternPanelNode: ASDisplayNode {
if let subnodes = self.scrollNode.subnodes { if let subnodes = self.scrollNode.subnodes {
for case let subnode as SettingsThemeWallpaperNode in subnodes { for case let subnode as SettingsThemeWallpaperNode in subnodes {
subnode.setSelected(wallpaper == subnode.wallpaper, animated: false) var selected = false
if case let .file(file) = subnode.wallpaper, file.id == selectedFileId {
selected = true
}
subnode.setSelected(selected, animated: false)
} }
} }

View File

@ -6,7 +6,7 @@ import TelegramUIPreferences
public let defaultDarkPresentationTheme = makeDefaultDarkPresentationTheme(preview: false) public let defaultDarkPresentationTheme = makeDefaultDarkPresentationTheme(preview: false)
public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?) -> PresentationTheme { public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil) -> PresentationTheme {
if (theme.referenceTheme != .night) { if (theme.referenceTheme != .night) {
return theme return theme
} }
@ -80,7 +80,9 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
} }
var defaultWallpaper: TelegramWallpaper? var defaultWallpaper: TelegramWallpaper?
if let backgroundColors = backgroundColors { if let forcedWallpaper = forcedWallpaper {
defaultWallpaper = forcedWallpaper
} else if let backgroundColors = backgroundColors {
if let secondColor = backgroundColors.1 { if let secondColor = backgroundColors.1 {
defaultWallpaper = .gradient(Int32(bitPattern: backgroundColors.0.rgb), Int32(bitPattern: secondColor.rgb), WallpaperSettings()) defaultWallpaper = .gradient(Int32(bitPattern: backgroundColors.0.rgb), Int32(bitPattern: secondColor.rgb), WallpaperSettings())
} else { } else {

View File

@ -7,15 +7,7 @@ import TelegramUIPreferences
private let defaultDarkTintedAccentColor = UIColor(rgb: 0x2ea6ff) private let defaultDarkTintedAccentColor = UIColor(rgb: 0x2ea6ff)
public let defaultDarkTintedPresentationTheme = makeDefaultDarkTintedPresentationTheme(preview: false) public let defaultDarkTintedPresentationTheme = makeDefaultDarkTintedPresentationTheme(preview: false)
//public func makeDarkAccentPresentationTheme(accentColor: UIColor?, bubbleColors: (UIColor, UIColor?)?, preview: Bool) -> PresentationTheme { public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil) -> PresentationTheme {
// var accentColor = accentColor ?? defaultDarkAccentColor
// if accentColor == PresentationThemeBaseColor.blue.color {
// accentColor = defaultDarkAccentColor
// }
// return makeDarkPresentationTheme(accentColor: accentColor, bubbleColors: bubbleColors, preview: preview)
//}
public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?) -> PresentationTheme {
if (theme.referenceTheme != .nightAccent) { if (theme.referenceTheme != .nightAccent) {
return theme return theme
} }
@ -217,7 +209,9 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
} }
var defaultWallpaper: TelegramWallpaper? var defaultWallpaper: TelegramWallpaper?
if let backgroundColors = backgroundColors { if let forcedWallpaper = forcedWallpaper {
defaultWallpaper = forcedWallpaper
} else if let backgroundColors = backgroundColors {
if let secondColor = backgroundColors.1 { if let secondColor = backgroundColors.1 {
defaultWallpaper = .gradient(Int32(bitPattern: backgroundColors.0.rgb), Int32(bitPattern: secondColor.rgb), WallpaperSettings()) defaultWallpaper = .gradient(Int32(bitPattern: backgroundColors.0.rgb), Int32(bitPattern: secondColor.rgb), WallpaperSettings())
} else { } else {

View File

@ -8,7 +8,7 @@ public let defaultServiceBackgroundColor = UIColor(rgb: 0x000000, alpha: 0.3)
public let defaultPresentationTheme = makeDefaultDayPresentationTheme(serviceBackgroundColor: defaultServiceBackgroundColor, day: false, preview: false) public let defaultPresentationTheme = makeDefaultDayPresentationTheme(serviceBackgroundColor: defaultServiceBackgroundColor, day: false, preview: false)
public let defaultDayAccentColor = UIColor(rgb: 0x007ee5) public let defaultDayAccentColor = UIColor(rgb: 0x007ee5)
public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, serviceBackgroundColor: UIColor?) -> PresentationTheme { public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor?) -> PresentationTheme {
if (theme.referenceTheme != .day && theme.referenceTheme != .dayClassic) { if (theme.referenceTheme != .day && theme.referenceTheme != .dayClassic) {
return theme return theme
} }
@ -172,7 +172,9 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ac
} }
var defaultWallpaper: TelegramWallpaper? var defaultWallpaper: TelegramWallpaper?
if let backgroundColors = backgroundColors { if let forcedWallpaper = forcedWallpaper {
defaultWallpaper = forcedWallpaper
} else if let backgroundColors = backgroundColors {
if let secondColor = backgroundColors.1 { if let secondColor = backgroundColors.1 {
defaultWallpaper = .gradient(Int32(bitPattern: backgroundColors.0.rgb), Int32(bitPattern: secondColor.rgb), WallpaperSettings()) defaultWallpaper = .gradient(Int32(bitPattern: backgroundColors.0.rgb), Int32(bitPattern: secondColor.rgb), WallpaperSettings())
} else { } else {

View File

@ -1,6 +1,7 @@
import Foundation import Foundation
import UIKit import UIKit
import Postbox import Postbox
import SyncCore
import TelegramUIPreferences import TelegramUIPreferences
public func makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference, serviceBackgroundColor: UIColor?, preview: Bool = false) -> PresentationTheme { public func makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference, serviceBackgroundColor: UIColor?, preview: Bool = false) -> PresentationTheme {
@ -18,37 +19,37 @@ public func makeDefaultPresentationTheme(reference: PresentationBuiltinThemeRefe
return theme return theme
} }
public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?) -> 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 {
return theme return theme
} }
switch theme.referenceTheme { switch theme.referenceTheme {
case .day, .dayClassic: case .day, .dayClassic:
return customizeDefaultDayTheme(theme: theme, editing: editing, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, serviceBackgroundColor: nil) return customizeDefaultDayTheme(theme: theme, editing: editing, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper, serviceBackgroundColor: nil)
case .night: case .night:
return customizeDefaultDarkPresentationTheme(theme: theme, editing: editing, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors) return customizeDefaultDarkPresentationTheme(theme: theme, editing: editing, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper)
case .nightAccent: case .nightAccent:
return customizeDefaultDarkTintedPresentationTheme(theme: theme, editing: editing, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors) return customizeDefaultDarkTintedPresentationTheme(theme: theme, editing: editing, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper)
} }
return theme return theme
} }
public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, accentColor: UIColor?, bubbleColors: (UIColor, UIColor?)?, backgroundColors: (UIColor, UIColor?)? = nil, serviceBackgroundColor: UIColor? = nil, preview: Bool = false) -> PresentationTheme? { 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? {
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, serviceBackgroundColor: serviceBackgroundColor, preview: preview)
theme = customizePresentationTheme(defaultTheme, editing: true, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors) 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, 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, resolvedWallpaper: info.resolvedWallpaper) {
theme = customizePresentationTheme(loadedTheme, editing: false, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors) theme = customizePresentationTheme(loadedTheme, editing: false, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper)
} else { } else {
return nil return nil
} }
case let .cloud(info): case let .cloud(info):
if let file = info.theme.file, let path = mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead), let loadedTheme = makePresentationTheme(data: data, resolvedWallpaper: info.resolvedWallpaper) { if let file = info.theme.file, let path = mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead), let loadedTheme = makePresentationTheme(data: data, resolvedWallpaper: info.resolvedWallpaper) {
theme = customizePresentationTheme(loadedTheme, editing: false, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors) theme = customizePresentationTheme(loadedTheme, editing: false, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper)
} else { } else {
return nil return nil
} }

View File

@ -39,6 +39,8 @@ extension TelegramWallpaper: Codable {
case "builtin": case "builtin":
self = .builtin(WallpaperSettings()) self = .builtin(WallpaperSettings())
default: default:
let options = ["motion", "blur"]
if [6,7].contains(value.count), let color = UIColor(hexString: value) { if [6,7].contains(value.count), let color = UIColor(hexString: value) {
self = .color(Int32(bitPattern: color.rgb)) self = .color(Int32(bitPattern: color.rgb))
} else { } else {
@ -52,28 +54,40 @@ extension TelegramWallpaper: Codable {
blur = true blur = true
} }
if components.count >= 2 && components.count <= 4 && [6,7].contains(components[0].count) && !["motion", "blur"].contains(components[0]) && [6,7].contains(components[1].count) && !["motion", "blur"].contains(components[1]), let topColor = UIColor(hexString: components[0]), let bottomColor = UIColor(hexString: components[1]) { if components.count >= 2 && components.count <= 4 && [6,7].contains(components[0].count) && !options.contains(components[0]) && [6,7].contains(components[1].count) && !options.contains(components[1]), let topColor = UIColor(hexString: components[0]), let bottomColor = UIColor(hexString: components[1]) {
self = .gradient(Int32(bitPattern: topColor.rgb), Int32(bitPattern: bottomColor.rgb), WallpaperSettings(blur: blur, motion: motion)) self = .gradient(Int32(bitPattern: topColor.rgb), Int32(bitPattern: bottomColor.rgb), WallpaperSettings(blur: blur, motion: motion))
} else { } else {
var slug: String? var slug: String?
var color: Int32? var color: Int32?
var bottomColor: Int32?
var intensity: Int32? var intensity: Int32?
if !components.isEmpty { if !components.isEmpty {
slug = components[0] slug = components[0]
} }
if components.count > 1, !["motion", "blur"].contains(components[1]), components[1].count == 6, let value = UIColor(hexString: components[1]) { if components.count > 1 {
color = Int32(bitPattern: value.rgb) for i in 1 ..< components.count {
} let component = components[i]
if components.count > 2, !["motion", "blur"].contains(components[2]), let value = Int32(components[2]) { if options.contains(component) {
if value >= 0 && value <= 100 { continue
intensity = value }
} else { if component.count == 6, let value = UIColor(hexString: component) {
intensity = 50 if color == nil {
color = Int32(bitPattern: value.rgb)
} else if bottomColor == nil {
bottomColor = Int32(bitPattern: value.rgb)
}
} else if component.count <= 3, let value = Int32(component) {
if value >= 0 && value <= 100 {
intensity = value
} else {
intensity = 50
}
}
} }
} }
if let slug = slug { if let slug = slug {
self = .file(id: 0, accessHash: 0, isCreator: false, isDefault: false, isPattern: color != nil, isDark: false, slug: slug, file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(blur: blur, motion: motion, color: color, intensity: intensity)) self = .file(id: 0, accessHash: 0, isCreator: false, isDefault: false, isPattern: color != nil, isDark: false, slug: slug, file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(blur: blur, motion: motion, color: color, bottomColor: bottomColor, intensity: intensity))
} else { } else {
throw PresentationThemeDecodingError.generic throw PresentationThemeDecodingError.generic
} }
@ -113,6 +127,9 @@ extension TelegramWallpaper: Codable {
if let intensity = file.settings.intensity { if let intensity = file.settings.intensity {
components.append("\(intensity)") components.append("\(intensity)")
} }
if let bottomColor = file.settings.bottomColor {
components.append(String(format: "%06x", bottomColor))
}
} }
if file.settings.motion { if file.settings.motion {
components.append("motion") components.append("motion")

View File

@ -1067,7 +1067,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
incomingColor = UIColor(rgb: 0xffffff) incomingColor = UIColor(rgb: 0xffffff)
if let accentColor = accentColor { if let accentColor = accentColor {
if let bubbleColors = bubbleColors { if let bubbleColors = bubbleColors {
backgroundColor = UIColor(rgb: 0xffffff) backgroundColor = UIColor(rgb: 0xd6e2ee)
outgoingColor = bubbleColors outgoingColor = bubbleColors
} else { } else {
backgroundColor = accentColor.withMultiplied(hue: 1.019, saturation: 0.867, brightness: 0.965) backgroundColor = accentColor.withMultiplied(hue: 1.019, saturation: 0.867, brightness: 0.965)
@ -1127,7 +1127,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
backgroundColor = (.black, nil) backgroundColor = (.black, nil)
case let .file(file): case let .file(file):
if file.isPattern, let color = file.settings.color { if file.isPattern, let color = file.settings.color {
backgroundColor = (UIColor(rgb: UInt32(bitPattern: color)), nil) backgroundColor = (UIColor(rgb: UInt32(bitPattern: color)), file.settings.bottomColor.flatMap { UIColor(rgb: UInt32(bitPattern: $0)) })
} else { } else {
backgroundColor = (theme.chatList.backgroundColor, nil) backgroundColor = (theme.chatList.backgroundColor, nil)
} }