From c0643cbd9774b71a62870ea974fedadbc61b06fe Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Tue, 22 Oct 2019 09:29:40 +0400 Subject: [PATCH] Wallet fixes --- .../ChatMessageSelectionInputPanelNode.swift | 5 - .../WalletUI/Sources/WalletInfoScreen.swift | 22 +- .../Sources/WalletReceiveScreen.swift | 18 +- .../Sources/WalletTransactionInfoScreen.swift | 210 ++++++++++++------ 4 files changed, 167 insertions(+), 88 deletions(-) diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageSelectionInputPanelNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageSelectionInputPanelNode.swift index 352b2e8e15..7266c79424 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageSelectionInputPanelNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageSelectionInputPanelNode.swift @@ -148,9 +148,6 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { self.deleteButton.isHidden = !self.deleteButton.isEnabled self.reportButton.isHidden = !self.reportButton.isEnabled - - self.deleteButton.isHidden = false - self.deleteButton.isEnabled = true } else { self.deleteButton.isEnabled = false self.deleteButton.isHidden = true @@ -158,8 +155,6 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode { self.reportButton.isHidden = true self.forwardButton.isEnabled = false self.shareButton.isEnabled = false - - self.deleteButton.isHidden = false } if self.deleteButton.isHidden && self.reportButton.isHidden { diff --git a/submodules/WalletUI/Sources/WalletInfoScreen.swift b/submodules/WalletUI/Sources/WalletInfoScreen.swift index 1582178fc8..7357a200be 100644 --- a/submodules/WalletUI/Sources/WalletInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletInfoScreen.swift @@ -135,24 +135,24 @@ public final class WalletInfoScreen: ViewController { } } -private final class WalletInfoBalanceNode: ASDisplayNode { +final class WalletInfoBalanceNode: ASDisplayNode { let dateTimeFormat: WalletPresentationDateTimeFormat let balanceIntegralTextNode: ImmediateTextNode let balanceFractionalTextNode: ImmediateTextNode let balanceIconNode: AnimatedStickerNode - var balance: String = " " { + var balance: (String, UIColor) = (" ", .white) { didSet { let integralString = NSMutableAttributedString() let fractionalString = NSMutableAttributedString() - if let range = self.balance.range(of: self.dateTimeFormat.decimalSeparator) { - let integralPart = String(self.balance[.. Void, receiveAction: @escaping () -> Void) { self.hasActions = hasActions - self.balanceNode = WalletInfoBalanceNode(theme: presentationData.theme, dateTimeFormat: presentationData.dateTimeFormat) + self.balanceNode = WalletInfoBalanceNode(dateTimeFormat: presentationData.dateTimeFormat) self.balanceSubtitleNode = ImmediateTextNode() self.balanceSubtitleNode.displaysAsynchronously = false @@ -856,7 +856,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { private func updateCombinedState(combinedState: CombinedWalletState?, isUpdated: Bool) { self.combinedState = combinedState if let combinedState = combinedState { - self.headerNode.balanceNode.balance = formatBalanceText(max(0, combinedState.walletState.balance), decimalSeparator: self.presentationData.dateTimeFormat.decimalSeparator) + self.headerNode.balanceNode.balance = (formatBalanceText(max(0, combinedState.walletState.balance), decimalSeparator: self.presentationData.dateTimeFormat.decimalSeparator), .white) self.headerNode.balance = max(0, combinedState.walletState.balance) if self.isReady, let (layout, navigationHeight) = self.validLayout { diff --git a/submodules/WalletUI/Sources/WalletReceiveScreen.swift b/submodules/WalletUI/Sources/WalletReceiveScreen.swift index a39308aac3..9b98be4e05 100644 --- a/submodules/WalletUI/Sources/WalletReceiveScreen.swift +++ b/submodules/WalletUI/Sources/WalletReceiveScreen.swift @@ -306,15 +306,25 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode { if case .receive = self.mode { url = url + "?" } - let count = min(url.count / 2, Int(ceil(min(layout.size.width, layout.size.height) * 0.0853))) + + let addressFont: UIFont + let countRatio: CGFloat + if layout.size.width == 320.0 { + addressFont = Font.monospace(16.0) + countRatio = 0.0999 + } else { + addressFont = Font.monospace(17.0) + countRatio = 0.0853 + } + let count = min(url.count / 2, Int(ceil(min(layout.size.width, layout.size.height) * countRatio))) let sliced = String(url.enumerated().map { $0 > 0 && $0 % count == 0 ? ["\n", $1] : [$1]}.joined()) - let addressFont = Font.monospace(17.0) self.urlTextNode.attributedText = NSAttributedString(string: sliced, font: addressFont, textColor: self.presentationData.theme.list.itemPrimaryTextColor, paragraphAlignment: .justified) } - let urlTextSize = self.urlTextNode.updateLayout(CGSize(width: layout.size.width - inset * 2.0, height: CGFloat.greatestFiniteMagnitude)) - transition.updateFrame(node: self.urlTextNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - urlTextSize.width) / 2.0), y: imageFrame.maxY + 25.0), size: urlTextSize)) + let addressInset: CGFloat = 12.0 + let urlTextSize = self.urlTextNode.updateLayout(CGSize(width: layout.size.width - addressInset * 2.0, height: CGFloat.greatestFiniteMagnitude)) + transition.updateFrame(node: self.urlTextNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - urlTextSize.width) / 2.0), y: imageFrame.maxY + 23.0), size: urlTextSize)) let buttonSideInset: CGFloat = 16.0 let bottomInset = insets.bottom + 10.0 diff --git a/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift b/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift index 504af8c5c4..d2649670a4 100644 --- a/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift @@ -235,16 +235,35 @@ final class WalletTransactionInfoScreen: ViewController { private let measureTextNode = TextNode() override func preferredContentSizeForLayout(_ layout: ContainerViewLayout) -> CGSize? { + let insets = layout.insets(options: []) + + let minHeight: CGFloat = 424.0 + let maxHeight: CGFloat = min(596.0, layout.size.height) + let text = NSAttributedString(string: extractDescription(self.walletTransaction), font: Font.regular(17.0), textColor: .black) let makeTextLayout = TextNode.asyncLayout(self.measureTextNode) let (textLayout, _) = makeTextLayout(TextNodeLayoutArguments(attributedString: text, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: layout.size.width - 36.0 * 2.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - var textHeight = textLayout.size.height - if textHeight > 0.0 { - textHeight += 24.0 - } - let insets = layout.insets(options: []) - return CGSize(width: layout.size.width, height: min(min(720.0, layout.size.height), 428.0 + insets.bottom + textHeight)) + var resultHeight = minHeight + if textLayout.size.height > 0.0 { + let textHeight = textLayout.size.height + 24.0 + let minOverscroll: CGFloat = 42.0 + let maxOverscroll: CGFloat = 148.0 + + let contentHeight = minHeight + textHeight + let difference = contentHeight - maxHeight + if difference < 0.0 { + resultHeight = contentHeight + } else if difference > maxOverscroll { + resultHeight = maxHeight + } else if difference > minOverscroll { + resultHeight = maxHeight - (maxOverscroll - difference) + } else { + resultHeight = maxHeight - (minOverscroll - difference) + } + } + + return CGSize(width: layout.size.width, height: resultHeight + insets.bottom) } override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { @@ -258,7 +277,7 @@ final class WalletTransactionInfoScreen: ViewController { } } -private let integralFont = Font.medium(48.0) +private let amountFont = Font.medium(48.0) private let fractionalFont = Font.medium(24.0) private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate { @@ -266,29 +285,25 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, private var presentationData: WalletPresentationData private let walletTransaction: WalletInfoTransaction private let incoming: Bool - + private let titleNode: ImmediateTextNode private let timeNode: ImmediateTextNode - private let navigationBackgroundNode: ASDisplayNode private let navigationSeparatorNode: ASDisplayNode - private let scrollNode: ASScrollNode - private let amountNode: ImmediateTextNode - private let iconNode: AnimatedStickerNode + private let amountNode: WalletInfoBalanceNode private let activateArea: AccessibilityAreaNode private let feesNode: ImmediateTextNode private let feesInfoIconNode: ASImageNode private let feesButtonNode: ASButtonNode - private let commentBackgroundNode: ASImageNode private let commentTextNode: ImmediateTextNode private let commentSeparatorNode: ASDisplayNode - private let addressTextNode: ImmediateTextNode - private let buttonNode: SolidRoundedButtonNode + private var validLayout: (ContainerViewLayout, CGFloat)? + var send: ((String) -> Void)? var displayFeesTooltip: ((ASDisplayNode, CGRect) -> Void)? var displayCopyContextMenu: ((ASDisplayNode, CGRect, String) -> Void)? @@ -311,19 +326,10 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, self.navigationBackgroundNode.alpha = 0.0 self.navigationSeparatorNode = ASDisplayNode() self.navigationSeparatorNode.backgroundColor = self.presentationData.theme.navigationBar.separatorColor - self.navigationSeparatorNode.alpha = 0.0 self.scrollNode = ASScrollNode() - self.amountNode = ImmediateTextNode() - self.amountNode.textAlignment = .center - self.amountNode.maximumNumberOfLines = 1 - - self.iconNode = AnimatedStickerNode() - if let path = getAppBundle().path(forResource: "WalletIntroStatic", ofType: "tgs") { - self.iconNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 120, height: 120, mode: .direct) - self.iconNode.visibility = true - } + self.amountNode = WalletInfoBalanceNode(dateTimeFormat: presentationData.dateTimeFormat) self.feesNode = ImmediateTextNode() self.feesNode.textAlignment = .center @@ -374,18 +380,17 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor - self.addSubnode(self.navigationBackgroundNode) - self.addSubnode(self.navigationSeparatorNode) - self.addSubnode(self.titleNode) - self.addSubnode(self.timeNode) - self.addSubnode(self.amountNode) - self.addSubnode(self.iconNode) + self.addSubnode(self.scrollNode) self.addSubnode(self.feesNode) self.addSubnode(self.feesInfoIconNode) self.addSubnode(self.feesButtonNode) - self.addSubnode(self.scrollNode) self.scrollNode.addSubnode(self.commentBackgroundNode) self.scrollNode.addSubnode(self.commentTextNode) + self.addSubnode(self.navigationBackgroundNode) + self.navigationBackgroundNode.addSubnode(self.navigationSeparatorNode) + self.addSubnode(self.titleNode) + self.addSubnode(self.timeNode) + self.addSubnode(self.amountNode) self.addSubnode(self.commentSeparatorNode) self.addSubnode(self.addressTextNode) self.addSubnode(self.buttonNode) @@ -399,7 +404,7 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, self.titleNode.attributedText = NSAttributedString(string: self.presentationData.strings.Wallet_TransactionInfo_Title, font: titleFont, textColor: textColor) self.timeNode.attributedText = NSAttributedString(string: stringForFullDate(timestamp: Int32(clamping: timestamp), strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat), font: subtitleFont, textColor: seccondaryTextColor) - + let amountString: String let amountColor: UIColor if transferredValue <= 0 { @@ -409,8 +414,8 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, amountString = "\(formatBalanceText(transferredValue, decimalSeparator: self.presentationData.dateTimeFormat.decimalSeparator))" amountColor = self.presentationData.theme.info.incomingFundsTitleColor } - self.amountNode.attributedText = amountAttributedString(amountString, integralFont: integralFont, fractionalFont: fractionalFont, color: amountColor) - + self.amountNode.balance = (amountString, amountColor) + var feesString: String = "" if case let .completed(transaction) = walletTransaction { if transaction.storageFee != 0 { @@ -455,6 +460,10 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, override func didLoad() { super.didLoad() + self.scrollNode.view.delegate = self + self.scrollNode.view.alwaysBounceVertical = true + self.scrollNode.view.showsVerticalScrollIndicator = false + let commentGestureRecognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapCommentGesture(_:))) commentGestureRecognizer.tapActionAtPoint = { [weak self] point in return .waitForSingleTap @@ -476,7 +485,7 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, case .longTap: let description = extractDescription(self.walletTransaction) if !description.isEmpty { - self.displayCopyContextMenu?(self, self.commentBackgroundNode.frame, description) + self.displayCopyContextMenu?(self, self.commentBackgroundNode.convert(self.commentBackgroundNode.bounds, to: self), description) } default: break @@ -500,7 +509,7 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, } if let address = singleAddress { - self.displayCopyContextMenu?(self, self.addressTextNode.frame, address) + self.displayCopyContextMenu?(self, self.addressTextNode.convert(self.addressTextNode.bounds, to: self), address) } default: break @@ -516,51 +525,107 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, } func scrollViewDidScroll(_ scrollView: UIScrollView) { - self.updateTitle() + self.updateTitle(transition: .immediate) } - private func updateTitle() { + private func updateTitle(transition: ContainedViewLayoutTransition) { + guard let (layout, navigationHeight) = self.validLayout else { + return + } + let width = layout.size.width + let sideInset: CGFloat = 16.0 + + let minOffset = navigationHeight + let maxOffset: CGFloat = 200.0 + + let nominalFeesHeight: CGFloat = 42.0 + let minHeaderOffset = minOffset + let maxHeaderOffset = (minOffset + maxOffset) / 2.0 + let maxHeaderPositionOffset = maxOffset - nominalFeesHeight + + let offset: CGFloat = max(0.0, maxOffset - self.scrollNode.view.contentOffset.y) + let effectiveOffset = max(offset, navigationHeight) + + let minFeesOffset = maxOffset - nominalFeesHeight + let maxFeesOffset = maxOffset + let feesTransition: CGFloat = max(0.0, min(1.0, (effectiveOffset - minFeesOffset) / (maxFeesOffset - minFeesOffset))) + let feesAlpha: CGFloat = feesTransition + transition.updateAlpha(node: self.feesNode, alpha: feesAlpha) + + let headerScaleTransition: CGFloat = max(0.0, min(1.0, (effectiveOffset - minHeaderOffset) / (maxHeaderOffset - minHeaderOffset))) + let balanceHeight = self.amountNode.update(width: width, scaleTransition: headerScaleTransition, transition: transition) + let balanceSize = CGSize(width: width, height: balanceHeight) + + let maxHeaderScale: CGFloat = min(1.0, (width - 40.0) / balanceSize.width) + let minHeaderScale: CGFloat = min(0.435, (width - 80.0 * 2.0) / balanceSize.width) + + let minHeaderHeight: CGFloat = balanceSize.height + + let minHeaderY = floor((navigationHeight - minHeaderHeight) / 2.0) + let maxHeaderY: CGFloat = 90.0 + let headerPositionTransition: CGFloat = min(1.0, max(0.0, (effectiveOffset - minHeaderOffset) / (maxHeaderPositionOffset - minHeaderOffset))) + let headerY = headerPositionTransition * maxHeaderY + (1.0 - headerPositionTransition) * minHeaderY + let headerScale = headerScaleTransition * maxHeaderScale + (1.0 - headerScaleTransition) * minHeaderScale + + let balanceFrame = CGRect(origin: CGPoint(x: 0.0, y: headerY), size: balanceSize) + transition.updateFrame(node: self.amountNode, frame: balanceFrame) + transition.updateSublayerTransformScale(node: self.amountNode, scale: headerScale) + + let feesSize = self.feesNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude)) + let feesFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - feesSize.width) / 2.0), y: headerY + 64.0), size: feesSize) + transition.updateFrame(node: self.feesNode, frame: feesFrame) + transition.updateFrame(node: self.feesButtonNode, frame: feesFrame) + self.feesButtonNode.isUserInteractionEnabled = feesAlpha > 1.0 - CGFloat.ulpOfOne + + let minTitleOffset = minOffset + let maxTitleOffset = (minOffset + maxOffset) / 2.0 + let titleTransition: CGFloat = max(0.0, min(1.0, (effectiveOffset - minTitleOffset) / (maxTitleOffset - minTitleOffset))) + let titleAlpha: CGFloat = titleTransition * titleTransition + transition.updateAlpha(node: self.titleNode, alpha: titleAlpha) + transition.updateAlpha(node: self.timeNode, alpha: titleAlpha) + + let minTitleY: CGFloat = -44.0 + let maxTitleY: CGFloat = 10.0 + let titleY: CGFloat = titleTransition * maxTitleY + (1.0 - titleTransition) * minTitleY + let titleSize = self.titleNode.updateLayout(CGSize(width: width - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude)) + let titleFrame = CGRect(origin: CGPoint(x: floor((width - titleSize.width) / 2.0), y: titleY), size: titleSize) + transition.updateFrame(node: self.titleNode, frame: titleFrame) + let subtitleSize = self.timeNode.updateLayout(CGSize(width: width - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude)) + let subtitleFrame = CGRect(origin: CGPoint(x: floor((width - subtitleSize.width) / 2.0), y: titleFrame.maxY + 1.0), size: subtitleSize) + transition.updateFrame(node: self.timeNode, frame: subtitleFrame) + + let alphaTransition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .easeInOut) + let navigationAlpha: CGFloat = (headerScaleTransition <= 0.0 + CGFloat.ulpOfOne) ? 1.0 : 0.0 + if self.navigationBackgroundNode.alpha != navigationAlpha { + alphaTransition.updateAlpha(node: self.navigationBackgroundNode, alpha: navigationAlpha, beginWithCurrentState: true) + } + + let separatorAlpha: CGFloat = self.scrollNode.view.contentOffset.y + self.scrollNode.frame.height >= self.scrollNode.view.contentSize.height ? 0.0 : 1.0 + if self.commentSeparatorNode.alpha != separatorAlpha { + alphaTransition.updateAlpha(node: self.commentSeparatorNode, alpha: separatorAlpha, beginWithCurrentState: true) + } } func containerLayoutUpdated(layout: ContainerViewLayout, navigationHeight: CGFloat, transition: ContainedViewLayoutTransition) { + self.validLayout = (layout, navigationHeight) + var insets = layout.insets(options: []) insets.top += navigationHeight - let inset: CGFloat = 22.0 - - let titleSize = self.titleNode.updateLayout(CGSize(width: layout.size.width - inset * 2.0, height: CGFloat.greatestFiniteMagnitude)) - let titleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: 10.0), size: titleSize) - transition.updateFrame(node: self.titleNode, frame: titleFrame) - - let subtitleSize = self.timeNode.updateLayout(CGSize(width: layout.size.width - inset * 2.0, height: CGFloat.greatestFiniteMagnitude)) - let subtitleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - subtitleSize.width) / 2.0), y: titleFrame.maxY + 1.0), size: subtitleSize) - transition.updateFrame(node: self.timeNode, frame: subtitleFrame) - - let amountSize = self.amountNode.updateLayout(CGSize(width: layout.size.width - inset * 2.0, height: CGFloat.greatestFiniteMagnitude)) - let amountFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - amountSize.width) / 2.0) + 18.0, y: 90.0), size: amountSize) - transition.updateFrame(node: self.amountNode, frame: amountFrame) - - let iconSize = CGSize(width: 50.0, height: 50.0) - let iconFrame = CGRect(origin: CGPoint(x: amountFrame.minX - iconSize.width, y: amountFrame.minY), size: iconSize) - self.iconNode.updateLayout(size: iconFrame.size) - self.iconNode.frame = iconFrame - - let feesSize = self.feesNode.updateLayout(CGSize(width: layout.size.width - inset * 2.0, height: CGFloat.greatestFiniteMagnitude)) - let feesFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - feesSize.width) / 2.0), y: amountFrame.maxY + 8.0), size: feesSize) - transition.updateFrame(node: self.feesNode, frame: feesFrame) - transition.updateFrame(node: self.feesButtonNode, frame: feesFrame) - + let sideInset: CGFloat = 22.0 + + self.updateTitle(transition: transition) + let buttonSideInset: CGFloat = 16.0 let bottomInset = insets.bottom + 10.0 let buttonWidth = layout.size.width - buttonSideInset * 2.0 let buttonHeight: CGFloat = 50.0 - let buttonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonWidth) / 2.0), y: layout.size.height - bottomInset - buttonHeight), size: CGSize(width: buttonWidth, height: buttonHeight)) transition.updateFrame(node: self.buttonNode, frame: buttonFrame) self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition) - let addressSize = self.addressTextNode.updateLayout(CGSize(width: layout.size.width - inset * 2.0, height: CGFloat.greatestFiniteMagnitude)) - let addressFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - addressSize.width) / 2.0), y: buttonFrame.minY - addressSize.height - 38.0), size: addressSize) + let addressSize = self.addressTextNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: CGFloat.greatestFiniteMagnitude)) + let addressFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - addressSize.width) / 2.0), y: buttonFrame.minY - addressSize.height - 34.0), size: addressSize) transition.updateFrame(node: self.addressTextNode, frame: addressFrame) transition.updateFrame(node: self.navigationBackgroundNode, frame: CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: navigationHeight)) @@ -573,14 +638,23 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, transition.updateFrame(node: self.scrollNode, frame: scrollFrame) let commentSize = self.commentTextNode.updateLayout(CGSize(width: layout.size.width - 36.0 * 2.0, height: CGFloat.greatestFiniteMagnitude)) - let commentFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - commentSize.width) / 2.0), y: amountFrame.maxY + 84.0 - navigationHeight), size: CGSize(width: commentSize.width, height: commentSize.height)) + let commentOrigin = CGPoint(x: floor((layout.size.width - commentSize.width) / 2.0), y: 175.0) + let commentFrame = CGRect(origin: commentOrigin, size: commentSize) transition.updateFrame(node: self.commentTextNode, frame: commentFrame) - + var commentBackgroundFrame = commentSize.width > 0.0 ? commentFrame.insetBy(dx: -11.0, dy: -7.0) : CGRect() commentBackgroundFrame.size.width += 7.0 if self.incoming { commentBackgroundFrame.origin.x -= 7.0 } transition.updateFrame(node: self.commentBackgroundNode, frame: commentBackgroundFrame) + + let contentHeight = commentOrigin.y + commentBackgroundFrame.height + self.scrollNode.view.contentSize = CGSize(width: layout.size.width, height: contentHeight) + + let isScrollEnabled = contentHeight - scrollFrame.height > 20.0 + self.scrollNode.view.isScrollEnabled = isScrollEnabled + self.scrollNode.clipsToBounds = isScrollEnabled + self.commentSeparatorNode.isHidden = !isScrollEnabled } }