mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-29 11:25:38 +00:00
Profile info improvements
This commit is contained in:
parent
ea7f2df382
commit
3bb658e3b8
@ -240,6 +240,8 @@ public final class EmojiStatusComponent: Component {
|
|||||||
var emojiLoopMode: LoopMode?
|
var emojiLoopMode: LoopMode?
|
||||||
var emojiSize = CGSize()
|
var emojiSize = CGSize()
|
||||||
|
|
||||||
|
var iconTintColor: UIColor?
|
||||||
|
|
||||||
self.isUserInteractionEnabled = component.action != nil
|
self.isUserInteractionEnabled = component.action != nil
|
||||||
|
|
||||||
//let previousContent = self.component?.content
|
//let previousContent = self.component?.content
|
||||||
@ -248,6 +250,11 @@ public final class EmojiStatusComponent: Component {
|
|||||||
case .none:
|
case .none:
|
||||||
iconImage = nil
|
iconImage = nil
|
||||||
case let .premium(color):
|
case let .premium(color):
|
||||||
|
iconTintColor = color
|
||||||
|
|
||||||
|
if case .premium = self.component?.content, let image = self.iconView?.image {
|
||||||
|
iconImage = image
|
||||||
|
} else {
|
||||||
if let sourceImage = UIImage(bundleImageName: "Chat/Input/Media/EntityInputPremiumIcon") {
|
if let sourceImage = UIImage(bundleImageName: "Chat/Input/Media/EntityInputPremiumIcon") {
|
||||||
iconImage = generateImage(sourceImage.size, contextGenerator: { size, context in
|
iconImage = generateImage(sourceImage.size, contextGenerator: { size, context in
|
||||||
if let cgImage = sourceImage.cgImage {
|
if let cgImage = sourceImage.cgImage {
|
||||||
@ -255,13 +262,14 @@ public final class EmojiStatusComponent: Component {
|
|||||||
let imageSize = CGSize(width: sourceImage.size.width - 8.0, height: sourceImage.size.height - 8.0)
|
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.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.setFillColor(UIColor.white.cgColor)
|
||||||
context.fill(CGRect(origin: CGPoint(), size: size))
|
context.fill(CGRect(origin: CGPoint(), size: size))
|
||||||
}
|
}
|
||||||
}, opaque: false)
|
}, opaque: false)?.withRenderingMode(.alwaysTemplate)
|
||||||
} else {
|
} else {
|
||||||
iconImage = nil
|
iconImage = nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case let .topic(title, color, realSize):
|
case let .topic(title, color, realSize):
|
||||||
let colors = topicIconColors(for: color)
|
let colors = topicIconColors(for: color)
|
||||||
if let image = generateTopicIcon(title: title, backgroundColors: colors.0.map(UIColor.init(rgb:)), strokeColors: colors.1.map(UIColor.init(rgb:)), size: realSize) {
|
if let image = generateTopicIcon(title: title, backgroundColors: colors.0.map(UIColor.init(rgb:)), strokeColors: colors.1.map(UIColor.init(rgb:)), size: realSize) {
|
||||||
@ -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.layer.animateSpring(from: 0.1 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if iconView.image !== iconImage {
|
||||||
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
|
var useFit = false
|
||||||
switch component.content {
|
switch component.content {
|
||||||
@ -504,12 +524,11 @@ public final class EmojiStatusComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if accentTint {
|
if accentTint {
|
||||||
animationLayer.contentTintColor = emojiThemeColor
|
animationLayer.updateTintColor(contentTintColor: emojiThemeColor, dynamicColor: emojiThemeColor, transition: transition)
|
||||||
animationLayer.dynamicColor = emojiThemeColor
|
|
||||||
} else {
|
} else {
|
||||||
animationLayer.contentTintColor = nil
|
animationLayer.updateTintColor(contentTintColor: nil, dynamicColor: nil, transition: transition)
|
||||||
animationLayer.dynamicColor = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
animationLayer.frame = CGRect(origin: CGPoint(), size: size)
|
animationLayer.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|||||||
@ -26,6 +26,8 @@ swift_library(
|
|||||||
"//submodules/ShimmerEffect:ShimmerEffect",
|
"//submodules/ShimmerEffect:ShimmerEffect",
|
||||||
"//submodules/TelegramUIPreferences",
|
"//submodules/TelegramUIPreferences",
|
||||||
"//submodules/TelegramUI/Components/Utils/GenerateStickerPlaceholderImage",
|
"//submodules/TelegramUI/Components/Utils/GenerateStickerPlaceholderImage",
|
||||||
|
"//submodules/UIKitRuntimeUtils",
|
||||||
|
"//submodules/ComponentFlow",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
|||||||
@ -17,6 +17,8 @@ import ShimmerEffect
|
|||||||
import TextFormat
|
import TextFormat
|
||||||
import TelegramUIPreferences
|
import TelegramUIPreferences
|
||||||
import GenerateStickerPlaceholderImage
|
import GenerateStickerPlaceholderImage
|
||||||
|
import UIKitRuntimeUtils
|
||||||
|
import ComponentFlow
|
||||||
|
|
||||||
public func generateTopicIcon(title: String, backgroundColors: [UIColor], strokeColors: [UIColor], size: CGSize) -> UIImage? {
|
public func generateTopicIcon(title: String, backgroundColors: [UIColor], strokeColors: [UIColor], size: CGSize) -> UIImage? {
|
||||||
let realSize = size
|
let realSize = size
|
||||||
@ -244,17 +246,27 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||||||
private var fetchDisposable: Disposable?
|
private var fetchDisposable: Disposable?
|
||||||
private var loadDisposable: Disposable?
|
private var loadDisposable: Disposable?
|
||||||
|
|
||||||
|
private var _contentTintColor: UIColor?
|
||||||
public var contentTintColor: UIColor? {
|
public var contentTintColor: UIColor? {
|
||||||
didSet {
|
get {
|
||||||
if self.contentTintColor != oldValue {
|
return self._contentTintColor
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
if self._contentTintColor != value {
|
||||||
|
self._contentTintColor = value
|
||||||
self.updateTintColor()
|
self.updateTintColor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var _dynamicColor: UIColor?
|
||||||
public var dynamicColor: UIColor? {
|
public var dynamicColor: UIColor? {
|
||||||
didSet {
|
get {
|
||||||
if self.dynamicColor != oldValue {
|
return self._dynamicColor
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
if self._dynamicColor != value {
|
||||||
|
self._dynamicColor = value
|
||||||
self.updateTintColor()
|
self.updateTintColor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,7 +308,7 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||||||
self.renderer = renderer
|
self.renderer = renderer
|
||||||
self.unique = unique
|
self.unique = unique
|
||||||
self.placeholderColor = placeholderColor
|
self.placeholderColor = placeholderColor
|
||||||
self.dynamicColor = dynamicColor
|
self._dynamicColor = dynamicColor
|
||||||
self.loopCount = loopCount
|
self.loopCount = loopCount
|
||||||
|
|
||||||
let scale = min(2.0, UIScreenScale)
|
let scale = min(2.0, UIScreenScale)
|
||||||
@ -348,6 +360,34 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||||||
return nullAction
|
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() {
|
private func updateTintColor() {
|
||||||
if !self.isDisplayingPlaceholder {
|
if !self.isDisplayingPlaceholder {
|
||||||
var customColor = self.contentTintColor
|
var customColor = self.contentTintColor
|
||||||
@ -357,8 +397,14 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.layerTintColor == nil {
|
||||||
|
setLayerContentsMaskMode(self, true)
|
||||||
|
}
|
||||||
self.layerTintColor = customColor?.cgColor
|
self.layerTintColor = customColor?.cgColor
|
||||||
} else {
|
} else {
|
||||||
|
if self.layerTintColor != nil {
|
||||||
|
setLayerContentsMaskMode(self, false)
|
||||||
|
}
|
||||||
self.layerTintColor = nil
|
self.layerTintColor = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,6 +43,7 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode {
|
|||||||
let referenceNode: ContextReferenceContentNode
|
let referenceNode: ContextReferenceContentNode
|
||||||
let containerNode: ContextControllerSourceNode
|
let containerNode: ContextControllerSourceNode
|
||||||
private let backgroundNode: NavigationBackgroundNode
|
private let backgroundNode: NavigationBackgroundNode
|
||||||
|
private let contentNode: ASDisplayNode
|
||||||
private let iconNode: ASImageNode
|
private let iconNode: ASImageNode
|
||||||
private let textNode: ImmediateTextNode
|
private let textNode: ImmediateTextNode
|
||||||
private var animatedIcon: ComponentView<Empty>?
|
private var animatedIcon: ComponentView<Empty>?
|
||||||
@ -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 = NavigationBackgroundNode(color: UIColor(white: 1.0, alpha: 0.2), enableBlur: true, enableSaturation: false)
|
||||||
self.backgroundNode.isUserInteractionEnabled = false
|
self.backgroundNode.isUserInteractionEnabled = false
|
||||||
|
|
||||||
|
self.contentNode = ASDisplayNode()
|
||||||
|
self.contentNode.isUserInteractionEnabled = false
|
||||||
|
|
||||||
self.iconNode = ASImageNode()
|
self.iconNode = ASImageNode()
|
||||||
self.iconNode.displaysAsynchronously = false
|
self.iconNode.displaysAsynchronously = false
|
||||||
self.iconNode.displayWithoutProcessing = true
|
self.iconNode.displayWithoutProcessing = true
|
||||||
@ -77,9 +81,10 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode {
|
|||||||
|
|
||||||
self.containerNode.addSubnode(self.referenceNode)
|
self.containerNode.addSubnode(self.referenceNode)
|
||||||
self.referenceNode.addSubnode(self.backgroundNode)
|
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.containerNode)
|
||||||
self.addSubnode(self.textNode)
|
self.contentNode.addSubnode(self.textNode)
|
||||||
|
|
||||||
self.highligthedChanged = { [weak self] highlighted in
|
self.highligthedChanged = { [weak self] highlighted in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
@ -114,7 +119,7 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode {
|
|||||||
self.action(self, nil)
|
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 previousIcon = self.icon
|
||||||
let themeUpdated = self.theme != presentationData.theme
|
let themeUpdated = self.theme != presentationData.theme
|
||||||
let iconUpdated = self.icon != icon
|
let iconUpdated = self.icon != icon
|
||||||
@ -224,7 +229,7 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode {
|
|||||||
|
|
||||||
if let animatedIconView = self.animatedIcon?.view as? LottieComponent.View {
|
if let animatedIconView = self.animatedIcon?.view as? LottieComponent.View {
|
||||||
if animatedIconView.superview == nil {
|
if animatedIconView.superview == nil {
|
||||||
self.referenceNode.view.addSubview(animatedIconView)
|
self.contentNode.view.addSubview(animatedIconView)
|
||||||
}
|
}
|
||||||
if playOnce {
|
if playOnce {
|
||||||
animatedIconView.playOnce()
|
animatedIconView.playOnce()
|
||||||
@ -249,8 +254,16 @@ final class PeerInfoHeaderButtonNode: HighlightableButtonNode {
|
|||||||
let titleSize = self.textNode.updateLayout(CGSize(width: 120.0, height: .greatestFiniteMagnitude))
|
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.containerNode, frame: CGRect(origin: CGPoint(), size: size))
|
||||||
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: size))
|
transition.updateFrame(node: self.contentNode, frame: CGRect(origin: CGPoint(x: 0.0, y: size.height * 0.5 * (1.0 - fraction)), size: size))
|
||||||
self.backgroundNode.update(size: size, cornerRadius: 11.0, transition: transition)
|
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)
|
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))
|
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 {
|
if let animatedIconView = self.animatedIcon?.view {
|
||||||
|
|||||||
@ -557,11 +557,30 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
|
|
||||||
let headerButtonBackgroundColor: UIColor
|
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
|
var effectiveSeparatorAlpha: CGFloat
|
||||||
if let navigationTransition = self.navigationTransition {
|
if let navigationTransition = self.navigationTransition {
|
||||||
transitionSourceHeight = navigationTransition.sourceNavigationBar.backgroundNode.bounds.height
|
transitionSourceHeight = navigationTransition.sourceNavigationBar.backgroundNode.bounds.height
|
||||||
transitionFraction = navigationTransition.fraction
|
transitionFraction = navigationTransition.fraction
|
||||||
|
|
||||||
|
innerBackgroundTransitionFraction = 0.0
|
||||||
|
backgroundBannerAlpha = 1.0
|
||||||
|
|
||||||
if let avatarNavigationNode = navigationTransition.sourceNavigationBar.rightButtonNode.singleCustomNode as? ChatAvatarNavigationNode {
|
if let avatarNavigationNode = navigationTransition.sourceNavigationBar.rightButtonNode.singleCustomNode as? ChatAvatarNavigationNode {
|
||||||
if let statusView = avatarNavigationNode.statusView.view {
|
if let statusView = avatarNavigationNode.statusView.view {
|
||||||
transitionSourceAvatarFrame = statusView.convert(statusView.bounds, to: navigationTransition.sourceNavigationBar.view)
|
transitionSourceAvatarFrame = statusView.convert(statusView.bounds, to: navigationTransition.sourceNavigationBar.view)
|
||||||
@ -584,36 +603,36 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.blurredBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - transitionFraction), forceKeepBlur: true, transition: transition)
|
self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.blurredBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - transitionFraction), forceKeepBlur: true, transition: transition)
|
||||||
effectiveSeparatorAlpha = transitionFraction
|
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 {
|
if self.isAvatarExpanded, case .animated = transition, transitionFraction == 1.0 {
|
||||||
self.avatarListNode.animateAvatarCollapse(transition: transition)
|
self.avatarListNode.animateAvatarCollapse(transition: transition)
|
||||||
}
|
}
|
||||||
self.avatarClippingNode.clipsToBounds = false
|
self.avatarClippingNode.clipsToBounds = false
|
||||||
} else {
|
} else {
|
||||||
let contentOffset = max(0.0, contentOffset - 140.0)
|
let backgroundTransitionStepDistance: CGFloat = 50.0
|
||||||
let backgroundTransitionFraction: CGFloat = max(0.0, min(1.0, contentOffset / 30.0))
|
var backgroundTransitionDistance: CGFloat = navigationHeight + panelWithAvatarHeight - backgroundTransitionStepDistance
|
||||||
self.expandedBackgroundNode.updateColor(color: presentationData.theme.rootController.navigationBar.opaqueBackgroundColor.mixedWith(headerBackgroundColor, alpha: 1.0 - backgroundTransitionFraction), forceKeepBlur: true, transition: transition)
|
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 {
|
||||||
|
backgroundBannerAlpha = 0.0
|
||||||
|
} else {
|
||||||
|
if 1.0 - innerBackgroundTransitionFraction < 0.5 {
|
||||||
|
backgroundBannerAlpha = 0.0
|
||||||
|
} else {
|
||||||
|
backgroundBannerAlpha = 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
navigationTransition.updateAlpha(layer: self.backgroundBannerView.layer, alpha: backgroundBannerAlpha)
|
||||||
|
|
||||||
|
effectiveSeparatorAlpha = innerBackgroundTransitionFraction
|
||||||
|
|
||||||
|
self.avatarClippingNode.clipsToBounds = true
|
||||||
|
}
|
||||||
|
|
||||||
if state.isEditing {
|
if state.isEditing {
|
||||||
navigationContentsAccentColor = collapsedHeaderNavigationContentsAccentColor
|
navigationContentsAccentColor = collapsedHeaderNavigationContentsAccentColor
|
||||||
@ -632,19 +651,16 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
|
|
||||||
headerButtonBackgroundColor = expandedAvatarHeaderButtonBackgroundColor
|
headerButtonBackgroundColor = expandedAvatarHeaderButtonBackgroundColor
|
||||||
} else {
|
} else {
|
||||||
navigationContentsAccentColor = regularNavigationContentsAccentColor.mixedWith(collapsedHeaderNavigationContentsAccentColor, alpha: backgroundTransitionFraction)
|
let effectiveTransitionFraction: CGFloat = innerBackgroundTransitionFraction < 0.5 ? 0.0 : 1.0
|
||||||
navigationContentsPrimaryColor = regularNavigationContentsPrimaryColor.mixedWith(collapsedHeaderNavigationContentsPrimaryColor, alpha: backgroundTransitionFraction)
|
|
||||||
navigationContentsSecondaryColor = regularNavigationContentsSecondaryColor.mixedWith(collapsedHeaderNavigationContentsSecondaryColor, alpha: backgroundTransitionFraction)
|
|
||||||
|
|
||||||
contentButtonBackgroundColor = regularContentButtonBackgroundColor.mixedWith(collapsedHeaderContentButtonBackgroundColor, alpha: backgroundTransitionFraction)
|
navigationContentsAccentColor = regularNavigationContentsAccentColor.mixedWith(collapsedHeaderNavigationContentsAccentColor, alpha: effectiveTransitionFraction)
|
||||||
contentButtonForegroundColor = regularContentButtonForegroundColor.mixedWith(collapsedHeaderContentButtonForegroundColor, alpha: backgroundTransitionFraction)
|
navigationContentsPrimaryColor = regularNavigationContentsPrimaryColor.mixedWith(collapsedHeaderNavigationContentsPrimaryColor, alpha: effectiveTransitionFraction)
|
||||||
|
navigationContentsSecondaryColor = regularNavigationContentsSecondaryColor.mixedWith(collapsedHeaderNavigationContentsSecondaryColor, alpha: effectiveTransitionFraction)
|
||||||
|
|
||||||
headerButtonBackgroundColor = regularHeaderButtonBackgroundColor.mixedWith(collapsedHeaderButtonBackgroundColor, alpha: backgroundTransitionFraction)
|
contentButtonBackgroundColor = regularContentButtonBackgroundColor//.mixedWith(collapsedHeaderContentButtonBackgroundColor, alpha: effectiveTransitionFraction)
|
||||||
}
|
contentButtonForegroundColor = regularContentButtonForegroundColor//.mixedWith(collapsedHeaderContentButtonForegroundColor, alpha: effectiveTransitionFraction)
|
||||||
|
|
||||||
effectiveSeparatorAlpha = backgroundTransitionFraction
|
headerButtonBackgroundColor = regularHeaderButtonBackgroundColor.mixedWith(collapsedHeaderButtonBackgroundColor, alpha: effectiveTransitionFraction)
|
||||||
|
|
||||||
self.avatarClippingNode.clipsToBounds = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -678,7 +694,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
//let animateStatusIcon = !self.titleCredibilityIconView.bounds.isEmpty
|
//let animateStatusIcon = !self.titleCredibilityIconView.bounds.isEmpty
|
||||||
|
|
||||||
let iconSize = self.titleCredibilityIconView.update(
|
let iconSize = self.titleCredibilityIconView.update(
|
||||||
transition: Transition(transition),
|
transition: Transition(navigationTransition),
|
||||||
component: AnyComponent(EmojiStatusComponent(
|
component: AnyComponent(EmojiStatusComponent(
|
||||||
context: self.context,
|
context: self.context,
|
||||||
animationCache: self.animationCache,
|
animationCache: self.animationCache,
|
||||||
@ -734,7 +750,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
containerSize: CGSize(width: 34.0, height: 34.0)
|
containerSize: CGSize(width: 34.0, height: 34.0)
|
||||||
)
|
)
|
||||||
let expandedIconSize = self.titleExpandedCredibilityIconView.update(
|
let expandedIconSize = self.titleExpandedCredibilityIconView.update(
|
||||||
transition: Transition(transition),
|
transition: Transition(navigationTransition),
|
||||||
component: AnyComponent(EmojiStatusComponent(
|
component: AnyComponent(EmojiStatusComponent(
|
||||||
context: self.context,
|
context: self.context,
|
||||||
animationCache: self.animationCache,
|
animationCache: self.animationCache,
|
||||||
@ -757,20 +773,20 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
self.titleExpandedCredibilityIconSize = expandedIconSize
|
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.titleNode.updateTintColor(color: navigationContentsPrimaryColor, transition: navigationTransition)
|
||||||
self.subtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: transition)
|
self.subtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: navigationTransition)
|
||||||
self.panelSubtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: transition)
|
self.panelSubtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: navigationTransition)
|
||||||
self.nextPanelSubtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: transition)
|
self.nextPanelSubtitleNode.updateTintColor(color: navigationContentsSecondaryColor, transition: navigationTransition)
|
||||||
if let navigationBar = self.controller?.navigationBar {
|
if let navigationBar = self.controller?.navigationBar {
|
||||||
if let mainContentNode = navigationBar.backButtonNode.mainContentNode {
|
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 {
|
if let mainContentNode = navigationBar.leftButtonNode.mainContentNode {
|
||||||
transition.updateTintColor(layer: mainContentNode.layer, color: navigationContentsAccentColor)
|
navigationTransition.updateTintColor(layer: mainContentNode.layer, color: navigationContentsAccentColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
navigationBar.rightButtonNode.contentsColor = navigationContentsAccentColor
|
navigationBar.rightButtonNode.contentsColor = navigationContentsAccentColor
|
||||||
@ -1427,11 +1443,6 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
self.avatarListNode.avatarContainerNode.canAttachVideo = false
|
self.avatarListNode.avatarContainerNode.canAttachVideo = false
|
||||||
}
|
}
|
||||||
|
|
||||||
var panelWithAvatarHeight: CGFloat = 35.0 + avatarSize
|
|
||||||
if threadData != nil {
|
|
||||||
panelWithAvatarHeight += 10.0
|
|
||||||
}
|
|
||||||
|
|
||||||
let rawHeight: CGFloat
|
let rawHeight: CGFloat
|
||||||
let height: CGFloat
|
let height: CGFloat
|
||||||
let maxY: 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 buttonSpacing: CGFloat = 8.0
|
||||||
let buttonSideInset = max(16.0, containerInset)
|
let buttonSideInset = max(16.0, containerInset)
|
||||||
|
|
||||||
@ -1685,12 +1710,12 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
isActive = buttonKey == highlightedButton
|
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 {
|
if wasAdded {
|
||||||
buttonNode.alpha = 0.0
|
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 .mute = buttonKey, buttonNode.containerNode.alpha.isZero, additive {
|
||||||
if case let .animated(duration, curve) = transition {
|
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.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)))
|
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)
|
navigationTransition.updateAlpha(node: self.buttonsContainerNode, alpha: backgroundBannerAlpha)
|
||||||
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)
|
|
||||||
|
|
||||||
let bannerFrame = CGRect(origin: CGPoint(x: 0.0, y: -2000.0 + apparentBackgroundHeight), size: CGSize(width: width, height: 2000.0))
|
let bannerFrame = CGRect(origin: CGPoint(x: 0.0, y: -2000.0 + apparentBackgroundHeight), size: CGSize(width: width, height: 2000.0))
|
||||||
|
|
||||||
|
if additive {
|
||||||
transition.updateFrameAdditive(view: self.backgroundBannerView, frame: bannerFrame)
|
transition.updateFrameAdditive(view: self.backgroundBannerView, frame: bannerFrame)
|
||||||
|
} else {
|
||||||
|
transition.updateFrame(view: self.backgroundBannerView, frame: bannerFrame)
|
||||||
|
}
|
||||||
|
|
||||||
let backgroundCoverSize = self.backgroundCover.update(
|
let backgroundCoverSize = self.backgroundCover.update(
|
||||||
transition: Transition(transition),
|
transition: Transition(transition),
|
||||||
component: AnyComponent(PeerInfoCoverComponent(
|
component: AnyComponent(PeerInfoCoverComponent(
|
||||||
@ -1769,7 +1794,11 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
|||||||
if backgroundCoverView.superview == nil {
|
if backgroundCoverView.superview == nil {
|
||||||
self.backgroundBannerView.addSubview(backgroundCoverView)
|
self.backgroundBannerView.addSubview(backgroundCoverView)
|
||||||
}
|
}
|
||||||
|
if additive {
|
||||||
transition.updateFrameAdditive(view: backgroundCoverView, frame: CGRect(origin: CGPoint(x: 0.0, y: bannerFrame.height - backgroundCoverSize.height), size: backgroundCoverSize))
|
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 {
|
if additive {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user