diff --git a/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift b/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift index 800502be73..5ccd91b090 100644 --- a/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift +++ b/submodules/TelegramUI/Components/EmojiStatusComponent/Sources/EmojiStatusComponent.swift @@ -240,6 +240,8 @@ public final class EmojiStatusComponent: Component { var emojiLoopMode: LoopMode? var emojiSize = CGSize() + var iconTintColor: UIColor? + self.isUserInteractionEnabled = component.action != nil //let previousContent = self.component?.content @@ -248,19 +250,25 @@ public final class EmojiStatusComponent: Component { case .none: iconImage = nil case let .premium(color): - if let sourceImage = UIImage(bundleImageName: "Chat/Input/Media/EntityInputPremiumIcon") { - iconImage = generateImage(sourceImage.size, contextGenerator: { size, context in - if let cgImage = sourceImage.cgImage { - context.clear(CGRect(origin: CGPoint(), size: size)) - let imageSize = CGSize(width: sourceImage.size.width - 8.0, height: sourceImage.size.height - 8.0) - context.clip(to: CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: floor((size.height - imageSize.height) / 2.0)), size: imageSize), mask: cgImage) - - context.setFillColor(color.cgColor) - context.fill(CGRect(origin: CGPoint(), size: size)) - } - }, opaque: false) + iconTintColor = color + + if case .premium = self.component?.content, let image = self.iconView?.image { + iconImage = image } else { - iconImage = nil + if let sourceImage = UIImage(bundleImageName: "Chat/Input/Media/EntityInputPremiumIcon") { + iconImage = generateImage(sourceImage.size, contextGenerator: { size, context in + if let cgImage = sourceImage.cgImage { + context.clear(CGRect(origin: CGPoint(), size: size)) + let imageSize = CGSize(width: sourceImage.size.width - 8.0, height: sourceImage.size.height - 8.0) + context.clip(to: CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: floor((size.height - imageSize.height) / 2.0)), size: imageSize), mask: cgImage) + + context.setFillColor(UIColor.white.cgColor) + context.fill(CGRect(origin: CGPoint(), size: size)) + } + }, opaque: false)?.withRenderingMode(.alwaysTemplate) + } else { + iconImage = nil + } } case let .topic(title, color, realSize): let colors = topicIconColors(for: color) @@ -402,7 +410,19 @@ public final class EmojiStatusComponent: Component { iconView.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.5) } } - iconView.image = iconImage + if iconView.image !== iconImage { + iconView.image = iconImage + } + + if let iconTintColor { + if transition.animation.isImmediate { + iconView.tintColor = iconTintColor + } else { + transition.setTintColor(layer: iconView.layer, color: iconTintColor) + } + } else { + iconView.tintColor = nil + } var useFit = false switch component.content { @@ -504,12 +524,11 @@ public final class EmojiStatusComponent: Component { } } } + if accentTint { - animationLayer.contentTintColor = emojiThemeColor - animationLayer.dynamicColor = emojiThemeColor + animationLayer.updateTintColor(contentTintColor: emojiThemeColor, dynamicColor: emojiThemeColor, transition: transition) } else { - animationLayer.contentTintColor = nil - animationLayer.dynamicColor = nil + animationLayer.updateTintColor(contentTintColor: nil, dynamicColor: nil, transition: transition) } animationLayer.frame = CGRect(origin: CGPoint(), size: size) diff --git a/submodules/TelegramUI/Components/EmojiTextAttachmentView/BUILD b/submodules/TelegramUI/Components/EmojiTextAttachmentView/BUILD index bff8f46635..294e001b6f 100644 --- a/submodules/TelegramUI/Components/EmojiTextAttachmentView/BUILD +++ b/submodules/TelegramUI/Components/EmojiTextAttachmentView/BUILD @@ -26,6 +26,8 @@ swift_library( "//submodules/ShimmerEffect:ShimmerEffect", "//submodules/TelegramUIPreferences", "//submodules/TelegramUI/Components/Utils/GenerateStickerPlaceholderImage", + "//submodules/UIKitRuntimeUtils", + "//submodules/ComponentFlow", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift b/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift index 018d5d4646..bacb99a5e2 100644 --- a/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift +++ b/submodules/TelegramUI/Components/EmojiTextAttachmentView/Sources/EmojiTextAttachmentView.swift @@ -17,6 +17,8 @@ import ShimmerEffect import TextFormat import TelegramUIPreferences import GenerateStickerPlaceholderImage +import UIKitRuntimeUtils +import ComponentFlow public func generateTopicIcon(title: String, backgroundColors: [UIColor], strokeColors: [UIColor], size: CGSize) -> UIImage? { let realSize = size @@ -244,17 +246,27 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { private var fetchDisposable: Disposable? private var loadDisposable: Disposable? + private var _contentTintColor: UIColor? public var contentTintColor: UIColor? { - didSet { - if self.contentTintColor != oldValue { + get { + return self._contentTintColor + } + set(value) { + if self._contentTintColor != value { + self._contentTintColor = value self.updateTintColor() } } } + private var _dynamicColor: UIColor? public var dynamicColor: UIColor? { - didSet { - if self.dynamicColor != oldValue { + get { + return self._dynamicColor + } + set(value) { + if self._dynamicColor != value { + self._dynamicColor = value self.updateTintColor() } } @@ -296,7 +308,7 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { self.renderer = renderer self.unique = unique self.placeholderColor = placeholderColor - self.dynamicColor = dynamicColor + self._dynamicColor = dynamicColor self.loopCount = loopCount let scale = min(2.0, UIScreenScale) @@ -348,6 +360,34 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { return nullAction } + public func updateTintColor(contentTintColor: UIColor?, dynamicColor: UIColor?, transition: Transition) { + self._contentTintColor = contentTintColor + self._dynamicColor = dynamicColor + + if !self.isDisplayingPlaceholder { + var customColor = self.contentTintColor + if let file = self.file { + if file.isCustomTemplateEmoji { + customColor = self.dynamicColor + } + } + + if self.layerTintColor == nil && customColor != nil { + setLayerContentsMaskMode(self, true) + } + if let customColor { + transition.setTintColor(layer: self, color: customColor) + } else { + self.layerTintColor = nil + } + } else { + if self.layerTintColor != nil { + setLayerContentsMaskMode(self, false) + } + self.layerTintColor = nil + } + } + private func updateTintColor() { if !self.isDisplayingPlaceholder { var customColor = self.contentTintColor @@ -357,8 +397,14 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget { } } + if self.layerTintColor == nil { + setLayerContentsMaskMode(self, true) + } self.layerTintColor = customColor?.cgColor } else { + if self.layerTintColor != nil { + setLayerContentsMaskMode(self, false) + } self.layerTintColor = nil } } diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderButtonNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderButtonNode.swift index f27a2281a0..38474a74ee 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderButtonNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderButtonNode.swift @@ -43,6 +43,7 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode { let referenceNode: ContextReferenceContentNode let containerNode: ContextControllerSourceNode private let backgroundNode: NavigationBackgroundNode + private let contentNode: ASDisplayNode private let iconNode: ASImageNode private let textNode: ImmediateTextNode private var animatedIcon: ComponentView? @@ -62,6 +63,9 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode { self.backgroundNode = NavigationBackgroundNode(color: UIColor(white: 1.0, alpha: 0.2), enableBlur: true, enableSaturation: false) self.backgroundNode.isUserInteractionEnabled = false + self.contentNode = ASDisplayNode() + self.contentNode.isUserInteractionEnabled = false + self.iconNode = ASImageNode() self.iconNode.displaysAsynchronously = false self.iconNode.displayWithoutProcessing = true @@ -77,9 +81,10 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode { self.containerNode.addSubnode(self.referenceNode) self.referenceNode.addSubnode(self.backgroundNode) - self.referenceNode.addSubnode(self.iconNode) + self.referenceNode.addSubnode(self.contentNode) + self.contentNode.addSubnode(self.iconNode) self.addSubnode(self.containerNode) - self.addSubnode(self.textNode) + self.contentNode.addSubnode(self.textNode) self.highligthedChanged = { [weak self] highlighted in if let strongSelf = self { @@ -114,7 +119,7 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode { self.action(self, nil) } - func update(size: CGSize, text: String, icon: PeerInfoHeaderButtonIcon, isActive: Bool, presentationData: PresentationData, backgroundColor: UIColor, foregroundColor: UIColor, transition: ContainedViewLayoutTransition) { + func update(size: CGSize, text: String, icon: PeerInfoHeaderButtonIcon, isActive: Bool, presentationData: PresentationData, backgroundColor: UIColor, foregroundColor: UIColor, fraction: CGFloat, transition: ContainedViewLayoutTransition) { let previousIcon = self.icon let themeUpdated = self.theme != presentationData.theme let iconUpdated = self.icon != icon @@ -224,7 +229,7 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode { if let animatedIconView = self.animatedIcon?.view as? LottieComponent.View { if animatedIconView.superview == nil { - self.referenceNode.view.addSubview(animatedIconView) + self.contentNode.view.addSubview(animatedIconView) } if playOnce { animatedIconView.playOnce() @@ -249,8 +254,16 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode { let titleSize = self.textNode.updateLayout(CGSize(width: 120.0, height: .greatestFiniteMagnitude)) transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(), size: size)) - transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: size)) - self.backgroundNode.update(size: size, cornerRadius: 11.0, transition: transition) + transition.updateFrame(node: self.contentNode, frame: CGRect(origin: CGPoint(x: 0.0, y: size.height * 0.5 * (1.0 - fraction)), size: size)) + transition.updateAlpha(node: self.contentNode, alpha: fraction) + + let backgroundY: CGFloat = size.height * (1.0 - fraction) + let backgroundFrame = CGRect(origin: CGPoint(x: 0.0, y: backgroundY), size: CGSize(width: size.width, height: max(0.0, size.height - backgroundY))) + transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame) + + transition.updateSublayerTransformScale(node: self.contentNode, scale: 1.0 * fraction + 0.001 * (1.0 - fraction)) + + self.backgroundNode.update(size: backgroundFrame.size, cornerRadius: min(11.0, backgroundFrame.height * 0.5), transition: transition) self.backgroundNode.updateColor(color: backgroundColor, transition: transition) transition.updateFrame(node: self.iconNode, frame: CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: 1.0), size: iconSize)) if let animatedIconView = self.animatedIcon?.view { diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift index e748af5675..834ccd76c5 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoHeaderNode.swift @@ -557,11 +557,30 @@ final class PeerInfoHeaderNode: ASDisplayNode { let headerButtonBackgroundColor: UIColor + var panelWithAvatarHeight: CGFloat = 35.0 + avatarSize + if threadData != nil { + panelWithAvatarHeight += 10.0 + } + + let innerBackgroundTransitionFraction: CGFloat + + let navigationTransition: ContainedViewLayoutTransition + if transition.isAnimated { + navigationTransition = transition + } else { + navigationTransition = animateHeader ? .animated(duration: 0.2, curve: .easeInOut) : .immediate + } + + let backgroundBannerAlpha: CGFloat + var effectiveSeparatorAlpha: CGFloat if let navigationTransition = self.navigationTransition { transitionSourceHeight = navigationTransition.sourceNavigationBar.backgroundNode.bounds.height transitionFraction = navigationTransition.fraction + innerBackgroundTransitionFraction = 0.0 + backgroundBannerAlpha = 1.0 + if let avatarNavigationNode = navigationTransition.sourceNavigationBar.rightButtonNode.singleCustomNode as? ChatAvatarNavigationNode { if let statusView = avatarNavigationNode.statusView.view { transitionSourceAvatarFrame = statusView.convert(statusView.bounds, to: navigationTransition.sourceNavigationBar.view) @@ -584,69 +603,66 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.blurredBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - transitionFraction), forceKeepBlur: true, transition: transition) effectiveSeparatorAlpha = transitionFraction - if self.isAvatarExpanded { - navigationContentsAccentColor = expandedAvatarNavigationContentsAccentColor - navigationContentsPrimaryColor = expandedAvatarNavigationContentsPrimaryColor - navigationContentsSecondaryColor = expandedAvatarNavigationContentsSecondaryColor - - contentButtonBackgroundColor = expandedAvatarContentButtonBackgroundColor - contentButtonForegroundColor = expandedAvatarContentButtonForegroundColor - - headerButtonBackgroundColor = expandedAvatarHeaderButtonBackgroundColor - } else { - navigationContentsAccentColor = regularNavigationContentsAccentColor - navigationContentsPrimaryColor = regularNavigationContentsPrimaryColor - navigationContentsSecondaryColor = regularNavigationContentsSecondaryColor - - contentButtonBackgroundColor = regularContentButtonBackgroundColor - contentButtonForegroundColor = regularContentButtonForegroundColor - - headerButtonBackgroundColor = regularHeaderButtonBackgroundColor - } - if self.isAvatarExpanded, case .animated = transition, transitionFraction == 1.0 { self.avatarListNode.animateAvatarCollapse(transition: transition) } self.avatarClippingNode.clipsToBounds = false } else { - let contentOffset = max(0.0, contentOffset - 140.0) - let backgroundTransitionFraction: CGFloat = max(0.0, min(1.0, contentOffset / 30.0)) - self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.opaqueBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - backgroundTransitionFraction), forceKeepBlur: true, transition: transition) + let backgroundTransitionStepDistance: CGFloat = 50.0 + var backgroundTransitionDistance: CGFloat = navigationHeight + panelWithAvatarHeight - backgroundTransitionStepDistance + if self.isSettings { + backgroundTransitionDistance -= 100.0 + } + let contentOffset = max(0.0, contentOffset - backgroundTransitionDistance) + innerBackgroundTransitionFraction = max(0.0, min(1.0, contentOffset / backgroundTransitionStepDistance)) - transition.updateAlpha(layer: self.backgroundBannerView.layer, alpha: state.isEditing ? 0.0 : (1.0 - backgroundTransitionFraction)) + self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.opaqueBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - innerBackgroundTransitionFraction), forceKeepBlur: true, transition: transition) if state.isEditing { - navigationContentsAccentColor = collapsedHeaderNavigationContentsAccentColor - navigationContentsPrimaryColor = collapsedHeaderNavigationContentsPrimaryColor - navigationContentsSecondaryColor = collapsedHeaderNavigationContentsSecondaryColor - contentButtonBackgroundColor = collapsedHeaderContentButtonBackgroundColor - contentButtonForegroundColor = collapsedHeaderContentButtonForegroundColor - - headerButtonBackgroundColor = collapsedHeaderButtonBackgroundColor - } else if self.isAvatarExpanded { - navigationContentsAccentColor = expandedAvatarNavigationContentsAccentColor - navigationContentsPrimaryColor = expandedAvatarNavigationContentsPrimaryColor - navigationContentsSecondaryColor = expandedAvatarNavigationContentsSecondaryColor - contentButtonBackgroundColor = expandedAvatarContentButtonBackgroundColor - contentButtonForegroundColor = expandedAvatarContentButtonForegroundColor - - headerButtonBackgroundColor = expandedAvatarHeaderButtonBackgroundColor + backgroundBannerAlpha = 0.0 } else { - navigationContentsAccentColor = regularNavigationContentsAccentColor.mixedWith(collapsedHeaderNavigationContentsAccentColor, alpha: backgroundTransitionFraction) - navigationContentsPrimaryColor = regularNavigationContentsPrimaryColor.mixedWith(collapsedHeaderNavigationContentsPrimaryColor, alpha: backgroundTransitionFraction) - navigationContentsSecondaryColor = regularNavigationContentsSecondaryColor.mixedWith(collapsedHeaderNavigationContentsSecondaryColor, alpha: backgroundTransitionFraction) - - contentButtonBackgroundColor = regularContentButtonBackgroundColor.mixedWith(collapsedHeaderContentButtonBackgroundColor, alpha: backgroundTransitionFraction) - contentButtonForegroundColor = regularContentButtonForegroundColor.mixedWith(collapsedHeaderContentButtonForegroundColor, alpha: backgroundTransitionFraction) - - headerButtonBackgroundColor = regularHeaderButtonBackgroundColor.mixedWith(collapsedHeaderButtonBackgroundColor, alpha: backgroundTransitionFraction) + if 1.0 - innerBackgroundTransitionFraction < 0.5 { + backgroundBannerAlpha = 0.0 + } else { + backgroundBannerAlpha = 1.0 + } } + navigationTransition.updateAlpha(layer: self.backgroundBannerView.layer, alpha: backgroundBannerAlpha) - effectiveSeparatorAlpha = backgroundTransitionFraction + effectiveSeparatorAlpha = innerBackgroundTransitionFraction self.avatarClippingNode.clipsToBounds = true } + if state.isEditing { + navigationContentsAccentColor = collapsedHeaderNavigationContentsAccentColor + navigationContentsPrimaryColor = collapsedHeaderNavigationContentsPrimaryColor + navigationContentsSecondaryColor = collapsedHeaderNavigationContentsSecondaryColor + contentButtonBackgroundColor = collapsedHeaderContentButtonBackgroundColor + contentButtonForegroundColor = collapsedHeaderContentButtonForegroundColor + + headerButtonBackgroundColor = collapsedHeaderButtonBackgroundColor + } else if self.isAvatarExpanded { + navigationContentsAccentColor = expandedAvatarNavigationContentsAccentColor + navigationContentsPrimaryColor = expandedAvatarNavigationContentsPrimaryColor + navigationContentsSecondaryColor = expandedAvatarNavigationContentsSecondaryColor + contentButtonBackgroundColor = expandedAvatarContentButtonBackgroundColor + contentButtonForegroundColor = expandedAvatarContentButtonForegroundColor + + headerButtonBackgroundColor = expandedAvatarHeaderButtonBackgroundColor + } else { + let effectiveTransitionFraction: CGFloat = innerBackgroundTransitionFraction < 0.5 ? 0.0 : 1.0 + + navigationContentsAccentColor = regularNavigationContentsAccentColor.mixedWith(collapsedHeaderNavigationContentsAccentColor, alpha: effectiveTransitionFraction) + navigationContentsPrimaryColor = regularNavigationContentsPrimaryColor.mixedWith(collapsedHeaderNavigationContentsPrimaryColor, alpha: effectiveTransitionFraction) + navigationContentsSecondaryColor = regularNavigationContentsSecondaryColor.mixedWith(collapsedHeaderNavigationContentsSecondaryColor, alpha: effectiveTransitionFraction) + + contentButtonBackgroundColor = regularContentButtonBackgroundColor//.mixedWith(collapsedHeaderContentButtonBackgroundColor, alpha: effectiveTransitionFraction) + contentButtonForegroundColor = regularContentButtonForegroundColor//.mixedWith(collapsedHeaderContentButtonForegroundColor, alpha: effectiveTransitionFraction) + + headerButtonBackgroundColor = regularHeaderButtonBackgroundColor.mixedWith(collapsedHeaderButtonBackgroundColor, alpha: effectiveTransitionFraction) + } + do { self.currentCredibilityIcon = credibilityIcon @@ -678,7 +694,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { //let animateStatusIcon = !self.titleCredibilityIconView.bounds.isEmpty let iconSize = self.titleCredibilityIconView.update( - transition: Transition(transition), + transition: Transition(navigationTransition), component: AnyComponent(EmojiStatusComponent( context: self.context, animationCache: self.animationCache, @@ -734,7 +750,7 @@ final class PeerInfoHeaderNode: ASDisplayNode { containerSize: CGSize(width: 34.0, height: 34.0) ) let expandedIconSize = self.titleExpandedCredibilityIconView.update( - transition: Transition(transition), + transition: Transition(navigationTransition), component: AnyComponent(EmojiStatusComponent( context: self.context, animationCache: self.animationCache, @@ -757,20 +773,20 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.titleExpandedCredibilityIconSize = expandedIconSize } - self.navigationButtonContainer.updateContentsColor(backgroundContentColor: headerButtonBackgroundColor, contentsColor: navigationContentsAccentColor, transition: transition) + self.navigationButtonContainer.updateContentsColor(backgroundContentColor: headerButtonBackgroundColor, contentsColor: navigationContentsAccentColor, transition: navigationTransition) - self.titleNode.updateTintColor(color: navigationContentsPrimaryColor, transition: transition) - self.subtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: transition) - self.panelSubtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: transition) - self.nextPanelSubtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: transition) + self.titleNode.updateTintColor(color: navigationContentsPrimaryColor, transition: navigationTransition) + self.subtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: navigationTransition) + self.panelSubtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: navigationTransition) + self.nextPanelSubtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: navigationTransition) if let navigationBar = self.controller?.navigationBar { if let mainContentNode = navigationBar.backButtonNode.mainContentNode { - transition.updateTintColor(layer: mainContentNode.layer, color: navigationContentsAccentColor) + navigationTransition.updateTintColor(layer: mainContentNode.layer, color: navigationContentsAccentColor) } - transition.updateTintColor(layer: navigationBar.backButtonArrow.layer, color: navigationContentsAccentColor) + navigationTransition.updateTintColor(layer: navigationBar.backButtonArrow.layer, color: navigationContentsAccentColor) if let mainContentNode = navigationBar.leftButtonNode.mainContentNode { - transition.updateTintColor(layer: mainContentNode.layer, color: navigationContentsAccentColor) + navigationTransition.updateTintColor(layer: mainContentNode.layer, color: navigationContentsAccentColor) } navigationBar.rightButtonNode.contentsColor = navigationContentsAccentColor @@ -1427,11 +1443,6 @@ final class PeerInfoHeaderNode: ASDisplayNode { self.avatarListNode.avatarContainerNode.canAttachVideo = false } - var panelWithAvatarHeight: CGFloat = 35.0 + avatarSize - if threadData != nil { - panelWithAvatarHeight += 10.0 - } - let rawHeight: CGFloat let height: CGFloat let maxY: CGFloat @@ -1542,6 +1553,20 @@ final class PeerInfoHeaderNode: ASDisplayNode { } } + let buttonsTransitionDistance: CGFloat = -min(0.0, apparentBackgroundHeight - backgroundHeight) + let buttonsTransitionDistanceNorm: CGFloat = 40.0 + + let innerContentOffset = max(0.0, contentOffset - 140.0) + let backgroundTransitionFraction: CGFloat = 1.0 - max(0.0, min(1.0, innerContentOffset / 30.0)) + + let innerButtonsTransitionStepDistance: CGFloat = 58.0 + let innerButtonsTransitionStepInset: CGFloat = 28.0 + let innerButtonsTransitionDistance: CGFloat = navigationHeight + panelWithAvatarHeight - innerButtonsTransitionStepDistance - innerButtonsTransitionStepInset + let innerButtonsContentOffset = max(0.0, contentOffset - innerButtonsTransitionDistance) + let innerButtonsTransitionFraction = max(0.0, min(1.0, innerButtonsContentOffset / innerButtonsTransitionStepDistance)) + + let buttonsTransitionFraction: CGFloat = 1.0 - max(0.0, min(1.0, buttonsTransitionDistance / buttonsTransitionDistanceNorm)) + let buttonSpacing: CGFloat = 8.0 let buttonSideInset = max(16.0, containerInset) @@ -1685,12 +1710,12 @@ final class PeerInfoHeaderNode: ASDisplayNode { isActive = buttonKey == highlightedButton } - buttonNode.update(size: buttonFrame.size, text: buttonText, icon: buttonIcon, isActive: isActive, presentationData: presentationData, backgroundColor: contentButtonBackgroundColor, foregroundColor: contentButtonForegroundColor, transition: buttonTransition) + buttonNode.update(size: buttonFrame.size, text: buttonText, icon: buttonIcon, isActive: isActive, presentationData: presentationData, backgroundColor: contentButtonBackgroundColor, foregroundColor: contentButtonForegroundColor, fraction: 1.0 - innerButtonsTransitionFraction, transition: buttonTransition) if wasAdded { buttonNode.alpha = 0.0 } - transition.updateAlpha(node: buttonNode, alpha: 1.0) + transition.updateAlpha(node: buttonNode, alpha: buttonsTransitionFraction) if case .mute = buttonKey, buttonNode.containerNode.alpha.isZero, additive { if case let .animated(duration, curve) = transition { @@ -1739,17 +1764,17 @@ final class PeerInfoHeaderNode: ASDisplayNode { transition.updateFrame(node: self.regularContentNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: resolvedHeight))) transition.updateFrameAdditive(node: self.buttonsContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: apparentBackgroundHeight - backgroundHeight), size: CGSize(width: width, height: 1000.0))) - let buttonsTransitionDistance: CGFloat = -min(0.0, apparentBackgroundHeight - backgroundHeight) - let buttonsTransitionDistanceNorm: CGFloat = 40.0 - let innerContentOffset = max(0.0, contentOffset - 140.0) - let backgroundTransitionFraction: CGFloat = 1.0 - max(0.0, min(1.0, innerContentOffset / 30.0)) - - let buttonsTransitionFraction: CGFloat = 1.0 - max(0.0, min(1.0, buttonsTransitionDistance / buttonsTransitionDistanceNorm)) - transition.updateAlpha(node: self.buttonsContainerNode, alpha: buttonsTransitionFraction * backgroundTransitionFraction) + navigationTransition.updateAlpha(node: self.buttonsContainerNode, alpha: backgroundBannerAlpha) let bannerFrame = CGRect(origin: CGPoint(x: 0.0, y: -2000.0 + apparentBackgroundHeight), size: CGSize(width: width, height: 2000.0)) - transition.updateFrameAdditive(view: self.backgroundBannerView, frame: bannerFrame) + + if additive { + transition.updateFrameAdditive(view: self.backgroundBannerView, frame: bannerFrame) + } else { + transition.updateFrame(view: self.backgroundBannerView, frame: bannerFrame) + } + let backgroundCoverSize = self.backgroundCover.update( transition: Transition(transition), component: AnyComponent(PeerInfoCoverComponent( @@ -1769,7 +1794,11 @@ final class PeerInfoHeaderNode: ASDisplayNode { if backgroundCoverView.superview == nil { self.backgroundBannerView.addSubview(backgroundCoverView) } - transition.updateFrameAdditive(view: backgroundCoverView, frame: CGRect(origin: CGPoint(x: 0.0, y: bannerFrame.height - backgroundCoverSize.height), size: backgroundCoverSize)) + if additive { + transition.updateFrameAdditive(view: backgroundCoverView, frame: CGRect(origin: CGPoint(x: 0.0, y: bannerFrame.height - backgroundCoverSize.height), size: backgroundCoverSize)) + } else { + transition.updateFrame(view: backgroundCoverView, frame: CGRect(origin: CGPoint(x: 0.0, y: bannerFrame.height - backgroundCoverSize.height), size: backgroundCoverSize)) + } } if additive {