Prepare for chat background optimization

This commit is contained in:
Ali 2021-11-04 21:10:38 +04:00
parent ddb0999af0
commit 146b458f8a
18 changed files with 232 additions and 64 deletions

View File

@ -62,7 +62,7 @@ private final class BubbleSettingsControllerNode: ASDisplayNode, UIScrollViewDel
self.scrollNode = ASScrollNode()
self.chatBackgroundNode = WallpaperBackgroundNode(context: context)
self.chatBackgroundNode = createWallpaperBackgroundNode(context: context)
self.chatBackgroundNode.displaysAsynchronously = false
self.messagesContainerNode = ASDisplayNode()

View File

@ -132,7 +132,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
return { item, params, neighbors in
if currentBackgroundNode == nil {
currentBackgroundNode = WallpaperBackgroundNode(context: item.context)
currentBackgroundNode = createWallpaperBackgroundNode(context: item.context)
}
currentBackgroundNode?.update(wallpaper: item.wallpaper)
currentBackgroundNode?.updateBubbleTheme(bubbleTheme: item.theme, bubbleCorners: item.chatBubbleCorners)

View File

@ -74,7 +74,7 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView
self.pageControlNode = PageControlNode(dotSpacing: 7.0, dotColor: .white, inactiveDotColor: UIColor.white.withAlphaComponent(0.4))
self.chatListBackgroundNode = ASDisplayNode()
self.chatBackgroundNode = WallpaperBackgroundNode(context: context)
self.chatBackgroundNode = createWallpaperBackgroundNode(context: context)
self.chatBackgroundNode.displaysAsynchronously = false
self.messagesContainerNode = ASDisplayNode()

View File

@ -285,7 +285,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
self.backgroundContainerNode = ASDisplayNode()
self.backgroundContainerNode.clipsToBounds = true
self.backgroundWrapperNode = ASDisplayNode()
self.backgroundNode = WallpaperBackgroundNode(context: context)
self.backgroundNode = createWallpaperBackgroundNode(context: context)
self.messagesContainerNode = ASDisplayNode()
self.messagesContainerNode.clipsToBounds = true
@ -1354,7 +1354,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
@objc private func playPressed() {
if self.state.backgroundColors.count >= 3 || self.state.messagesColors.count >= 3 {
self.backgroundNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring))
self.backgroundNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring), extendAnimation: false)
} else {
self.updateState({ state in
var state = state

View File

@ -107,7 +107,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
self.messagesContainerNode.clipsToBounds = true
self.messagesContainerNode.transform = CATransform3DMakeScale(1.0, -1.0, 1.0)
self.instantChatBackgroundNode = WallpaperBackgroundNode(context: context)
self.instantChatBackgroundNode = createWallpaperBackgroundNode(context: context)
self.instantChatBackgroundNode.displaysAsynchronously = false
self.ready.set(.single(true))
@ -121,7 +121,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
self.blurredNode = BlurredImageNode()
self.blurredNode.blurView.contentMode = .scaleAspectFill
self.wallpaperNode = WallpaperBackgroundNode(context: context)
self.wallpaperNode = createWallpaperBackgroundNode(context: context)
self.toolbarNode = WallpaperGalleryToolbarNode(theme: self.previewTheme, strings: self.presentationData.strings, doneButtonType: .set)

View File

@ -138,7 +138,7 @@ class ThemeSettingsChatPreviewItemNode: ListViewItemNode {
return { item, params, neighbors in
if currentBackgroundNode == nil {
currentBackgroundNode = WallpaperBackgroundNode(context: item.context)
currentBackgroundNode = createWallpaperBackgroundNode(context: item.context)
}
currentBackgroundNode?.update(wallpaper: item.wallpaper)
currentBackgroundNode?.updateBubbleTheme(bubbleTheme: item.componentTheme, bubbleCorners: item.chatBubbleCorners)

View File

@ -136,7 +136,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.wrapperNode = ASDisplayNode()
self.imageNode = TransformImageNode()
self.imageNode.contentAnimations = .subsequentUpdates
self.nativeNode = WallpaperBackgroundNode(context: context)
self.nativeNode = createWallpaperBackgroundNode(context: context)
self.cropNode = WallpaperCropNode()
self.statusNode = RadialStatusNode(backgroundNodeColor: UIColor(white: 0.0, alpha: 0.6))
self.statusNode.frame = CGRect(x: 0.0, y: 0.0, width: progressDiameter, height: progressDiameter)
@ -812,7 +812,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
switch wallpaper {
case let .gradient(gradient):
if gradient.colors.count >= 3 {
self.nativeNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring))
self.nativeNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring), extendAnimation: false)
} else {
let rotation = gradient.settings.rotation ?? 0
self.requestRotateGradient?((rotation + 90) % 360)
@ -820,7 +820,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
case let .file(file):
if file.isPattern {
if file.settings.colors.count >= 3 {
self.nativeNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring))
self.nativeNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring), extendAnimation: false)
} else {
let rotation = file.settings.rotation ?? 0
self.requestRotateGradient?((rotation + 90) % 360)

View File

@ -964,7 +964,7 @@ final class MessageStoryRenderer {
self.containerNode = ASDisplayNode()
self.instantChatBackgroundNode = WallpaperBackgroundNode(context: context)
self.instantChatBackgroundNode = createWallpaperBackgroundNode(context: context)
self.instantChatBackgroundNode.displaysAsynchronously = false
self.messagesContainerNode = ASDisplayNode()

View File

@ -508,7 +508,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
default:
break
}
self.chatBackgroundNode = WallpaperBackgroundNode(context: context, useSharedAnimationPhase: useSharedAnimationPhase)
self.chatBackgroundNode = createWallpaperBackgroundNode(context: context, useSharedAnimationPhase: useSharedAnimationPhase)
self.wallpaperReady.set(self.chatBackgroundNode.isReady)
var locationBroadcastPanelSource: LocationBroadcastPanelSource

View File

@ -370,7 +370,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
if (strongSelf.context.sharedContext.currentPresentationData.with({ $0 })).reduceMotion {
return
}
strongSelf.backgroundNode.animateEvent(transition: transition)
strongSelf.backgroundNode.animateEvent(transition: transition, extendAnimation: false)
}
getMessageTransitionNode = { [weak self] in
@ -1648,7 +1648,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
if (self.context.sharedContext.currentPresentationData.with({ $0 })).reduceMotion {
return
}
self.backgroundNode.animateEvent(transition: transition)
self.backgroundNode.animateEvent(transition: transition, extendAnimation: false)
}
//self.historyNode.didScrollWithOffset?(listBottomInset - previousListBottomInset, transition, nil)
}

View File

@ -24,7 +24,7 @@ private func attributedServiceMessageString(theme: ChatPresentationThemeData, st
class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
let labelNode: TextNode
var backgroundNode: WallpaperBackgroundNode.BubbleBackgroundNode?
var backgroundNode: WallpaperBubbleBackgroundNode?
var backgroundColorNode: ASDisplayNode
let backgroundMaskNode: ASImageNode
var linkHighlightingNode: LinkHighlightingNode?
@ -327,7 +327,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
var backgroundFrame = backgroundNode.frame
backgroundFrame.origin.x += rect.minX
backgroundFrame.origin.y += rect.minY
backgroundNode.update(rect: backgroundFrame, within: containerSize)
backgroundNode.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
}
}

View File

@ -165,7 +165,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
private let containerNode: ContextControllerSourceNode
let imageNode: TransformImageNode
private var enableSynchronousImageApply: Bool = false
private var backgroundNode: WallpaperBackgroundNode.BubbleBackgroundNode?
private var backgroundNode: WallpaperBubbleBackgroundNode?
private(set) var placeholderNode: StickerShimmerEffectNode
private(set) var animationNode: GenericAnimatedStickerNode?
private var animationSize: CGSize?
@ -650,7 +650,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.placeholderNode.updateAbsoluteRect(CGRect(origin: CGPoint(x: rect.minX + self.placeholderNode.frame.minX, y: rect.minY + self.placeholderNode.frame.minY), size: self.placeholderNode.frame.size), within: containerSize)
if let backgroundNode = self.backgroundNode {
backgroundNode.update(rect: CGRect(origin: CGPoint(x: rect.minX + self.placeholderNode.frame.minX, y: rect.minY + self.placeholderNode.frame.minY), size: self.placeholderNode.frame.size), within: containerSize)
backgroundNode.update(rect: CGRect(origin: CGPoint(x: rect.minX + self.placeholderNode.frame.minX, y: rect.minY + self.placeholderNode.frame.minY), size: self.placeholderNode.frame.size), within: containerSize, transition: .immediate)
}
}
}

View File

@ -55,7 +55,7 @@ func bubbleMaskForType(_ type: ChatMessageBackgroundType, graphics: PrincipalThe
}
final class ChatMessageBubbleBackdrop: ASDisplayNode {
private var backgroundContent: WallpaperBackgroundNode.BubbleBackgroundNode?
private var backgroundContent: WallpaperBubbleBackgroundNode?
private var currentType: ChatMessageBackgroundType?
private var currentMaskMode: Bool?
@ -86,7 +86,7 @@ final class ChatMessageBubbleBackdrop: ASDisplayNode {
var backgroundFrame = backgroundContent.frame
backgroundFrame.origin.x += rect.minX
backgroundFrame.origin.y += rect.minY
backgroundContent.update(rect: backgroundFrame, within: containerSize)
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
}
}
}
@ -142,7 +142,7 @@ final class ChatMessageBubbleBackdrop: ASDisplayNode {
var backgroundFrame = backgroundContent.frame
backgroundFrame.origin.x += rect.minX
backgroundFrame.origin.y += rect.minY
backgroundContent.update(rect: backgroundFrame, within: containerSize)
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
}
}
@ -162,7 +162,7 @@ final class ChatMessageBubbleBackdrop: ASDisplayNode {
var backgroundFrame = backgroundContent.frame
backgroundFrame.origin.x += rect.minX
backgroundFrame.origin.y += rect.minY
backgroundContent.update(rect: backgroundFrame, within: containerSize)
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
}
self.backgroundContent = backgroundContent
self.insertSubnode(backgroundContent, at: 0)
@ -174,7 +174,7 @@ final class ChatMessageBubbleBackdrop: ASDisplayNode {
var backgroundFrame = backgroundContent.frame
backgroundFrame.origin.x += rect.minX
backgroundFrame.origin.y += rect.minY
backgroundContent.update(rect: backgroundFrame, within: containerSize)
backgroundContent.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
}
self.backgroundContent = backgroundContent
self.insertSubnode(backgroundContent, at: 0)

View File

@ -22,7 +22,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
let contextSourceNode: ContextExtractedContentContainingNode
private let containerNode: ContextControllerSourceNode
let imageNode: TransformImageNode
private var backgroundNode: WallpaperBackgroundNode.BubbleBackgroundNode?
private var backgroundNode: WallpaperBubbleBackgroundNode?
private var placeholderNode: StickerShimmerEffectNode
var textNode: TextNode?
@ -250,7 +250,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
self.placeholderNode.updateAbsoluteRect(CGRect(origin: CGPoint(x: rect.minX + placeholderNode.frame.minX, y: rect.minY + placeholderNode.frame.minY), size: placeholderNode.frame.size), within: containerSize)
if let backgroundNode = self.backgroundNode {
backgroundNode.update(rect: CGRect(origin: CGPoint(x: rect.minX + self.placeholderNode.frame.minX, y: rect.minY + self.placeholderNode.frame.minY), size: self.placeholderNode.frame.size), within: containerSize)
backgroundNode.update(rect: CGRect(origin: CGPoint(x: rect.minX + self.placeholderNode.frame.minX, y: rect.minY + self.placeholderNode.frame.minY), size: self.placeholderNode.frame.size), within: containerSize, transition: .immediate)
}
}
}

View File

@ -353,7 +353,7 @@ final class BadgeComponent: CombinedComponent {
if lhs.withinSize != rhs.withinSize {
return false
}
if lhs.wallpaperNode != rhs.wallpaperNode {
if lhs.wallpaperNode !== rhs.wallpaperNode {
return false
}
return true
@ -564,7 +564,7 @@ final class AvatarComponent: Component {
}
private final class WallpaperBlurNode: ASDisplayNode {
private var backgroundNode: WallpaperBackgroundNode.BubbleBackgroundNode?
private var backgroundNode: WallpaperBubbleBackgroundNode?
private let colorNode: ASDisplayNode
override init() {

View File

@ -99,7 +99,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
self.automaticMediaDownloadSettings = context.sharedContext.currentAutomaticMediaDownloadSettings.with { $0 }
self.backgroundNode = WallpaperBackgroundNode(context: context)
self.backgroundNode = createWallpaperBackgroundNode(context: context)
self.backgroundNode.isUserInteractionEnabled = false
self.panelBackgroundNode = NavigationBackgroundNode(color: self.presentationData.theme.chat.inputPanel.panelBackgroundColor)

View File

@ -64,7 +64,7 @@ class ChatReplyCountItem: ListViewItem {
class ChatReplyCountItemNode: ListViewItemNode {
var item: ChatReplyCountItem?
private let labelNode: TextNode
private var backgroundNode: WallpaperBackgroundNode.BubbleBackgroundNode?
private var backgroundNode: WallpaperBubbleBackgroundNode?
private let backgroundColorNode: ASDisplayNode
private var theme: ChatPresentationThemeData?
@ -201,7 +201,7 @@ class ChatReplyCountItemNode: ListViewItemNode {
backgroundFrame.origin.x += rect.minX
backgroundFrame.origin.y += rect.minY
backgroundNode.update(rect: backgroundFrame, within: containerSize)
backgroundNode.update(rect: backgroundFrame, within: containerSize, transition: .immediate)
}
}

View File

@ -27,25 +27,47 @@ private func generateBlurredContents(image: UIImage) -> UIImage? {
return context.generateImage()
}
public final class WallpaperBackgroundNode: ASDisplayNode {
public final class BubbleBackgroundNode: ASDisplayNode {
public enum BubbleType {
case incoming
case outgoing
case free
}
public enum WallpaperBubbleType {
case incoming
case outgoing
case free
}
private let bubbleType: BubbleType
public protocol WallpaperBubbleBackgroundNode: ASDisplayNode {
var frame: CGRect { get set }
func update(rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition)
func update(rect: CGRect, within containerSize: CGSize, transition: CombinedTransition)
func offset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double)
func offsetSpring(value: CGFloat, duration: Double, damping: CGFloat)
}
public protocol WallpaperBackgroundNode: ASDisplayNode {
var isReady: Signal<Bool, NoError> { get }
var rotation: CGFloat { get set }
func update(wallpaper: TelegramWallpaper)
func _internalUpdateIsSettingUpWallpaper()
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition)
func animateEvent(transition: ContainedViewLayoutTransition, extendAnimation: Bool)
func updateBubbleTheme(bubbleTheme: PresentationTheme, bubbleCorners: PresentationChatBubbleCorners)
func hasBubbleBackground(for type: WallpaperBubbleType) -> Bool
func makeBubbleBackground(for type: WallpaperBubbleType) -> WallpaperBubbleBackgroundNode?
}
final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode {
final class BubbleBackgroundNodeImpl: ASDisplayNode, WallpaperBubbleBackgroundNode {
private let bubbleType: WallpaperBubbleType
private let contentNode: ASImageNode
private var cleanWallpaperNode: ASDisplayNode?
private var gradientWallpaperNode: GradientBackgroundNode.CloneNode?
private weak var backgroundNode: WallpaperBackgroundNode?
private var index: SparseBag<BubbleBackgroundNode>.Index?
private weak var backgroundNode: WallpaperBackgroundNodeImpl?
private var index: SparseBag<BubbleBackgroundNodeImpl>.Index?
private var currentLayout: (rect: CGRect, containerSize: CGSize)?
public override var frame: CGRect {
override var frame: CGRect {
didSet {
if oldValue.size != self.bounds.size {
self.contentNode.frame = self.bounds
@ -59,7 +81,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
}
}
init(backgroundNode: WallpaperBackgroundNode, bubbleType: BubbleType) {
init(backgroundNode: WallpaperBackgroundNodeImpl, bubbleType: WallpaperBubbleType) {
self.backgroundNode = backgroundNode
self.bubbleType = bubbleType
@ -210,7 +232,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
}
}
public func update(rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition = .immediate) {
func update(rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition = .immediate) {
self.currentLayout = (rect, containerSize)
let shiftedContentsRect = CGRect(origin: CGPoint(x: rect.minX / containerSize.width, y: rect.minY / containerSize.height), size: CGSize(width: rect.width / containerSize.width, height: rect.height / containerSize.height))
@ -233,7 +255,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
}
}
public func update(rect: CGRect, within containerSize: CGSize, transition: CombinedTransition) {
func update(rect: CGRect, within containerSize: CGSize, transition: CombinedTransition) {
self.currentLayout = (rect, containerSize)
let shiftedContentsRect = CGRect(origin: CGPoint(x: rect.minX / containerSize.width, y: rect.minY / containerSize.height), size: CGSize(width: rect.width / containerSize.width, height: rect.height / containerSize.height))
@ -250,7 +272,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
}
}
public func offset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) {
func offset(value: CGPoint, animationCurve: ContainedViewLayoutTransitionCurve, duration: Double) {
guard let (_, containerSize) = self.currentLayout else {
return
}
@ -267,7 +289,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
}
}
public func offsetSpring(value: CGFloat, duration: Double, damping: CGFloat) {
func offsetSpring(value: CGFloat, duration: Double, damping: CGFloat) {
guard let (_, containerSize) = self.currentLayout else {
return
}
@ -285,9 +307,9 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
}
private final class BubbleBackgroundNodeReference {
weak var node: BubbleBackgroundNode?
weak var node: BubbleBackgroundNodeImpl?
init(node: BubbleBackgroundNode) {
init(node: BubbleBackgroundNodeImpl) {
self.node = node
}
}
@ -303,6 +325,8 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
private let patternImageNode: ASImageNode
private var isGeneratingPatternImage: Bool = false
private let bakedBackgroundView: UIImageView
private var validLayout: CGSize?
private var wallpaper: TelegramWallpaper?
private var isSettingUpWallpaper: Bool = false
@ -367,7 +391,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
}
}
public var rotation: CGFloat = 0.0 {
var rotation: CGFloat = 0.0 {
didSet {
var fromValue: CGFloat = 0.0
if let value = (self.layer.value(forKeyPath: "transform.rotation.z") as? NSNumber)?.floatValue {
@ -400,11 +424,11 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
private static var cachedSharedPattern: (PatternKey, UIImage)?
private let _isReady = ValuePromise<Bool>(false, ignoreRepeated: true)
public var isReady: Signal<Bool, NoError> {
var isReady: Signal<Bool, NoError> {
return self._isReady.get()
}
public init(context: AccountContext, useSharedAnimationPhase: Bool = false) {
init(context: AccountContext, useSharedAnimationPhase: Bool) {
self.context = context
self.useSharedAnimationPhase = useSharedAnimationPhase
self.imageContentMode = .scaleAspectFill
@ -413,6 +437,9 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
self.contentNode.contentMode = self.imageContentMode
self.patternImageNode = ASImageNode()
self.bakedBackgroundView = UIImageView()
self.bakedBackgroundView.isHidden = true
super.init()
@ -420,6 +447,8 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
self.contentNode.frame = self.bounds
self.addSubnode(self.contentNode)
self.addSubnode(self.patternImageNode)
//self.view.addSubview(self.bakedBackgroundView)
}
deinit {
@ -428,7 +457,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
self.imageDisposable.dispose()
}
public func update(wallpaper: TelegramWallpaper) {
func update(wallpaper: TelegramWallpaper) {
if self.wallpaper == wallpaper {
return
}
@ -539,7 +568,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
}
}
public func _internalUpdateIsSettingUpWallpaper() {
func _internalUpdateIsSettingUpWallpaper() {
self.isSettingUpWallpaper = true
}
@ -622,7 +651,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
self.validPatternGeneratedImage = nil
self.validPatternImage = nil
if let cachedValidPatternImage = WallpaperBackgroundNode.cachedValidPatternImage, cachedValidPatternImage.generated.wallpaper == wallpaper {
if let cachedValidPatternImage = WallpaperBackgroundNodeImpl.cachedValidPatternImage, cachedValidPatternImage.generated.wallpaper == wallpaper {
self.validPatternImage = ValidPatternImage(wallpaper: cachedValidPatternImage.generated.wallpaper, generate: cachedValidPatternImage.generate)
} else {
func reference(for resource: EngineMediaResource, media: EngineMedia) -> MediaResourceReference {
@ -688,7 +717,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
if self.validPatternGeneratedImage != updatedGeneratedImage {
self.validPatternGeneratedImage = updatedGeneratedImage
if let cachedValidPatternImage = WallpaperBackgroundNode.cachedValidPatternImage, cachedValidPatternImage.generated == updatedGeneratedImage {
if let cachedValidPatternImage = WallpaperBackgroundNodeImpl.cachedValidPatternImage, cachedValidPatternImage.generated == updatedGeneratedImage {
self.patternImageNode.image = cachedValidPatternImage.image
self.updatePatternPresentation()
} else {
@ -700,7 +729,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
self.updatePatternPresentation()
if self.useSharedAnimationPhase {
WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
WallpaperBackgroundNodeImpl.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
}
} else {
self.updatePatternPresentation()
@ -721,7 +750,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
strongSelf.updatePatternPresentation()
if let image = image, strongSelf.useSharedAnimationPhase {
WallpaperBackgroundNode.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
WallpaperBackgroundNodeImpl.cachedValidPatternImage = CachedValidPatternImage(generate: validPatternImage.generate, generated: updatedGeneratedImage, image: image)
}
}
}
@ -743,7 +772,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
transition.updateFrame(node: self.patternImageNode, frame: CGRect(origin: CGPoint(), size: size))
}
public func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
let isFirstLayout = self.validLayout == nil
self.validLayout = size
@ -767,12 +796,25 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
}
}
public func animateEvent(transition: ContainedViewLayoutTransition, extendAnimation: Bool = false) {
func animateEvent(transition: ContainedViewLayoutTransition, extendAnimation: Bool) {
self.gradientBackgroundNode?.animateEvent(transition: transition, extendAnimation: extendAnimation)
self.outgoingBubbleGradientBackgroundNode?.animateEvent(transition: transition, extendAnimation: extendAnimation)
}
public func updateBubbleTheme(bubbleTheme: PresentationTheme, bubbleCorners: PresentationChatBubbleCorners) {
private func updateBakedBackground() {
guard let size = self.validLayout else {
return
}
let context = DrawingContext(size: size, scale: UIScreenScale, opaque: true)
context.withContext { context in
context.clear(CGRect(origin: CGPoint(), size: size))
}
self.bakedBackgroundView.image = context.generateImage()
}
func updateBubbleTheme(bubbleTheme: PresentationTheme, bubbleCorners: PresentationChatBubbleCorners) {
if self.bubbleTheme !== bubbleTheme || self.bubbleCorners != bubbleCorners {
self.bubbleTheme = bubbleTheme
self.bubbleCorners = bubbleCorners
@ -801,7 +843,7 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
}
}
public func hasBubbleBackground(for type: WallpaperBackgroundNode.BubbleBackgroundNode.BubbleType) -> Bool {
func hasBubbleBackground(for type: WallpaperBubbleType) -> Bool {
guard let bubbleTheme = self.bubbleTheme, let bubbleCorners = self.bubbleCorners else {
return false
}
@ -846,12 +888,138 @@ public final class WallpaperBackgroundNode: ASDisplayNode {
return false
}
public func makeBubbleBackground(for type: WallpaperBackgroundNode.BubbleBackgroundNode.BubbleType) -> WallpaperBackgroundNode.BubbleBackgroundNode? {
func makeBubbleBackground(for type: WallpaperBubbleType) -> WallpaperBubbleBackgroundNode? {
if !self.hasBubbleBackground(for: type) {
return nil
}
let node = WallpaperBackgroundNode.BubbleBackgroundNode(backgroundNode: self, bubbleType: type)
let node = WallpaperBackgroundNodeImpl.BubbleBackgroundNodeImpl(backgroundNode: self, bubbleType: type)
node.updateContents()
return node
}
}
final class WallpaperBackgroundNodeMergedImpl: ASDisplayNode, WallpaperBackgroundNode {
final class SharedStorage {
}
private class WallpaperComponentView: UIView {
let updated: () -> Void
init(updated: @escaping () -> Void) {
self.updated = updated
super.init(frame: CGRect())
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
private final class WallpaperGradiendComponentView: WallpaperComponentView {
struct Spec {
var colors: [UInt32]
}
}
private final class WallpaperPatternComponentView: WallpaperComponentView {
struct Spec {
}
}
private let context: AccountContext
private let storage: SharedStorage
private let staticView: UIImageView
private var gradient: WallpaperGradiendComponentView?
private var pattern: WallpaperPatternComponentView?
private let _isReady = ValuePromise<Bool>(false, ignoreRepeated: true)
var isReady: Signal<Bool, NoError> {
return self._isReady.get()
}
var rotation: CGFloat = 0.0 {
didSet {
}
}
init(context: AccountContext, storage: SharedStorage?) {
self.context = context
self.storage = storage ?? SharedStorage()
self.staticView = UIImageView()
super.init()
self.view.addSubview(self.staticView)
}
func update(wallpaper: TelegramWallpaper) {
var gradientSpec: WallpaperGradiendComponentView.Spec?
switch wallpaper {
case let .builtin(wallpaperSettings):
let _ = wallpaperSettings
case let .color(color):
let _ = color
case let .gradient(gradient):
if gradient.colors.count >= 3 {
gradientSpec = WallpaperGradiendComponentView.Spec(colors: gradient.colors)
}
case let .image(representations, settings):
let _ = representations
let _ = settings
case let .file(file):
if file.settings.colors.count >= 3 {
gradientSpec = WallpaperGradiendComponentView.Spec(colors: file.settings.colors)
}
}
if let gradientSpec = gradientSpec {
let gradient: WallpaperGradiendComponentView
if let current = self.gradient {
gradient = current
} else {
gradient = WallpaperGradiendComponentView(updated: { [weak self] in
self?.componentsUpdated()
})
}
let _ = gradient
let _ = gradientSpec
} else if let gradient = self.gradient {
self.gradient = nil
gradient.removeFromSuperview()
}
}
private func componentsUpdated() {
}
func _internalUpdateIsSettingUpWallpaper() {
}
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
}
func animateEvent(transition: ContainedViewLayoutTransition, extendAnimation: Bool) {
}
func updateBubbleTheme(bubbleTheme: PresentationTheme, bubbleCorners: PresentationChatBubbleCorners) {
}
func hasBubbleBackground(for type: WallpaperBubbleType) -> Bool {
return false
}
func makeBubbleBackground(for type: WallpaperBubbleType) -> WallpaperBubbleBackgroundNode? {
return nil
}
}
public func createWallpaperBackgroundNode(context: AccountContext, useSharedAnimationPhase: Bool = false) -> WallpaperBackgroundNode {
return WallpaperBackgroundNodeImpl(context: context, useSharedAnimationPhase: useSharedAnimationPhase)
}