mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Reduce dark pattern glitching
This commit is contained in:
parent
ace2fc600e
commit
3a4a082265
@ -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 {
|
final class SettingsThemeWallpaperNode: ASDisplayNode {
|
||||||
var wallpaper: TelegramWallpaper?
|
var wallpaper: TelegramWallpaper?
|
||||||
private var arguments: PatternWallpaperArguments?
|
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 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>
|
let imageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>
|
||||||
|
var placeholder: UIImage?
|
||||||
if wallpaper.isPattern {
|
if wallpaper.isPattern {
|
||||||
var patternIntensity: CGFloat = 0.5
|
var patternIntensity: CGFloat = 0.5
|
||||||
if !file.settings.colors.isEmpty {
|
if !file.settings.colors.isEmpty {
|
||||||
@ -211,6 +221,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if patternIntensity < 0.0 {
|
if patternIntensity < 0.0 {
|
||||||
|
placeholder = blackColorImage
|
||||||
self.imageNode.alpha = 1.0
|
self.imageNode.alpha = 1.0
|
||||||
self.arguments = PatternWallpaperArguments(colors: [.clear], rotation: nil, customPatternColor: UIColor(white: 0.0, alpha: 1.0 + patternIntensity))
|
self.arguments = PatternWallpaperArguments(colors: [.clear], rotation: nil, customPatternColor: UIColor(white: 0.0, alpha: 1.0 + patternIntensity))
|
||||||
} else {
|
} else {
|
||||||
|
@ -279,6 +279,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
|||||||
|
|
||||||
private var gradientBackgroundNode: GradientBackgroundNode?
|
private var gradientBackgroundNode: GradientBackgroundNode?
|
||||||
private let patternImageNode: ASImageNode
|
private let patternImageNode: ASImageNode
|
||||||
|
private var isGeneratingPatternImage: Bool = false
|
||||||
|
|
||||||
private var validLayout: CGSize?
|
private var validLayout: CGSize?
|
||||||
private var wallpaper: TelegramWallpaper?
|
private var wallpaper: TelegramWallpaper?
|
||||||
@ -520,6 +521,50 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
|||||||
self.isSettingUpWallpaper = true
|
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) {
|
private func loadPatternForSizeIfNeeded(size: CGSize, transition: ContainedViewLayoutTransition) {
|
||||||
guard let wallpaper = self.wallpaper else {
|
guard let wallpaper = self.wallpaper else {
|
||||||
return
|
return
|
||||||
@ -527,14 +572,12 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
|||||||
|
|
||||||
var invertPattern: Bool = false
|
var invertPattern: Bool = false
|
||||||
var patternIsLight: Bool = false
|
var patternIsLight: Bool = false
|
||||||
var patternIsBlack: Bool = false
|
|
||||||
|
|
||||||
switch wallpaper {
|
switch wallpaper {
|
||||||
case let .file(_, _, _, _, isPattern, _, _, file, settings) where isPattern:
|
case let .file(_, _, _, _, isPattern, _, _, file, settings) where isPattern:
|
||||||
var updated = true
|
var updated = true
|
||||||
let brightness = UIColor.average(of: settings.colors.map(UIColor.init(rgb:))).hsb.b
|
let brightness = UIColor.average(of: settings.colors.map(UIColor.init(rgb:))).hsb.b
|
||||||
let isLight = brightness > 0.3
|
patternIsLight = brightness > 0.3
|
||||||
patternIsBlack = brightness <= 0.01
|
|
||||||
if let previousWallpaper = self.validPatternImage?.wallpaper {
|
if let previousWallpaper = self.validPatternImage?.wallpaper {
|
||||||
switch previousWallpaper {
|
switch previousWallpaper {
|
||||||
case let .file(_, _, _, _, _, _, _, previousFile, _):
|
case let .file(_, _, _, _, _, _, _, previousFile, _):
|
||||||
@ -545,7 +588,6 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
patternIsLight = isLight
|
|
||||||
|
|
||||||
if updated {
|
if updated {
|
||||||
self.validPatternGeneratedImage = nil
|
self.validPatternGeneratedImage = nil
|
||||||
@ -589,36 +631,9 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let intensity = CGFloat(settings.intensity ?? 50) / 100.0
|
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
|
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:
|
default:
|
||||||
self.patternImageDisposable.set(nil)
|
self.updatePatternPresentation()
|
||||||
self.validPatternImage = nil
|
|
||||||
self.patternImageNode.isHidden = true
|
|
||||||
self.backgroundColor = nil
|
|
||||||
self.gradientBackgroundNode?.contentView.alpha = 1.0
|
|
||||||
self.contentNode.alpha = 1.0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let validPatternImage = self.validPatternImage {
|
if let validPatternImage = self.validPatternImage {
|
||||||
@ -643,26 +658,35 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
|||||||
|
|
||||||
if let cachedValidPatternImage = WallpaperBackgroundNode.cachedValidPatternImage, cachedValidPatternImage.generated == updatedGeneratedImage {
|
if let cachedValidPatternImage = WallpaperBackgroundNode.cachedValidPatternImage, cachedValidPatternImage.generated == updatedGeneratedImage {
|
||||||
self.patternImageNode.image = cachedValidPatternImage.image
|
self.patternImageNode.image = cachedValidPatternImage.image
|
||||||
|
self.updatePatternPresentation()
|
||||||
} else {
|
} 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))
|
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 self.useSharedAnimationPhase || self.patternImageNode.image == nil {
|
||||||
if let drawingContext = validPatternImage.generate(patternArguments) {
|
if let drawingContext = validPatternImage.generate(patternArguments) {
|
||||||
if let image = drawingContext.generateImage() {
|
if let image = drawingContext.generateImage() {
|
||||||
self.patternImageNode.image = image
|
self.patternImageNode.image = image
|
||||||
|
self.updatePatternPresentation()
|
||||||
|
|
||||||
if self.useSharedAnimationPhase {
|
if self.useSharedAnimationPhase {
|
||||||
WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
|
WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
self.updatePatternPresentation()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
self.updatePatternPresentation()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.isGeneratingPatternImage = true
|
||||||
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
|
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
|
||||||
let image = validPatternImage.generate(patternArguments)?.generateImage()
|
let image = validPatternImage.generate(patternArguments)?.generateImage()
|
||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
strongSelf.isGeneratingPatternImage = false
|
||||||
strongSelf.patternImageNode.image = image
|
strongSelf.patternImageNode.image = image
|
||||||
|
strongSelf.updatePatternPresentation()
|
||||||
|
|
||||||
if let image = image, strongSelf.useSharedAnimationPhase {
|
if let image = image, strongSelf.useSharedAnimationPhase {
|
||||||
WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
|
WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
|
||||||
@ -673,6 +697,14 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self._isReady.set(true)
|
self._isReady.set(true)
|
||||||
|
} else {
|
||||||
|
if !self.isGeneratingPatternImage {
|
||||||
|
self.updatePatternPresentation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if !self.isGeneratingPatternImage {
|
||||||
|
self.updatePatternPresentation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,6 +603,14 @@ public func patternWallpaperImageInternal(thumbnailData: Data?, fullSizeData: Da
|
|||||||
c.clear(CGRect(origin: CGPoint(), size: size))
|
c.clear(CGRect(origin: CGPoint(), size: size))
|
||||||
let image = customArguments.preview ? (scaledSizeImage ?? fullSizeImage) : fullSizeImage
|
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 {
|
if let image = image {
|
||||||
var fittedSize = CGSize(width: image.width, height: image.height)
|
var fittedSize = CGSize(width: image.width, height: image.height)
|
||||||
if abs(fittedSize.width - arguments.boundingSize.width).isLessThanOrEqualTo(CGFloat(1.0)) {
|
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)
|
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.interpolationQuality = customArguments.preview ? .low : .medium
|
||||||
c.clip(to: fittedRect, mask: image)
|
c.clip(to: fittedRect, mask: image)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user