mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
[WIP] Quotes
This commit is contained in:
@@ -163,22 +163,50 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
|
||||
private final class ControllerContentNode: ASDisplayNode {
|
||||
let controller: ViewController
|
||||
let passthroughTouches: Bool
|
||||
var storedContentHeight: CGFloat?
|
||||
|
||||
init(controller: ViewController) {
|
||||
init(controller: ViewController, passthroughTouches: Bool) {
|
||||
self.controller = controller
|
||||
self.passthroughTouches = passthroughTouches
|
||||
|
||||
super.init()
|
||||
|
||||
self.clipsToBounds = true
|
||||
self.cornerRadius = 14.0
|
||||
|
||||
self.addSubnode(self.controller.displayNode)
|
||||
}
|
||||
|
||||
func update(presentationData: PresentationData, size: CGSize, transition: ContainedViewLayoutTransition) {
|
||||
func update(presentationData: PresentationData, parentLayout: ContainerViewLayout, size: CGSize, transition: ContainedViewLayoutTransition) {
|
||||
transition.updateFrame(node: self.controller.displayNode, frame: CGRect(origin: CGPoint(), size: size))
|
||||
self.controller.containerLayoutUpdated(
|
||||
ContainerViewLayout(
|
||||
size: size,
|
||||
metrics: LayoutMetrics(widthClass: .compact, heightClass: .compact),
|
||||
deviceMetrics: parentLayout.deviceMetrics,
|
||||
intrinsicInsets: UIEdgeInsets(),
|
||||
safeInsets: UIEdgeInsets(),
|
||||
additionalInsets: UIEdgeInsets(),
|
||||
statusBarHeight: nil,
|
||||
inputHeight: nil,
|
||||
inputHeightIsInteractivellyChanging: false,
|
||||
inVoiceOver: false
|
||||
),
|
||||
transition: transition
|
||||
)
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
if !self.bounds.contains(point) {
|
||||
return nil
|
||||
}
|
||||
if self.passthroughTouches {
|
||||
let controllerPoint = self.view.convert(point, to: self.controller.view)
|
||||
if let result = self.controller.view.hitTest(controllerPoint, with: event) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
return self.view
|
||||
}
|
||||
}
|
||||
@@ -476,11 +504,21 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
if !items.disablePositionLock {
|
||||
positionLock = self.getActionsStackPositionLock()
|
||||
}
|
||||
if self.actionsStackNode.topPositionLock == nil {
|
||||
if let contentNode = self.controllerContentNode, contentNode.bounds.height != 0.0 {
|
||||
contentNode.storedContentHeight = contentNode.bounds.height
|
||||
}
|
||||
}
|
||||
self.actionsStackNode.push(item: makeContextControllerActionsStackItem(items: items).first!, currentScrollingState: currentScrollingState, positionLock: positionLock, animated: true)
|
||||
}
|
||||
|
||||
func popItems() {
|
||||
self.actionsStackNode.pop()
|
||||
if self.actionsStackNode.topPositionLock == nil {
|
||||
if let contentNode = self.controllerContentNode {
|
||||
contentNode.storedContentHeight = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func getCurrentScrollingState() -> CGFloat {
|
||||
@@ -517,7 +555,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
|
||||
let contentActionsSpacing: CGFloat = 7.0
|
||||
let actionsEdgeInset: CGFloat
|
||||
let actionsSideInset: CGFloat = 6.0
|
||||
let actionsSideInset: CGFloat
|
||||
let topInset: CGFloat = layout.insets(options: .statusBar).top + 8.0
|
||||
let bottomInset: CGFloat = 10.0
|
||||
|
||||
@@ -540,7 +578,8 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
transition: .immediate
|
||||
)
|
||||
actionsEdgeInset = 16.0
|
||||
case .extracted, .controller:
|
||||
actionsSideInset = 6.0
|
||||
case .extracted:
|
||||
self.backgroundNode.updateColor(
|
||||
color: presentationData.theme.contextMenu.dimColor,
|
||||
enableBlur: true,
|
||||
@@ -548,6 +587,16 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
transition: .immediate
|
||||
)
|
||||
actionsEdgeInset = 12.0
|
||||
actionsSideInset = 6.0
|
||||
case .controller:
|
||||
self.backgroundNode.updateColor(
|
||||
color: presentationData.theme.contextMenu.dimColor,
|
||||
enableBlur: true,
|
||||
forceKeepBlur: true,
|
||||
transition: .immediate
|
||||
)
|
||||
actionsEdgeInset = 12.0
|
||||
actionsSideInset = -2.0
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.backgroundNode, frame: CGRect(origin: CGPoint(), size: layout.size), beginWithCurrentState: true)
|
||||
@@ -583,7 +632,18 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
} else {
|
||||
switch self.source {
|
||||
case let .controller(source):
|
||||
controllerContentNode = ControllerContentNode(controller: source.controller)
|
||||
let controllerContentNodeValue = ControllerContentNode(controller: source.controller, passthroughTouches: source.passthroughTouches)
|
||||
|
||||
//source.controller.viewWillAppear(false)
|
||||
//source.controller.setIgnoreAppearanceMethodInvocations(true)
|
||||
|
||||
self.scrollNode.insertSubnode(controllerContentNodeValue, aboveSubnode: self.actionsContainerNode)
|
||||
self.controllerContentNode = controllerContentNodeValue
|
||||
controllerContentNode = controllerContentNodeValue
|
||||
contentTransition = .immediate
|
||||
|
||||
//source.controller.setIgnoreAppearanceMethodInvocations(false)
|
||||
//source.controller.viewDidAppear(false)
|
||||
case .location, .reference, .extracted:
|
||||
controllerContentNode = nil
|
||||
}
|
||||
@@ -688,6 +748,8 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
|
||||
let contentParentGlobalFrame: CGRect
|
||||
var contentRect: CGRect
|
||||
var isContentResizeableVertically: Bool = false
|
||||
let _ = isContentResizeableVertically
|
||||
|
||||
switch self.source {
|
||||
case let .location(location):
|
||||
@@ -718,10 +780,21 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
return
|
||||
}
|
||||
case .controller:
|
||||
//TODO
|
||||
if let contentNode = controllerContentNode {
|
||||
let _ = contentNode
|
||||
contentRect = CGRect(origin: CGPoint(x: layout.size.width * 0.5 - 100.0, y: layout.size.height * 0.5 - 100.0), size: CGSize(width: 200.0, height: 200.0))
|
||||
var defaultContentSize = CGSize(width: layout.size.width - 12.0 * 2.0, height: layout.size.height - 12.0 * 2.0 - contentTopInset - layout.safeInsets.bottom)
|
||||
defaultContentSize.height = min(defaultContentSize.height, 460.0)
|
||||
|
||||
let contentSize: CGSize
|
||||
if let preferredSize = contentNode.controller.preferredContentSizeForLayout(ContainerViewLayout(size: defaultContentSize, metrics: LayoutMetrics(widthClass: .compact, heightClass: .compact), deviceMetrics: layout.deviceMetrics, intrinsicInsets: UIEdgeInsets(), safeInsets: UIEdgeInsets(), additionalInsets: UIEdgeInsets(), statusBarHeight: nil, inputHeight: nil, inputHeightIsInteractivellyChanging: false, inVoiceOver: false)) {
|
||||
contentSize = preferredSize
|
||||
} else if let storedContentHeight = contentNode.storedContentHeight {
|
||||
contentSize = CGSize(width: defaultContentSize.width, height: storedContentHeight)
|
||||
} else {
|
||||
contentSize = defaultContentSize
|
||||
isContentResizeableVertically = true
|
||||
}
|
||||
|
||||
contentRect = CGRect(origin: CGPoint(x: floor((layout.size.width - contentSize.width) * 0.5), y: floor((layout.size.height - contentSize.height) * 0.5)), size: contentSize)
|
||||
contentParentGlobalFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: layout.size.height))
|
||||
} else {
|
||||
return
|
||||
@@ -752,14 +825,6 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
transition: contentTransition
|
||||
)
|
||||
}
|
||||
if let contentNode = controllerContentNode {
|
||||
//TODO
|
||||
contentNode.update(
|
||||
presentationData: presentationData,
|
||||
size: CGSize(),
|
||||
transition: contentTransition
|
||||
)
|
||||
}
|
||||
|
||||
let actionsConstrainedHeight: CGFloat
|
||||
if let actionsPositionLock = self.actionsStackNode.topPositionLock {
|
||||
@@ -795,6 +860,14 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
transition: transition
|
||||
)
|
||||
|
||||
if isContentResizeableVertically && self.actionsStackNode.topPositionLock == nil {
|
||||
var contentHeight = layout.size.height - contentTopInset - contentActionsSpacing - bottomInset - layout.intrinsicInsets.bottom - actionsSize.height
|
||||
contentHeight = min(contentHeight, contentRect.height)
|
||||
contentHeight = max(contentHeight, 200.0)
|
||||
|
||||
contentRect = CGRect(origin: CGPoint(x: 12.0, y: floor((layout.size.height - contentHeight) * 0.5)), size: CGSize(width: layout.size.width - 12.0 * 2.0, height: contentHeight))
|
||||
}
|
||||
|
||||
var isAnimatingOut = false
|
||||
if case .animateOut = stateTransition {
|
||||
isAnimatingOut = true
|
||||
@@ -950,11 +1023,18 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
}
|
||||
if let contentNode = controllerContentNode {
|
||||
//TODO:
|
||||
var contentFrame = CGRect(origin: CGPoint(x: contentRect.minX, y: contentRect.minY + contentVerticalOffset + additionalVisibleOffsetY), size: CGSize(width: 200.0, height: 200.0))
|
||||
var contentFrame = CGRect(origin: CGPoint(x: contentRect.minX, y: contentRect.minY + contentVerticalOffset + additionalVisibleOffsetY), size: contentRect.size)
|
||||
if case let .extracted(extracted) = self.source, extracted.centerVertically, contentFrame.midX > layout.size.width / 2.0 {
|
||||
contentFrame.origin.x = layout.size.width - contentFrame.maxX
|
||||
}
|
||||
contentTransition.updateFrame(node: contentNode, frame: contentFrame, beginWithCurrentState: true)
|
||||
|
||||
contentNode.update(
|
||||
presentationData: presentationData,
|
||||
parentLayout: layout,
|
||||
size: contentFrame.size,
|
||||
transition: contentTransition
|
||||
)
|
||||
}
|
||||
|
||||
let contentHeight: CGFloat
|
||||
@@ -1046,6 +1126,34 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
damping: springDamping,
|
||||
additive: true
|
||||
)
|
||||
} else if let contentNode = controllerContentNode {
|
||||
if case let .controller(source) = self.source, let transitionInfo = source.transitionInfo(), let (sourceView, sourceRect) = transitionInfo.sourceNode() {
|
||||
let sourcePoint = sourceView.convert(sourceRect.center, to: self.view)
|
||||
animationInContentYDistance = contentRect.midY - sourcePoint.y
|
||||
} else {
|
||||
animationInContentYDistance = 0.0
|
||||
}
|
||||
currentContentScreenFrame = contentRect
|
||||
|
||||
contentNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15)
|
||||
contentNode.layer.animateSpring(
|
||||
from: -animationInContentYDistance as NSNumber, to: 0.0 as NSNumber,
|
||||
keyPath: "position.y",
|
||||
duration: duration,
|
||||
delay: 0.0,
|
||||
initialVelocity: 0.0,
|
||||
damping: springDamping,
|
||||
additive: true
|
||||
)
|
||||
contentNode.layer.animateSpring(
|
||||
from: 0.01 as NSNumber, to: 1.0 as NSNumber,
|
||||
keyPath: "transform.scale",
|
||||
duration: duration,
|
||||
delay: 0.0,
|
||||
initialVelocity: 0.0,
|
||||
damping: springDamping,
|
||||
additive: false
|
||||
)
|
||||
} else {
|
||||
animationInContentYDistance = 0.0
|
||||
currentContentScreenFrame = contentRect
|
||||
@@ -1200,8 +1308,8 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
case let .controller(source):
|
||||
if let putBackInfo = source.transitionInfo() {
|
||||
let _ = putBackInfo
|
||||
self.clippingNode.layer.animateFrame(from: CGRect(origin: CGPoint(), size: layout.size), to: CGRect(origin: CGPoint(x: 0.0, y: putBackInfo.contentAreaInScreenSpace.minY), size: CGSize(width: layout.size.width, height: putBackInfo.contentAreaInScreenSpace.height)), duration: duration, timingFunction: timingFunction, removeOnCompletion: false)
|
||||
self.clippingNode.layer.animateBoundsOriginYAdditive(from: 0.0, to: putBackInfo.contentAreaInScreenSpace.minY, duration: duration, timingFunction: timingFunction, removeOnCompletion: false)
|
||||
/*self.clippingNode.layer.animateFrame(from: CGRect(origin: CGPoint(), size: layout.size), to: CGRect(origin: CGPoint(x: 0.0, y: putBackInfo.contentAreaInScreenSpace.minY), size: CGSize(width: layout.size.width, height: putBackInfo.contentAreaInScreenSpace.height)), duration: duration, timingFunction: timingFunction, removeOnCompletion: false)
|
||||
self.clippingNode.layer.animateBoundsOriginYAdditive(from: 0.0, to: putBackInfo.contentAreaInScreenSpace.minY, duration: duration, timingFunction: timingFunction, removeOnCompletion: false)*/
|
||||
|
||||
//TODO:
|
||||
currentContentScreenFrame = CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: 1.0))
|
||||
@@ -1216,7 +1324,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
|
||||
let currentContentLocalFrame = convertFrame(contentRect, from: self.scrollNode.view, to: self.view)
|
||||
|
||||
let animationInContentYDistance: CGFloat
|
||||
var animationInContentYDistance: CGFloat
|
||||
|
||||
switch result {
|
||||
case .default, .custom:
|
||||
@@ -1295,10 +1403,37 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
|
||||
}
|
||||
)
|
||||
}
|
||||
if let controllerContentNode {
|
||||
let _ = controllerContentNode
|
||||
//TODO
|
||||
completion()
|
||||
if let contentNode = controllerContentNode {
|
||||
if case let .controller(source) = self.source, let transitionInfo = source.transitionInfo(), let (sourceView, sourceRect) = transitionInfo.sourceNode() {
|
||||
let sourcePoint = sourceView.convert(sourceRect.center, to: self.view)
|
||||
animationInContentYDistance = contentRect.midY - sourcePoint.y
|
||||
} else {
|
||||
animationInContentYDistance = 0.0
|
||||
}
|
||||
|
||||
contentNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: duration * 0.8, removeOnCompletion: false, completion: { _ in
|
||||
completion()
|
||||
})
|
||||
contentNode.layer.animate(
|
||||
from: 0.0 as NSNumber,
|
||||
to: -animationInContentYDistance as NSNumber,
|
||||
keyPath: "position.y",
|
||||
timingFunction: timingFunction,
|
||||
duration: duration,
|
||||
delay: 0.0,
|
||||
removeOnCompletion: false,
|
||||
additive: true
|
||||
)
|
||||
contentNode.layer.animate(
|
||||
from: 1.0 as NSNumber,
|
||||
to: 0.01 as NSNumber,
|
||||
keyPath: "transform.scale",
|
||||
timingFunction: timingFunction,
|
||||
duration: duration,
|
||||
delay: 0.0,
|
||||
removeOnCompletion: false,
|
||||
additive: false
|
||||
)
|
||||
}
|
||||
|
||||
self.actionsContainerNode.layer.animateAlpha(from: self.actionsContainerNode.alpha, to: 0.0, duration: duration, removeOnCompletion: false)
|
||||
|
||||
Reference in New Issue
Block a user