diff --git a/submodules/WalletUI/Sources/WalletInfoScreen.swift b/submodules/WalletUI/Sources/WalletInfoScreen.swift index 3cb1d9a1b3..226b0d6254 100644 --- a/submodules/WalletUI/Sources/WalletInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletInfoScreen.swift @@ -130,7 +130,7 @@ public final class WalletInfoScreen: ViewController { guard let strongSelf = self else { return } - strongSelf.push(WalletTransactionInfoScreen(context: strongSelf.context, walletInfo: strongSelf.walletInfo, walletTransaction: transaction, enableDebugActions: strongSelf.enableDebugActions)) + strongSelf.push(WalletTransactionInfoScreen(context: strongSelf.context, walletInfo: strongSelf.walletInfo, walletTransaction: transaction, walletState: (strongSelf.displayNode as! WalletInfoScreenNode).statePromise.get(), enableDebugActions: strongSelf.enableDebugActions)) }, present: { [weak self] c, a in guard let strongSelf = self else { return @@ -578,6 +578,8 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { fileprivate var combinedState: CombinedWalletState? private var currentEntries: [WalletInfoListEntry]? + fileprivate let statePromise = Promise<(CombinedWalletState, Bool)>() + private var isReady: Bool = false let contentReady = Promise() @@ -817,6 +819,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { self.transactionListDisposable.set(nil) self.loadingMoreTransactions = true self.reloadingState = true + self.updateStatePromise() self.headerNode.isRefreshing = true self.headerNode.refreshNode.refreshProgress = 0.0 @@ -852,7 +855,8 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { return } - strongSelf.reloadingState = false + strongSelf.reloadingState = false + strongSelf.updateStatePromise() if let combinedState = strongSelf.combinedState { strongSelf.headerNode.timestamp = Int32(clamping: combinedState.timestamp) @@ -962,6 +966,14 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { self.didSetContentReady = true self.contentReady.set(.single(true)) } + + self.updateStatePromise() + } + + private func updateStatePromise() { + if let combinedState = self.combinedState { + self.statePromise.set(.single((combinedState, self.reloadingState))) + } } private func loadMoreTransactions() { diff --git a/submodules/WalletUI/Sources/WalletSendScreen.swift b/submodules/WalletUI/Sources/WalletSendScreen.swift index f4a5a3553e..5d1fdc9bc2 100644 --- a/submodules/WalletUI/Sources/WalletSendScreen.swift +++ b/submodules/WalletUI/Sources/WalletSendScreen.swift @@ -16,17 +16,17 @@ private final class WalletSendScreenArguments { let context: WalletContext let updateState: ((WalletSendScreenState) -> WalletSendScreenState) -> Void let updateText: (WalletSendScreenEntryTag, String) -> Void - let selectNextInputItem: (WalletSendScreenEntryTag) -> Void + let selectInputItem: (WalletSendScreenEntryTag) -> Void let scrollToBottom: () -> Void let dismissInput: () -> Void let openQrScanner: () -> Void let proceed: () -> Void - init(context: WalletContext, updateState: @escaping ((WalletSendScreenState) -> WalletSendScreenState) -> Void, updateText: @escaping (WalletSendScreenEntryTag, String) -> Void, selectNextInputItem: @escaping (WalletSendScreenEntryTag) -> Void, scrollToBottom: @escaping () -> Void, dismissInput: @escaping () -> Void, openQrScanner: @escaping () -> Void, proceed: @escaping () -> Void) { + init(context: WalletContext, updateState: @escaping ((WalletSendScreenState) -> WalletSendScreenState) -> Void, updateText: @escaping (WalletSendScreenEntryTag, String) -> Void, selectInputItem: @escaping (WalletSendScreenEntryTag) -> Void, scrollToBottom: @escaping () -> Void, dismissInput: @escaping () -> Void, openQrScanner: @escaping () -> Void, proceed: @escaping () -> Void) { self.context = context self.updateState = updateState self.updateText = updateText - self.selectNextInputItem = selectNextInputItem + self.selectInputItem = selectInputItem self.scrollToBottom = scrollToBottom self.dismissInput = dismissInput self.openQrScanner = openQrScanner @@ -190,28 +190,54 @@ private enum WalletSendScreenEntry: ItemListNodeEntry { if let amount = parsedUrl.amount { state.amount = formatBalanceText(amount, decimalSeparator: arguments.context.presentationData.dateTimeFormat.decimalSeparator) } else if state.amount.isEmpty { - focusItemTag = WalletSendScreenEntryTag.address + focusItemTag = WalletSendScreenEntryTag.amount } if let comment = parsedUrl.comment { state.comment = comment } else if state.comment.isEmpty && focusItemTag == nil { - focusItemTag = WalletSendScreenEntryTag.amount + focusItemTag = WalletSendScreenEntryTag.comment } return state } if let focusItemTag = focusItemTag { - arguments.selectNextInputItem(focusItemTag) + arguments.selectInputItem(focusItemTag) } else { arguments.dismissInput() } } else if isValidAddress(text) { arguments.updateText(WalletSendScreenEntryTag.address, text) if isValidAddress(text, exactLength: true) { - arguments.selectNextInputItem(WalletSendScreenEntryTag.address) + var focusItemTag: WalletSendScreenEntryTag? = .comment + arguments.updateState { state in + if state.amount.isEmpty { + focusItemTag = .amount + } else if state.comment.isEmpty { + focusItemTag = .comment + } + return state + } + if let focusItemTag = focusItemTag { + arguments.selectInputItem(focusItemTag) + } else { + arguments.dismissInput() + } } } }, tag: WalletSendScreenEntryTag.address, action: { - arguments.selectNextInputItem(WalletSendScreenEntryTag.address) + var focusItemTag: WalletSendScreenEntryTag? + arguments.updateState { state in + if state.amount.isEmpty { + focusItemTag = .amount + } else if state.comment.isEmpty { + focusItemTag = .comment + } + return state + } + if let focusItemTag = focusItemTag { + arguments.selectInputItem(focusItemTag) + } else { + arguments.dismissInput() + } }, inlineAction: ItemListMultilineInputInlineAction(icon: UIImage(bundleImageName: "Wallet/QrIcon")!, action: { arguments.openQrScanner() })) @@ -290,7 +316,7 @@ public func walletSendScreen(context: WalletContext, randomId: Int64, walletInfo var popImpl: (() -> Void)? var dismissImpl: (() -> Void)? var dismissInputImpl: (() -> Void)? - var selectNextInputItemImpl: ((WalletSendScreenEntryTag) -> Void)? + var selectInputItemImpl: ((WalletSendScreenEntryTag) -> Void)? var ensureItemVisibleImpl: ((WalletSendScreenEntryTag, Bool) -> Void)? let arguments = WalletSendScreenArguments(context: context, updateState: { f in @@ -309,8 +335,8 @@ public func walletSendScreen(context: WalletContext, randomId: Int64, walletInfo return state } ensureItemVisibleImpl?(tag, false) - }, selectNextInputItem: { tag in - selectNextInputItemImpl?(tag) + }, selectInputItem: { tag in + selectInputItemImpl?(tag) }, scrollToBottom: { ensureItemVisibleImpl?(WalletSendScreenEntryTag.comment, true) }, dismissInput: { @@ -336,9 +362,9 @@ public func walletSendScreen(context: WalletContext, randomId: Int64, walletInfo popImpl?() if let updatedState = updatedState { if updatedState.amount.isEmpty { - selectNextInputItemImpl?(WalletSendScreenEntryTag.amount) + selectInputItemImpl?(WalletSendScreenEntryTag.amount) } else if updatedState.comment.isEmpty { - selectNextInputItemImpl?(WalletSendScreenEntryTag.comment) + selectInputItemImpl?(WalletSendScreenEntryTag.comment) } } })) @@ -572,19 +598,16 @@ public func walletSendScreen(context: WalletContext, randomId: Int64, walletInfo dismissInputImpl = { [weak controller] in controller?.view.endEditing(true) } - selectNextInputItemImpl = { [weak controller] currentTag in + selectInputItemImpl = { [weak controller] nextTag in guard let controller = controller else { return } var resultItemNode: ItemListItemFocusableNode? - var focusOnNext = false let _ = controller.frameForItemNode({ itemNode in if let itemNode = itemNode as? ItemListItemNode, let tag = itemNode.tag, let focusableItemNode = itemNode as? ItemListItemFocusableNode { - if focusOnNext && resultItemNode == nil { + if nextTag.isEqual(to: tag) { resultItemNode = focusableItemNode return true - } else if currentTag.isEqual(to: tag) { - focusOnNext = true } } return false diff --git a/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift b/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift index 661463aa3b..12b9061deb 100644 --- a/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletTransactionInfoScreen.swift @@ -147,16 +147,22 @@ final class WalletTransactionInfoScreen: ViewController { private let context: WalletContext private let walletInfo: WalletInfo? private let walletTransaction: WalletInfoTransaction + private let walletState: Signal<(CombinedWalletState, Bool), NoError> private var presentationData: WalletPresentationData + + private var walletStateDisposable: Disposable? + private var combinedState: CombinedWalletState? + private var reloadingState = false private var previousScreenBrightness: CGFloat? private var displayLinkAnimator: DisplayLinkAnimator? private let idleTimerExtensionDisposable: Disposable - public init(context: WalletContext, walletInfo: WalletInfo?, walletTransaction: WalletInfoTransaction, enableDebugActions: Bool) { + public init(context: WalletContext, walletInfo: WalletInfo?, walletTransaction: WalletInfoTransaction, walletState: Signal<(CombinedWalletState, Bool), NoError>, enableDebugActions: Bool) { self.context = context self.walletInfo = walletInfo self.walletTransaction = walletTransaction + self.walletState = walletState self.presentationData = context.presentationData @@ -174,10 +180,21 @@ final class WalletTransactionInfoScreen: ViewController { self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: UIView()) self.navigationItem.backBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Wallet_Navigation_Back, style: .plain, target: nil, action: nil) self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Wallet_Navigation_Done, style: .done, target: self, action: #selector(self.donePressed)) + + self.walletStateDisposable = (walletState + |> deliverOnMainQueue).start(next: { [weak self] combinedState, reloadingState in + guard let strongSelf = self else { + return + } + + strongSelf.combinedState = combinedState + strongSelf.reloadingState = reloadingState + }) } deinit { self.idleTimerExtensionDisposable.dispose() + self.walletStateDisposable?.dispose() } required init(coder aDecoder: NSCoder) { @@ -190,11 +207,24 @@ final class WalletTransactionInfoScreen: ViewController { guard let strongSelf = self else { return } - var randomId: Int64 = 0 - arc4random_buf(&randomId, 8) - if let walletInfo = strongSelf.walletInfo { - strongSelf.push(walletSendScreen(context: strongSelf.context, randomId: randomId, walletInfo: walletInfo, address: address)) - strongSelf.dismiss() + + if strongSelf.reloadingState { + strongSelf.present(standardTextAlertController(theme: strongSelf.presentationData.theme.alert, title: nil, text: strongSelf.presentationData.strings.Wallet_Send_SyncInProgress, actions: [ + TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Wallet_Alert_OK, action: { + }) + ]), in: .window(.root)) + } else if let combinedState = strongSelf.combinedState, !combinedState.pendingTransactions.isEmpty { + strongSelf.present(standardTextAlertController(theme: strongSelf.presentationData.theme.alert, title: nil, text: strongSelf.presentationData.strings.Wallet_Send_TransactionInProgress, actions: [ + TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Wallet_Alert_OK, action: { + }) + ]), in: .window(.root)) + } else { + var randomId: Int64 = 0 + arc4random_buf(&randomId, 8) + if let walletInfo = strongSelf.walletInfo { + strongSelf.push(walletSendScreen(context: strongSelf.context, randomId: randomId, walletInfo: walletInfo, address: address)) + strongSelf.dismiss() + } } } (self.displayNode as! WalletTransactionInfoScreenNode).displayFeesTooltip = { [weak self] node, rect in @@ -465,7 +495,7 @@ private final class WalletTransactionInfoScreenNode: ViewControllerTracingNode, } } } - + override func didLoad() { super.didLoad()