Fix reactions

This commit is contained in:
peter 2019-08-22 19:18:12 +04:00
parent caa75cbc86
commit 4041715e5b
7 changed files with 48 additions and 28 deletions

View File

@ -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)
} }
} }

View File

@ -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)
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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

View File

@ -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) {

View File

@ -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 {

View File

@ -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)
} }