This commit is contained in:
Isaac
2025-10-31 18:23:12 +04:00
parent 5145b9e605
commit 9397ece5a8
5 changed files with 102 additions and 7 deletions
@@ -1998,6 +1998,7 @@ public protocol ControlledTransitionAnimator: AnyObject {
func updateContentsRect(layer: CALayer, contentsRect: CGRect, completion: ((Bool) -> Void)?)
func updateTransform(layer: CALayer, transform: CATransform3D, completion: ((Bool) -> Void)?)
func updateBackgroundColor(layer: CALayer, color: UIColor, completion: ((Bool) -> Void)?)
func updateShapeLayerPath(layer: CAShapeLayer, path: CGPath, completion: ((Bool) -> Void)?)
}
protocol AnyValueProviding {
@@ -2214,6 +2215,37 @@ extension CGColor: AnyValueProviding {
}
}
extension CGPath: AnyValueProviding {
func interpolate(with other: CGPath, fraction: CGFloat) -> CGPath {
if fraction == 0.0 {
return self
} else {
return other
}
}
var anyValue: ControlledTransitionProperty.AnyValue {
return ControlledTransitionProperty.AnyValue(
value: self,
nsValue: self,
stringValue: { "\(self)" },
isEqual: { other in
if CFGetTypeID(other.value as CFTypeRef) == CGPath.typeID {
return self == (other.value as! CGPath)
} else {
return false
}
},
interpolate: { other, fraction in
guard CFGetTypeID(other.value as CFTypeRef) == CGColor.typeID else {
preconditionFailure()
}
return self.interpolate(with: other.value as! CGPath, fraction: fraction).anyValue
}
)
}
}
final class ControlledTransitionProperty {
final class AnyValue: Equatable, CustomStringConvertible {
let value: Any
@@ -2549,6 +2581,47 @@ public final class ControlledTransition {
))
}
public func updateShapeLayerPath(layer: CAShapeLayer, path: CGPath, completion: ((Bool) -> Void)?) {
if let currentPath = layer.path, currentPath == path {
if let completion = completion {
completion(true)
}
return
}
let fromValue: CGPath?
if let animationKeys = layer.animationKeys(), animationKeys.contains(where: { key in
guard let animation = layer.animation(forKey: key) as? CAPropertyAnimation else {
return false
}
if animation.keyPath == "path" {
return true
} else {
return false
}
}) {
fromValue = layer.presentation()?.path ?? layer.path
} else {
fromValue = layer.path
}
var mappedFromValue: CGPath
if let fromValue {
mappedFromValue = fromValue
} else {
mappedFromValue = CGMutablePath()
}
layer.path = path
self.add(animation: ControlledTransitionProperty(
layer: layer,
path: "path",
fromValue: mappedFromValue,
toValue: path,
completion: completion
))
}
public func updateCornerRadius(layer: CALayer, cornerRadius: CGFloat, completion: ((Bool) -> Void)?) {
if layer.cornerRadius == cornerRadius {
return
@@ -2630,6 +2703,10 @@ public final class ControlledTransition {
self.transition.updateBackgroundColor(layer: layer, color: color, completion: completion)
}
public func updateShapeLayerPath(layer: CAShapeLayer, path: CGPath, completion: ((Bool) -> Void)?) {
self.transition.updatePath(layer: layer, path: path, completion: completion)
}
public func animatePosition(layer: CALayer, from fromValue: CGPoint, to toValue: CGPoint, completion: ((Bool) -> Void)?) {
self.transition.animatePosition(layer: layer, from: fromValue, to: toValue, completion: completion)
}
@@ -166,6 +166,7 @@ private final class BadgeNode: ASDisplayNode {
public final class SolidRoundedButtonNode: ASDisplayNode {
private var theme: SolidRoundedButtonTheme
private var glass: Bool
private var glassInset: Bool
private var fontSize: CGFloat
private let isShimmering: Bool
@@ -342,9 +343,10 @@ public final class SolidRoundedButtonNode: ASDisplayNode {
}
}
public init(title: String? = nil, icon: UIImage? = nil, theme: SolidRoundedButtonTheme, glass: Bool = false, font: SolidRoundedButtonFont = .bold, fontSize: CGFloat = 17.0, height: CGFloat = 48.0, cornerRadius: CGFloat = 24.0, isShimmering: Bool = false) {
public init(title: String? = nil, icon: UIImage? = nil, theme: SolidRoundedButtonTheme, glass: Bool = false, glassInset: Bool = false, font: SolidRoundedButtonFont = .bold, fontSize: CGFloat = 17.0, height: CGFloat = 48.0, cornerRadius: CGFloat = 24.0, isShimmering: Bool = false) {
self.theme = theme
self.glass = glass
self.glassInset = glassInset
self.font = font
self.fontSize = fontSize
self.buttonHeight = height
@@ -387,7 +387,7 @@ private final class ChatMessageActionButtonNode: ASDisplayNode {
if let backgroundContent = node.backgroundContent {
//node.backgroundBlurNode.isHidden = true
node.backgroundBlurView?.view.isHidden = true
backgroundContent.frame = CGRect(origin: CGPoint(), size: CGSize(width: max(0.0, width), height: 42.0))
animation.animator.updateFrame(layer: backgroundContent.layer, frame: CGRect(origin: CGPoint(), size: CGSize(width: max(0.0, width), height: 42.0)), completion: nil)
node.backgroundColorNode?.frame = backgroundContent.bounds
@@ -424,9 +424,13 @@ private final class ChatMessageActionButtonNode: ASDisplayNode {
if currentMaskPath != effectiveMaskPath {
if let effectiveMaskPath = effectiveMaskPath {
let shapeLayer = CAShapeLayer()
shapeLayer.path = effectiveMaskPath
node.layer.mask = shapeLayer
if let shapeLayer = node.layer.mask as? SimpleShapeLayer {
animation.animator.updateShapeLayerPath(layer: shapeLayer, path: effectiveMaskPath, completion: nil)
} else {
let shapeLayer = SimpleShapeLayer()
shapeLayer.path = effectiveMaskPath
node.layer.mask = shapeLayer
}
} else {
node.layer.mask = nil
}
@@ -625,7 +625,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
self.menuButtonIconNode.customColor = presentationInterfaceState.theme.chat.inputPanel.actionControlForegroundColor
self.menuButtonTextNode = ImmediateTextNode()
self.startButton = SolidRoundedButtonNode(title: presentationInterfaceState.strings.Bot_Start, theme: SolidRoundedButtonTheme(theme: presentationInterfaceState.theme), height: 50.0, cornerRadius: 11.0, isShimmering: true)
self.startButton = SolidRoundedButtonNode(title: presentationInterfaceState.strings.Bot_Start, theme: SolidRoundedButtonTheme(theme: presentationInterfaceState.theme), glass: true, glassInset: true, height: 50.0, cornerRadius: 50.0 * 0.5, isShimmering: true)
self.startButton.progressType = .embedded
self.startButton.isHidden = true
@@ -233,10 +233,22 @@ func floatingTopicsPanelForChatPresentationInterfaceState(_ chatPresentationInte
guard let peerId = chatPresentationInterfaceState.chatLocation.peerId else {
return nil
}
if chatPresentationInterfaceState.subject?.isService ?? false {
return nil
}
if peerId.namespace == Namespaces.Peer.CloudUser {
guard let chatHistoryState = chatPresentationInterfaceState.chatHistoryState else {
return nil
}
switch chatHistoryState {
case .loading:
return nil
case let .loaded(isEmpty, _):
if isEmpty {
return nil
}
}
}
if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = chatPresentationInterfaceState.renderedPeer?.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.hasPermission(.manageDirect), chatPresentationInterfaceState.search == nil {
let topicListDisplayModeOnTheSide = chatPresentationInterfaceState.persistentData.topicListPanelLocation