diff --git a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift index ad9c969781..d4cd1100ed 100644 --- a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift +++ b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift @@ -30,6 +30,15 @@ private func whiteColorImage(theme: PresentationTheme, color: UIColor) -> Signal }) } +private let blackColorImage: UIImage? = { + let context = DrawingContext(size: CGSize(width: 1.0, height: 1.0), scale: 1.0, opaque: true, clear: false) + context.withContext { c in + c.setFillColor(UIColor.black.cgColor) + c.fill(CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: 1.0))) + } + return context.generateImage() +}() + final class SettingsThemeWallpaperNode: ASDisplayNode { var wallpaper: TelegramWallpaper? private var arguments: PatternWallpaperArguments? @@ -202,6 +211,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { let convertedFullRepresentations = [ImageRepresentationWithReference(representation: .init(dimensions: fullDimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))] let imageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError> + var placeholder: UIImage? if wallpaper.isPattern { var patternIntensity: CGFloat = 0.5 if !file.settings.colors.isEmpty { @@ -211,6 +221,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode { } if patternIntensity < 0.0 { + placeholder = blackColorImage self.imageNode.alpha = 1.0 self.arguments = PatternWallpaperArguments(colors: [.clear], rotation: nil, customPatternColor: UIColor(white: 0.0, alpha: 1.0 + patternIntensity)) } else { diff --git a/submodules/TelegramCore/Sources/Wallpapers.swift b/submodules/TelegramCore/Sources/Wallpapers.swift index 4557a74894..77c9ec5d6e 100644 --- a/submodules/TelegramCore/Sources/Wallpapers.swift +++ b/submodules/TelegramCore/Sources/Wallpapers.swift @@ -162,10 +162,16 @@ private func saveUnsaveWallpaper(account: Account, wallpaper: TelegramWallpaper, } public func installWallpaper(account: Account, wallpaper: TelegramWallpaper) -> Signal { - guard case let .file(_, _, _, _, _, _, slug, _, settings) = wallpaper else { + guard case let .file(id, accessHash, _, _, _, _, slug, _, settings) = wallpaper else { return .complete() } - return account.network.request(Api.functions.account.installWallPaper(wallpaper: Api.InputWallPaper.inputWallPaperSlug(slug: slug), settings: apiWallpaperSettings(settings))) + let inputWallpaper: Api.InputWallPaper + if id != 0 && accessHash != 0 { + inputWallpaper = .inputWallPaper(id: id, accessHash: accessHash) + } else { + inputWallpaper = .inputWallPaperSlug(slug: slug) + } + return account.network.request(Api.functions.account.installWallPaper(wallpaper: inputWallpaper, settings: apiWallpaperSettings(settings))) |> `catch` { _ -> Signal in return .complete() } diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index f4c9636a99..4c22d96741 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -983,7 +983,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { if let inputPanelNode = self.inputPanelNode { self.insertSubnode(accessoryPanelNode, belowSubnode: inputPanelNode) } else { - self.insertSubnode(accessoryPanelNode, aboveSubnode: self.navigateButtons) + self.insertSubnode(accessoryPanelNode, aboveSubnode: self.inputPanelBackgroundNode) } accessoryPanelNode.dismiss = { [weak self, weak accessoryPanelNode] in diff --git a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift index 1a2bb99131..09b8399382 100644 --- a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift @@ -279,6 +279,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode { private var gradientBackgroundNode: GradientBackgroundNode? private let patternImageNode: ASImageNode + private var isGeneratingPatternImage: Bool = false private var validLayout: CGSize? private var wallpaper: TelegramWallpaper? @@ -520,6 +521,50 @@ public final class WallpaperBackgroundNode: ASDisplayNode { self.isSettingUpWallpaper = true } + private func updatePatternPresentation() { + guard let wallpaper = self.wallpaper else { + return + } + + switch wallpaper { + case let .file(_, _, _, _, isPattern, _, _, _, settings) where isPattern: + let brightness = UIColor.average(of: settings.colors.map(UIColor.init(rgb:))).hsb.b + let patternIsBlack = brightness <= 0.01 + + let intensity = CGFloat(settings.intensity ?? 50) / 100.0 + if intensity < 0 { + self.patternImageNode.alpha = 1.0 + self.patternImageNode.layer.compositingFilter = nil + } else { + self.patternImageNode.alpha = intensity + if patternIsBlack { + self.patternImageNode.layer.compositingFilter = nil + } else { + self.patternImageNode.layer.compositingFilter = "softLightBlendMode" + } + } + self.patternImageNode.isHidden = false + let invertPattern = intensity < 0 + if invertPattern { + self.backgroundColor = .black + let contentAlpha = abs(intensity) + self.gradientBackgroundNode?.contentView.alpha = contentAlpha + self.contentNode.alpha = contentAlpha + } else { + self.backgroundColor = nil + self.gradientBackgroundNode?.contentView.alpha = 1.0 + self.contentNode.alpha = 1.0 + } + default: + self.patternImageDisposable.set(nil) + self.validPatternImage = nil + self.patternImageNode.isHidden = true + self.backgroundColor = nil + self.gradientBackgroundNode?.contentView.alpha = 1.0 + self.contentNode.alpha = 1.0 + } + } + private func loadPatternForSizeIfNeeded(size: CGSize, transition: ContainedViewLayoutTransition) { guard let wallpaper = self.wallpaper else { return @@ -527,14 +572,12 @@ public final class WallpaperBackgroundNode: ASDisplayNode { var invertPattern: Bool = false var patternIsLight: Bool = false - var patternIsBlack: Bool = false switch wallpaper { case let .file(_, _, _, _, isPattern, _, _, file, settings) where isPattern: var updated = true let brightness = UIColor.average(of: settings.colors.map(UIColor.init(rgb:))).hsb.b - let isLight = brightness > 0.3 - patternIsBlack = brightness <= 0.01 + patternIsLight = brightness > 0.3 if let previousWallpaper = self.validPatternImage?.wallpaper { switch previousWallpaper { case let .file(_, _, _, _, _, _, _, previousFile, _): @@ -545,7 +588,6 @@ public final class WallpaperBackgroundNode: ASDisplayNode { break } } - patternIsLight = isLight if updated { self.validPatternGeneratedImage = nil @@ -589,36 +631,9 @@ public final class WallpaperBackgroundNode: ASDisplayNode { } } let intensity = CGFloat(settings.intensity ?? 50) / 100.0 - if intensity < 0 { - self.patternImageNode.alpha = 1.0 - self.patternImageNode.layer.compositingFilter = nil - } else { - self.patternImageNode.alpha = intensity - if patternIsBlack { - self.patternImageNode.layer.compositingFilter = nil - } else { - self.patternImageNode.layer.compositingFilter = "softLightBlendMode" - } - } - self.patternImageNode.isHidden = false invertPattern = intensity < 0 - if invertPattern { - self.backgroundColor = .black - let contentAlpha = abs(intensity) - self.gradientBackgroundNode?.contentView.alpha = contentAlpha - self.contentNode.alpha = contentAlpha - } else { - self.backgroundColor = nil - self.gradientBackgroundNode?.contentView.alpha = 1.0 - self.contentNode.alpha = 1.0 - } default: - self.patternImageDisposable.set(nil) - self.validPatternImage = nil - self.patternImageNode.isHidden = true - self.backgroundColor = nil - self.gradientBackgroundNode?.contentView.alpha = 1.0 - self.contentNode.alpha = 1.0 + self.updatePatternPresentation() } if let validPatternImage = self.validPatternImage { @@ -643,26 +658,35 @@ public final class WallpaperBackgroundNode: ASDisplayNode { if let cachedValidPatternImage = WallpaperBackgroundNode.cachedValidPatternImage, cachedValidPatternImage.generated == updatedGeneratedImage { self.patternImageNode.image = cachedValidPatternImage.image + self.updatePatternPresentation() } 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 self.useSharedAnimationPhase || self.patternImageNode.image == nil { if let drawingContext = validPatternImage.generate(patternArguments) { if let image = drawingContext.generateImage() { self.patternImageNode.image = image + self.updatePatternPresentation() if self.useSharedAnimationPhase { WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image) } + } else { + self.updatePatternPresentation() } + } else { + self.updatePatternPresentation() } } else { + self.isGeneratingPatternImage = true DispatchQueue.global(qos: .userInteractive).async { [weak self] in let image = validPatternImage.generate(patternArguments)?.generateImage() Queue.mainQueue().async { guard let strongSelf = self else { return } + strongSelf.isGeneratingPatternImage = false strongSelf.patternImageNode.image = image + strongSelf.updatePatternPresentation() if let image = image, strongSelf.useSharedAnimationPhase { WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image) @@ -673,6 +697,14 @@ public final class WallpaperBackgroundNode: ASDisplayNode { } self._isReady.set(true) + } else { + if !self.isGeneratingPatternImage { + self.updatePatternPresentation() + } + } + } else { + if !self.isGeneratingPatternImage { + self.updatePatternPresentation() } } diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index fb1b2703e0..79610d8aab 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -603,6 +603,14 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da c.clear(CGRect(origin: CGPoint(), size: size)) let image = customArguments.preview ? (scaledSizeImage ?? fullSizeImage) : fullSizeImage + if let customPatternColor = customArguments.customPatternColor, customPatternColor.alpha < 1.0 { + c.setBlendMode(.copy) + c.setFillColor(UIColor.black.cgColor) + c.fill(CGRect(origin: CGPoint(), size: size)) + } else { + c.setBlendMode(.normal) + } + if let image = image { var fittedSize = CGSize(width: image.width, height: image.height) if abs(fittedSize.width - arguments.boundingSize.width).isLessThanOrEqualTo(CGFloat(1.0)) { @@ -615,14 +623,6 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize) - if let customPatternColor = customArguments.customPatternColor, customPatternColor.alpha < 1.0 { - c.setBlendMode(.copy) - c.setFillColor(UIColor.black.cgColor) - c.fill(CGRect(origin: CGPoint(), size: size)) - } else { - c.setBlendMode(.normal) - } - c.interpolationQuality = customArguments.preview ? .low : .medium c.clip(to: fittedRect, mask: image)