mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
f5f60b9933
@ -4429,8 +4429,8 @@ Sorry for the inconvenience.";
|
||||
"Appearance.AppIconClassicX" = "Classic X";
|
||||
"Appearance.AppIconFilled" = "Filled";
|
||||
"Appearance.AppIconFilledX" = "Filled X";
|
||||
"Appearance.AppIconNew1" = "New 1";
|
||||
"Appearance.AppIconNew2" = "New 2";
|
||||
"Appearance.AppIconNew1" = "Sunset";
|
||||
"Appearance.AppIconNew2" = "Aqua";
|
||||
|
||||
"Appearance.ThemeCarouselClassic" = "Classic";
|
||||
"Appearance.ThemeCarouselDay" = "Day";
|
||||
|
@ -3,6 +3,6 @@ import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
|
||||
public func createGradientBackgroundNode(useSharedAnimationPhase: Bool = false) -> GradientBackgroundNode {
|
||||
return GradientBackgroundNode(useSharedAnimationPhase: useSharedAnimationPhase)
|
||||
public func createGradientBackgroundNode(colors: [UIColor]? = nil, useSharedAnimationPhase: Bool = false) -> GradientBackgroundNode {
|
||||
return GradientBackgroundNode(colors: colors, useSharedAnimationPhase: useSharedAnimationPhase)
|
||||
}
|
||||
|
@ -192,6 +192,7 @@ public final class GradientBackgroundNode: ASDisplayNode {
|
||||
return generateGradient(size: size, colors: colors, positions: positions)
|
||||
}
|
||||
|
||||
private var colors: [UIColor]
|
||||
private var phase: Int = 0
|
||||
|
||||
public let contentView: UIImageView
|
||||
@ -213,13 +214,6 @@ public final class GradientBackgroundNode: ASDisplayNode {
|
||||
|
||||
private var validLayout: CGSize?
|
||||
|
||||
private var colors: [UIColor] = [
|
||||
UIColor(rgb: 0x7FA381),
|
||||
UIColor(rgb: 0xFFF5C5),
|
||||
UIColor(rgb: 0x336F55),
|
||||
UIColor(rgb: 0xFBE37D)
|
||||
]
|
||||
|
||||
private struct PhaseTransitionKey: Hashable {
|
||||
var width: Int
|
||||
var height: Int
|
||||
@ -234,9 +228,16 @@ public final class GradientBackgroundNode: ASDisplayNode {
|
||||
private let useSharedAnimationPhase: Bool
|
||||
static var sharedPhase: Int = 0
|
||||
|
||||
public init(useSharedAnimationPhase: Bool = false) {
|
||||
public init(colors: [UIColor]? = nil, useSharedAnimationPhase: Bool = false) {
|
||||
self.useSharedAnimationPhase = useSharedAnimationPhase
|
||||
self.contentView = UIImageView()
|
||||
let defaultColors: [UIColor] = [
|
||||
UIColor(rgb: 0x7FA381),
|
||||
UIColor(rgb: 0xFFF5C5),
|
||||
UIColor(rgb: 0x336F55),
|
||||
UIColor(rgb: 0xFBE37D)
|
||||
]
|
||||
self.colors = colors ?? defaultColors
|
||||
|
||||
super.init()
|
||||
|
||||
@ -395,10 +396,23 @@ public final class GradientBackgroundNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
public func updateColors(colors: [UIColor]) {
|
||||
self.colors = colors
|
||||
self.invalidated = true
|
||||
if let size = self.validLayout {
|
||||
self.updateLayout(size: size, transition: .immediate)
|
||||
var updated = false
|
||||
if self.colors.count != colors.count {
|
||||
updated = true
|
||||
} else {
|
||||
for i in 0 ..< self.colors.count {
|
||||
if !self.colors[i].isEqual(colors[i]) {
|
||||
updated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if updated {
|
||||
self.colors = colors
|
||||
self.invalidated = true
|
||||
if let size = self.validLayout {
|
||||
self.updateLayout(size: size, transition: .immediate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode {
|
||||
|
||||
var colors: [UInt32] = []
|
||||
var intensity: CGFloat = 0.5
|
||||
if case let .gradient(value, _) = wallpaper {
|
||||
if case let .gradient(_, value, _) = wallpaper {
|
||||
colors = value
|
||||
} else if case let .file(file) = wallpaper {
|
||||
colors = file.settings.colors
|
||||
@ -250,7 +250,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode {
|
||||
} else {
|
||||
self.imageNode.alpha = 1.0
|
||||
|
||||
imageSignal = wallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, thumbnail: true, autoFetchFullSize: true, synchronousLoad: synchronousLoad)
|
||||
imageSignal = wallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, thumbnail: true, autoFetchFullSize: true, blurred: file.settings.blur, synchronousLoad: synchronousLoad)
|
||||
|
||||
self.updateIsLoaded(isLoaded: true, animated: false)
|
||||
self.isLoadedDisposable.set(nil)
|
||||
|
@ -164,7 +164,7 @@ final class ThemeAccentColorController: ViewController {
|
||||
if let patternWallpaper = state.patternWallpaper {
|
||||
coloredWallpaper = patternWallpaper.withUpdatedSettings(WallpaperSettings(colors: state.backgroundColors, intensity: state.patternIntensity, rotation: state.rotation))
|
||||
} else if state.backgroundColors.count >= 2 {
|
||||
coloredWallpaper = .gradient(state.backgroundColors, WallpaperSettings(rotation: state.rotation))
|
||||
coloredWallpaper = .gradient(nil, state.backgroundColors, WallpaperSettings(rotation: state.rotation))
|
||||
} else {
|
||||
coloredWallpaper = .color(state.backgroundColors[0])
|
||||
}
|
||||
@ -425,12 +425,18 @@ final class ThemeAccentColorController: ViewController {
|
||||
rotation = file.settings.rotation ?? 0
|
||||
} else if case let .color(color) = wallpaper {
|
||||
backgroundColors = [color]
|
||||
} else if case let .gradient(colors, settings) = wallpaper {
|
||||
} else if case let .gradient(_, colors, settings) = wallpaper {
|
||||
backgroundColors = colors
|
||||
motion = settings.motion
|
||||
rotation = settings.rotation ?? 0
|
||||
} else {
|
||||
backgroundColors = []
|
||||
if let image = chatControllerBackgroundImage(theme: nil, wallpaper: wallpaper, mediaBox: strongSelf.context.sharedContext.accountManager.mediaBox, knockoutMode: false) {
|
||||
backgroundColors = [averageColor(from: image).rgb]
|
||||
} else if let image = chatControllerBackgroundImage(theme: nil, wallpaper: wallpaper, mediaBox: strongSelf.context.account.postbox.mediaBox, knockoutMode: false) {
|
||||
backgroundColors = [averageColor(from: image).rgb]
|
||||
} else {
|
||||
backgroundColors = [UIColor.gray.rgb]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
}
|
||||
convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)))
|
||||
} else if backgroundColors.count >= 2 {
|
||||
wallpaper = .gradient(backgroundColors, WallpaperSettings(rotation: state.rotation))
|
||||
wallpaper = .gradient(nil, backgroundColors, WallpaperSettings(rotation: state.rotation))
|
||||
} else {
|
||||
wallpaper = .color(backgroundColors.first ?? 0xffffff)
|
||||
}
|
||||
@ -468,7 +468,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
case .dayClassic:
|
||||
let topColor = accentColor.withMultiplied(hue: 1.010, saturation: 0.414, brightness: 0.957)
|
||||
let bottomColor = accentColor.withMultiplied(hue: 1.019, saturation: 0.867, brightness: 0.965)
|
||||
suggestedWallpaper = .gradient([topColor.rgb, bottomColor.rgb], WallpaperSettings())
|
||||
suggestedWallpaper = .gradient(nil, [topColor.rgb, bottomColor.rgb], WallpaperSettings())
|
||||
backgroundColors = [topColor.rgb, bottomColor.rgb]
|
||||
case .nightAccent:
|
||||
let color = accentColor.withMultiplied(hue: 1.024, saturation: 0.573, brightness: 0.18)
|
||||
|
@ -3,22 +3,31 @@ import Postbox
|
||||
import SyncCore
|
||||
import TelegramUIPreferences
|
||||
|
||||
private func patternWallpaper(slug: String, topColor: UInt32, bottomColor: UInt32?, intensity: Int32?, rotation: Int32?) -> TelegramWallpaper {
|
||||
var colors: [UInt32] = [topColor]
|
||||
if let bottomColor = bottomColor {
|
||||
colors.append(bottomColor)
|
||||
}
|
||||
private func patternWallpaper(slug: String, colors: [UInt32], intensity: Int32?, rotation: Int32?) -> TelegramWallpaper {
|
||||
return TelegramWallpaper.file(id: 0, accessHash: 0, isCreator: false, isDefault: true, isPattern: true, isDark: false, slug: slug, file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: LocalFileMediaResource(fileId: 0), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(colors: colors, intensity: intensity ?? 50, rotation: rotation))
|
||||
}
|
||||
|
||||
var dayClassicColorPresets: [PresentationThemeAccentColor] = [
|
||||
PresentationThemeAccentColor(index: 106, baseColor: .preset, accentColor: 0xfff55783, bubbleColors: (0xffd6f5ff, 0xffc9fdfe), wallpaper: patternWallpaper(slug: "p-pXcflrmFIBAAAAvXYQk-mCwZU", topColor: 0xfffce3ec, bottomColor: 0xfffec8ff, intensity: 50, rotation: 45)),
|
||||
PresentationThemeAccentColor(index: 102, baseColor: .preset, accentColor: 0xffff5fa9, bubbleColors: (0xfffff4d7, nil), wallpaper: patternWallpaper(slug: "51nnTjx8mFIBAAAAaFGJsMIvWkk", topColor: 0xfff6b594, bottomColor: 0xffebf6cd, intensity: 46, rotation: 45)),
|
||||
PresentationThemeAccentColor(index: 104, baseColor: .preset, accentColor: 0xff5a9e29, bubbleColors: (0xfffff8df, 0xffdcf8c6), wallpaper: patternWallpaper(slug: "R3j69wKskFIBAAAAoUdXWCKMzCM", topColor: 0xffede6dd, bottomColor: 0xffffd59e, intensity: 50, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 101, baseColor: .preset, accentColor: 0xff7e5fe5, bubbleColors: (0xfff5e2ff, nil), wallpaper: patternWallpaper(slug: "nQcFYJe1mFIBAAAAcI95wtIK0fk", topColor: 0xfffcccf4, bottomColor: 0xffae85f0, intensity: 54, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 107, baseColor: .preset, accentColor: 0xff2cb9ed, bubbleColors: (0xffadf7b5, 0xfffcff8b), wallpaper: patternWallpaper(slug: "CJNyxPMgSVAEAAAAvW9sMwc51cw", topColor: 0xff1a2d1a, bottomColor: 0xff5f6f54, intensity: 50, rotation: 225)),
|
||||
PresentationThemeAccentColor(index: 103, baseColor: .preset, accentColor: 0xff199972, bubbleColors: (0xfffffec7, nil), wallpaper: patternWallpaper(slug: "fqv01SQemVIBAAAApND8LDRUhRU", topColor: 0xffc1e7cb, bottomColor: nil, intensity: 50, rotation: nil)),
|
||||
PresentationThemeAccentColor(index: 105, baseColor: .preset, accentColor: 0x0ff09eee, bubbleColors: (0xff94fff9, 0xffccffc7), wallpaper: patternWallpaper(slug: "p-pXcflrmFIBAAAAvXYQk-mCwZU", topColor: 0xffffbca6, bottomColor: 0xffff63bd, intensity: 57, rotation: 225))
|
||||
// Pink with Blue
|
||||
PresentationThemeAccentColor(index: 106, baseColor: .preset, accentColor: 0xfff55783, bubbleColors: (0xffd6f5ff, 0xffc9fdfe), wallpaper: patternWallpaper(slug: "fqv01SQemVIBAAAApND8LDRUhRU", colors: [0x8dc0eb, 0xb9d1ea, 0xc6b1ef, 0xebd7ef], intensity: 50, rotation: nil)),
|
||||
|
||||
// Pink with Gold
|
||||
PresentationThemeAccentColor(index: 102, baseColor: .preset, accentColor: 0xFFFF5FA9, bubbleColors: (0xFFFFF4D7, nil), wallpaper: patternWallpaper(slug: "9GcNVISdSVADAAAAUcw5BYjELW4", colors: [0xeaa36e, 0xf0e486, 0xf29ebf, 0xe8c06e], intensity: 50, rotation: nil)),
|
||||
|
||||
// Green
|
||||
PresentationThemeAccentColor(index: 104, baseColor: .preset, accentColor: 0xFF5A9E29, bubbleColors: (0xffFFF8DF, nil), wallpaper: patternWallpaper(slug: "-Xc-np9y2VMCAAAARKr0yNNPYW0", colors: [0x7fc289, 0xe4d573, 0xafd677, 0xf0c07a], intensity: 50, rotation: nil)),
|
||||
|
||||
// Purple
|
||||
PresentationThemeAccentColor(index: 101, baseColor: .preset, accentColor: 0xFF7E5FE5, bubbleColors: (0xFFF5e2FF, nil), wallpaper: patternWallpaper(slug: "JrNEYdNhSFABAAAA9WtRdJkPRbY", colors: [0xe4b2ea, 0x8376c2, 0xeab9d9, 0xb493e6], intensity: 50, rotation: nil)),
|
||||
|
||||
// Light Blue
|
||||
PresentationThemeAccentColor(index: 107, baseColor: .preset, accentColor: 0xFF2CB9ED, bubbleColors: (0xFFADF7B5, 0xFFFCFF8B), wallpaper: patternWallpaper(slug: "CJNyxPMgSVAEAAAAvW9sMwc51cw", colors: [0x1a2e1a, 0x47623c, 0x222e24, 0x314429], intensity: 50, rotation: nil)),
|
||||
|
||||
// Mint
|
||||
PresentationThemeAccentColor(index: 103, baseColor: .preset, accentColor: 0xFF199972, bubbleColors: (0xFFFFFEC7, nil), wallpaper: patternWallpaper(slug: "CJNyxPMgSVAEAAAAvW9sMwc51cw", colors: [0xdceb92, 0x8fe1d6, 0x67a3f2, 0x85d685], intensity: 50, rotation: nil)),
|
||||
|
||||
// Pink with Green
|
||||
PresentationThemeAccentColor(index: 105, baseColor: .preset, accentColor: 0xFFDA90D9, bubbleColors: (0xFF94FFF9, 0xFFCCFFC7), wallpaper: patternWallpaper(slug: "mP3FG_iwSFAFAAAA2AklJO978pA", colors: [0xffc3b2, 0xe2c0ff, 0xffe7b2], intensity: 50, rotation: nil))
|
||||
]
|
||||
|
||||
var dayColorPresets: [PresentationThemeAccentColor] = [
|
||||
|
@ -145,9 +145,50 @@ final class ThemeGridController: ViewController {
|
||||
})
|
||||
}
|
||||
}, presentColors: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
/*if let strongSelf = self {
|
||||
let controller = ThemeColorsGridController(context: strongSelf.context)
|
||||
(strongSelf.navigationController as? NavigationController)?.pushViewController(controller)
|
||||
}*/
|
||||
|
||||
if let strongSelf = self {
|
||||
let _ = (strongSelf.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings])
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] sharedData in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let settings = (sharedData.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings] as? PresentationThemeSettings) ?? PresentationThemeSettings.defaultSettings
|
||||
|
||||
let autoNightModeTriggered = strongSelf.presentationData.autoNightModeTriggered
|
||||
let themeReference: PresentationThemeReference
|
||||
if autoNightModeTriggered {
|
||||
themeReference = settings.automaticThemeSwitchSetting.theme
|
||||
} else {
|
||||
themeReference = settings.theme
|
||||
}
|
||||
|
||||
let controller = ThemeAccentColorController(context: strongSelf.context, mode: .background(themeReference: themeReference))
|
||||
controller.completion = { [weak self] in
|
||||
if let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController {
|
||||
var controllers = navigationController.viewControllers
|
||||
controllers = controllers.filter { controller in
|
||||
if controller is ThemeColorsGridController {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
navigationController.setViewControllers(controllers, animated: false)
|
||||
controllers = controllers.filter { controller in
|
||||
if controller is ThemeAccentColorController {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
navigationController.setViewControllers(controllers, animated: true)
|
||||
}
|
||||
}
|
||||
strongSelf.push(controller)
|
||||
})
|
||||
}
|
||||
}, emptyStateUpdated: { [weak self] empty in
|
||||
if let strongSelf = self {
|
||||
|
@ -61,7 +61,7 @@ struct ThemeGridControllerEntry: Comparable, Identifiable {
|
||||
return .builtin
|
||||
case let .color(color):
|
||||
return .color(color)
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
return .gradient(colors)
|
||||
case let .file(id, _, _, _, _, _, _, _, settings):
|
||||
return .file(id, settings.colors, settings.intensity ?? 0)
|
||||
|
@ -192,7 +192,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
if file.settings.blur {
|
||||
self.chatContainerNode.insertSubnode(self.blurredNode, belowSubnode: self.messagesContainerNode)
|
||||
}
|
||||
} else if case let .gradient(colors, _) = self.wallpaper {
|
||||
} else if case let .gradient(_, colors, _) = self.wallpaper {
|
||||
gradientColors = colors
|
||||
}
|
||||
|
||||
|
@ -525,19 +525,21 @@ final class WallpaperColorPanelNode: ASDisplayNode {
|
||||
if colorWasRemovable != self.multiColorFieldNode.isRemovable {
|
||||
updateLayout = true
|
||||
}
|
||||
|
||||
if let index = self.state.selection {
|
||||
if self.state.colors.count > index {
|
||||
self.colorPickerNode.color = UIColor(rgb: self.state.colors[index])
|
||||
}
|
||||
}
|
||||
|
||||
if updateLayout, let size = self.validLayout {
|
||||
if let index = self.state.selection {
|
||||
if self.state.colors.count > index {
|
||||
self.colorPickerNode.color = UIColor(rgb: self.state.colors[index])
|
||||
}
|
||||
}
|
||||
|
||||
self.updateLayout(size: size, transition: animated ? .animated(duration: 0.3, curve: .easeInOut) : .immediate)
|
||||
}
|
||||
|
||||
if let index = state.selection {
|
||||
self.multiColorFieldNode.setColor(UIColor(rgb: self.state.colors[index]), update: false)
|
||||
if self.state.colors.count > index {
|
||||
self.multiColorFieldNode.setColor(UIColor(rgb: self.state.colors[index]), update: false)
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0 ..< state.colors.count {
|
||||
|
@ -342,10 +342,10 @@ public class WallpaperGalleryController: ViewController {
|
||||
return GalleryPagerTransaction(deleteItems: [], insertItems: [], updateItems: updateItems, focusOnItem: self.galleryNode.pager.centralItemNode()?.index, synchronous: false)
|
||||
}
|
||||
|
||||
private func updateCurrentEntryTransaction(entry: WallpaperGalleryEntry, arguments: WallpaperGalleryItemArguments) -> GalleryPagerTransaction {
|
||||
private func updateCurrentEntryTransaction(entry: WallpaperGalleryEntry, arguments: WallpaperGalleryItemArguments, index: Int) -> GalleryPagerTransaction {
|
||||
var updateItems: [GalleryPagerUpdateItem] = []
|
||||
for index in 0 ..< self.entries.count {
|
||||
if index == self.centralEntryIndex {
|
||||
for i in 0 ..< self.entries.count {
|
||||
if i == index {
|
||||
let item = GalleryPagerUpdateItem(index: index, previousIndex: index, item: WallpaperGalleryItem(context: self.context, index: index, entry: entry, arguments: arguments, source: self.source))
|
||||
updateItems.append(item)
|
||||
}
|
||||
@ -627,7 +627,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
switch initialWallpaper {
|
||||
case let .color(color):
|
||||
strongSelf.patternPanelNode?.backgroundColors = ([color], nil, nil)
|
||||
case let .gradient(colors, settings):
|
||||
case let .gradient(_, colors, settings):
|
||||
strongSelf.patternPanelNode?.backgroundColors = (colors, settings.rotation, nil)
|
||||
case let .file(file) where file.isPattern:
|
||||
strongSelf.patternPanelNode?.backgroundColors = (file.settings.colors, file.settings.rotation, file.settings.intensity)
|
||||
@ -647,7 +647,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
case let .file(file):
|
||||
if !file.settings.colors.isEmpty {
|
||||
if file.settings.colors.count >= 2 {
|
||||
strongSelf.updateEntries(wallpaper: .gradient(file.settings.colors, WallpaperSettings(rotation: file.settings.rotation)))
|
||||
strongSelf.updateEntries(wallpaper: .gradient(nil, file.settings.colors, WallpaperSettings(rotation: file.settings.rotation)))
|
||||
} else {
|
||||
strongSelf.updateEntries(wallpaper: .color(file.settings.colors[0]))
|
||||
}
|
||||
@ -770,7 +770,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
entries[centralEntryIndex] = currentEntry
|
||||
self.entries = entries
|
||||
|
||||
self.galleryNode.pager.transaction(self.updateCurrentEntryTransaction(entry: currentEntry, arguments: WallpaperGalleryItemArguments(colorPreview: preview, isColorsList: false, patternEnabled: self.patternPanelEnabled)))
|
||||
self.galleryNode.pager.transaction(self.updateCurrentEntryTransaction(entry: currentEntry, arguments: WallpaperGalleryItemArguments(colorPreview: preview, isColorsList: false, patternEnabled: self.patternPanelEnabled), index: centralEntryIndex))
|
||||
}
|
||||
|
||||
private func updateEntries(pattern: TelegramWallpaper?, intensity: Int32? = nil, preview: Bool = false) {
|
||||
@ -782,7 +782,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
entryColors = [color]
|
||||
} else if case let .file(file) = wallpaper, file.isPattern {
|
||||
entryColors = file.settings.colors
|
||||
} else if case let .gradient(colors, _) = wallpaper {
|
||||
} else if case let .gradient(_, colors, _) = wallpaper {
|
||||
entryColors = colors
|
||||
}
|
||||
}
|
||||
@ -797,7 +797,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
let newWallpaper = TelegramWallpaper.color(entryColors[0])
|
||||
updatedEntries.append(.wallpaper(newWallpaper, nil))
|
||||
} else {
|
||||
let newWallpaper = TelegramWallpaper.gradient(entryColors, WallpaperSettings(rotation: nil))
|
||||
let newWallpaper = TelegramWallpaper.gradient(nil, entryColors, WallpaperSettings(rotation: nil))
|
||||
updatedEntries.append(.wallpaper(newWallpaper, nil))
|
||||
}
|
||||
}
|
||||
@ -847,7 +847,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
case let .file(file):
|
||||
colors = file.settings.colors
|
||||
rotation = file.settings.rotation
|
||||
case let .gradient(colorsValue, settings):
|
||||
case let .gradient(_, colorsValue, settings):
|
||||
colors = colorsValue
|
||||
rotation = settings.rotation
|
||||
default:
|
||||
@ -893,7 +893,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
return
|
||||
}
|
||||
|
||||
var wallpaper: TelegramWallpaper = .gradient(colors, WallpaperSettings(blur: false, motion: false, colors: [], intensity: nil, rotation: nil))
|
||||
var wallpaper: TelegramWallpaper = .gradient(nil, colors, WallpaperSettings(blur: false, motion: false, colors: [], intensity: nil, rotation: nil))
|
||||
|
||||
if case let .file(file) = currentWallpaper {
|
||||
wallpaper = currentWallpaper.withUpdatedSettings(WallpaperSettings(blur: false, motion: false, colors: colors, intensity: file.settings.intensity, rotation: file.settings.rotation))
|
||||
@ -1011,7 +1011,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
controller = ShareController(context: context, subject: .url("https://t.me/bg/\(slug)\(optionsString)"))
|
||||
case let .color(color):
|
||||
controller = ShareController(context: context, subject: .url("https://t.me/bg/\(UIColor(rgb: color).hexString)"))
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
var colorsString = ""
|
||||
|
||||
for color in colors {
|
||||
|
@ -105,6 +105,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
|
||||
private let messagesContainerNode: ASDisplayNode
|
||||
private var messageNodes: [ListViewItemNode]?
|
||||
private var validMessages: [String]?
|
||||
|
||||
fileprivate let _ready = Promise<Void>()
|
||||
private let fetchDisposable = MetaDisposable()
|
||||
@ -310,7 +311,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
} else {
|
||||
self.playButtonNode.setImage(self.playButtonRotateImage, for: [])
|
||||
}
|
||||
} else if case let .gradient(colors, _) = wallpaper {
|
||||
} else if case let .gradient(_, colors, _) = wallpaper {
|
||||
self.nativeNode.isHidden = false
|
||||
self.nativeNode.update(wallpaper: wallpaper)
|
||||
self.patternButtonNode.isSelected = false
|
||||
@ -359,7 +360,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
actionSignal = .single(defaultAction)
|
||||
colorSignal = chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: self.context.account.postbox.mediaBox)
|
||||
isBlurrable = false
|
||||
case let .gradient(colors, settings):
|
||||
case let .gradient(_, colors, settings):
|
||||
displaySize = CGSize(width: 1.0, height: 1.0)
|
||||
contentSize = displaySize
|
||||
signal = .single({ _ in nil })
|
||||
@ -800,7 +801,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
return colors.map(UIColor.init(rgb:))
|
||||
case let .color(color):
|
||||
return [UIColor(rgb: color)]
|
||||
@ -824,7 +825,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
return
|
||||
}
|
||||
switch wallpaper {
|
||||
case let .gradient(colors, settings):
|
||||
case let .gradient(_, colors, settings):
|
||||
if colors.count >= 3 {
|
||||
self.nativeNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring))
|
||||
} else {
|
||||
@ -972,7 +973,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
blurFrame = leftButtonFrame
|
||||
motionAlpha = 1.0
|
||||
motionFrame = rightButtonFrame
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
motionAlpha = 0.0
|
||||
patternAlpha = 1.0
|
||||
|
||||
@ -1075,7 +1076,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
if file.settings.colors.count >= 3 {
|
||||
hasAnimatableGradient = true
|
||||
}
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
if colors.count >= 3 {
|
||||
hasAnimatableGradient = true
|
||||
}
|
||||
@ -1097,7 +1098,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
if file.settings.colors.count >= 3 {
|
||||
hasAnimatableGradient = true
|
||||
}
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
if colors.count >= 3 {
|
||||
hasAnimatableGradient = true
|
||||
}
|
||||
@ -1130,18 +1131,22 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
|
||||
let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, availableHeight: layout.size.height)
|
||||
if let messageNodes = self.messageNodes {
|
||||
for i in 0 ..< items.count {
|
||||
items[i].updateNode(async: { f in f() }, node: { return messageNodes[i] }, params: params, previousItem: i == 0 ? nil : items[i - 1], nextItem: i == (items.count - 1) ? nil : items[i + 1], animation: .None) { layout, apply in
|
||||
let nodeFrame = CGRect(origin: messageNodes[i].frame.origin, size: CGSize(width: layout.size.width, height: layout.size.height))
|
||||
if self.validMessages != [topMessageText, bottomMessageText] {
|
||||
self.validMessages = [topMessageText, bottomMessageText]
|
||||
for i in 0 ..< items.count {
|
||||
items[i].updateNode(async: { f in f() }, node: { return messageNodes[i] }, params: params, previousItem: i == 0 ? nil : items[i - 1], nextItem: i == (items.count - 1) ? nil : items[i + 1], animation: .None) { layout, apply in
|
||||
let nodeFrame = CGRect(origin: messageNodes[i].frame.origin, size: CGSize(width: layout.size.width, height: layout.size.height))
|
||||
|
||||
messageNodes[i].contentSize = layout.contentSize
|
||||
messageNodes[i].insets = layout.insets
|
||||
messageNodes[i].frame = nodeFrame
|
||||
messageNodes[i].contentSize = layout.contentSize
|
||||
messageNodes[i].insets = layout.insets
|
||||
messageNodes[i].frame = nodeFrame
|
||||
|
||||
apply(ListViewItemApply(isOnScreen: true))
|
||||
apply(ListViewItemApply(isOnScreen: true))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.validMessages = [topMessageText, bottomMessageText]
|
||||
var messageNodes: [ListViewItemNode] = []
|
||||
for i in 0 ..< items.count {
|
||||
var itemNode: ListViewItemNode?
|
||||
|
@ -579,6 +579,10 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
||||
public func withUpdatedPartialReference(_ partialReference: PartialMediaReference?) -> TelegramMediaFile {
|
||||
return TelegramMediaFile(fileId: self.fileId, partialReference: partialReference, resource: self.resource, previewRepresentations: self.previewRepresentations, videoThumbnails: self.videoThumbnails, immediateThumbnailData: self.immediateThumbnailData, mimeType: self.mimeType, size: self.size, attributes: self.attributes)
|
||||
}
|
||||
|
||||
public func withUpdatedResource(_ resource: TelegramMediaResource) -> TelegramMediaFile {
|
||||
return TelegramMediaFile(fileId: self.fileId, partialReference: self.partialReference, resource: resource, previewRepresentations: self.previewRepresentations, videoThumbnails: self.videoThumbnails, immediateThumbnailData: self.immediateThumbnailData, mimeType: self.mimeType, size: self.size, attributes: self.attributes)
|
||||
}
|
||||
|
||||
public func withUpdatedSize(_ size: Int?) -> TelegramMediaFile {
|
||||
return TelegramMediaFile(fileId: self.fileId, partialReference: self.partialReference, resource: self.resource, previewRepresentations: self.previewRepresentations, videoThumbnails: self.videoThumbnails, immediateThumbnailData: self.immediateThumbnailData, mimeType: self.mimeType, size: size, attributes: self.attributes)
|
||||
|
@ -71,7 +71,7 @@ public struct WallpaperSettings: PostboxCoding, Equatable {
|
||||
public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
|
||||
case builtin(WallpaperSettings)
|
||||
case color(UInt32)
|
||||
case gradient([UInt32], WallpaperSettings)
|
||||
case gradient(Int64?, [UInt32], WallpaperSettings)
|
||||
case image([TelegramMediaImageRepresentation], WallpaperSettings)
|
||||
case file(id: Int64, accessHash: Int64, isCreator: Bool, isDefault: Bool, isPattern: Bool, isDark: Bool, slug: String, file: TelegramMediaFile, settings: WallpaperSettings)
|
||||
|
||||
@ -106,7 +106,7 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
|
||||
colors = decoder.decodeInt32ArrayForKey("colors").map(UInt32.init(bitPattern:))
|
||||
}
|
||||
|
||||
self = .gradient(colors, settings)
|
||||
self = .gradient(decoder.decodeOptionalInt64ForKey("id"), colors, settings)
|
||||
default:
|
||||
assertionFailure()
|
||||
self = .color(0xffffff)
|
||||
@ -130,8 +130,13 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
|
||||
case let .color(color):
|
||||
encoder.encodeInt32(1, forKey: "v")
|
||||
encoder.encodeInt32(Int32(bitPattern: color), forKey: "c")
|
||||
case let .gradient(colors, settings):
|
||||
case let .gradient(id, colors, settings):
|
||||
encoder.encodeInt32(4, forKey: "v")
|
||||
if let id = id {
|
||||
encoder.encodeInt64(id, forKey: "id")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "id")
|
||||
}
|
||||
encoder.encodeInt32Array(colors.map(Int32.init(bitPattern:)), forKey: "colors")
|
||||
encoder.encodeObject(settings, forKey: "settings")
|
||||
case let .image(representations, settings):
|
||||
@ -166,8 +171,8 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .gradient(colors, settings):
|
||||
if case .gradient(colors, settings) = rhs {
|
||||
case let .gradient(id, colors, settings):
|
||||
if case .gradient(id, colors, settings) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -201,8 +206,8 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .gradient(colors, _):
|
||||
if case .gradient(colors, _) = wallpaper {
|
||||
case let .gradient(_, colors, _):
|
||||
if case .gradient(_, colors, _) = wallpaper {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -224,7 +229,7 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
|
||||
|
||||
public var settings: WallpaperSettings? {
|
||||
switch self {
|
||||
case let .builtin(settings), let .gradient(_, settings), let .image(_, settings), let .file(_, _, _, _, _, _, _, _, settings):
|
||||
case let .builtin(settings), let .gradient(_, _, settings), let .image(_, settings), let .file(_, _, _, _, _, _, _, _, settings):
|
||||
return settings
|
||||
default:
|
||||
return nil
|
||||
@ -237,12 +242,12 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
|
||||
return .builtin(settings)
|
||||
case .color:
|
||||
return self
|
||||
case let .gradient(colors, _):
|
||||
return .gradient(colors, settings)
|
||||
case let .gradient(id, colors, _):
|
||||
return .gradient(id, colors, settings)
|
||||
case let .image(representations, _):
|
||||
return .image(representations, settings)
|
||||
case let .file(id, accessHash, isCreator, isDefault, isPattern, isDark, slug, file, _):
|
||||
return .file(id: id, accessHash: accessHash, isCreator: isCreator, isDefault: isDefault, isPattern: settings.colors.isEmpty ? isPattern : true, isDark: isDark, slug: slug, file: file, settings: settings)
|
||||
return .file(id: id, accessHash: accessHash, isCreator: isCreator, isDefault: isDefault, isPattern: isPattern, isDark: isDark, slug: slug, file: file, settings: settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,13 +77,13 @@ extension TelegramWallpaper {
|
||||
//assertionFailure()
|
||||
self = .color(0xffffff)
|
||||
}
|
||||
case let .wallPaperNoFile(_, _, settings):
|
||||
case let .wallPaperNoFile(id, _, settings):
|
||||
if let settings = settings, case let .wallPaperSettings(_, backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor, _, rotation) = settings {
|
||||
let colors: [UInt32] = ([backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor] as [Int32?]).compactMap({ color -> UInt32? in
|
||||
return color.flatMap(UInt32.init(bitPattern:))
|
||||
})
|
||||
if colors.count > 1 {
|
||||
self = .gradient(colors, WallpaperSettings(rotation: rotation))
|
||||
self = .gradient(id, colors, WallpaperSettings(rotation: rotation))
|
||||
} else if colors.count == 1 {
|
||||
self = .color(UInt32(bitPattern: colors[0]))
|
||||
} else {
|
||||
@ -104,8 +104,8 @@ extension TelegramWallpaper {
|
||||
return (.inputWallPaperSlug(slug: slug), apiWallpaperSettings(settings))
|
||||
case let .color(color):
|
||||
return (.inputWallPaperNoFile(id: 0), apiWallpaperSettings(WallpaperSettings(colors: [color])))
|
||||
case let .gradient(colors, settings):
|
||||
return (.inputWallPaperNoFile(id: 0), apiWallpaperSettings(WallpaperSettings(colors: colors, rotation: settings.rotation)))
|
||||
case let .gradient(id, colors, settings):
|
||||
return (.inputWallPaperNoFile(id: id ?? 0), apiWallpaperSettings(WallpaperSettings(colors: colors, rotation: settings.rotation)))
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import SyncCore
|
||||
|
||||
public func telegramWallpapers(postbox: Postbox, network: Network, forceUpdate: Bool = false) -> Signal<[TelegramWallpaper], NoError> {
|
||||
let fetch: ([TelegramWallpaper]?, Int32?) -> Signal<[TelegramWallpaper], NoError> = { current, hash in
|
||||
network.request(Api.functions.account.getWallPapers(hash: 0))//hash ?? 0))
|
||||
network.request(Api.functions.account.getWallPapers(hash: hash ?? 0))
|
||||
|> retryRequest
|
||||
|> mapToSignal { result -> Signal<([TelegramWallpaper], Int32), NoError> in
|
||||
switch result {
|
||||
|
@ -17,6 +17,7 @@ swift_library(
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/StringPluralization:StringPluralization",
|
||||
"//submodules/Sunrise:Sunrise",
|
||||
"//submodules/TinyThumbnail:TinyThumbnail",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -8,6 +8,7 @@ import SwiftSignalKit
|
||||
import Postbox
|
||||
import MediaResources
|
||||
import AppBundle
|
||||
import TinyThumbnail
|
||||
|
||||
private var backgroundImageForWallpaper: (TelegramWallpaper, Bool, UIImage)?
|
||||
|
||||
@ -42,7 +43,7 @@ public func chatControllerBackgroundImage(theme: PresentationTheme?, wallpaper i
|
||||
context.setFillColor(UIColor(argb: color).withAlphaComponent(1.0).cgColor)
|
||||
context.fill(CGRect(origin: CGPoint(), size: size))
|
||||
})
|
||||
case let .gradient(colors, settings):
|
||||
case let .gradient(_, colors, settings):
|
||||
backgroundImage = generateImage(CGSize(width: 640.0, height: 1280.0), rotatedContext: { size, context in
|
||||
let gradientColors = [UIColor(argb: colors.count >= 1 ? colors[0] : 0).cgColor, UIColor(argb: colors.count >= 2 ? colors[1] : 0).cgColor] as CFArray
|
||||
|
||||
@ -134,7 +135,7 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me
|
||||
|> afterNext { image in
|
||||
cacheWallpaper(image?.0)
|
||||
}
|
||||
case let .gradient(colors, settings):
|
||||
case let .gradient(_, colors, settings):
|
||||
return .single((generateImage(CGSize(width: 640.0, height: 1280.0).fitted(CGSize(width: 100.0, height: 100.0)), rotatedContext: { size, context in
|
||||
let gradientColors = [UIColor(rgb: colors.count >= 1 ? colors[0] : 0).cgColor, UIColor(rgb: colors.count >= 2 ? colors[1] : 0).cgColor] as CFArray
|
||||
|
||||
@ -191,7 +192,7 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me
|
||||
} else {
|
||||
let interimWallpaper: TelegramWallpaper
|
||||
if file.settings.colors.count >= 2 {
|
||||
interimWallpaper = .gradient(file.settings.colors, file.settings)
|
||||
interimWallpaper = .gradient(nil, file.settings.colors, file.settings)
|
||||
} else {
|
||||
interimWallpaper = .color(file.settings.colors.count >= 1 ? file.settings.colors[0] : 0)
|
||||
}
|
||||
@ -225,24 +226,46 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me
|
||||
} else {
|
||||
if file.settings.blur {
|
||||
let representation = CachedBlurredWallpaperRepresentation()
|
||||
|
||||
let effectiveMediaBox: MediaBox
|
||||
|
||||
if FileManager.default.fileExists(atPath: mediaBox.cachedRepresentationCompletePath(file.file.resource.id, representation: representation)) {
|
||||
effectiveMediaBox = mediaBox
|
||||
} else {
|
||||
effectiveMediaBox = accountMediaBox
|
||||
}
|
||||
|
||||
return effectiveMediaBox.cachedResourceRepresentation(file.file.resource, representation: representation, complete: true, fetch: true, attemptSynchronously: true)
|
||||
|> map { data -> (UIImage?, Bool)? in
|
||||
if data.complete {
|
||||
return (UIImage(contentsOfFile: data.path)?.precomposed(), true)
|
||||
} else {
|
||||
return nil
|
||||
let effectiveMediaBox = mediaBox
|
||||
|
||||
return effectiveMediaBox.cachedResourceRepresentation(file.file.resource, representation: representation, complete: true, fetch: true, attemptSynchronously: true)
|
||||
|> map { data -> (UIImage?, Bool)? in
|
||||
if data.complete {
|
||||
return (UIImage(contentsOfFile: data.path)?.precomposed(), true)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|> afterNext { image in
|
||||
cacheWallpaper(image?.0)
|
||||
}
|
||||
} else {
|
||||
return Signal { subscriber in
|
||||
let fetch = fetchedMediaResource(mediaBox: accountMediaBox, reference: MediaResourceReference.wallpaper(wallpaper: WallpaperReference.slug(file.slug), resource: file.file.resource)).start()
|
||||
var didOutputBlurred = false
|
||||
let data = accountMediaBox.cachedResourceRepresentation(file.file.resource, representation: representation, complete: true, fetch: true, attemptSynchronously: true).start(next: { data in
|
||||
if data.complete {
|
||||
if let image = UIImage(contentsOfFile: data.path)?.precomposed() {
|
||||
mediaBox.copyResourceData(file.file.resource.id, fromTempPath: data.path)
|
||||
subscriber.putNext((image, true))
|
||||
}
|
||||
} else if !didOutputBlurred {
|
||||
didOutputBlurred = true
|
||||
if let immediateThumbnailData = file.file.immediateThumbnailData, let decodedData = decodeTinyThumbnail(data: immediateThumbnailData) {
|
||||
if let image = UIImage(data: decodedData)?.precomposed() {
|
||||
subscriber.putNext((image, false))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return ActionDisposable {
|
||||
fetch.dispose()
|
||||
data.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|> afterNext { image in
|
||||
cacheWallpaper(image?.0)
|
||||
}
|
||||
} else {
|
||||
var path: String?
|
||||
@ -259,12 +282,20 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me
|
||||
} else {
|
||||
return Signal { subscriber in
|
||||
let fetch = fetchedMediaResource(mediaBox: accountMediaBox, reference: MediaResourceReference.wallpaper(wallpaper: WallpaperReference.slug(file.slug), resource: file.file.resource)).start()
|
||||
var didOutputBlurred = false
|
||||
let data = accountMediaBox.resourceData(file.file.resource).start(next: { data in
|
||||
if data.complete {
|
||||
if let image = UIImage(contentsOfFile: data.path)?.precomposed() {
|
||||
mediaBox.copyResourceData(file.file.resource.id, fromTempPath: data.path)
|
||||
subscriber.putNext((image, true))
|
||||
}
|
||||
} else if !didOutputBlurred {
|
||||
didOutputBlurred = true
|
||||
if let immediateThumbnailData = file.file.immediateThumbnailData, let decodedData = decodeTinyThumbnail(data: immediateThumbnailData) {
|
||||
if let image = UIImage(data: decodedData)?.precomposed() {
|
||||
subscriber.putNext((image, false))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -84,7 +84,7 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
|
||||
defaultWallpaper = forcedWallpaper
|
||||
} else if !backgroundColors.isEmpty {
|
||||
if backgroundColors.count >= 2 {
|
||||
defaultWallpaper = .gradient(backgroundColors, WallpaperSettings())
|
||||
defaultWallpaper = .gradient(nil, backgroundColors, WallpaperSettings())
|
||||
} else {
|
||||
defaultWallpaper = .color(backgroundColors[0])
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
||||
defaultWallpaper = forcedWallpaper
|
||||
} else if !backgroundColors.isEmpty {
|
||||
if backgroundColors.count >= 2 {
|
||||
defaultWallpaper = .gradient(backgroundColors, WallpaperSettings())
|
||||
defaultWallpaper = .gradient(nil, backgroundColors, WallpaperSettings())
|
||||
} else {
|
||||
defaultWallpaper = .color(backgroundColors[0])
|
||||
}
|
||||
|
@ -60,10 +60,10 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
||||
outgoingAccent = accentColor
|
||||
}
|
||||
|
||||
suggestedWallpaper = .gradient(defaultBuiltinWallpaperGradientColors.map(\.rgb), WallpaperSettings())
|
||||
suggestedWallpaper = .gradient(nil, defaultBuiltinWallpaperGradientColors.map(\.rgb), WallpaperSettings())
|
||||
} else {
|
||||
bubbleColors = (UIColor(rgb: 0xe1ffc7), nil)
|
||||
suggestedWallpaper = .gradient(defaultBuiltinWallpaperGradientColors.map(\.rgb), WallpaperSettings())
|
||||
suggestedWallpaper = .gradient(nil, defaultBuiltinWallpaperGradientColors.map(\.rgb), WallpaperSettings())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -222,7 +222,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
||||
defaultWallpaper = forcedWallpaper
|
||||
} else if !backgroundColors.isEmpty {
|
||||
if backgroundColors.count >= 2 {
|
||||
defaultWallpaper = .gradient(backgroundColors, WallpaperSettings())
|
||||
defaultWallpaper = .gradient(nil, backgroundColors, WallpaperSettings())
|
||||
} else {
|
||||
defaultWallpaper = .color(backgroundColors[0])
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ public func serviceColor(for wallpaper: (TelegramWallpaper, UIImage?)) -> UIColo
|
||||
return UIColor(rgb: 0x748391, alpha: 0.45)
|
||||
case let .color(color):
|
||||
return serviceColor(with: UIColor(argb: color))
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
if colors.count == 2 {
|
||||
let mixedColor = UIColor(argb: colors[0]).mixedWith(UIColor(argb: colors[1]), alpha: 0.5)
|
||||
return serviceColor(with: mixedColor)
|
||||
@ -503,7 +503,7 @@ public func chatServiceBackgroundColor(wallpaper: TelegramWallpaper, mediaBox: M
|
||||
return .single(UIColor(rgb: 0x000000, alpha: 0.2))
|
||||
case let .color(color):
|
||||
return .single(serviceColor(with: UIColor(argb: color)))
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
if colors.count == 2 {
|
||||
let mixedColor = UIColor(argb: colors[0]).mixedWith(UIColor(argb: colors[1]), alpha: 0.5)
|
||||
return .single(
|
||||
|
@ -65,11 +65,10 @@ extension TelegramWallpaper: Codable {
|
||||
}
|
||||
}
|
||||
|
||||
self = .gradient([topColor.argb, bottomColor.argb], WallpaperSettings(blur: blur, motion: motion, rotation: rotation))
|
||||
self = .gradient(nil, [topColor.argb, bottomColor.argb], WallpaperSettings(blur: blur, motion: motion, rotation: rotation))
|
||||
} else {
|
||||
var slug: String?
|
||||
var color: UInt32?
|
||||
var bottomColor: UInt32?
|
||||
var colors: [UInt32] = []
|
||||
var intensity: Int32?
|
||||
var rotation: Int32?
|
||||
|
||||
@ -83,11 +82,7 @@ extension TelegramWallpaper: Codable {
|
||||
continue
|
||||
}
|
||||
if [6, 8].contains(component.count), let value = UIColor(hexString: component) {
|
||||
if color == nil {
|
||||
color = value.argb
|
||||
} else if bottomColor == nil {
|
||||
bottomColor = value.argb
|
||||
}
|
||||
colors.append(value.rgb)
|
||||
} else if component.count <= 3, let value = Int32(component) {
|
||||
if intensity == nil {
|
||||
if value >= 0 && value <= 100 {
|
||||
@ -104,14 +99,7 @@ extension TelegramWallpaper: Codable {
|
||||
}
|
||||
}
|
||||
if let slug = slug {
|
||||
var colors: [UInt32] = []
|
||||
if let color = color {
|
||||
colors.append(color)
|
||||
}
|
||||
if let bottomColor = bottomColor {
|
||||
colors.append(bottomColor)
|
||||
}
|
||||
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: WallpaperDataResource(slug: slug), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(blur: blur, motion: motion, colors: colors, intensity: intensity, rotation: rotation))
|
||||
self = .file(id: 0, accessHash: 0, isCreator: false, isDefault: false, isPattern: !colors.isEmpty, isDark: false, slug: slug, file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: WallpaperDataResource(slug: slug), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(blur: blur, motion: motion, colors: colors, intensity: intensity, rotation: rotation))
|
||||
} else {
|
||||
throw PresentationThemeDecodingError.generic
|
||||
}
|
||||
@ -130,7 +118,7 @@ extension TelegramWallpaper: Codable {
|
||||
try container.encode("builtin")
|
||||
case let .color(color):
|
||||
try container.encode(String(format: "%06x", color))
|
||||
case let .gradient(colors, settings):
|
||||
case let .gradient(_, colors, settings):
|
||||
var components: [String] = []
|
||||
for color in colors {
|
||||
components.append(String(format: "%06x", color))
|
||||
@ -428,6 +416,13 @@ extension PresentationThemeRootNavigationBar: Codable {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
let blurredBackgroundColor = try decodeColor(values, .background)
|
||||
|
||||
let opaqueBackgroundColor: UIColor
|
||||
if blurredBackgroundColor.alpha >= 0.99 {
|
||||
opaqueBackgroundColor = blurredBackgroundColor
|
||||
} else {
|
||||
opaqueBackgroundColor = (try? decodeColor(values, .opaqueBackground)) ?? blurredBackgroundColor
|
||||
}
|
||||
|
||||
self.init(
|
||||
buttonColor: try decodeColor(values, .button),
|
||||
disabledButtonColor: try decodeColor(values, .disabledButton),
|
||||
@ -436,7 +431,7 @@ extension PresentationThemeRootNavigationBar: Codable {
|
||||
controlColor: try decodeColor(values, .control),
|
||||
accentTextColor: try decodeColor(values, .accentText),
|
||||
blurredBackgroundColor: blurredBackgroundColor,
|
||||
opaqueBackgroundColor: (try? decodeColor(values, .opaqueBackground)) ?? blurredBackgroundColor.withAlphaComponent(1.0),
|
||||
opaqueBackgroundColor: opaqueBackgroundColor,
|
||||
separatorColor: try decodeColor(values, .separator),
|
||||
badgeBackgroundColor: try decodeColor(values, .badgeFill),
|
||||
badgeStrokeColor: try decodeColor(values, .badgeStroke),
|
||||
|
@ -848,7 +848,7 @@ final class SharedApplicationContext {
|
||||
}
|
||||
var exists = false
|
||||
strongSelf.mainWindow.forEachViewController({ controller in
|
||||
if controller is ThemeSettingsCrossfadeController || controller is ThemeSettingsController {
|
||||
if controller is ThemeSettingsCrossfadeController || controller is ThemeSettingsController || controller is ThemePreviewController {
|
||||
exists = true
|
||||
}
|
||||
return true
|
||||
|
@ -434,8 +434,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.botStart = botStart
|
||||
self.peekData = peekData
|
||||
|
||||
self.chatBackgroundNode = WallpaperBackgroundNode(context: context, useSharedAnimationPhase: true)
|
||||
self.wallpaperReady.set(chatBackgroundNode.isReady)
|
||||
var useSharedAnimationPhase = false
|
||||
switch mode {
|
||||
case .standard(false):
|
||||
useSharedAnimationPhase = true
|
||||
default:
|
||||
break
|
||||
}
|
||||
self.chatBackgroundNode = WallpaperBackgroundNode(context: context, useSharedAnimationPhase: useSharedAnimationPhase)
|
||||
self.wallpaperReady.set(self.chatBackgroundNode.isReady)
|
||||
|
||||
var locationBroadcastPanelSource: LocationBroadcastPanelSource
|
||||
var groupCallPanelSource: GroupCallPanelSource
|
||||
|
@ -54,6 +54,7 @@ extension SlotMachineAnimationNode: GenericAnimatedStickerNode {
|
||||
class ChatMessageShareButton: HighlightableButtonNode {
|
||||
private let backgroundNode: NavigationBackgroundNode
|
||||
private let iconNode: ASImageNode
|
||||
private var iconOffset = CGPoint()
|
||||
|
||||
private var theme: PresentationTheme?
|
||||
private var isReplies: Bool = false
|
||||
@ -100,17 +101,20 @@ class ChatMessageShareButton: HighlightableButtonNode {
|
||||
self.isReplies = isReplies
|
||||
|
||||
var updatedIconImage: UIImage?
|
||||
var updatedIconOffset = CGPoint()
|
||||
if case .pinnedMessages = subject {
|
||||
updatedIconImage = PresentationResourcesChat.chatFreeNavigateButtonIcon(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
||||
} else if isReplies {
|
||||
updatedIconImage = PresentationResourcesChat.chatFreeCommentButtonIcon(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
||||
} else if message.id.peerId.isRepliesOrSavedMessages(accountPeerId: account.peerId) {
|
||||
updatedIconImage = PresentationResourcesChat.chatFreeNavigateButtonIcon(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
||||
updatedIconOffset = CGPoint(x: UIScreenPixel, y: 1.0)
|
||||
} else {
|
||||
updatedIconImage = PresentationResourcesChat.chatFreeShareButtonIcon(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
||||
}
|
||||
self.backgroundNode.updateColor(color: selectDateFillStaticColor(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper), transition: .immediate)
|
||||
self.iconNode.image = updatedIconImage
|
||||
self.iconOffset = updatedIconOffset
|
||||
}
|
||||
var size = CGSize(width: 30.0, height: 30.0)
|
||||
var offsetIcon = false
|
||||
@ -148,7 +152,7 @@ class ChatMessageShareButton: HighlightableButtonNode {
|
||||
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
self.backgroundNode.update(size: self.backgroundNode.bounds.size, cornerRadius: self.backgroundNode.bounds.height / 2.0, transition: .immediate)
|
||||
if let image = self.iconNode.image {
|
||||
self.iconNode.frame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) / 2.0), y: floor((size.width - image.size.width) / 2.0) - (offsetIcon ? 1.0 : 0.0)), size: image.size)
|
||||
self.iconNode.frame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) / 2.0) + self.iconOffset.x, y: floor((size.width - image.size.width) / 2.0) - (offsetIcon ? 1.0 : 0.0) + self.iconOffset.y), size: image.size)
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
@ -1398,7 +1398,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
switch item.presentationData.theme.wallpaper {
|
||||
case .color:
|
||||
hasSolidWallpaper = true
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
hasSolidWallpaper = colors.count <= 2
|
||||
default:
|
||||
break
|
||||
|
@ -503,6 +503,8 @@ private func fetchCachedPatternWallpaperRepresentation(resource: MediaResource,
|
||||
colorImage = generateImage(size, contextGenerator: { size, c in
|
||||
let rect = CGRect(origin: CGPoint(), size: size)
|
||||
c.setBlendMode(.copy)
|
||||
|
||||
let averageBackgroundColor = UIColor.average(of: colors)
|
||||
|
||||
if colors.count == 1, let color = colors.first {
|
||||
c.setFillColor(color.cgColor)
|
||||
@ -511,11 +513,11 @@ private func fetchCachedPatternWallpaperRepresentation(resource: MediaResource,
|
||||
let drawingRect = rect
|
||||
let image = GradientBackgroundNode.generatePreview(size: CGSize(width: 60.0, height: 60.0), colors: colors)
|
||||
c.translateBy(x: drawingRect.midX, y: drawingRect.midY)
|
||||
c.scaleBy(x: 1.0, y: -1.0)
|
||||
c.scaleBy(x: 1.0, y: 1.0)
|
||||
c.translateBy(x: -drawingRect.midX, y: -drawingRect.midY)
|
||||
c.draw(image.cgImage!, in: drawingRect)
|
||||
c.translateBy(x: drawingRect.midX, y: drawingRect.midY)
|
||||
c.scaleBy(x: 1.0, y: -1.0)
|
||||
c.scaleBy(x: 1.0, y: 1.0)
|
||||
c.translateBy(x: -drawingRect.midX, y: -drawingRect.midY)
|
||||
} else {
|
||||
let gradientColors = colors.map { $0.cgColor } as CFArray
|
||||
@ -546,7 +548,16 @@ private func fetchCachedPatternWallpaperRepresentation(resource: MediaResource,
|
||||
c.setBlendMode(.softLight)
|
||||
}
|
||||
|
||||
if colors.count == 1, let color = colors.first {
|
||||
let isLight = averageBackgroundColor.hsb.b >= 0.3
|
||||
if isLight {
|
||||
c.setFillColor(UIColor(white: 0.0, alpha: abs(intensity)).cgColor)
|
||||
c.fill(rect)
|
||||
} else {
|
||||
c.setFillColor(UIColor(white: 1.0, alpha: abs(intensity)).cgColor)
|
||||
c.fill(rect)
|
||||
}
|
||||
|
||||
/*if colors.count == 1, let color = colors.first {
|
||||
c.setFillColor(patternColor(for: color, intensity: intensity).cgColor)
|
||||
c.fill(rect)
|
||||
} else {
|
||||
@ -565,7 +576,7 @@ private func fetchCachedPatternWallpaperRepresentation(resource: MediaResource,
|
||||
c.translateBy(x: -rect.width / 2.0, y: -rect.height / 2.0)
|
||||
|
||||
c.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: rect.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])
|
||||
}
|
||||
}*/
|
||||
}, scale: 1.0)
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ func openChatWallpaper(context: AccountContext, message: Message, present: @esca
|
||||
case let .color(color):
|
||||
source = .wallpaper(.color(color.argb), nil, [], nil, nil, message)
|
||||
case let .gradient(colors, rotation):
|
||||
source = .wallpaper(.gradient(colors, WallpaperSettings(rotation: rotation)), nil, [], nil, rotation, message)
|
||||
source = .wallpaper(.gradient(nil, colors, WallpaperSettings(rotation: rotation)), nil, [], nil, rotation, message)
|
||||
}
|
||||
|
||||
let controller = WallpaperGalleryController(context: context, source: source)
|
||||
|
@ -309,7 +309,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
case let .color(color):
|
||||
signal = .single(.color(color.argb))
|
||||
case let .gradient(colors, rotation):
|
||||
signal = .single(.gradient(colors, WallpaperSettings(rotation: rotation)))
|
||||
signal = .single(.gradient(nil, colors, WallpaperSettings(rotation: rotation)))
|
||||
}
|
||||
|
||||
let _ = (signal
|
||||
|
@ -103,7 +103,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
if !isPattern {
|
||||
needsCleanBackground = false
|
||||
}
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
hasComplexGradient = colors.count >= 3
|
||||
default:
|
||||
break
|
||||
@ -381,7 +381,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
if case let .color(color) = wallpaper {
|
||||
gradientColors = [color]
|
||||
self._isReady.set(true)
|
||||
} else if case let .gradient(colors, settings) = wallpaper {
|
||||
} else if case let .gradient(_, colors, settings) = wallpaper {
|
||||
gradientColors = colors
|
||||
gradientAngle = settings.rotation ?? 0
|
||||
self._isReady.set(true)
|
||||
@ -391,15 +391,16 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
if gradientColors.count >= 3 {
|
||||
let mappedColors = gradientColors.map { color -> UIColor in
|
||||
return UIColor(rgb: color)
|
||||
}
|
||||
if self.gradientBackgroundNode == nil {
|
||||
let gradientBackgroundNode = createGradientBackgroundNode(useSharedAnimationPhase: self.useSharedAnimationPhase)
|
||||
let gradientBackgroundNode = createGradientBackgroundNode(colors: mappedColors, useSharedAnimationPhase: self.useSharedAnimationPhase)
|
||||
self.gradientBackgroundNode = gradientBackgroundNode
|
||||
self.insertSubnode(gradientBackgroundNode, aboveSubnode: self.contentNode)
|
||||
gradientBackgroundNode.addSubnode(self.patternImageNode)
|
||||
}
|
||||
self.gradientBackgroundNode?.updateColors(colors: gradientColors.map { color -> UIColor in
|
||||
return UIColor(rgb: color)
|
||||
})
|
||||
self.gradientBackgroundNode?.updateColors(colors: mappedColors)
|
||||
|
||||
self.contentNode.backgroundColor = nil
|
||||
self.contentNode.contents = nil
|
||||
@ -591,12 +592,28 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
||||
self.patternImageNode.image = cachedValidPatternImage.image
|
||||
} else {
|
||||
let patternArguments = TransformImageArguments(corners: ImageCorners(), imageSize: size, boundingSize: size, intrinsicInsets: UIEdgeInsets(), custom: PatternWallpaperArguments(colors: [patternBackgroundColor], rotation: nil, customPatternColor: patternColor, preview: false), scale: min(2.0, UIScreenScale))
|
||||
if let drawingContext = validPatternImage.generate(patternArguments) {
|
||||
if let image = drawingContext.generateImage() {
|
||||
self.patternImageNode.image = image
|
||||
if self.useSharedAnimationPhase || self.patternImageNode.image == nil {
|
||||
if let drawingContext = validPatternImage.generate(patternArguments) {
|
||||
if let image = drawingContext.generateImage() {
|
||||
self.patternImageNode.image = image
|
||||
|
||||
if self.useSharedAnimationPhase {
|
||||
WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
|
||||
if self.useSharedAnimationPhase {
|
||||
WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
|
||||
let image = validPatternImage.generate(patternArguments)?.generateImage()
|
||||
Queue.mainQueue().async {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.patternImageNode.image = image
|
||||
|
||||
if let image = image, strongSelf.useSharedAnimationPhase {
|
||||
WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,13 @@ public func cachedWallpaper(account: Account, slug: String, settings: WallpaperS
|
||||
let key = ValueBoxKey(length: 8)
|
||||
key.setInt64(0, value: Int64(bitPattern: slug.persistentHashValue))
|
||||
let id = ItemCacheEntryId(collectionId: ApplicationSpecificItemCacheCollectionId.cachedWallpapers, key: key)
|
||||
if let wallpaper = wallpaper {
|
||||
if var wallpaper = wallpaper {
|
||||
switch wallpaper {
|
||||
case let .file(id, accessHash, isCreator, isDefault, isPattern, isDark, slug, file, settings):
|
||||
wallpaper = .file(id: id, accessHash: accessHash, isCreator: isCreator, isDefault: isDefault, isPattern: isPattern, isDark: isDark, slug: slug, file: file.withUpdatedResource(WallpaperDataResource(slug: slug)), settings: settings)
|
||||
default:
|
||||
break
|
||||
}
|
||||
let entry = CachedWallpaper(wallpaper: wallpaper)
|
||||
transaction.putItemCacheEntry(id: id, entry: entry, collectionSpec: collectionSpec)
|
||||
if let settings = settings {
|
||||
|
@ -175,7 +175,7 @@ public func wallpaperDatas(account: Account, accountManager: AccountManager, fil
|
||||
}
|
||||
}
|
||||
|
||||
public func wallpaperImage(account: Account, accountManager: AccountManager, fileReference: FileMediaReference? = nil, representations: [ImageRepresentationWithReference], alwaysShowThumbnailFirst: Bool = false, thumbnail: Bool = false, onlyFullSize: Bool = false, autoFetchFullSize: Bool = false, synchronousLoad: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||
public func wallpaperImage(account: Account, accountManager: AccountManager, fileReference: FileMediaReference? = nil, representations: [ImageRepresentationWithReference], alwaysShowThumbnailFirst: Bool = false, thumbnail: Bool = false, onlyFullSize: Bool = false, autoFetchFullSize: Bool = false, blurred: Bool = false, synchronousLoad: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||
let signal = wallpaperDatas(account: account, accountManager: accountManager, fileReference: fileReference, representations: representations, alwaysShowThumbnailFirst: alwaysShowThumbnailFirst, thumbnail: thumbnail, onlyFullSize: onlyFullSize, autoFetchFullSize: autoFetchFullSize, synchronousLoad: synchronousLoad)
|
||||
|
||||
return signal
|
||||
@ -214,6 +214,39 @@ public func wallpaperImage(account: Account, accountManager: AccountManager, fil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if blurred, let fullSizeImageValue = fullSizeImage {
|
||||
let thumbnailSize = CGSize(width: fullSizeImageValue.width, height: fullSizeImageValue.height)
|
||||
|
||||
let initialThumbnailContextFittingSize = fittedSize.fitted(CGSize(width: 90.0, height: 90.0))
|
||||
|
||||
let thumbnailContextSize = thumbnailSize.aspectFitted(initialThumbnailContextFittingSize)
|
||||
let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0)
|
||||
thumbnailContext.withFlippedContext { c in
|
||||
c.draw(fullSizeImageValue, in: CGRect(origin: CGPoint(), size: thumbnailContextSize))
|
||||
}
|
||||
telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
|
||||
|
||||
var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5))
|
||||
if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 {
|
||||
thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0))
|
||||
}
|
||||
|
||||
if false, thumbnailContextFittingSize.width > thumbnailContextSize.width {
|
||||
let additionalContextSize = thumbnailContextFittingSize
|
||||
let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0)
|
||||
additionalBlurContext.withFlippedContext { c in
|
||||
c.interpolationQuality = .default
|
||||
if let image = thumbnailContext.generateImage()?.cgImage {
|
||||
c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize))
|
||||
}
|
||||
}
|
||||
imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes)
|
||||
fullSizeImage = additionalBlurContext.generateImage()?.cgImage
|
||||
} else {
|
||||
fullSizeImage = thumbnailContext.generateImage()?.cgImage
|
||||
}
|
||||
}
|
||||
|
||||
var thumbnailImage: CGImage?
|
||||
if let thumbnailData = thumbnailData, let imageSource = CGImageSourceCreateWithData(thumbnailData as CFData, nil), let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) {
|
||||
@ -839,7 +872,7 @@ public func drawThemeImage(context c: CGContext, theme: PresentationTheme, wallp
|
||||
case let .color(color):
|
||||
c.setFillColor(UIColor(rgb: color).cgColor)
|
||||
c.fill(drawingRect)
|
||||
case let .gradient(colors, _):
|
||||
case let .gradient(_, colors, _):
|
||||
if colors.count >= 3 {
|
||||
let image = GradientBackgroundNode.generatePreview(size: CGSize(width: 60.0, height: 60.0), colors: colors.map(UIColor.init(rgb:)))
|
||||
c.draw(image.cgImage!, in: drawingRect)
|
||||
@ -1077,7 +1110,7 @@ public func themeImage(account: Account, accountManager: AccountManager, source:
|
||||
if wallpaper.wallpaper.isPattern, !file.settings.colors.isEmpty, let intensity = file.settings.intensity {
|
||||
return accountManager.mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedPatternWallpaperRepresentation(colors: file.settings.colors, intensity: intensity, rotation: file.settings.rotation), complete: true, fetch: true)
|
||||
|> mapToSignal { data in
|
||||
if data.complete, let data = try? Data(contentsOf: URL(fileURLWithPath: data.path)), let image = UIImage(data: data) {
|
||||
if data.complete, let imageData = try? Data(contentsOf: URL(fileURLWithPath: data.path)), let image = UIImage(data: imageData) {
|
||||
return .single((theme, image, thumbnailData))
|
||||
} else {
|
||||
return .complete()
|
||||
@ -1217,7 +1250,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
if file.settings.colors.count >= 2 {
|
||||
bottomBackgroundColor = UIColor(rgb: file.settings.colors[1])
|
||||
}
|
||||
} else if let wallpaper = wallpaper, case let .gradient(colors, _) = wallpaper {
|
||||
} else if let wallpaper = wallpaper, case let .gradient(_, colors, _) = wallpaper {
|
||||
topBackgroundColor = colors.first.flatMap { UIColor(rgb: $0) } ?? UIColor(rgb: 0xd6e2ee)
|
||||
if colors.count >= 2 {
|
||||
bottomBackgroundColor = UIColor(rgb: colors[1])
|
||||
@ -1257,7 +1290,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
case let .color(color):
|
||||
colors = [color]
|
||||
topBackgroundColor = UIColor(rgb: color)
|
||||
case let .gradient(colorsValue, settings):
|
||||
case let .gradient(_, colorsValue, settings):
|
||||
colors = colorsValue
|
||||
if colors.count >= 1 {
|
||||
topBackgroundColor = UIColor(rgb: colors[0])
|
||||
@ -1336,7 +1369,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
|
||||
backgroundColor = (UIColor(rgb: 0xd6e2ee), nil, [])
|
||||
case let .color(color):
|
||||
backgroundColor = (UIColor(rgb: color), nil, [])
|
||||
case let .gradient(colors, settings):
|
||||
case let .gradient(_, colors, settings):
|
||||
if colors.count >= 2 {
|
||||
backgroundColor = (UIColor(rgb: colors[0]), UIColor(rgb: colors[1]), colors)
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user