diff --git a/submodules/SettingsUI/Sources/Themes/EditThemeController.swift b/submodules/SettingsUI/Sources/Themes/EditThemeController.swift index 1b96ae7ca5..8ccfb5b0a0 100644 --- a/submodules/SettingsUI/Sources/Themes/EditThemeController.swift +++ b/submodules/SettingsUI/Sources/Themes/EditThemeController.swift @@ -359,7 +359,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll |> mapToSignal { wallpaper -> Signal in if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper { var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .media(media: .standalone(media: file.file), resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) return wallpaperDatas(account: context.account, accountManager: context.sharedContext.accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) |> mapToSignal { _, fullSizeData, complete -> Signal in guard complete, let fullSizeData = fullSizeData else { diff --git a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift index 7c0561e3cc..f1fb72e4cf 100644 --- a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift +++ b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift @@ -113,7 +113,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { self.imageNode.isHidden = false self.backgroundNode.isHidden = true - let convertedRepresentations: [ImageRepresentationWithReference] = representations.map({ ImageRepresentationWithReference(representation: $0, reference: .wallpaper(resource: $0.resource)) }) + let convertedRepresentations: [ImageRepresentationWithReference] = representations.map({ ImageRepresentationWithReference(representation: $0, reference: .wallpaper(wallpaper: nil, resource: $0.resource)) }) self.imageNode.setSignal(wallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, representations: convertedRepresentations, thumbnail: true, autoFetchFullSize: true, synchronousLoad: synchronousLoad)) let apply = self.imageNode.asyncLayout()(TransformImageArguments(corners: corners, imageSize: largestImageRepresentation(representations)!.dimensions.cgSize.aspectFilled(size), boundingSize: size, intrinsicInsets: UIEdgeInsets())) @@ -122,7 +122,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { self.imageNode.isHidden = false let convertedRepresentations : [ImageRepresentationWithReference] = file.file.previewRepresentations.map { - ImageRepresentationWithReference(representation: $0, reference: .wallpaper(resource: $0.resource)) + ImageRepresentationWithReference(representation: $0, reference: .wallpaper(wallpaper: .slug(file.slug), resource: $0.resource)) } let imageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError> diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift index c336ef26e1..c0ba784996 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorController.swift @@ -138,16 +138,16 @@ final class ThemeAccentColorController: ViewController { super.loadDisplayNode() let theme: PresentationTheme - let wallpaper: TelegramWallpaper + let initialWallpaper: TelegramWallpaper if case let .edit(editedTheme, walpaper, _, _, _, _) = self.mode { theme = editedTheme - wallpaper = walpaper ?? editedTheme.chat.defaultWallpaper + initialWallpaper = walpaper ?? editedTheme.chat.defaultWallpaper } else { theme = self.presentationData.theme - wallpaper = self.presentationData.chatWallpaper + initialWallpaper = self.presentationData.chatWallpaper } - self.displayNode = ThemeAccentColorControllerNode(context: self.context, mode: self.mode, theme: theme, wallpaper: wallpaper, dismiss: { [weak self] in + self.displayNode = ThemeAccentColorControllerNode(context: self.context, mode: self.mode, theme: theme, wallpaper: initialWallpaper, dismiss: { [weak self] in if let strongSelf = self { strongSelf.dismiss() } @@ -202,7 +202,7 @@ final class ThemeAccentColorController: ViewController { prepareWallpaper = .complete() } - if case let .edit(theme, _, generalThemeReference, themeReference, _, completion) = strongSelf.mode { + if case let .edit(theme, initialWallpaper, generalThemeReference, themeReference, _, completion) = strongSelf.mode { let _ = (prepareWallpaper |> deliverOnMainQueue).start(completed: { [weak self] in let updatedTheme: PresentationTheme @@ -248,10 +248,7 @@ final class ThemeAccentColorController: ViewController { baseTheme = .classic } - var wallpaper: TelegramWallpaper? = nil //themeSpecificChatWallpapers[theme.index] - if let coloredWallpaper = coloredWallpaper { - wallpaper = coloredWallpaper - } + let wallpaper = state.initialWallpaper ?? coloredWallpaper let settings = TelegramThemeSettings(baseTheme: baseTheme, accentColor: state.accentColor, messageColors: state.messagesColors, wallpaper: wallpaper) let baseThemeReference = PresentationThemeReference.builtin(PresentationBuiltinThemeReference(baseTheme: baseTheme)) @@ -345,6 +342,9 @@ final class ThemeAccentColorController: ViewController { let progressDisposable = progress.start() cancelImpl = { + if let strongSelf = self { + strongSelf.controllerNode.dismissed = false + } disposable.set(nil) } disposable.set((apply diff --git a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift index 26ba04aae7..b2ece20ad4 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeAccentColorControllerNode.swift @@ -204,6 +204,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate var themeUpdated: ((PresentationTheme) -> Void)? var requestSectionUpdate: ((ThemeColorSection) -> Void)? + var dismissed = false + private var validLayout: (ContainerViewLayout, CGFloat, CGFloat)? var requiresWallpaperChange: Bool { @@ -404,7 +406,6 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate } } - var dismissed = false self.toolbarNode.done = { [weak self] in if let strongSelf = self { if strongSelf.state.displayPatternPanel { @@ -414,8 +415,8 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate return updated }, animated: true) } else { - if !dismissed { - dismissed = true + if !strongSelf.dismissed { + strongSelf.dismissed = true apply(strongSelf.state, strongSelf.serviceBackgroundColor) } } @@ -452,9 +453,9 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate let dimensions = file.file.dimensions ?? PixelDimensions(width: 100, height: 100) var convertedRepresentations: [ImageRepresentationWithReference] = [] for representation in file.file.previewRepresentations { - convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: .wallpaper(resource: representation.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: .wallpaper(wallpaper: .slug(file.slug), resource: representation.resource))) } - convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource), reference: .wallpaper(resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) wallpaperSignal = patternWallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, representations: convertedRepresentations, mode: .screen, autoFetchFullSize: true) } else if let bottomColor = backgroundColors.1 { diff --git a/submodules/SettingsUI/Sources/Themes/ThemeColorPresets.swift b/submodules/SettingsUI/Sources/Themes/ThemeColorPresets.swift index 69a988cfeb..7b964136f9 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeColorPresets.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeColorPresets.swift @@ -8,13 +8,13 @@ private func patternWallpaper(slug: String, topColor: UInt32, bottomColor: UInt3 } var dayClassicColorPresets: [PresentationThemeAccentColor] = [ - PresentationThemeAccentColor(index: 106, baseColor: .preset, accentColor: 0xf55783, bubbleColors: (0xd6f5ff, 0xc9fdfe), wallpaper: patternWallpaper(slug: "p-pXcflrmFIBAAAAvXYQk-mCwZU", topColor: 0xfce3ec, bottomColor: 0xfec8ff, intensity: 50, rotation: 45)), - PresentationThemeAccentColor(index: 102, baseColor: .preset, accentColor: 0xff5fa9, bubbleColors: (0xfff4d7, nil), wallpaper: patternWallpaper(slug: "51nnTjx8mFIBAAAAaFGJsMIvWkk", topColor: 0xf6b594, bottomColor: 0xebf6cd, intensity: 46, rotation: 45)), - PresentationThemeAccentColor(index: 104, baseColor: .preset, accentColor: 0x5a9e29, bubbleColors: (0xfff8df, 0xdcf8c6), wallpaper: patternWallpaper(slug: "R3j69wKskFIBAAAAoUdXWCKMzCM", topColor: 0xede6dd, bottomColor: 0xffd59e, intensity: 50, rotation: nil)), - PresentationThemeAccentColor(index: 101, baseColor: .preset, accentColor: 0x7e5fe5, bubbleColors: (0xf5e2ff, nil), wallpaper: patternWallpaper(slug: "nQcFYJe1mFIBAAAAcI95wtIK0fk", topColor: 0xfcccf4, bottomColor: 0xae85f0, intensity: 54, rotation: nil)), - PresentationThemeAccentColor(index: 107, baseColor: .preset, accentColor: 0x2cb9ed, bubbleColors: (0xadf7b5, 0xfcff8b), wallpaper: patternWallpaper(slug: "nQcFYJe1mFIBAAAAcI95wtIK0fk", topColor: 0x1a2d1a, bottomColor: 0x5f6f54, intensity: 50, rotation: 225)), - PresentationThemeAccentColor(index: 103, baseColor: .preset, accentColor: 0x199972, bubbleColors: (0xfffec7, nil), wallpaper: patternWallpaper(slug: "fqv01SQemVIBAAAApND8LDRUhRU", topColor: 0xc1e7cb, bottomColor: nil, intensity: 50, rotation: nil)), - PresentationThemeAccentColor(index: 105, baseColor: .preset, accentColor: 0x009eee, bubbleColors: (0x94fff9, 0xccffc7), wallpaper: patternWallpaper(slug: "p-pXcflrmFIBAAAAvXYQk-mCwZU", topColor: 0xffbca6, bottomColor: 0xff63bd, intensity: 57, rotation: 225)) + 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: "nQcFYJe1mFIBAAAAcI95wtIK0fk", 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)) ] var dayColorPresets: [PresentationThemeAccentColor] = [ diff --git a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift index be0932144d..717653206a 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemePreviewControllerNode.swift @@ -67,6 +67,8 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { private var statusDisposable: Disposable? private var fetchDisposable = MetaDisposable() + private var dismissed = false + init(context: AccountContext, previewTheme: PresentationTheme, initialWallpaper: TelegramWallpaper?, dismiss: @escaping () -> Void, apply: @escaping () -> Void, isPreview: Bool, ready: Promise) { self.context = context self.previewTheme = previewTheme @@ -122,11 +124,8 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { self.toolbarNode = WallpaperGalleryToolbarNode(theme: self.previewTheme, strings: self.presentationData.strings, doneButtonType: .set) - if case let .file(file) = previewTheme.chat.defaultWallpaper, file.id == 0 { - self.remoteChatBackgroundNode.isHidden = false + if case let .file(file) = previewTheme.chat.defaultWallpaper { self.toolbarNode.setDoneEnabled(false) - } else { - self.remoteChatBackgroundNode.isHidden = true } self.maskNode = ASImageNode() @@ -175,11 +174,12 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { self.toolbarNode.cancel = { dismiss() } - var dismissed = false - self.toolbarNode.done = { - if !dismissed { - dismissed = true - apply() + self.toolbarNode.done = { [weak self] in + if let strongSelf = self { + if !strongSelf.dismissed { + strongSelf.dismissed = true + apply() + } } } @@ -229,9 +229,9 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { var convertedRepresentations: [ImageRepresentationWithReference] = [] for representation in file.file.previewRepresentations { - convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: MediaResourceReference.media(media: .standalone(media: file.file), resource: representation.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: .wallpaper(wallpaper: .slug(file.slug), resource: representation.resource))) } - convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource), reference: .media(media: .standalone(media: file.file), resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) let signal: Signal<(TransformImageArguments) -> DrawingContext?, NoError> let fileReference = FileMediaReference.standalone(media: file.file) @@ -249,9 +249,9 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { signal = .complete() } strongSelf.remoteChatBackgroundNode.setSignal(signal) - - strongSelf.fetchDisposable.set(freeMediaFileInteractiveFetched(account: context.account, fileReference: .standalone(media: file.file)).start()) + strongSelf.fetchDisposable.set(fetchedMediaResource(mediaBox: context.sharedContext.accountManager.mediaBox, reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)).start()) + let account = strongSelf.context.account let statusSignal = strongSelf.context.sharedContext.accountManager.mediaBox.resourceStatus(file.file.resource) |> take(1) @@ -270,7 +270,6 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate { } }) - var patternArguments: PatternWallpaperArguments? if let color = file.settings.color { var patternIntensity: CGFloat = 0.5 diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift index 2125efb66d..613408098a 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsChatPreviewItem.swift @@ -102,6 +102,7 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { private var messageNodes: [ListViewItemNode]? private var item: ThemeSettingsChatPreviewItem? + private var finalImage = true private let disposable = MetaDisposable() @@ -140,14 +141,9 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { let currentNodes = self.messageNodes return { item, params, neighbors in - var updatedBackgroundSignal: Signal? - var backgroundImageContentMode = UIView.ContentMode.scaleAspectFill + var updatedBackgroundSignal: Signal<(UIImage?, Bool)?, NoError>? if currentItem?.wallpaper != item.wallpaper { - updatedBackgroundSignal = chatControllerBackgroundImageSignal(wallpaper: item.wallpaper, mediaBox: item.context.sharedContext.accountManager.mediaBox) - - if case .gradient = item.wallpaper { - backgroundImageContentMode = .scaleToFill - } + updatedBackgroundSignal = chatControllerBackgroundImageSignal(wallpaper: item.wallpaper, mediaBox: item.context.account.postbox.mediaBox) } let insets: UIEdgeInsets @@ -230,9 +226,18 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode { if let updatedBackgroundSignal = updatedBackgroundSignal { strongSelf.disposable.set((updatedBackgroundSignal |> deliverOnMainQueue).start(next: { [weak self] image in - if let strongSelf = self, let image = image { + if let strongSelf = self, let (image, final) = image { + if final && !strongSelf.finalImage { + let tempLayer = CALayer() + tempLayer.frame = strongSelf.backgroundNode.bounds + tempLayer.contentsGravity = strongSelf.backgroundNode.layer.contentsGravity + tempLayer.contents = strongSelf.contents + strongSelf.layer.addSublayer(tempLayer) + tempLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false, completion: { [weak tempLayer] _ in + tempLayer?.removeFromSuperlayer() + }) + } strongSelf.backgroundNode.image = image - strongSelf.backgroundNode.contentMode = backgroundImageContentMode } })) } diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift index 60c73d24a5..eba2379a92 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsController.swift @@ -1203,25 +1203,17 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The if let wallpaper = cachedWallpaper?.wallpaper, case let .file(file) = wallpaper { let resource = file.file.resource let representation = CachedPatternWallpaperRepresentation(color: file.settings.color ?? 0xd6e2ee, bottomColor: file.settings.bottomColor, intensity: file.settings.intensity ?? 50, rotation: file.settings.rotation) - - var data: Data? - if let path = context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { - data = maybeData - } else if let path = context.sharedContext.accountManager.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { - data = maybeData - } - - if let data = data { - context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true) - return (context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: true, fetch: true) - |> filter({ $0.complete }) - |> take(1) - |> mapToSignal { _ -> Signal in - return .single(wallpaper) - }) - } else { - return .single(nil) - } + + let _ = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)).start() + + let _ = (context.account.postbox.mediaBox.cachedResourceRepresentation(resource, representation: representation, complete: false, fetch: true) + |> filter({ $0.complete })).start(next: { data in + if data.complete, let path = context.account.postbox.mediaBox.completedResourcePath(resource), let maybeData = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedRead) { + context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: maybeData, synchronous: true) + } + }) + return .single(wallpaper) + } else { return .single(nil) } @@ -1263,12 +1255,20 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The themeSpecificAccentColors[generalThemeReference.index] = accentColor?.withUpdatedWallpaper(presetWallpaper) if case let .builtin(theme) = generalThemeReference { - if let wallpaper = current.themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)], wallpaper.isColorOrGradient || wallpaper.isPattern || wallpaper.isBuiltin { - themeSpecificChatWallpapers[currentTheme.index] = nil - if let accentColor = accentColor { - themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)] = nil + let index = coloredThemeIndex(reference: currentTheme, accentColor: accentColor) + if let wallpaper = current.themeSpecificChatWallpapers[index] { + if wallpaper.isColorOrGradient || wallpaper.isPattern || wallpaper.isBuiltin { + themeSpecificChatWallpapers[index] = presetWallpaper } + } else { + themeSpecificChatWallpapers[index] = presetWallpaper } +// if let wallpaper = current.themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)], wallpaper.isColorOrGradient || wallpaper.isPattern || wallpaper.isBuiltin { +// themeSpecificChatWallpapers[currentTheme.index] = nil +// if let accentColor = accentColor { +// themeSpecificChatWallpapers[coloredThemeIndex(reference: currentTheme, accentColor: accentColor)] = nil +// } +// } } return PresentationThemeSettings(theme: updatedTheme, themeSpecificAccentColors: themeSpecificAccentColors, themeSpecificChatWallpapers: themeSpecificChatWallpapers, useSystemFont: current.useSystemFont, fontSize: current.fontSize, automaticThemeSwitchSetting: updatedAutomaticThemeSwitchSetting, largeEmoji: current.largeEmoji, disableAnimations: current.disableAnimations) diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index c4ffc4fa88..de5de846b6 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -68,7 +68,7 @@ private func reference(for resource: MediaResource, media: Media, message: Messa if let message = message { return .media(media: .message(message: MessageReference(message), media: media), resource: resource) } - return .wallpaper(resource: resource) + return .wallpaper(wallpaper: nil, resource: resource) } final class WallpaperGalleryItemNode: GalleryItemNode { @@ -347,7 +347,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { contentSize = largestSize.dimensions.cgSize displaySize = largestSize.dimensions.cgSize.dividedByScreenScale().integralFloor - let convertedRepresentations: [ImageRepresentationWithReference] = representations.map({ ImageRepresentationWithReference(representation: $0, reference: .wallpaper(resource: $0.resource)) }) + let convertedRepresentations: [ImageRepresentationWithReference] = representations.map({ ImageRepresentationWithReference(representation: $0, reference: .wallpaper(wallpaper: nil, resource: $0.resource)) }) signal = wallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, representations: convertedRepresentations, alwaysShowThumbnailFirst: true, autoFetchFullSize: false) if let largestIndex = convertedRepresentations.firstIndex(where: { $0.representation == largestSize }) { diff --git a/submodules/SyncCore/Sources/MediaReference.swift b/submodules/SyncCore/Sources/MediaReference.swift index b7a29e7463..0a8876b606 100644 --- a/submodules/SyncCore/Sources/MediaReference.swift +++ b/submodules/SyncCore/Sources/MediaReference.swift @@ -175,6 +175,39 @@ public enum ThemeReference: PostboxCoding, Hashable, Equatable { } } +public enum WallpaperReference: PostboxCoding, Hashable, Equatable { + case slug(String) + + public init(decoder: PostboxDecoder) { + switch decoder.decodeInt32ForKey("r", orElse: 0) { + case 0: + self = .slug(decoder.decodeStringForKey("s", orElse: "")) + default: + self = .slug("") + assertionFailure() + } + } + + public func encode(_ encoder: PostboxEncoder) { + switch self { + case let .slug(slug): + encoder.encodeInt32(0, forKey: "r") + encoder.encodeString(slug, forKey: "s") + } + } + + public static func ==(lhs: WallpaperReference, rhs: WallpaperReference) -> Bool { + switch lhs { + case let .slug(slug): + if case .slug(slug) = rhs { + return true + } else { + return false + } + } + } +} + public enum AnyMediaReference: Equatable { case standalone(media: Media) case message(message: MessageReference, media: Media) @@ -461,7 +494,7 @@ public enum MediaResourceReference: Equatable { case standalone(resource: MediaResource) case avatar(peer: PeerReference, resource: MediaResource) case messageAuthorAvatar(message: MessageReference, resource: MediaResource) - case wallpaper(resource: MediaResource) + case wallpaper(wallpaper: WallpaperReference?, resource: MediaResource) case stickerPackThumbnail(stickerPack: StickerPackReference, resource: MediaResource) case theme(theme: ThemeReference, resource: MediaResource) @@ -475,7 +508,7 @@ public enum MediaResourceReference: Equatable { return resource case let .messageAuthorAvatar(_, resource): return resource - case let .wallpaper(resource): + case let .wallpaper(_, resource): return resource case let .stickerPackThumbnail(_, resource): return resource @@ -510,8 +543,8 @@ public enum MediaResourceReference: Equatable { } else { return false } - case let .wallpaper(lhsResource): - if case let .wallpaper(rhsResource) = rhs, lhsResource.isEqual(to: rhsResource) { + case let .wallpaper(lhsWallpaper, lhsResource): + if case let .wallpaper(rhsWallpaper, rhsResource) = rhs, lhsWallpaper == rhsWallpaper, lhsResource.isEqual(to: rhsResource) { return true } else { return false diff --git a/submodules/TelegramCore/Sources/FetchedMediaResource.swift b/submodules/TelegramCore/Sources/FetchedMediaResource.swift index 8eaa86572c..7adb6c9e2a 100644 --- a/submodules/TelegramCore/Sources/FetchedMediaResource.swift +++ b/submodules/TelegramCore/Sources/FetchedMediaResource.swift @@ -140,6 +140,7 @@ private enum MediaReferenceRevalidationKey: Hashable { case stickerPack(stickerPack: StickerPackReference) case savedGifs case peer(peer: PeerReference) + case wallpaper(wallpaper: WallpaperReference) case wallpapers case themes } @@ -380,13 +381,24 @@ final class MediaReferenceRevalidationContext { } } - func wallpapers(postbox: Postbox, network: Network, background: Bool) -> Signal<[TelegramWallpaper], RevalidateMediaReferenceError> { + func wallpapers(postbox: Postbox, network: Network, background: Bool, wallpaper: WallpaperReference?) -> Signal<[TelegramWallpaper], RevalidateMediaReferenceError> { return self.genericItem(key: .wallpapers, background: background, request: { next, error in - return (telegramWallpapers(postbox: postbox, network: network, forceUpdate: true) - |> last - |> mapError { _ -> RevalidateMediaReferenceError in - return .generic - }).start(next: { value in + let signal: Signal<[TelegramWallpaper]?, RevalidateMediaReferenceError> + if let wallpaper = wallpaper, case let .slug(slug) = wallpaper { + signal = getWallpaper(network: network, slug: slug) + |> mapError { _ -> RevalidateMediaReferenceError in + return .generic + } + |> map { [$0] } + } else { + signal = telegramWallpapers(postbox: postbox, network: network, forceUpdate: true) + |> last + |> mapError { _ -> RevalidateMediaReferenceError in + return .generic + } + } + return (signal + ).start(next: { value in if let value = value { next(value) } else { @@ -569,8 +581,8 @@ func revalidateMediaResourceReference(postbox: Postbox, network: Network, revali } return .fail(.generic) } - case .wallpaper: - return revalidationContext.wallpapers(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation) + case let .wallpaper(wallpaper, _): + return revalidationContext.wallpapers(postbox: postbox, network: network, background: info.preferBackgroundReferenceRevalidation, wallpaper: wallpaper) |> mapToSignal { wallpapers -> Signal in for wallpaper in wallpapers { switch wallpaper { diff --git a/submodules/TelegramCore/Sources/Wallpapers.swift b/submodules/TelegramCore/Sources/Wallpapers.swift index 061aa7d4ac..039f88385e 100644 --- a/submodules/TelegramCore/Sources/Wallpapers.swift +++ b/submodules/TelegramCore/Sources/Wallpapers.swift @@ -132,8 +132,8 @@ public enum GetWallpaperError { case generic } -public func getWallpaper(account: Account, slug: String) -> Signal { - return account.network.request(Api.functions.account.getWallPaper(wallpaper: .inputWallPaperSlug(slug: slug))) +public func getWallpaper(network: Network, slug: String) -> Signal { + return network.request(Api.functions.account.getWallPaper(wallpaper: .inputWallPaperSlug(slug: slug))) |> mapError { _ -> GetWallpaperError in return .generic } |> map { wallpaper -> TelegramWallpaper in return TelegramWallpaper(apiWallpaper: wallpaper) diff --git a/submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift b/submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift index f77010e630..ea05ba574d 100644 --- a/submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift +++ b/submodules/TelegramPresentationData/Sources/ChatControllerBackgroundNode.swift @@ -104,35 +104,39 @@ public func chatControllerBackgroundImage(theme: PresentationTheme?, wallpaper i return backgroundImage } -public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, mediaBox: MediaBox) -> Signal { +private var signalBackgroundImageForWallpaper: (TelegramWallpaper, Bool, UIImage)? + +public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, mediaBox: MediaBox) -> Signal<(UIImage?, Bool)?, NoError> { var backgroundImage: UIImage? - if wallpaper == backgroundImageForWallpaper?.0, (wallpaper.settings?.blur ?? false) == backgroundImageForWallpaper?.1 { - return .single(backgroundImageForWallpaper?.2) + if wallpaper == signalBackgroundImageForWallpaper?.0, (wallpaper.settings?.blur ?? false) == signalBackgroundImageForWallpaper?.1, let image = signalBackgroundImageForWallpaper?.2 { + return .single((image, true)) } else { func cacheWallpaper(_ image: UIImage?) { if let image = image { - backgroundImageForWallpaper = (wallpaper, (wallpaper.settings?.blur ?? false), image) + Queue.mainQueue().async { + signalBackgroundImageForWallpaper = (wallpaper, (wallpaper.settings?.blur ?? false), image) + } } } switch wallpaper { case .builtin: if let filePath = getAppBundle().path(forResource: "ChatWallpaperBuiltin0", ofType: "jpg") { - return .single(UIImage(contentsOfFile: filePath)?.precomposed()) + return .single((UIImage(contentsOfFile: filePath)?.precomposed(), true)) |> afterNext { image in - cacheWallpaper(image) + cacheWallpaper(image?.0) } } case let .color(color): - return .single(generateImage(CGSize(width: 1.0, height: 1.0), rotatedContext: { size, context in + return .single((generateImage(CGSize(width: 1.0, height: 1.0), rotatedContext: { size, context in context.setFillColor(UIColor(argb: color).withAlphaComponent(1.0).cgColor) context.fill(CGRect(origin: CGPoint(), size: size)) - })) + }), true)) |> afterNext { image in - cacheWallpaper(image) + cacheWallpaper(image?.0) } case let .gradient(topColor, bottomColor, settings): - return .single(generateImage(CGSize(width: 640.0, height: 1280.0), rotatedContext: { size, context in + return .single((generateImage(CGSize(width: 640.0, height: 1280.0), rotatedContext: { size, context in let gradientColors = [UIColor(argb: topColor).cgColor, UIColor(argb: bottomColor).cgColor] as CFArray var locations: [CGFloat] = [0.0, 1.0] @@ -144,28 +148,28 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me context.translateBy(x: -320.0, y: -640.0) context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) - })) + }), true)) |> afterNext { image in - cacheWallpaper(image) + cacheWallpaper(image?.0) } case let .image(representations, settings): if let largest = largestImageRepresentation(representations) { if settings.blur { return mediaBox.cachedResourceRepresentation(largest.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true, attemptSynchronously: true) - |> map { data -> UIImage? in + |> map { data -> (UIImage?, Bool)? in if data.complete { - return UIImage(contentsOfFile: data.path)?.precomposed() + return (UIImage(contentsOfFile: data.path)?.precomposed(), true) } else { return nil } } |> afterNext { image in - cacheWallpaper(image) + cacheWallpaper(image?.0) } } else if let path = mediaBox.completedResourcePath(largest.resource) { - return .single(UIImage(contentsOfFile: path)?.precomposed()) + return .single((UIImage(contentsOfFile: path)?.precomposed(), true)) |> afterNext { image in - cacheWallpaper(image) + cacheWallpaper(image?.0) } } } @@ -173,9 +177,9 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me if wallpaper.isPattern, let color = file.settings.color, let intensity = file.settings.intensity { return mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedPatternWallpaperRepresentation(color: color, bottomColor: file.settings.bottomColor, intensity: intensity, rotation: file.settings.rotation), complete: true, fetch: true, attemptSynchronously: true) |> take(1) - |> mapToSignal { data -> Signal in + |> mapToSignal { data -> Signal<(UIImage?, Bool)?, NoError> in if data.complete { - return .single(UIImage(contentsOfFile: data.path)?.precomposed()) + return .single((UIImage(contentsOfFile: data.path)?.precomposed(), true)) } else { let interimWallpaper: TelegramWallpaper if let secondColor = file.settings.bottomColor { @@ -183,34 +187,50 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me } else { interimWallpaper = .color(color) } + + let settings = file.settings + let interrimImage = generateImage(CGSize(width: 640.0, height: 1280.0), rotatedContext: { size, context in + if let color = settings.color { + let gradientColors = [UIColor(argb: color).cgColor, UIColor(argb: settings.bottomColor ?? color).cgColor] as CFArray + + var locations: [CGFloat] = [0.0, 1.0] + let colorSpace = CGColorSpaceCreateDeviceRGB() + let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)! + + context.translateBy(x: 320.0, y: 640.0) + context.rotate(by: CGFloat(settings.rotation ?? 0) * CGFloat.pi / 180.0) + context.translateBy(x: -320.0, y: -640.0) + + context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: [.drawsBeforeStartLocation, .drawsAfterEndLocation]) + } + }) - return chatControllerBackgroundImageSignal(wallpaper: interimWallpaper, mediaBox: mediaBox) - |> then(mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedPatternWallpaperRepresentation(color: color, bottomColor: file.settings.bottomColor, intensity: intensity, rotation: file.settings.rotation), complete: true, fetch: true, attemptSynchronously: false) - |> map { data -> UIImage? in - return UIImage(contentsOfFile: data.path)?.precomposed() + return .single((interrimImage, false)) |> then(mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedPatternWallpaperRepresentation(color: color, bottomColor: file.settings.bottomColor, intensity: intensity, rotation: file.settings.rotation), complete: true, fetch: true, attemptSynchronously: false) + |> map { data -> (UIImage?, Bool)? in + return (UIImage(contentsOfFile: data.path)?.precomposed(), true) }) } } |> afterNext { image in - cacheWallpaper(image) + cacheWallpaper(image?.0) } } else { if file.settings.blur { return mediaBox.cachedResourceRepresentation(file.file.resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true, attemptSynchronously: true) - |> map { data -> UIImage? in + |> map { data -> (UIImage?, Bool)? in if data.complete { - return UIImage(contentsOfFile: data.path)?.precomposed() + return (UIImage(contentsOfFile: data.path)?.precomposed(), true) } else { return nil } } |> afterNext { image in - cacheWallpaper(image) + cacheWallpaper(image?.0) } } else if let path = mediaBox.completedResourcePath(file.file.resource) { - return .single(UIImage(contentsOfFile: path)?.precomposed()) + return .single((UIImage(contentsOfFile: path)?.precomposed(), true)) |> afterNext { image in - cacheWallpaper(image) + cacheWallpaper(image?.0) } } } diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift index dff2736fa6..d71494e8cd 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift @@ -6,7 +6,7 @@ import TelegramUIPreferences public let defaultDarkPresentationTheme = makeDefaultDarkPresentationTheme(preview: false) -public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil) -> PresentationTheme { +public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, editing: Bool, title: String?, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil) -> PresentationTheme { if (theme.referenceTheme != .night) { return theme } @@ -204,7 +204,7 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit ) return PresentationTheme( - name: theme.name, + name: title.flatMap { .custom($0) } ?? theme.name, index: theme.index, referenceTheme: theme.referenceTheme, overallDarkAppearance: theme.overallDarkAppearance, diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift index 2001f01610..1261eb0bd6 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDarkTintedPresentationTheme.swift @@ -7,7 +7,7 @@ import TelegramUIPreferences private let defaultDarkTintedAccentColor = UIColor(rgb: 0x2ea6ff) public let defaultDarkTintedPresentationTheme = makeDefaultDarkTintedPresentationTheme(preview: false) -public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil) -> PresentationTheme { +public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme, editing: Bool, title: String?, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil) -> PresentationTheme { if (theme.referenceTheme != .nightAccent) { return theme } @@ -424,7 +424,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme ) return PresentationTheme( - name: theme.name, + name: title.flatMap { .custom($0) } ?? theme.name, index: theme.index, referenceTheme: theme.referenceTheme, overallDarkAppearance: theme.overallDarkAppearance, diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift index b6de6a4ce5..4e07057c8d 100644 --- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift @@ -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 defaultDayAccentColor = UIColor(rgb: 0x007ee5) -public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor?) -> PresentationTheme { +public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, title: String?, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper forcedWallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor?) -> PresentationTheme { if (theme.referenceTheme != .day && theme.referenceTheme != .dayClassic) { return theme } @@ -294,7 +294,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ac ) return PresentationTheme( - name: theme.name, + name: title.flatMap { .custom($0) } ?? theme.name, index: theme.index, referenceTheme: theme.referenceTheme, overallDarkAppearance: theme.overallDarkAppearance, diff --git a/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift b/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift index e41ddd1b21..6bd5dbfcec 100644 --- a/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift +++ b/submodules/TelegramPresentationData/Sources/MakePresentationTheme.swift @@ -19,22 +19,27 @@ public func makeDefaultPresentationTheme(reference: PresentationBuiltinThemeRefe return theme } -public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper: TelegramWallpaper? = nil) -> PresentationTheme { +public func customizePresentationTheme(_ theme: PresentationTheme, editing: Bool, title: String? = nil, accentColor: UIColor?, backgroundColors: (UIColor, UIColor?)?, bubbleColors: (UIColor, UIColor?)?, wallpaper: TelegramWallpaper? = nil) -> PresentationTheme { if accentColor == nil && bubbleColors == nil && backgroundColors == nil && wallpaper == nil { return theme } switch theme.referenceTheme { case .day, .dayClassic: - return customizeDefaultDayTheme(theme: theme, editing: editing, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper, serviceBackgroundColor: nil) + return customizeDefaultDayTheme(theme: theme, editing: editing, title: title, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper, serviceBackgroundColor: nil) case .night: - return customizeDefaultDarkPresentationTheme(theme: theme, editing: editing, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper) + return customizeDefaultDarkPresentationTheme(theme: theme, editing: editing, title: title, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper) case .nightAccent: - return customizeDefaultDarkTintedPresentationTheme(theme: theme, editing: editing, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper) + return customizeDefaultDarkTintedPresentationTheme(theme: theme, editing: editing, title: title, accentColor: accentColor, backgroundColors: backgroundColors, bubbleColors: bubbleColors, wallpaper: wallpaper) } return theme } +public func makePresentationTheme(settings: TelegramThemeSettings, title: String? = nil, serviceBackgroundColor: UIColor? = nil) -> PresentationTheme? { + let defaultTheme = makeDefaultPresentationTheme(reference: PresentationBuiltinThemeReference(baseTheme: settings.baseTheme), extendingThemeReference: nil, serviceBackgroundColor: serviceBackgroundColor, preview: false) + return customizePresentationTheme(defaultTheme, editing: true, title: title, accentColor: UIColor(argb: settings.accentColor), backgroundColors: nil, bubbleColors: settings.messageColors.flatMap { (UIColor(argb: $0.top), UIColor(argb: $0.bottom)) }, wallpaper: settings.wallpaper) +} + public func makePresentationTheme(mediaBox: MediaBox, themeReference: PresentationThemeReference, extendingThemeReference: PresentationThemeReference? = nil, accentColor: UIColor? = nil, backgroundColors: (UIColor, UIColor?)? = nil, bubbleColors: (UIColor, UIColor?)? = nil, wallpaper: TelegramWallpaper? = nil, serviceBackgroundColor: UIColor? = nil, preview: Bool = false) -> PresentationTheme? { let theme: PresentationTheme switch themeReference { diff --git a/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift b/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift index a44fbc8836..5d051eb157 100644 --- a/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift +++ b/submodules/TelegramUI/TelegramUI/OpenChatMessage.swift @@ -569,7 +569,7 @@ func openChatTheme(context: AccountContext, message: Message, pushController: @e } } } else if let settings = settings { - if let theme = makePresentationTheme(mediaBox: context.sharedContext.accountManager.mediaBox, themeReference: .builtin(PresentationBuiltinThemeReference(baseTheme: settings.baseTheme)), accentColor: UIColor(argb: settings.accentColor), backgroundColors: nil, bubbleColors: settings.messageColors.flatMap { (UIColor(argb: $0.top), UIColor(argb: $0.bottom)) }, wallpaper: settings.wallpaper, serviceBackgroundColor: nil, preview: false) { + if let theme = makePresentationTheme(settings: settings, title: content.title) { let controller = ThemePreviewController(context: context, previewTheme: theme, source: .themeSettings(slug, settings)) pushController(controller) } else { diff --git a/submodules/TelegramUI/TelegramUI/OpenResolvedUrl.swift b/submodules/TelegramUI/TelegramUI/OpenResolvedUrl.swift index f00ed8066c..31c5965dd5 100644 --- a/submodules/TelegramUI/TelegramUI/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/TelegramUI/OpenResolvedUrl.swift @@ -255,7 +255,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur var rotation: Int32? switch parameter { case let .slug(slug, wallpaperOptions, firstColor, secondColor, intensityValue, rotationValue): - signal = getWallpaper(account: context.account, slug: slug) + signal = getWallpaper(network: context.account.network, slug: slug) options = wallpaperOptions topColor = firstColor bottomColor = secondColor diff --git a/submodules/TelegramUI/TelegramUI/ThemeUpdateManager.swift b/submodules/TelegramUI/TelegramUI/ThemeUpdateManager.swift index ab8fbf9b7a..d9ea0e75a6 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeUpdateManager.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeUpdateManager.swift @@ -104,7 +104,7 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager { |> mapToSignal { wallpaper -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in if let wallpaper = wallpaper, case let .file(file) = wallpaper { var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .media(media: .standalone(media: file.file), resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) |> mapToSignal { _, fullSizeData, complete -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in guard complete, let fullSizeData = fullSizeData else { diff --git a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift index 9a2cf3ee9f..31e51196e0 100644 --- a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift +++ b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift @@ -404,8 +404,8 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { public var index: Int32 public var baseColor: PresentationThemeBaseColor - public var accentColor: Int32? - public var bubbleColors: (Int32, Int32?)? + public var accentColor: UInt32? + public var bubbleColors: (UInt32, UInt32?)? public var wallpaper: TelegramWallpaper? public var themeIndex: Int64? @@ -421,7 +421,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { self.wallpaper = nil } - public init(index: Int32, baseColor: PresentationThemeBaseColor, accentColor: Int32? = nil, bubbleColors: (Int32, Int32?)? = nil, wallpaper: TelegramWallpaper? = nil) { + public init(index: Int32, baseColor: PresentationThemeBaseColor, accentColor: UInt32? = nil, bubbleColors: (UInt32, UInt32?)? = nil, wallpaper: TelegramWallpaper? = nil) { self.index = index self.baseColor = baseColor self.accentColor = accentColor @@ -441,12 +441,12 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { public init(decoder: PostboxDecoder) { self.index = decoder.decodeInt32ForKey("i", orElse: -1) self.baseColor = PresentationThemeBaseColor(rawValue: decoder.decodeInt32ForKey("b", orElse: 0)) ?? .blue - self.accentColor = decoder.decodeOptionalInt32ForKey("c") + self.accentColor = decoder.decodeOptionalInt32ForKey("c").flatMap { UInt32(bitPattern: $0) } if let bubbleTopColor = decoder.decodeOptionalInt32ForKey("bt") { if let bubbleBottomColor = decoder.decodeOptionalInt32ForKey("bb") { - self.bubbleColors = (bubbleTopColor, bubbleBottomColor) + self.bubbleColors = (UInt32(bitPattern: bubbleTopColor), UInt32(bitPattern: bubbleBottomColor)) } else { - self.bubbleColors = (bubbleTopColor, nil) + self.bubbleColors = (UInt32(bitPattern: bubbleTopColor), nil) } } else { self.bubbleColors = nil @@ -459,14 +459,14 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { encoder.encodeInt32(self.index, forKey: "i") encoder.encodeInt32(self.baseColor.rawValue, forKey: "b") if let value = self.accentColor { - encoder.encodeInt32(value, forKey: "c") + encoder.encodeInt32(Int32(bitPattern: value), forKey: "c") } else { encoder.encodeNil(forKey: "c") } if let bubbleColors = self.bubbleColors { - encoder.encodeInt32(bubbleColors.0, forKey: "bt") + encoder.encodeInt32(Int32(bitPattern: bubbleColors.0), forKey: "bt") if let bubbleBottomColor = bubbleColors.1 { - encoder.encodeInt32(bubbleBottomColor, forKey: "bb") + encoder.encodeInt32(Int32(bitPattern: bubbleBottomColor), forKey: "bb") } else { encoder.encodeNil(forKey: "bb") } diff --git a/submodules/WallpaperResources/Sources/WallpaperCache.swift b/submodules/WallpaperResources/Sources/WallpaperCache.swift index ac5557bf32..c21875181e 100644 --- a/submodules/WallpaperResources/Sources/WallpaperCache.swift +++ b/submodules/WallpaperResources/Sources/WallpaperCache.swift @@ -37,7 +37,7 @@ public func cachedWallpaper(account: Account, slug: String, settings: WallpaperS return .single(entry) } } else { - return getWallpaper(account: account, slug: slug) + return getWallpaper(network: account.network, slug: slug) |> map(Optional.init) |> `catch` { _ -> Signal in return .single(nil) diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index 2edb407bab..d23f1d5612 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -967,7 +967,7 @@ public func themeImage(account: Account, accountManager: AccountManager, source: |> mapToSignal { wallpaper -> Signal<(PresentationTheme?, UIImage?, Data?), NoError> in if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper { var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .media(media: .standalone(media: file.file), resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) |> mapToSignal { _, fullSizeData, complete -> Signal<(PresentationTheme?, UIImage?, Data?), NoError> in guard complete, let fullSizeData = fullSizeData else { @@ -1224,7 +1224,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the } var convertedRepresentations: [ImageRepresentationWithReference] = [] - convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .media(media: .standalone(media: file.file), resource: file.file.resource))) + convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) |> mapToSignal { _, fullSizeData, complete -> Signal<((UIColor, UIColor?), (UIColor, UIColor), (UIColor, UIColor), UIImage?, Int32?), NoError> in guard complete, let fullSizeData = fullSizeData else {