mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-20 23:46:02 +00:00
Wallet fixes
This commit is contained in:
parent
10f06f45fc
commit
c0643cbd97
@ -148,9 +148,6 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
|||||||
|
|
||||||
self.deleteButton.isHidden = !self.deleteButton.isEnabled
|
self.deleteButton.isHidden = !self.deleteButton.isEnabled
|
||||||
self.reportButton.isHidden = !self.reportButton.isEnabled
|
self.reportButton.isHidden = !self.reportButton.isEnabled
|
||||||
|
|
||||||
self.deleteButton.isHidden = false
|
|
||||||
self.deleteButton.isEnabled = true
|
|
||||||
} else {
|
} else {
|
||||||
self.deleteButton.isEnabled = false
|
self.deleteButton.isEnabled = false
|
||||||
self.deleteButton.isHidden = true
|
self.deleteButton.isHidden = true
|
||||||
@ -158,8 +155,6 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
|||||||
self.reportButton.isHidden = true
|
self.reportButton.isHidden = true
|
||||||
self.forwardButton.isEnabled = false
|
self.forwardButton.isEnabled = false
|
||||||
self.shareButton.isEnabled = false
|
self.shareButton.isEnabled = false
|
||||||
|
|
||||||
self.deleteButton.isHidden = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.deleteButton.isHidden && self.reportButton.isHidden {
|
if self.deleteButton.isHidden && self.reportButton.isHidden {
|
||||||
|
|||||||
@ -135,24 +135,24 @@ public final class WalletInfoScreen: ViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class WalletInfoBalanceNode: ASDisplayNode {
|
final class WalletInfoBalanceNode: ASDisplayNode {
|
||||||
let dateTimeFormat: WalletPresentationDateTimeFormat
|
let dateTimeFormat: WalletPresentationDateTimeFormat
|
||||||
|
|
||||||
let balanceIntegralTextNode: ImmediateTextNode
|
let balanceIntegralTextNode: ImmediateTextNode
|
||||||
let balanceFractionalTextNode: ImmediateTextNode
|
let balanceFractionalTextNode: ImmediateTextNode
|
||||||
let balanceIconNode: AnimatedStickerNode
|
let balanceIconNode: AnimatedStickerNode
|
||||||
|
|
||||||
var balance: String = " " {
|
var balance: (String, UIColor) = (" ", .white) {
|
||||||
didSet {
|
didSet {
|
||||||
let integralString = NSMutableAttributedString()
|
let integralString = NSMutableAttributedString()
|
||||||
let fractionalString = NSMutableAttributedString()
|
let fractionalString = NSMutableAttributedString()
|
||||||
if let range = self.balance.range(of: self.dateTimeFormat.decimalSeparator) {
|
if let range = self.balance.0.range(of: self.dateTimeFormat.decimalSeparator) {
|
||||||
let integralPart = String(self.balance[..<range.lowerBound])
|
let integralPart = String(self.balance.0[..<range.lowerBound])
|
||||||
let fractionalPart = String(self.balance[range.lowerBound...])
|
let fractionalPart = String(self.balance.0[range.lowerBound...])
|
||||||
integralString.append(NSAttributedString(string: integralPart, font: Font.medium(48.0), textColor: .white))
|
integralString.append(NSAttributedString(string: integralPart, font: Font.medium(48.0), textColor: self.balance.1))
|
||||||
fractionalString.append(NSAttributedString(string: fractionalPart, font: Font.medium(48.0), textColor: .white))
|
fractionalString.append(NSAttributedString(string: fractionalPart, font: Font.medium(48.0), textColor: self.balance.1))
|
||||||
} else {
|
} else {
|
||||||
integralString.append(NSAttributedString(string: self.balance, font: Font.medium(48.0), textColor: .white))
|
integralString.append(NSAttributedString(string: self.balance.0, font: Font.medium(48.0), textColor: self.balance.1))
|
||||||
}
|
}
|
||||||
self.balanceIntegralTextNode.attributedText = integralString
|
self.balanceIntegralTextNode.attributedText = integralString
|
||||||
self.balanceFractionalTextNode.attributedText = fractionalString
|
self.balanceFractionalTextNode.attributedText = fractionalString
|
||||||
@ -161,7 +161,7 @@ private final class WalletInfoBalanceNode: ASDisplayNode {
|
|||||||
|
|
||||||
var isLoading: Bool = true
|
var isLoading: Bool = true
|
||||||
|
|
||||||
init(theme: WalletTheme, dateTimeFormat: WalletPresentationDateTimeFormat) {
|
init(dateTimeFormat: WalletPresentationDateTimeFormat) {
|
||||||
self.dateTimeFormat = dateTimeFormat
|
self.dateTimeFormat = dateTimeFormat
|
||||||
|
|
||||||
self.balanceIntegralTextNode = ImmediateTextNode()
|
self.balanceIntegralTextNode = ImmediateTextNode()
|
||||||
@ -244,7 +244,7 @@ private final class WalletInfoHeaderNode: ASDisplayNode {
|
|||||||
init(presentationData: WalletPresentationData, hasActions: Bool, sendAction: @escaping () -> Void, receiveAction: @escaping () -> Void) {
|
init(presentationData: WalletPresentationData, hasActions: Bool, sendAction: @escaping () -> Void, receiveAction: @escaping () -> Void) {
|
||||||
self.hasActions = hasActions
|
self.hasActions = hasActions
|
||||||
|
|
||||||
self.balanceNode = WalletInfoBalanceNode(theme: presentationData.theme, dateTimeFormat: presentationData.dateTimeFormat)
|
self.balanceNode = WalletInfoBalanceNode(dateTimeFormat: presentationData.dateTimeFormat)
|
||||||
|
|
||||||
self.balanceSubtitleNode = ImmediateTextNode()
|
self.balanceSubtitleNode = ImmediateTextNode()
|
||||||
self.balanceSubtitleNode.displaysAsynchronously = false
|
self.balanceSubtitleNode.displaysAsynchronously = false
|
||||||
@ -856,7 +856,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode {
|
|||||||
private func updateCombinedState(combinedState: CombinedWalletState?, isUpdated: Bool) {
|
private func updateCombinedState(combinedState: CombinedWalletState?, isUpdated: Bool) {
|
||||||
self.combinedState = combinedState
|
self.combinedState = combinedState
|
||||||
if let 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)
|
self.headerNode.balance = max(0, combinedState.walletState.balance)
|
||||||
|
|
||||||
if self.isReady, let (layout, navigationHeight) = self.validLayout {
|
if self.isReady, let (layout, navigationHeight) = self.validLayout {
|
||||||
|
|||||||
@ -306,15 +306,25 @@ private final class WalletReceiveScreenNode: ViewControllerTracingNode {
|
|||||||
if case .receive = self.mode {
|
if case .receive = self.mode {
|
||||||
url = url + "?"
|
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 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)
|
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))
|
let addressInset: CGFloat = 12.0
|
||||||
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 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 buttonSideInset: CGFloat = 16.0
|
||||||
let bottomInset = insets.bottom + 10.0
|
let bottomInset = insets.bottom + 10.0
|
||||||
|
|||||||
@ -235,16 +235,35 @@ final class WalletTransactionInfoScreen: ViewController {
|
|||||||
|
|
||||||
private let measureTextNode = TextNode()
|
private let measureTextNode = TextNode()
|
||||||
override func preferredContentSizeForLayout(_ layout: ContainerViewLayout) -> CGSize? {
|
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 text = NSAttributedString(string: extractDescription(self.walletTransaction), font: Font.regular(17.0), textColor: .black)
|
||||||
let makeTextLayout = TextNode.asyncLayout(self.measureTextNode)
|
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()))
|
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) {
|
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 let fractionalFont = Font.medium(24.0)
|
||||||
|
|
||||||
private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate {
|
private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate {
|
||||||
@ -269,26 +288,22 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode,
|
|||||||
|
|
||||||
private let titleNode: ImmediateTextNode
|
private let titleNode: ImmediateTextNode
|
||||||
private let timeNode: ImmediateTextNode
|
private let timeNode: ImmediateTextNode
|
||||||
|
|
||||||
private let navigationBackgroundNode: ASDisplayNode
|
private let navigationBackgroundNode: ASDisplayNode
|
||||||
private let navigationSeparatorNode: ASDisplayNode
|
private let navigationSeparatorNode: ASDisplayNode
|
||||||
|
|
||||||
private let scrollNode: ASScrollNode
|
private let scrollNode: ASScrollNode
|
||||||
private let amountNode: ImmediateTextNode
|
private let amountNode: WalletInfoBalanceNode
|
||||||
private let iconNode: AnimatedStickerNode
|
|
||||||
private let activateArea: AccessibilityAreaNode
|
private let activateArea: AccessibilityAreaNode
|
||||||
private let feesNode: ImmediateTextNode
|
private let feesNode: ImmediateTextNode
|
||||||
private let feesInfoIconNode: ASImageNode
|
private let feesInfoIconNode: ASImageNode
|
||||||
private let feesButtonNode: ASButtonNode
|
private let feesButtonNode: ASButtonNode
|
||||||
|
|
||||||
private let commentBackgroundNode: ASImageNode
|
private let commentBackgroundNode: ASImageNode
|
||||||
private let commentTextNode: ImmediateTextNode
|
private let commentTextNode: ImmediateTextNode
|
||||||
private let commentSeparatorNode: ASDisplayNode
|
private let commentSeparatorNode: ASDisplayNode
|
||||||
|
|
||||||
private let addressTextNode: ImmediateTextNode
|
private let addressTextNode: ImmediateTextNode
|
||||||
|
|
||||||
private let buttonNode: SolidRoundedButtonNode
|
private let buttonNode: SolidRoundedButtonNode
|
||||||
|
|
||||||
|
private var validLayout: (ContainerViewLayout, CGFloat)?
|
||||||
|
|
||||||
var send: ((String) -> Void)?
|
var send: ((String) -> Void)?
|
||||||
var displayFeesTooltip: ((ASDisplayNode, CGRect) -> Void)?
|
var displayFeesTooltip: ((ASDisplayNode, CGRect) -> Void)?
|
||||||
var displayCopyContextMenu: ((ASDisplayNode, CGRect, String) -> Void)?
|
var displayCopyContextMenu: ((ASDisplayNode, CGRect, String) -> Void)?
|
||||||
@ -311,19 +326,10 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode,
|
|||||||
self.navigationBackgroundNode.alpha = 0.0
|
self.navigationBackgroundNode.alpha = 0.0
|
||||||
self.navigationSeparatorNode = ASDisplayNode()
|
self.navigationSeparatorNode = ASDisplayNode()
|
||||||
self.navigationSeparatorNode.backgroundColor = self.presentationData.theme.navigationBar.separatorColor
|
self.navigationSeparatorNode.backgroundColor = self.presentationData.theme.navigationBar.separatorColor
|
||||||
self.navigationSeparatorNode.alpha = 0.0
|
|
||||||
|
|
||||||
self.scrollNode = ASScrollNode()
|
self.scrollNode = ASScrollNode()
|
||||||
|
|
||||||
self.amountNode = ImmediateTextNode()
|
self.amountNode = WalletInfoBalanceNode(dateTimeFormat: presentationData.dateTimeFormat)
|
||||||
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.feesNode = ImmediateTextNode()
|
self.feesNode = ImmediateTextNode()
|
||||||
self.feesNode.textAlignment = .center
|
self.feesNode.textAlignment = .center
|
||||||
@ -374,18 +380,17 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode,
|
|||||||
|
|
||||||
self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
|
||||||
|
|
||||||
self.addSubnode(self.navigationBackgroundNode)
|
self.addSubnode(self.scrollNode)
|
||||||
self.addSubnode(self.navigationSeparatorNode)
|
|
||||||
self.addSubnode(self.titleNode)
|
|
||||||
self.addSubnode(self.timeNode)
|
|
||||||
self.addSubnode(self.amountNode)
|
|
||||||
self.addSubnode(self.iconNode)
|
|
||||||
self.addSubnode(self.feesNode)
|
self.addSubnode(self.feesNode)
|
||||||
self.addSubnode(self.feesInfoIconNode)
|
self.addSubnode(self.feesInfoIconNode)
|
||||||
self.addSubnode(self.feesButtonNode)
|
self.addSubnode(self.feesButtonNode)
|
||||||
self.addSubnode(self.scrollNode)
|
|
||||||
self.scrollNode.addSubnode(self.commentBackgroundNode)
|
self.scrollNode.addSubnode(self.commentBackgroundNode)
|
||||||
self.scrollNode.addSubnode(self.commentTextNode)
|
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.commentSeparatorNode)
|
||||||
self.addSubnode(self.addressTextNode)
|
self.addSubnode(self.addressTextNode)
|
||||||
self.addSubnode(self.buttonNode)
|
self.addSubnode(self.buttonNode)
|
||||||
@ -409,7 +414,7 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode,
|
|||||||
amountString = "\(formatBalanceText(transferredValue, decimalSeparator: self.presentationData.dateTimeFormat.decimalSeparator))"
|
amountString = "\(formatBalanceText(transferredValue, decimalSeparator: self.presentationData.dateTimeFormat.decimalSeparator))"
|
||||||
amountColor = self.presentationData.theme.info.incomingFundsTitleColor
|
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 = ""
|
var feesString: String = ""
|
||||||
if case let .completed(transaction) = walletTransaction {
|
if case let .completed(transaction) = walletTransaction {
|
||||||
@ -455,6 +460,10 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode,
|
|||||||
override func didLoad() {
|
override func didLoad() {
|
||||||
super.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(_:)))
|
let commentGestureRecognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapCommentGesture(_:)))
|
||||||
commentGestureRecognizer.tapActionAtPoint = { [weak self] point in
|
commentGestureRecognizer.tapActionAtPoint = { [weak self] point in
|
||||||
return .waitForSingleTap
|
return .waitForSingleTap
|
||||||
@ -476,7 +485,7 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode,
|
|||||||
case .longTap:
|
case .longTap:
|
||||||
let description = extractDescription(self.walletTransaction)
|
let description = extractDescription(self.walletTransaction)
|
||||||
if !description.isEmpty {
|
if !description.isEmpty {
|
||||||
self.displayCopyContextMenu?(self, self.commentBackgroundNode.frame, description)
|
self.displayCopyContextMenu?(self, self.commentBackgroundNode.convert(self.commentBackgroundNode.bounds, to: self), description)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
@ -500,7 +509,7 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let address = singleAddress {
|
if let address = singleAddress {
|
||||||
self.displayCopyContextMenu?(self, self.addressTextNode.frame, address)
|
self.displayCopyContextMenu?(self, self.addressTextNode.convert(self.addressTextNode.bounds, to: self), address)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
@ -516,51 +525,107 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
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) {
|
func containerLayoutUpdated(layout: ContainerViewLayout, navigationHeight: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
|
self.validLayout = (layout, navigationHeight)
|
||||||
|
|
||||||
var insets = layout.insets(options: [])
|
var insets = layout.insets(options: [])
|
||||||
insets.top += navigationHeight
|
insets.top += navigationHeight
|
||||||
let inset: CGFloat = 22.0
|
let sideInset: CGFloat = 22.0
|
||||||
|
|
||||||
let titleSize = self.titleNode.updateLayout(CGSize(width: layout.size.width - inset * 2.0, height: CGFloat.greatestFiniteMagnitude))
|
self.updateTitle(transition: transition)
|
||||||
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 buttonSideInset: CGFloat = 16.0
|
let buttonSideInset: CGFloat = 16.0
|
||||||
let bottomInset = insets.bottom + 10.0
|
let bottomInset = insets.bottom + 10.0
|
||||||
let buttonWidth = layout.size.width - buttonSideInset * 2.0
|
let buttonWidth = layout.size.width - buttonSideInset * 2.0
|
||||||
let buttonHeight: CGFloat = 50.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))
|
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)
|
transition.updateFrame(node: self.buttonNode, frame: buttonFrame)
|
||||||
self.buttonNode.updateLayout(width: buttonFrame.width, transition: transition)
|
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 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 - 38.0), size: addressSize)
|
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.addressTextNode, frame: addressFrame)
|
||||||
|
|
||||||
transition.updateFrame(node: self.navigationBackgroundNode, frame: CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: navigationHeight))
|
transition.updateFrame(node: self.navigationBackgroundNode, frame: CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: navigationHeight))
|
||||||
@ -573,7 +638,8 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode,
|
|||||||
transition.updateFrame(node: self.scrollNode, frame: scrollFrame)
|
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 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)
|
transition.updateFrame(node: self.commentTextNode, frame: commentFrame)
|
||||||
|
|
||||||
var commentBackgroundFrame = commentSize.width > 0.0 ? commentFrame.insetBy(dx: -11.0, dy: -7.0) : CGRect()
|
var commentBackgroundFrame = commentSize.width > 0.0 ? commentFrame.insetBy(dx: -11.0, dy: -7.0) : CGRect()
|
||||||
@ -582,5 +648,13 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode,
|
|||||||
commentBackgroundFrame.origin.x -= 7.0
|
commentBackgroundFrame.origin.x -= 7.0
|
||||||
}
|
}
|
||||||
transition.updateFrame(node: self.commentBackgroundNode, frame: commentBackgroundFrame)
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user