mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-04 21:41:45 +00:00
Fix reactions
This commit is contained in:
parent
caa75cbc86
commit
4041715e5b
@ -579,7 +579,9 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi
|
|||||||
contentParentNode.updateAbsoluteRect?(absoluteContentRect, layout.size)
|
contentParentNode.updateAbsoluteRect?(absoluteContentRect, layout.size)
|
||||||
|
|
||||||
if let reactionContextNode = self.reactionContextNode {
|
if let reactionContextNode = self.reactionContextNode {
|
||||||
reactionContextNode.updateLayout(size: layout.size, anchorRect: CGRect(origin: CGPoint(x: absoluteContentRect.minX + contentParentNode.contentRect.minX, y: absoluteContentRect.minY + contentParentNode.contentRect.minY), size: contentParentNode.contentRect.size), transition: transition)
|
let insets = layout.insets(options: [.statusBar])
|
||||||
|
transition.updateFrame(node: reactionContextNode, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||||
|
reactionContextNode.updateLayout(size: layout.size, insets: insets, anchorRect: CGRect(origin: CGPoint(x: absoluteContentRect.minX + contentParentNode.contentRect.minX, y: absoluteContentRect.minY + contentParentNode.contentRect.minY), size: contentParentNode.contentRect.size), transition: transition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -120,6 +120,7 @@ public final class TextNodeLayout: NSObject {
|
|||||||
fileprivate let cutout: TextNodeCutout?
|
fileprivate let cutout: TextNodeCutout?
|
||||||
fileprivate let insets: UIEdgeInsets
|
fileprivate let insets: UIEdgeInsets
|
||||||
public let size: CGSize
|
public let size: CGSize
|
||||||
|
public let rawTextSize: CGSize
|
||||||
public let truncated: Bool
|
public let truncated: Bool
|
||||||
fileprivate let firstLineOffset: CGFloat
|
fileprivate let firstLineOffset: CGFloat
|
||||||
fileprivate let lines: [TextNodeLine]
|
fileprivate let lines: [TextNodeLine]
|
||||||
@ -128,7 +129,7 @@ public final class TextNodeLayout: NSObject {
|
|||||||
fileprivate let textShadowColor: UIColor?
|
fileprivate let textShadowColor: UIColor?
|
||||||
public let hasRTL: Bool
|
public let hasRTL: Bool
|
||||||
|
|
||||||
fileprivate init(attributedString: NSAttributedString?, maximumNumberOfLines: Int, truncationType: CTLineTruncationType, constrainedSize: CGSize, alignment: NSTextAlignment, lineSpacing: CGFloat, cutout: TextNodeCutout?, insets: UIEdgeInsets, size: CGSize, truncated: Bool, firstLineOffset: CGFloat, lines: [TextNodeLine], blockQuotes: [TextNodeBlockQuote], backgroundColor: UIColor?, lineColor: UIColor?, textShadowColor: UIColor?) {
|
fileprivate init(attributedString: NSAttributedString?, maximumNumberOfLines: Int, truncationType: CTLineTruncationType, constrainedSize: CGSize, alignment: NSTextAlignment, lineSpacing: CGFloat, cutout: TextNodeCutout?, insets: UIEdgeInsets, size: CGSize, rawTextSize: CGSize, truncated: Bool, firstLineOffset: CGFloat, lines: [TextNodeLine], blockQuotes: [TextNodeBlockQuote], backgroundColor: UIColor?, lineColor: UIColor?, textShadowColor: UIColor?) {
|
||||||
self.attributedString = attributedString
|
self.attributedString = attributedString
|
||||||
self.maximumNumberOfLines = maximumNumberOfLines
|
self.maximumNumberOfLines = maximumNumberOfLines
|
||||||
self.truncationType = truncationType
|
self.truncationType = truncationType
|
||||||
@ -138,6 +139,7 @@ public final class TextNodeLayout: NSObject {
|
|||||||
self.cutout = cutout
|
self.cutout = cutout
|
||||||
self.insets = insets
|
self.insets = insets
|
||||||
self.size = size
|
self.size = size
|
||||||
|
self.rawTextSize = rawTextSize
|
||||||
self.truncated = truncated
|
self.truncated = truncated
|
||||||
self.firstLineOffset = firstLineOffset
|
self.firstLineOffset = firstLineOffset
|
||||||
self.lines = lines
|
self.lines = lines
|
||||||
@ -816,7 +818,7 @@ public class TextNode: ASDisplayNode {
|
|||||||
var maybeTypesetter: CTTypesetter?
|
var maybeTypesetter: CTTypesetter?
|
||||||
maybeTypesetter = CTTypesetterCreateWithAttributedString(attributedString as CFAttributedString)
|
maybeTypesetter = CTTypesetterCreateWithAttributedString(attributedString as CFAttributedString)
|
||||||
if maybeTypesetter == nil {
|
if maybeTypesetter == nil {
|
||||||
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(), truncated: false, firstLineOffset: 0.0, lines: [], blockQuotes: [], backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor)
|
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(), rawTextSize: CGSize(), truncated: false, firstLineOffset: 0.0, lines: [], blockQuotes: [], backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
let typesetter = maybeTypesetter!
|
let typesetter = maybeTypesetter!
|
||||||
@ -997,6 +999,7 @@ public class TextNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let rawLayoutSize = layoutSize
|
||||||
if !lines.isEmpty && bottomCutoutEnabled {
|
if !lines.isEmpty && bottomCutoutEnabled {
|
||||||
let proposedWidth = lines[lines.count - 1].frame.width + bottomCutoutSize.width
|
let proposedWidth = lines[lines.count - 1].frame.width + bottomCutoutSize.width
|
||||||
if proposedWidth > layoutSize.width {
|
if proposedWidth > layoutSize.width {
|
||||||
@ -1008,9 +1011,9 @@ public class TextNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(width: ceil(layoutSize.width) + insets.left + insets.right, height: ceil(layoutSize.height) + insets.top + insets.bottom), truncated: truncated, firstLineOffset: firstLineOffset, lines: lines, blockQuotes: blockQuotes, backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor)
|
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(width: ceil(layoutSize.width) + insets.left + insets.right, height: ceil(layoutSize.height) + insets.top + insets.bottom), rawTextSize: CGSize(width: ceil(rawLayoutSize.width) + insets.left + insets.right, height: ceil(layoutSize.height) + insets.top + insets.bottom), truncated: truncated, firstLineOffset: firstLineOffset, lines: lines, blockQuotes: blockQuotes, backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor)
|
||||||
} else {
|
} else {
|
||||||
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(), truncated: false, firstLineOffset: 0.0, lines: [], blockQuotes: [], backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor)
|
return TextNodeLayout(attributedString: attributedString, maximumNumberOfLines: maximumNumberOfLines, truncationType: truncationType, constrainedSize: constrainedSize, alignment: alignment, lineSpacing: lineSpacingFactor, cutout: cutout, insets: insets, size: CGSize(), rawTextSize: CGSize(), truncated: false, firstLineOffset: 0.0, lines: [], blockQuotes: [], backgroundColor: backgroundColor, lineColor: lineColor, textShadowColor: textShadowColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -90,7 +90,7 @@ public final class ReactionContextNode: ASDisplayNode {
|
|||||||
|
|
||||||
private var isExpanded: Bool = false
|
private var isExpanded: Bool = false
|
||||||
private var highlightedReaction: String?
|
private var highlightedReaction: String?
|
||||||
private var validLayout: (CGSize, CGRect)?
|
private var validLayout: (CGSize, UIEdgeInsets, CGRect)?
|
||||||
|
|
||||||
public var reactionSelected: ((ReactionGestureItem) -> Void)?
|
public var reactionSelected: ((ReactionGestureItem) -> Void)?
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ public final class ReactionContextNode: ASDisplayNode {
|
|||||||
self.addSubnode(self.backgroundContainerNode)
|
self.addSubnode(self.backgroundContainerNode)
|
||||||
|
|
||||||
self.itemNodes = self.items.map { item in
|
self.itemNodes = self.items.map { item in
|
||||||
return ReactionNode(account: account, theme: theme, reaction: .reaction(value: item.value, text: item.text, path: item.path), maximizedReactionSize: 30.0 - 18.0, loadFirstFrame: false)
|
return ReactionNode(account: account, theme: theme, reaction: .reaction(value: item.value, text: item.text, path: item.path), maximizedReactionSize: 30.0 - 18.0, loadFirstFrame: true)
|
||||||
}
|
}
|
||||||
self.itemNodes.forEach(self.addSubnode)
|
self.itemNodes.forEach(self.addSubnode)
|
||||||
}
|
}
|
||||||
@ -162,11 +162,11 @@ public final class ReactionContextNode: ASDisplayNode {
|
|||||||
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
|
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateLayout(size: CGSize, anchorRect: CGRect, transition: ContainedViewLayoutTransition) {
|
public func updateLayout(size: CGSize, insets: UIEdgeInsets, anchorRect: CGRect, transition: ContainedViewLayoutTransition) {
|
||||||
self.updateLayout(size: size, anchorRect: anchorRect, transition: transition, animateInFromAnchorRect: nil, animateOutToAnchorRect: nil)
|
self.updateLayout(size: size, insets: insets, anchorRect: anchorRect, transition: transition, animateInFromAnchorRect: nil, animateOutToAnchorRect: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func calculateBackgroundFrame(containerSize: CGSize, anchorRect: CGRect, contentSize: CGSize) -> (CGRect, Bool) {
|
private func calculateBackgroundFrame(containerSize: CGSize, insets: UIEdgeInsets, anchorRect: CGRect, contentSize: CGSize) -> (CGRect, Bool) {
|
||||||
let sideInset: CGFloat = 12.0
|
let sideInset: CGFloat = 12.0
|
||||||
let backgroundOffset: CGPoint = CGPoint(x: 22.0, y: -7.0)
|
let backgroundOffset: CGPoint = CGPoint(x: 22.0, y: -7.0)
|
||||||
|
|
||||||
@ -180,13 +180,13 @@ public final class ReactionContextNode: ASDisplayNode {
|
|||||||
isLeftAligned = false
|
isLeftAligned = false
|
||||||
}
|
}
|
||||||
rect.origin.x = max(sideInset, rect.origin.x)
|
rect.origin.x = max(sideInset, rect.origin.x)
|
||||||
rect.origin.y = max(sideInset, rect.origin.y)
|
rect.origin.y = max(insets.top + sideInset, rect.origin.y)
|
||||||
rect.origin.x = min(containerSize.width - contentSize.width - sideInset, rect.origin.x)
|
rect.origin.x = min(containerSize.width - contentSize.width - sideInset, rect.origin.x)
|
||||||
return (rect, isLeftAligned)
|
return (rect, isLeftAligned)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateLayout(size: CGSize, anchorRect: CGRect, transition: ContainedViewLayoutTransition, animateInFromAnchorRect: CGRect?, animateOutToAnchorRect: CGRect?, animateReactionHighlight: Bool = false) {
|
private func updateLayout(size: CGSize, insets: UIEdgeInsets, anchorRect: CGRect, transition: ContainedViewLayoutTransition, animateInFromAnchorRect: CGRect?, animateOutToAnchorRect: CGRect?, animateReactionHighlight: Bool = false) {
|
||||||
self.validLayout = (size, anchorRect)
|
self.validLayout = (size, insets, anchorRect)
|
||||||
|
|
||||||
let sideInset: CGFloat = 10.0
|
let sideInset: CGFloat = 10.0
|
||||||
let itemSpacing: CGFloat = 6.0
|
let itemSpacing: CGFloat = 6.0
|
||||||
@ -200,7 +200,7 @@ public final class ReactionContextNode: ASDisplayNode {
|
|||||||
let rowCount = self.items.count / columnCount + (self.items.count % columnCount == 0 ? 0 : 1)
|
let rowCount = self.items.count / columnCount + (self.items.count % columnCount == 0 ? 0 : 1)
|
||||||
let contentHeight = rowHeight * CGFloat(rowCount)
|
let contentHeight = rowHeight * CGFloat(rowCount)
|
||||||
|
|
||||||
let (backgroundFrame, isLeftAligned) = self.calculateBackgroundFrame(containerSize: size, anchorRect: anchorRect, contentSize: CGSize(width: contentWidth, height: contentHeight))
|
let (backgroundFrame, isLeftAligned) = self.calculateBackgroundFrame(containerSize: size, insets: insets, anchorRect: anchorRect, contentSize: CGSize(width: contentWidth, height: contentHeight))
|
||||||
|
|
||||||
for i in 0 ..< self.items.count {
|
for i in 0 ..< self.items.count {
|
||||||
let row = CGFloat(i / columnCount)
|
let row = CGFloat(i / columnCount)
|
||||||
@ -226,7 +226,7 @@ public final class ReactionContextNode: ASDisplayNode {
|
|||||||
|
|
||||||
transition.updateFrame(node: self.itemNodes[i], frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + sideInset + column * (minimizedItemSize + itemSpacing) - itemOffset, y: backgroundFrame.minY + row * rowHeight + floor((rowHeight - minimizedItemSize) / 2.0) - itemOffset), size: CGSize(width: itemSize, height: itemSize)), beginWithCurrentState: true)
|
transition.updateFrame(node: self.itemNodes[i], frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + sideInset + column * (minimizedItemSize + itemSpacing) - itemOffset, y: backgroundFrame.minY + row * rowHeight + floor((rowHeight - minimizedItemSize) / 2.0) - itemOffset), size: CGSize(width: itemSize, height: itemSize)), beginWithCurrentState: true)
|
||||||
self.itemNodes[i].updateLayout(size: CGSize(width: itemSize, height: itemSize), scale: itemSize / (maximizedItemSize + 18.0), transition: transition, displayText: false)
|
self.itemNodes[i].updateLayout(size: CGSize(width: itemSize, height: itemSize), scale: itemSize / (maximizedItemSize + 18.0), transition: transition, displayText: false)
|
||||||
self.itemNodes[i].updateIsAnimating(true, animated: false)
|
self.itemNodes[i].updateIsAnimating(false, animated: false)
|
||||||
if row != 0 {
|
if row != 0 {
|
||||||
if self.isExpanded {
|
if self.isExpanded {
|
||||||
self.itemNodes[i].alpha = 1.0
|
self.itemNodes[i].alpha = 1.0
|
||||||
@ -270,11 +270,11 @@ public final class ReactionContextNode: ASDisplayNode {
|
|||||||
let springDuration: Double = 0.42
|
let springDuration: Double = 0.42
|
||||||
let springDamping: CGFloat = 104.0
|
let springDamping: CGFloat = 104.0
|
||||||
|
|
||||||
let sourceBackgroundFrame = self.calculateBackgroundFrame(containerSize: size, anchorRect: animateInFromAnchorRect, contentSize: CGSize(width: contentWidth, height: contentHeight)).0
|
let sourceBackgroundFrame = self.calculateBackgroundFrame(containerSize: size, insets: insets, anchorRect: animateInFromAnchorRect, contentSize: CGSize(width: contentWidth, height: contentHeight)).0
|
||||||
|
|
||||||
self.layer.animateSpring(from: NSValue(cgPoint: CGPoint(x: sourceBackgroundFrame.minX - backgroundFrame.minX, y: sourceBackgroundFrame.minY - backgroundFrame.minY)), to: NSValue(cgPoint: CGPoint()), keyPath: "position", duration: springDuration, initialVelocity: 0.0, damping: springDamping, additive: true)
|
self.layer.animateSpring(from: NSValue(cgPoint: CGPoint(x: sourceBackgroundFrame.minX - backgroundFrame.minX, y: sourceBackgroundFrame.minY - backgroundFrame.minY)), to: NSValue(cgPoint: CGPoint()), keyPath: "position", duration: springDuration, initialVelocity: 0.0, damping: springDamping, additive: true)
|
||||||
} else if let animateOutToAnchorRect = animateOutToAnchorRect {
|
} else if let animateOutToAnchorRect = animateOutToAnchorRect {
|
||||||
let targetBackgroundFrame = self.calculateBackgroundFrame(containerSize: size, anchorRect: animateOutToAnchorRect, contentSize: CGSize(width: contentWidth, height: contentHeight)).0
|
let targetBackgroundFrame = self.calculateBackgroundFrame(containerSize: size, insets: insets, anchorRect: animateOutToAnchorRect, contentSize: CGSize(width: contentWidth, height: contentHeight)).0
|
||||||
|
|
||||||
self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: targetBackgroundFrame.minX - backgroundFrame.minX, y: targetBackgroundFrame.minY - backgroundFrame.minY), duration: 0.2, removeOnCompletion: false, additive: true)
|
self.layer.animatePosition(from: CGPoint(), to: CGPoint(x: targetBackgroundFrame.minX - backgroundFrame.minX, y: targetBackgroundFrame.minY - backgroundFrame.minY), duration: 0.2, removeOnCompletion: false, additive: true)
|
||||||
}
|
}
|
||||||
@ -283,8 +283,8 @@ public final class ReactionContextNode: ASDisplayNode {
|
|||||||
public func animateIn(from sourceAnchorRect: CGRect) {
|
public func animateIn(from sourceAnchorRect: CGRect) {
|
||||||
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
|
|
||||||
if let (size, anchorRect) = self.validLayout {
|
if let (size, insets, anchorRect) = self.validLayout {
|
||||||
self.updateLayout(size: size, anchorRect: anchorRect, transition: .immediate, animateInFromAnchorRect: sourceAnchorRect, animateOutToAnchorRect: nil)
|
self.updateLayout(size: size, insets: insets, anchorRect: anchorRect, transition: .immediate, animateInFromAnchorRect: sourceAnchorRect, animateOutToAnchorRect: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,8 +299,8 @@ public final class ReactionContextNode: ASDisplayNode {
|
|||||||
itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false)
|
itemNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let targetAnchorRect = targetAnchorRect, let (size, anchorRect) = self.validLayout {
|
if let targetAnchorRect = targetAnchorRect, let (size, insets, anchorRect) = self.validLayout {
|
||||||
self.updateLayout(size: size, anchorRect: anchorRect, transition: .immediate, animateInFromAnchorRect: nil, animateOutToAnchorRect: targetAnchorRect)
|
self.updateLayout(size: size, insets: insets, anchorRect: anchorRect, transition: .immediate, animateInFromAnchorRect: nil, animateOutToAnchorRect: targetAnchorRect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,8 +416,8 @@ public final class ReactionContextNode: ASDisplayNode {
|
|||||||
|
|
||||||
public func setHighlightedReaction(_ value: String?) {
|
public func setHighlightedReaction(_ value: String?) {
|
||||||
self.highlightedReaction = value
|
self.highlightedReaction = value
|
||||||
if let (size, anchorRect) = self.validLayout {
|
if let (size, insets, anchorRect) = self.validLayout {
|
||||||
self.updateLayout(size: size, anchorRect: anchorRect, transition: .animated(duration: 0.18, curve: .easeInOut), animateInFromAnchorRect: nil, animateOutToAnchorRect: nil, animateReactionHighlight: true)
|
self.updateLayout(size: size, insets: insets, anchorRect: anchorRect, transition: .animated(duration: 0.18, curve: .easeInOut), animateInFromAnchorRect: nil, animateOutToAnchorRect: nil, animateReactionHighlight: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -208,6 +208,11 @@ final class ReactionSelectionNode: ASDisplayNode {
|
|||||||
func updateLayout(constrainedSize: CGSize, startingPoint: CGPoint, offsetFromStart: CGFloat, isInitial: Bool) {
|
func updateLayout(constrainedSize: CGSize, startingPoint: CGPoint, offsetFromStart: CGFloat, isInitial: Bool) {
|
||||||
let initialAnchorX = startingPoint.x
|
let initialAnchorX = startingPoint.x
|
||||||
|
|
||||||
|
var isRightAligned = false
|
||||||
|
if initialAnchorX > constrainedSize.width / 2.0 {
|
||||||
|
isRightAligned = true
|
||||||
|
}
|
||||||
|
|
||||||
if isInitial && self.reactionNodes.isEmpty {
|
if isInitial && self.reactionNodes.isEmpty {
|
||||||
let availableContentWidth = constrainedSize.width //max(100.0, initialAnchorX)
|
let availableContentWidth = constrainedSize.width //max(100.0, initialAnchorX)
|
||||||
var minimizedReactionSize = (availableContentWidth - self.maximizedReactionSize) / (CGFloat(self.reactions.count - 1) + CGFloat(self.reactions.count + 1) * 0.2)
|
var minimizedReactionSize = (availableContentWidth - self.maximizedReactionSize) / (CGFloat(self.reactions.count - 1) + CGFloat(self.reactions.count + 1) * 0.2)
|
||||||
@ -241,13 +246,13 @@ final class ReactionSelectionNode: ASDisplayNode {
|
|||||||
let contentWidth: CGFloat = CGFloat(self.reactionNodes.count - 1) * (minimizedReactionSize) + maximizedReactionSize + CGFloat(self.reactionNodes.count + 1) * reactionSpacing
|
let contentWidth: CGFloat = CGFloat(self.reactionNodes.count - 1) * (minimizedReactionSize) + maximizedReactionSize + CGFloat(self.reactionNodes.count + 1) * reactionSpacing
|
||||||
|
|
||||||
var backgroundFrame = CGRect(origin: CGPoint(x: -shadowBlur, y: -shadowBlur), size: CGSize(width: contentWidth + shadowBlur * 2.0, height: backgroundHeight + shadowBlur * 2.0))
|
var backgroundFrame = CGRect(origin: CGPoint(x: -shadowBlur, y: -shadowBlur), size: CGSize(width: contentWidth + shadowBlur * 2.0, height: backgroundHeight + shadowBlur * 2.0))
|
||||||
var isRightAligned = false
|
if isRightAligned {
|
||||||
if initialAnchorX > constrainedSize.width / 2.0 {
|
|
||||||
isRightAligned = true
|
|
||||||
backgroundFrame = backgroundFrame.offsetBy(dx: initialAnchorX - contentWidth + backgroundHeight / 2.0, dy: startingPoint.y - backgroundHeight - 16.0)
|
backgroundFrame = backgroundFrame.offsetBy(dx: initialAnchorX - contentWidth + backgroundHeight / 2.0, dy: startingPoint.y - backgroundHeight - 16.0)
|
||||||
} else {
|
} else {
|
||||||
backgroundFrame = backgroundFrame.offsetBy(dx: initialAnchorX - backgroundHeight / 2.0, dy: startingPoint.y - backgroundHeight - 16.0)
|
backgroundFrame = backgroundFrame.offsetBy(dx: initialAnchorX - backgroundHeight / 2.0, dy: startingPoint.y - backgroundHeight - 16.0)
|
||||||
}
|
}
|
||||||
|
backgroundFrame.origin.x = max(0.0, backgroundFrame.minX)
|
||||||
|
backgroundFrame.origin.x = min(constrainedSize.width - backgroundFrame.width, backgroundFrame.minX)
|
||||||
|
|
||||||
self.isRightAligned = isRightAligned
|
self.isRightAligned = isRightAligned
|
||||||
self.backgroundNode.frame = backgroundFrame
|
self.backgroundNode.frame = backgroundFrame
|
||||||
|
|||||||
@ -213,7 +213,6 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
self.historyNodeContainer.addSubnode(self.historyNode)
|
self.historyNodeContainer.addSubnode(self.historyNode)
|
||||||
|
|
||||||
self.reactionContainerNode = ReactionSelectionParentNode(account: context.account, theme: chatPresentationInterfaceState.theme)
|
self.reactionContainerNode = ReactionSelectionParentNode(account: context.account, theme: chatPresentationInterfaceState.theme)
|
||||||
self.historyNodeContainer.addSubnode(self.reactionContainerNode)
|
|
||||||
|
|
||||||
self.loadingNode = ChatLoadingNode(theme: self.chatPresentationInterfaceState.theme, chatWallpaper: self.chatPresentationInterfaceState.chatWallpaper)
|
self.loadingNode = ChatLoadingNode(theme: self.chatPresentationInterfaceState.theme, chatWallpaper: self.chatPresentationInterfaceState.chatWallpaper)
|
||||||
|
|
||||||
@ -1447,6 +1446,10 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.reactionContainerNode.supernode == nil {
|
||||||
|
self.addSubnode(self.reactionContainerNode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateAutomaticMediaDownloadSettings(_ settings: MediaAutoDownloadSettings) {
|
func updateAutomaticMediaDownloadSettings(_ settings: MediaAutoDownloadSettings) {
|
||||||
|
|||||||
@ -596,7 +596,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
let lineImage = incoming ? PresentationResourcesChat.chatBubbleVerticalLineIncomingImage(presentationData.theme.theme) : PresentationResourcesChat.chatBubbleVerticalLineOutgoingImage(presentationData.theme.theme)
|
let lineImage = incoming ? PresentationResourcesChat.chatBubbleVerticalLineIncomingImage(presentationData.theme.theme) : PresentationResourcesChat.chatBubbleVerticalLineOutgoingImage(presentationData.theme.theme)
|
||||||
|
|
||||||
var boundingSize = textFrame.size
|
var boundingSize = textFrame.size
|
||||||
var lineHeight = textFrame.size.height
|
var lineHeight = textLayout.rawTextSize.height
|
||||||
if let statusFrame = statusFrame {
|
if let statusFrame = statusFrame {
|
||||||
boundingSize = textFrame.union(statusFrame).size
|
boundingSize = textFrame.union(statusFrame).size
|
||||||
if let _ = actionTitle {
|
if let _ = actionTitle {
|
||||||
|
|||||||
@ -158,6 +158,13 @@ private func chatMessageGalleryControllerData(context: AccountContext, message:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if internalDocumentItemSupportsMimeType(file.mimeType, fileName: file.fileName ?? "file") {
|
||||||
|
let gallery = GalleryController(context: context, source: .peerMessagesAtId(message.id), invertItemOrder: reverseMessageGalleryOrder, streamSingleVideo: stream, fromPlayingVideo: autoplayingVideo, landscape: landscape, timecode: timecode, synchronousLoad: synchronousLoad, replaceRootController: { [weak navigationController] controller, ready in
|
||||||
|
navigationController?.replaceTopController(controller, animated: false, ready: ready)
|
||||||
|
}, baseNavigationController: navigationController, actionInteraction: actionInteraction)
|
||||||
|
return .gallery(gallery)
|
||||||
|
}
|
||||||
|
|
||||||
if !file.isVideo {
|
if !file.isVideo {
|
||||||
return .document(file)
|
return .document(file)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user