mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-28 16:42:20 +00:00
Forum sharing fixes
This commit is contained in:
parent
f4ceb40d22
commit
02e53fd67c
@ -73,7 +73,7 @@ public final class SelectablePeerNode: ASDisplayNode {
|
||||
private let avatarNode: AvatarNode
|
||||
private let onlineNode: PeerOnlineMarkerNode
|
||||
private var checkNode: CheckNode?
|
||||
private let textNode: ASTextNode
|
||||
private let textNode: ImmediateTextNode
|
||||
|
||||
private let iconView: ComponentView<Empty>
|
||||
|
||||
@ -117,7 +117,7 @@ public final class SelectablePeerNode: ASDisplayNode {
|
||||
self.avatarNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: 60.0, height: 60.0))
|
||||
self.avatarNode.isLayerBacked = !smartInvertColorsEnabled()
|
||||
|
||||
self.textNode = ASTextNode()
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.isUserInteractionEnabled = false
|
||||
self.textNode.displaysAsynchronously = false
|
||||
|
||||
@ -309,16 +309,16 @@ public final class SelectablePeerNode: ASDisplayNode {
|
||||
self.avatarNodeContainer.frame = CGRect(origin: CGPoint(x: floor((bounds.size.width - 60.0) / 2.0), y: 4.0), size: CGSize(width: 60.0, height: 60.0))
|
||||
|
||||
let iconSize = CGSize(width: 18.0, height: 18.0)
|
||||
let textSize = self.textNode.calculateSizeThatFits(bounds.size)
|
||||
let textSize = self.textNode.updateLayout(bounds.size)
|
||||
var totalWidth = textSize.width
|
||||
var leftOrigin = floorToScreenPixels((bounds.width - textSize.width) / 2.0)
|
||||
if let iconView = self.iconView.view, iconView.superview != nil {
|
||||
totalWidth += iconView.frame.width + 2.0
|
||||
leftOrigin = floorToScreenPixels((bounds.width - totalWidth) / 2.0)
|
||||
iconView.frame = CGRect(origin: CGPoint(x: leftOrigin, y: 4.0 + 60.0 + 1.0), size: iconSize)
|
||||
iconView.frame = CGRect(origin: CGPoint(x: leftOrigin, y: 4.0 + 60.0 + 4.0 + floorToScreenPixels((textSize.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
leftOrigin += iconSize.width + 2.0
|
||||
}
|
||||
self.textNode.frame = CGRect(origin: CGPoint(x: leftOrigin, y: 4.0 + 60.0 + 4.0), size: CGSize(width: textSize.width, height: 34.0))
|
||||
self.textNode.frame = CGRect(origin: CGPoint(x: leftOrigin, y: 4.0 + 60.0 + 4.0), size: textSize)
|
||||
|
||||
let avatarFrame = self.avatarNode.frame
|
||||
let avatarContainerFrame = self.avatarNodeContainer.frame
|
||||
|
@ -392,39 +392,53 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
strongSelf.topicsContentNode = topicsContentNode
|
||||
strongSelf.contentNode?.supernode?.addSubnode(topicsContentNode)
|
||||
topicsContentNode.setContentOffsetUpdated({ [weak self] contentOffset, transition in
|
||||
self?.contentNodeOffsetUpdated(contentOffset, transition: transition)
|
||||
})
|
||||
|
||||
if let (layout, navigationBarHeight, _) = strongSelf.containerLayout {
|
||||
strongSelf.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
|
||||
}
|
||||
|
||||
if let sourceFrame = strongSelf.peersContentNode?.animateOut(peerId: peer.peerId) {
|
||||
topicsContentNode.animateIn(sourceFrame: sourceFrame)
|
||||
if let peersContentNode = strongSelf.peersContentNode {
|
||||
peersContentNode.setContentOffsetUpdated(nil)
|
||||
let scrollDelta = topicsContentNode.contentGridNode.scrollView.contentOffset.y - peersContentNode.contentGridNode.scrollView.contentOffset.y
|
||||
if let sourceFrame = peersContentNode.animateOut(peerId: peer.peerId, scrollDelta: scrollDelta) {
|
||||
topicsContentNode.animateIn(sourceFrame: sourceFrame, scrollDelta: scrollDelta)
|
||||
}
|
||||
}
|
||||
|
||||
topicsContentNode.setContentOffsetUpdated({ [weak self] contentOffset, transition in
|
||||
self?.contentNodeOffsetUpdated(contentOffset, transition: transition)
|
||||
})
|
||||
strongSelf.contentNodeOffsetUpdated(topicsContentNode.contentGridNode.scrollView.contentOffset.y, transition: .animated(duration: 0.4, curve: .spring))
|
||||
})
|
||||
}
|
||||
|
||||
func closePeerTopics(_ peerId: EnginePeer.Id) {
|
||||
if let topicsContentNode = self.topicsContentNode, let peersContentNode = self.peersContentNode {
|
||||
topicsContentNode.setContentOffsetUpdated(nil)
|
||||
topicsContentNode.supernode?.insertSubnode(topicsContentNode, belowSubnode: peersContentNode)
|
||||
}
|
||||
self.peersContentNode?.setContentOffsetUpdated({ [weak self] contentOffset, transition in
|
||||
self?.contentNodeOffsetUpdated(contentOffset, transition: transition)
|
||||
})
|
||||
|
||||
if let (layout, navigationBarHeight, _) = self.containerLayout {
|
||||
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .animated(duration: 0.4, curve: .spring))
|
||||
}
|
||||
|
||||
if let targetFrame = self.peersContentNode?.animateIn(peerId: peerId), let topicsContentNode = self.topicsContentNode {
|
||||
topicsContentNode.animateOut(targetFrame: targetFrame, completion: { [weak self] in
|
||||
if let topicsContentNode = self?.topicsContentNode {
|
||||
topicsContentNode.removeFromSupernode()
|
||||
self?.topicsContentNode = nil
|
||||
}
|
||||
|
||||
if let peersContentNode = self.peersContentNode {
|
||||
peersContentNode.setContentOffsetUpdated({ [weak self] contentOffset, transition in
|
||||
self?.contentNodeOffsetUpdated(contentOffset, transition: transition)
|
||||
})
|
||||
self.contentNodeOffsetUpdated(peersContentNode.contentGridNode.scrollView.contentOffset.y, transition: .animated(duration: 0.4, curve: .spring))
|
||||
}
|
||||
|
||||
if let peersContentNode = self.peersContentNode, let topicsContentNode = self.topicsContentNode {
|
||||
let scrollDelta = topicsContentNode.contentGridNode.scrollView.contentOffset.y - peersContentNode.contentGridNode.scrollView.contentOffset.y
|
||||
if let targetFrame = peersContentNode.animateIn(peerId: peerId, scrollDelta: scrollDelta) {
|
||||
topicsContentNode.animateOut(targetFrame: targetFrame, scrollDelta: scrollDelta, completion: { [weak self] in
|
||||
if let topicsContentNode = self?.topicsContentNode {
|
||||
topicsContentNode.removeFromSupernode()
|
||||
self?.topicsContentNode = nil
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,8 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
private var entries: [SharePeerEntry] = []
|
||||
private var enqueuedTransitions: [(ShareGridTransaction, Bool)] = []
|
||||
|
||||
private let contentGridNode: GridNode
|
||||
let contentGridNode: GridNode
|
||||
private let headerNode: ASDisplayNode
|
||||
private let contentTitleNode: ASTextNode
|
||||
private let contentSubtitleNode: ASTextNode
|
||||
private let contentTitleAccountNode: AvatarNode
|
||||
@ -193,6 +194,7 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
}
|
||||
|
||||
self.contentGridNode = GridNode()
|
||||
self.headerNode = ASDisplayNode()
|
||||
|
||||
self.contentTitleNode = ASTextNode()
|
||||
self.contentTitleNode.attributedText = NSAttributedString(string: strings.ShareMenu_ShareTo, font: Font.medium(20.0), textColor: self.theme.actionSheet.primaryTextColor)
|
||||
@ -247,17 +249,19 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.contentGridNode)
|
||||
self.addSubnode(self.headerNode)
|
||||
|
||||
self.addSubnode(self.contentTitleNode)
|
||||
self.addSubnode(self.contentSubtitleNode)
|
||||
self.addSubnode(self.contentTitleAccountNode)
|
||||
self.addSubnode(self.segmentedNode)
|
||||
self.addSubnode(self.searchButtonNode)
|
||||
self.headerNode.addSubnode(self.contentTitleNode)
|
||||
self.headerNode.addSubnode(self.contentSubtitleNode)
|
||||
self.headerNode.addSubnode(self.contentTitleAccountNode)
|
||||
self.headerNode.addSubnode(self.segmentedNode)
|
||||
self.headerNode.addSubnode(self.searchButtonNode)
|
||||
|
||||
self.shareContainerNode.addSubnode(self.shareReferenceNode)
|
||||
self.shareButtonNode.addSubnode(self.shareContainerNode)
|
||||
|
||||
self.addSubnode(self.shareButtonNode)
|
||||
self.headerNode.addSubnode(self.shareButtonNode)
|
||||
|
||||
self.addSubnode(self.contentSeparatorNode)
|
||||
|
||||
self.shareContainerNode.activated = { [weak self] gesture, _ in
|
||||
@ -367,7 +371,11 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
node = itemNode
|
||||
}
|
||||
}
|
||||
return node?.frame.offsetBy(dx: 0.0, dy: -10.0)
|
||||
if let node = node {
|
||||
return node.frame.offsetBy(dx: 0.0, dy: -10.0)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func generateMaskImage() -> UIImage? {
|
||||
@ -385,10 +393,16 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
})?.stretchableImage(withLeftCapWidth: 49, topCapHeight: 49)
|
||||
}
|
||||
|
||||
func animateIn(peerId: EnginePeer.Id) -> CGRect? {
|
||||
func animateIn(peerId: EnginePeer.Id, scrollDelta: CGFloat) -> CGRect? {
|
||||
self.headerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: -scrollDelta), to: .zero, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
|
||||
self.searchButtonNode.alpha = 1.0
|
||||
self.searchButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
self.searchButtonNode.layer.animatePosition(from: CGPoint(x: -20.0, y: 0.0), to: .zero, duration: 0.2, additive: true)
|
||||
|
||||
self.shareButtonNode.alpha = 1.0
|
||||
self.shareButtonNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
self.shareButtonNode.layer.animatePosition(from: CGPoint(x: 0.0, y: 0.0), to: .zero, duration: 0.2, additive: true)
|
||||
|
||||
self.contentTitleNode.alpha = 1.0
|
||||
self.contentTitleNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
@ -400,14 +414,17 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
self.contentSubtitleNode.layer.animatePosition(from: CGPoint(x: 0.0, y: -10.0), to: .zero, duration: 0.2, additive: true)
|
||||
self.contentSubtitleNode.layer.animateScale(from: 0.85, to: 1.0, duration: 0.2)
|
||||
|
||||
self.contentGridNode.layer.animatePosition(from: CGPoint(x: 0.0, y: -scrollDelta), to: .zero, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
|
||||
if let targetFrame = self.frameForPeerId(peerId), let (size, bottomInset) = self.validLayout {
|
||||
let sourceCenter = targetFrame.center
|
||||
let clippedNode = ASDisplayNode()
|
||||
clippedNode.clipsToBounds = true
|
||||
clippedNode.cornerRadius = 16.0
|
||||
clippedNode.frame = CGRect(origin: CGPoint(x: 0.0, y: self.contentTitleNode.frame.minY - 15.0), size: CGSize(width: size.width, height: size.height - bottomInset))
|
||||
self.contentGridNode.view.superview?.insertSubview(clippedNode.view, aboveSubview: self.contentGridNode.view)
|
||||
|
||||
clippedNode.layer.animatePosition(from: CGPoint(x: 0.0, y: -scrollDelta), to: .zero, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
|
||||
let maskView = UIView()
|
||||
maskView.frame = clippedNode.bounds
|
||||
|
||||
@ -415,33 +432,31 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
maskImageView.image = generateMaskImage()
|
||||
maskImageView.frame = maskView.bounds.offsetBy(dx: 0.0, dy: 36.0)
|
||||
maskView.addSubview(maskImageView)
|
||||
|
||||
clippedNode.view.mask = maskView
|
||||
|
||||
|
||||
self.contentGridNode.alpha = 1.0
|
||||
self.contentGridNode.forEachItemNode { itemNode in
|
||||
if let snapshotView = itemNode.view.snapshotView(afterScreenUpdates: false) {
|
||||
if let itemNode = itemNode as? ShareControllerPeerGridItemNode, itemNode.peerId == peerId {
|
||||
itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, removeOnCompletion: false)
|
||||
itemNode.layer.animateScale(from: 1.35, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, completion: { [weak clippedNode] _ in
|
||||
clippedNode?.view.removeFromSuperview()
|
||||
})
|
||||
} else if let snapshotView = itemNode.view.snapshotView(afterScreenUpdates: false) {
|
||||
snapshotView.frame = itemNode.view.convert(itemNode.bounds, to: clippedNode.view)
|
||||
|
||||
if let itemNode = itemNode as? ShareControllerPeerGridItemNode, itemNode.peerId == peerId {
|
||||
itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, removeOnCompletion: false)
|
||||
itemNode.layer.animateScale(from: 1.35, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, completion: { [weak clippedNode] _ in
|
||||
clippedNode?.view.removeFromSuperview()
|
||||
})
|
||||
} else {
|
||||
clippedNode.view.addSubview(snapshotView)
|
||||
|
||||
itemNode.alpha = 0.0
|
||||
let angle = sourceCenter.angle(to: itemNode.position)
|
||||
let distance = sourceCenter.distance(to: itemNode.position)
|
||||
let newDistance = distance * 2.8
|
||||
let newPosition = snapshotView.center.offsetBy(distance: newDistance, inDirection: angle)
|
||||
snapshotView.layer.animatePosition(from: newPosition, to: snapshotView.center, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
||||
snapshotView.layer.animateScale(from: 1.35, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, completion: { [weak itemNode] _ in
|
||||
itemNode?.alpha = 1.0
|
||||
})
|
||||
snapshotView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, removeOnCompletion: false)
|
||||
}
|
||||
clippedNode.view.addSubview(snapshotView)
|
||||
|
||||
itemNode.alpha = 0.0
|
||||
let angle = targetFrame.center.angle(to: itemNode.position)
|
||||
let distance = targetFrame.center.distance(to: itemNode.position)
|
||||
let newDistance = distance * 2.8
|
||||
let newPosition = snapshotView.center.offsetBy(distance: newDistance, inDirection: angle)
|
||||
snapshotView.layer.animatePosition(from: newPosition, to: snapshotView.center, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
||||
snapshotView.layer.animateScale(from: 1.35, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, completion: { [weak itemNode] _ in
|
||||
itemNode?.alpha = 1.0
|
||||
})
|
||||
snapshotView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, removeOnCompletion: false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -451,11 +466,17 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
}
|
||||
}
|
||||
|
||||
func animateOut(peerId: EnginePeer.Id) -> CGRect? {
|
||||
func animateOut(peerId: EnginePeer.Id, scrollDelta: CGFloat) -> CGRect? {
|
||||
self.headerNode.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: -scrollDelta), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
|
||||
self.searchButtonNode.alpha = 0.0
|
||||
self.searchButtonNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
|
||||
self.searchButtonNode.layer.animatePosition(from: .zero, to: CGPoint(x: -20.0, y: 0.0), duration: 0.2, additive: true)
|
||||
|
||||
self.shareButtonNode.alpha = 0.0
|
||||
self.shareButtonNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
|
||||
self.shareButtonNode.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: 0.0), duration: 0.2, additive: true)
|
||||
|
||||
self.contentTitleNode.alpha = 0.0
|
||||
self.contentTitleNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
|
||||
self.contentTitleNode.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: -10.0), duration: 0.2, additive: true)
|
||||
@ -466,14 +487,17 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
self.contentSubtitleNode.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: -10.0), duration: 0.2, additive: true)
|
||||
self.contentSubtitleNode.layer.animateScale(from: 1.0, to: 0.85, duration: 0.3)
|
||||
|
||||
self.contentGridNode.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: -scrollDelta), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
|
||||
if let sourceFrame = self.frameForPeerId(peerId), let (size, bottomInset) = self.validLayout {
|
||||
let sourceCenter = sourceFrame.center
|
||||
let clippedNode = ASDisplayNode()
|
||||
clippedNode.clipsToBounds = true
|
||||
clippedNode.cornerRadius = 16.0
|
||||
clippedNode.frame = CGRect(origin: CGPoint(x: 0.0, y: self.contentTitleNode.frame.minY - 15.0), size: CGSize(width: size.width, height: size.height - bottomInset))
|
||||
self.contentGridNode.view.superview?.insertSubview(clippedNode.view, aboveSubview: self.contentGridNode.view)
|
||||
|
||||
clippedNode.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: -scrollDelta), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
|
||||
let maskView = UIView()
|
||||
maskView.frame = clippedNode.bounds
|
||||
|
||||
@ -481,7 +505,6 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
maskImageView.image = generateMaskImage()
|
||||
maskImageView.frame = maskView.bounds.offsetBy(dx: 0.0, dy: 36.0)
|
||||
maskView.addSubview(maskImageView)
|
||||
|
||||
clippedNode.view.mask = maskView
|
||||
|
||||
self.contentGridNode.forEachItemNode { itemNode in
|
||||
@ -492,8 +515,8 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
if let itemNode = itemNode as? ShareControllerPeerGridItemNode, itemNode.peerId == peerId {
|
||||
|
||||
} else {
|
||||
let angle = sourceCenter.angle(to: itemNode.position)
|
||||
let distance = sourceCenter.distance(to: itemNode.position)
|
||||
let angle = sourceFrame.center.angle(to: itemNode.position)
|
||||
let distance = sourceFrame.center.distance(to: itemNode.position)
|
||||
let newDistance = distance * 2.8
|
||||
let newPosition = snapshotView.center.offsetBy(distance: newDistance, inDirection: angle)
|
||||
snapshotView.layer.animatePosition(from: snapshotView.center, to: newPosition, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring)
|
||||
@ -562,12 +585,15 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
let rawTitleOffset = -titleAreaHeight - presentationLayout.contentOffset.y
|
||||
let titleOffset = max(-titleAreaHeight, rawTitleOffset)
|
||||
|
||||
let headerFrame = CGRect(origin: CGPoint(x: 0.0, y: titleOffset), size: CGSize(width: size.width, height: 64.0))
|
||||
transition.updateFrame(node: self.headerNode, frame: headerFrame)
|
||||
|
||||
let titleSize = self.contentTitleNode.measure(size)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: titleOffset + 15.0), size: titleSize)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: 15.0), size: titleSize)
|
||||
transition.updateFrame(node: self.contentTitleNode, frame: titleFrame)
|
||||
|
||||
let subtitleSize = self.contentSubtitleNode.measure(CGSize(width: size.width - 44.0 * 2.0 - 8.0 * 2.0, height: titleAreaHeight))
|
||||
let subtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - subtitleSize.width) / 2.0), y: titleOffset + 40.0), size: subtitleSize)
|
||||
let subtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - subtitleSize.width) / 2.0), y: 40.0), size: subtitleSize)
|
||||
var originalSubtitleFrame = self.contentSubtitleNode.frame
|
||||
originalSubtitleFrame.origin.x = subtitleFrame.origin.x
|
||||
originalSubtitleFrame.size = subtitleFrame.size
|
||||
@ -575,19 +601,19 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
transition.updateFrame(node: self.contentSubtitleNode, frame: subtitleFrame)
|
||||
|
||||
let titleButtonSize = CGSize(width: 44.0, height: 44.0)
|
||||
let searchButtonFrame = CGRect(origin: CGPoint(x: 12.0, y: titleOffset + 12.0), size: titleButtonSize)
|
||||
let searchButtonFrame = CGRect(origin: CGPoint(x: 12.0, y: 12.0), size: titleButtonSize)
|
||||
transition.updateFrame(node: self.searchButtonNode, frame: searchButtonFrame)
|
||||
|
||||
let shareButtonFrame = CGRect(origin: CGPoint(x: size.width - titleButtonSize.width - 12.0, y: titleOffset + 12.0), size: titleButtonSize)
|
||||
let shareButtonFrame = CGRect(origin: CGPoint(x: size.width - titleButtonSize.width - 12.0, y: 12.0), size: titleButtonSize)
|
||||
transition.updateFrame(node: self.shareButtonNode, frame: shareButtonFrame)
|
||||
transition.updateFrame(node: self.shareContainerNode, frame: CGRect(origin: CGPoint(), size: titleButtonSize))
|
||||
transition.updateFrame(node: self.shareReferenceNode, frame: CGRect(origin: CGPoint(), size: titleButtonSize))
|
||||
|
||||
let segmentedSize = self.segmentedNode.updateLayout(.sizeToFit(maximumWidth: size.width - titleButtonSize.width * 2.0, minimumWidth: 160.0, height: 32.0), transition: transition)
|
||||
transition.updateFrame(node: self.segmentedNode, frame: CGRect(origin: CGPoint(x: floor((size.width - segmentedSize.width) / 2.0), y: titleOffset + 18.0), size: segmentedSize))
|
||||
transition.updateFrame(node: self.segmentedNode, frame: CGRect(origin: CGPoint(x: floor((size.width - segmentedSize.width) / 2.0), y: 18.0), size: segmentedSize))
|
||||
|
||||
let avatarButtonSize = CGSize(width: 36.0, height: 36.0)
|
||||
let avatarButtonFrame = CGRect(origin: CGPoint(x: size.width - avatarButtonSize.width - 20.0, y: titleOffset + 15.0), size: avatarButtonSize)
|
||||
let avatarButtonFrame = CGRect(origin: CGPoint(x: size.width - avatarButtonSize.width - 20.0, y: 15.0), size: avatarButtonSize)
|
||||
transition.updateFrame(node: self.contentTitleAccountNode, frame: avatarButtonFrame)
|
||||
|
||||
transition.updateFrame(node: self.contentSeparatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: titleOffset + titleAreaHeight), size: CGSize(width: size.width, height: UIScreenPixel)))
|
||||
|
@ -63,6 +63,8 @@ final class ShareTopicGridItemNode: GridItemNode {
|
||||
override init() {
|
||||
self.iconView = ComponentView<Empty>()
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.maximumNumberOfLines = 2
|
||||
self.textNode.textAlignment = .center
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -165,7 +165,8 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
private var entries: [ShareTopicEntry] = []
|
||||
private var enqueuedTransitions: [(ShareGridTransaction, Bool)] = []
|
||||
|
||||
private let contentGridNode: GridNode
|
||||
let contentGridNode: GridNode
|
||||
private let headerNode: ASDisplayNode
|
||||
private let contentTitleNode: ASTextNode
|
||||
private let contentSubtitleNode: ASTextNode
|
||||
private let backNode: CancelButtonNode
|
||||
@ -203,6 +204,7 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
}
|
||||
|
||||
self.contentGridNode = GridNode()
|
||||
self.headerNode = ASDisplayNode()
|
||||
|
||||
self.contentTitleNode = ASTextNode()
|
||||
self.contentTitleNode.attributedText = NSAttributedString(string: peer.compactDisplayTitle, font: Font.medium(20.0), textColor: self.theme.actionSheet.primaryTextColor)
|
||||
@ -219,10 +221,11 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.contentGridNode)
|
||||
self.addSubnode(self.headerNode)
|
||||
|
||||
self.addSubnode(self.contentTitleNode)
|
||||
self.addSubnode(self.contentSubtitleNode)
|
||||
self.addSubnode(self.backNode)
|
||||
self.headerNode.addSubnode(self.contentTitleNode)
|
||||
self.headerNode.addSubnode(self.contentSubtitleNode)
|
||||
self.headerNode.addSubnode(self.backNode)
|
||||
|
||||
let previousItems = Atomic<[ShareTopicEntry]?>(value: [])
|
||||
self.disposable.set((items
|
||||
@ -304,7 +307,9 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
func deactivate() {
|
||||
}
|
||||
|
||||
func animateIn(sourceFrame: CGRect) {
|
||||
func animateIn(sourceFrame: CGRect, scrollDelta: CGFloat) {
|
||||
self.headerNode.layer.animatePosition(from: CGPoint(x: 0.0, y: scrollDelta), to: .zero, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
|
||||
self.backNode.alpha = 1.0
|
||||
self.backNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
self.backNode.layer.animatePosition(from: CGPoint(x: 20.0, y: 0.0), to: .zero, duration: 0.2, additive: true)
|
||||
@ -319,6 +324,7 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
self.contentSubtitleNode.layer.animatePosition(from: CGPoint(x: 0.0, y: 10.0), to: .zero, duration: 0.2, additive: true)
|
||||
self.contentSubtitleNode.layer.animateScale(from: 0.85, to: 1.0, duration: 0.2)
|
||||
|
||||
self.contentGridNode.layer.animatePosition(from: CGPoint(x: 0.0, y: scrollDelta), to: .zero, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
self.contentGridNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
|
||||
|
||||
self.contentGridNode.forEachItemNode { itemNode in
|
||||
@ -327,7 +333,9 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
}
|
||||
}
|
||||
|
||||
func animateOut(targetFrame: CGRect, completion: @escaping () -> Void = {}) {
|
||||
func animateOut(targetFrame: CGRect, scrollDelta: CGFloat, completion: @escaping () -> Void = {}) {
|
||||
self.headerNode.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: scrollDelta), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
|
||||
self.backNode.alpha = 0.0
|
||||
self.backNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2)
|
||||
self.backNode.layer.animatePosition(from: .zero, to: CGPoint(x: 20.0, y: 0.0), duration: 0.2, additive: true)
|
||||
@ -342,13 +350,15 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
self.contentSubtitleNode.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: 10.0), duration: 0.2, additive: true)
|
||||
self.contentSubtitleNode.layer.animateScale(from: 1.0, to: 0.85, duration: 0.2)
|
||||
|
||||
self.contentGridNode.layer.animatePosition(from: .zero, to: CGPoint(x: 0.0, y: scrollDelta), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
|
||||
|
||||
self.contentGridNode.alpha = 0.0
|
||||
self.contentGridNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, completion: { _ in
|
||||
completion()
|
||||
})
|
||||
|
||||
self.contentGridNode.forEachItemNode { itemNode in
|
||||
itemNode.layer.animatePosition(from: itemNode.position, to: targetFrame.center, duration: 0.45, timingFunction: kCAMediaTimingFunctionSpring)
|
||||
itemNode.layer.animatePosition(from: itemNode.position, to: targetFrame.center, duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring)
|
||||
itemNode.layer.animateScale(from: 1.0, to: 0.2, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
||||
}
|
||||
}
|
||||
@ -412,19 +422,22 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
let rawTitleOffset = -titleAreaHeight - presentationLayout.contentOffset.y
|
||||
let titleOffset = max(-titleAreaHeight, rawTitleOffset)
|
||||
|
||||
let headerFrame = CGRect(origin: CGPoint(x: 0.0, y: titleOffset), size: CGSize(width: size.width, height: 64.0))
|
||||
transition.updateFrame(node: self.headerNode, frame: headerFrame)
|
||||
|
||||
let titleSize = self.contentTitleNode.measure(size)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: titleOffset + 15.0), size: titleSize)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: 15.0), size: titleSize)
|
||||
transition.updateFrame(node: self.contentTitleNode, frame: titleFrame)
|
||||
|
||||
let subtitleSize = self.contentSubtitleNode.measure(CGSize(width: size.width - 44.0 * 2.0 - 8.0 * 2.0, height: titleAreaHeight))
|
||||
let subtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - subtitleSize.width) / 2.0), y: titleOffset + 40.0), size: subtitleSize)
|
||||
let subtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - subtitleSize.width) / 2.0), y: 40.0), size: subtitleSize)
|
||||
var originalSubtitleFrame = self.contentSubtitleNode.frame
|
||||
originalSubtitleFrame.origin.x = subtitleFrame.origin.x
|
||||
originalSubtitleFrame.size = subtitleFrame.size
|
||||
self.contentSubtitleNode.frame = originalSubtitleFrame
|
||||
transition.updateFrame(node: self.contentSubtitleNode, frame: subtitleFrame)
|
||||
|
||||
let backFrame = CGRect(origin: CGPoint(x: 30.0, y: titleOffset + 6.0), size: CGSize(width: 90.0, height: 56.0))
|
||||
let backFrame = CGRect(origin: CGPoint(x: 30.0, y: 6.0), size: CGSize(width: 90.0, height: 56.0))
|
||||
transition.updateFrame(node: self.backNode, frame: backFrame)
|
||||
|
||||
self.contentOffsetUpdated?(presentationLayout.contentOffset.y, actualTransition)
|
||||
|
Loading…
x
Reference in New Issue
Block a user