From d0d98ba15ab79e45df5a11a15344424c895115bb Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 27 Sep 2019 11:32:22 +0300 Subject: [PATCH 1/2] Wallet: limit amount input to Int64.max --- submodules/QrCode/Sources/QrCode.swift | 2 +- .../Wallet/QrGem.imageset/QrGem@2x.png | Bin 15003 -> 15212 bytes .../Wallet/QrGem.imageset/QrGem@3x.png | Bin 16738 -> 17086 bytes .../Sources/WalletInfoEmptyNode.swift | 33 +++++++++++++++- .../WalletUI/Sources/WalletInfoScreen.swift | 37 +++++++++++++----- .../WalletUI/Sources/WalletQrScanScreen.swift | 12 ++++-- submodules/WalletUI/Sources/WalletUtils.swift | 32 ++++++++++++++- .../Sources/WalletWordCheckScreen.swift | 2 +- 8 files changed, 101 insertions(+), 17 deletions(-) diff --git a/submodules/QrCode/Sources/QrCode.swift b/submodules/QrCode/Sources/QrCode.swift index 92030f0a61..d16e19f219 100644 --- a/submodules/QrCode/Sources/QrCode.swift +++ b/submodules/QrCode/Sources/QrCode.swift @@ -106,7 +106,7 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n let _ = try? drawSvgPath(c, path: "M24.1237113,50.5927835 L40.8762887,50.5927835 L40.8762887,60.9793814 L32.5,64.0928525 L24.1237113,60.9793814 Z") case let .custom(image): if let image = image { - let fittedSize = image.size.fitted(clipRect.size) + let fittedSize = image.size.aspectFitted(clipRect.size) let fittedRect = CGRect(origin: CGPoint(x: fittedRect.midX - fittedSize.width / 2.0, y: fittedRect.midY - fittedSize.height / 2.0), size: fittedSize) c.translateBy(x: fittedRect.midX, y: fittedRect.midY) c.scaleBy(x: 1.0, y: -1.0) diff --git a/submodules/TelegramUI/Images.xcassets/Wallet/QrGem.imageset/QrGem@2x.png b/submodules/TelegramUI/Images.xcassets/Wallet/QrGem.imageset/QrGem@2x.png index 614642452d43ff654d23eb4ce4257e81f7188f35..35d164f8b318bb1bee29ead067bdf02332cc2656 100644 GIT binary patch literal 15212 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 diff --git a/submodules/TelegramUI/Images.xcassets/Wallet/QrGem.imageset/QrGem@3x.png b/submodules/TelegramUI/Images.xcassets/Wallet/QrGem.imageset/QrGem@3x.png index 9e8067d885bb5727dbc9b742e4cdb7d4cbb55fdf..6f2e9e6ed6219d62fb04cee89edaccd7ba063eb9 100644 GIT binary patch literal 17086 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 j1x*SzFt~x2p92Z9FkN7nR=C$!Rv literal 16738 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 Void let selectable: Bool = false - init(account: Account, theme: PresentationTheme, strings: PresentationStrings, address: String) { + init(account: Account, theme: PresentationTheme, strings: PresentationStrings, address: String, displayAddressContextMenu: @escaping (ASDisplayNode, CGRect) -> Void) { self.account = account self.theme = theme self.strings = strings self.address = address + self.displayAddressContextMenu = displayAddressContextMenu } func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { @@ -62,6 +64,8 @@ final class WalletInfoEmptyItemNode: ListViewItemNode { private let textNode: TextNode private let addressNode: TextNode + private var item: WalletInfoEmptyItem? + init(account: Account) { self.offsetContainer = ASDisplayNode() @@ -88,6 +92,32 @@ final class WalletInfoEmptyItemNode: ListViewItemNode { self.addSubnode(self.offsetContainer) } + override func didLoad() { + super.didLoad() + + let recognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapLongTapOrDoubleTapGesture(_:))) + recognizer.tapActionAtPoint = { [weak self] point in + return .waitForSingleTap + } + self.addressNode.view.addGestureRecognizer(recognizer) + } + + @objc func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) { + switch recognizer.state { + case .ended: + if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation { + switch gesture { + case .longTap: + self.item?.displayAddressContextMenu(self, self.addressNode.frame) + default: + break + } + } + default: + break + } + } + override func layoutForParams(_ params: ListViewItemLayoutParams, item: ListViewItem, previousItem: ListViewItem?, nextItem: ListViewItem?) { let layout = self.asyncLayout() let (_, apply) = layout(item as! WalletInfoEmptyItem, params) @@ -139,6 +169,7 @@ final class WalletInfoEmptyItemNode: ListViewItemNode { guard let strongSelf = self else { return } + strongSelf.item = item strongSelf.offsetContainer.frame = CGRect(origin: CGPoint(), size: layout.contentSize) diff --git a/submodules/WalletUI/Sources/WalletInfoScreen.swift b/submodules/WalletUI/Sources/WalletInfoScreen.swift index a1d8343a9a..88123647f7 100644 --- a/submodules/WalletUI/Sources/WalletInfoScreen.swift +++ b/submodules/WalletUI/Sources/WalletInfoScreen.swift @@ -80,11 +80,11 @@ public final class WalletInfoScreen: ViewController { return } strongSelf.push(walletTransactionInfoController(context: strongSelf.context, tonContext: strongSelf.tonContext, walletInfo: strongSelf.walletInfo, walletTransaction: transaction)) - }, present: { [weak self] c in + }, present: { [weak self] c, a in guard let strongSelf = self else { return } - strongSelf.present(c, in: .window(.root)) + strongSelf.present(c, in: .window(.root), with: a) }) self.displayNodeDidLoad() @@ -403,10 +403,12 @@ private enum WalletInfoListEntry: Equatable, Comparable, Identifiable { } } - func item(account: Account, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, action: @escaping (WalletTransaction) -> Void) -> ListViewItem { + func item(account: Account, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, action: @escaping (WalletTransaction) -> Void, displayAddressContextMenu: @escaping (ASDisplayNode, CGRect) -> Void) -> ListViewItem { switch self { case let .empty(address): - return WalletInfoEmptyItem(account: account, theme: theme, strings: strings, address: address) + return WalletInfoEmptyItem(account: account, theme: theme, strings: strings, address: address, displayAddressContextMenu: { node, frame in + displayAddressContextMenu(node, frame) + }) case let .transaction(_, transaction): return WalletInfoTransactionItem(theme: theme, strings: strings, dateTimeFormat: dateTimeFormat, walletTransaction: transaction, action: { action(transaction) @@ -415,12 +417,12 @@ private enum WalletInfoListEntry: Equatable, Comparable, Identifiable { } } -private func preparedTransition(from fromEntries: [WalletInfoListEntry], to toEntries: [WalletInfoListEntry], account: Account, presentationData: PresentationData, action: @escaping (WalletTransaction) -> Void) -> WalletInfoListTransaction { +private func preparedTransition(from fromEntries: [WalletInfoListEntry], to toEntries: [WalletInfoListEntry], account: Account, presentationData: PresentationData, action: @escaping (WalletTransaction) -> Void, displayAddressContextMenu: @escaping (ASDisplayNode, CGRect) -> Void) -> WalletInfoListTransaction { let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries) let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) } - let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: presentationData.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, action: action), directionHint: nil) } - let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: presentationData.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, action: action), directionHint: nil) } + let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: presentationData.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, action: action, displayAddressContextMenu: displayAddressContextMenu), directionHint: nil) } + let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: presentationData.theme, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, action: action, displayAddressContextMenu: displayAddressContextMenu), directionHint: nil) } return WalletInfoListTransaction(deletions: deletions, insertions: insertions, updates: updates) } @@ -433,7 +435,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { private let address: String private let openTransaction: (WalletTransaction) -> Void - private let present: (ViewController) -> Void + private let present: (ViewController, Any?) -> Void private let hapticFeedback = HapticFeedback() @@ -463,7 +465,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { private var updateTimestampTimer: SwiftSignalKit.Timer? - init(account: Account, tonContext: TonContext, presentationData: PresentationData, walletInfo: WalletInfo, address: String, sendAction: @escaping () -> Void, receiveAction: @escaping () -> Void, openTransaction: @escaping (WalletTransaction) -> Void, present: @escaping (ViewController) -> Void) { + init(account: Account, tonContext: TonContext, presentationData: PresentationData, walletInfo: WalletInfo, address: String, sendAction: @escaping () -> Void, receiveAction: @escaping () -> Void, openTransaction: @escaping (WalletTransaction) -> Void, present: @escaping (ViewController, Any?) -> Void) { self.account = account self.tonContext = tonContext self.presentationData = presentationData @@ -740,7 +742,7 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.presentationData.theme), title: "An Error Occurred", text: "The wallet state can not be retrieved at this time. Please try again later.", actions: [ TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: { }) - ], actionLayout: .vertical)) + ], actionLayout: .vertical), nil) })) } @@ -821,6 +823,21 @@ private final class WalletInfoScreenNode: ViewControllerTracingNode { return } strongSelf.openTransaction(transaction) + }, displayAddressContextMenu: { [weak self] node, frame in + guard let strongSelf = self else { + return + } + let address = strongSelf.address + let contextMenuController = ContextMenuController(actions: [ContextMenuAction(content: .text(title: strongSelf.presentationData.strings.Conversation_ContextMenuCopy, accessibilityLabel: strongSelf.presentationData.strings.Conversation_ContextMenuCopy), action: { + UIPasteboard.general.string = address + })]) + strongSelf.present(contextMenuController, ContextMenuControllerPresentationArguments(sourceNodeAndRect: { [weak self] in + if let strongSelf = self { + return (node, frame.insetBy(dx: 0.0, dy: -2.0), strongSelf, strongSelf.view.bounds) + } else { + return nil + } + })) }) self.currentEntries = updatedEntries diff --git a/submodules/WalletUI/Sources/WalletQrScanScreen.swift b/submodules/WalletUI/Sources/WalletQrScanScreen.swift index 5996d4bfbf..acf8b5ae2d 100644 --- a/submodules/WalletUI/Sources/WalletQrScanScreen.swift +++ b/submodules/WalletUI/Sources/WalletQrScanScreen.swift @@ -100,14 +100,13 @@ public final class WalletQrScanScreen: ViewController { self.displayNodeDidLoad() - self.codeDisposable = (((self.displayNode as! WalletQrScanScreenNode).focusedCode.get() + self.codeDisposable = ((self.displayNode as! WalletQrScanScreenNode).focusedCode.get() |> map { code -> String? in return code?.message } |> distinctUntilChanged - |> delay(2.5, queue: Queue.mainQueue())) |> mapToSignal { code -> Signal in - return .single(code) + return .single(code) |> delay(0.5, queue: Queue.mainQueue()) }).start(next: { [weak self] code in guard let strongSelf = self, let code = code else { return @@ -270,13 +269,16 @@ private final class WalletQrScanScreenNode: ViewControllerTracingNode, UIScrollV let dimAlpha: CGFloat let dimRect: CGRect + let controlsAlpha: CGFloat if let focusedRect = self.focusedRect { dimAlpha = 1.0 + controlsAlpha = 0.0 let side = max(bounds.width * focusedRect.width, bounds.height * focusedRect.height) * 0.6 let center = CGPoint(x: (1.0 - focusedRect.center.y) * bounds.width, y: focusedRect.center.x * bounds.height) dimRect = CGRect(x: center.x - side / 2.0, y: center.y - side / 2.0, width: side, height: side) } else { dimAlpha = 0.625 + controlsAlpha = 1.0 dimRect = CGRect(x: dimInset, y: dimHeight, width: layout.size.width - dimInset * 2.0, height: layout.size.height - dimHeight * 2.0) } @@ -296,6 +298,10 @@ private final class WalletQrScanScreenNode: ViewControllerTracingNode, UIScrollV transition.updateFrame(node: self.galleryButtonNode, frame: CGRect(origin: CGPoint(x: floor(layout.size.width / 2.0) - buttonSize.width - 28.0, y: dimHeight + frameSide + 50.0), size: buttonSize)) transition.updateFrame(node: self.torchButtonNode, frame: CGRect(origin: CGPoint(x: floor(layout.size.width / 2.0) + 28.0, y: dimHeight + frameSide + 50.0), size: buttonSize)) + transition.updateAlpha(node: self.titleNode, alpha: controlsAlpha) + transition.updateAlpha(node: self.galleryButtonNode, alpha: controlsAlpha) + transition.updateAlpha(node: self.torchButtonNode, alpha: controlsAlpha) + let titleSize = self.titleNode.updateLayout(CGSize(width: layout.size.width - sideInset * 2.0, height: layout.size.height)) let titleFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: dimHeight - titleSize.height - titleSpacing), size: titleSize) transition.updateFrameAdditive(node: self.titleNode, frame: titleFrame) diff --git a/submodules/WalletUI/Sources/WalletUtils.swift b/submodules/WalletUI/Sources/WalletUtils.swift index 98d68ea9a9..7b31075067 100644 --- a/submodules/WalletUI/Sources/WalletUtils.swift +++ b/submodules/WalletUI/Sources/WalletUtils.swift @@ -63,11 +63,41 @@ func isValidAmount(_ amount: String) -> Bool { return false } + let string = amount.replacingOccurrences(of: ",", with: ".") + if let range = string.range(of: ".") { + let integralPart = String(string[.. Int64 { - return Int64((Double(string.replacingOccurrences(of: ",", with: ".")) ?? 0.0) * 1000000000.0) + let string = string.replacingOccurrences(of: ",", with: ".") + if let range = string.range(of: ".") { + let integralPart = String(string[.. maxIntegral { + return 0 + } + return integral * 1000000000 + } + return 0 } func normalizedStringForGramsString(_ string: String, decimalSeparator: String = ".") -> String { diff --git a/submodules/WalletUI/Sources/WalletWordCheckScreen.swift b/submodules/WalletUI/Sources/WalletWordCheckScreen.swift index 1337ab08f0..bb36256bf1 100644 --- a/submodules/WalletUI/Sources/WalletWordCheckScreen.swift +++ b/submodules/WalletUI/Sources/WalletWordCheckScreen.swift @@ -2706,7 +2706,7 @@ private final class WalletWordCheckScreenNode: ViewControllerTracingNode, UIScro guard let strongSelf = self else { return } - if node === strongSelf.inputNodes.last { + if node.isLast { if done { action() } else { From 64f54c625ce09a0f7385efe553b952c8459c373e Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 27 Sep 2019 13:23:37 +0300 Subject: [PATCH 2/2] Wallet: open QR codes from camera roll --- .../Sources/AccountContext.swift | 1 + .../LegacyComponents/TGViewController.mm | 4 +- .../LegacyUI/Sources/LegacyController.swift | 5 ++- .../TelegramUI/ChatController.swift | 1 - .../TelegramUI/SharedAccountContext.swift | 34 +++++++++++++++++ submodules/WalletUI/BUCK | 1 + .../WalletUI/Sources/WalletQrScanScreen.swift | 38 ++++++++++++++++++- 7 files changed, 80 insertions(+), 4 deletions(-) diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index c253c2002b..6fcc4bb66d 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -441,6 +441,7 @@ public protocol SharedAccountContext: class { func openAddPersonContact(context: AccountContext, peerId: PeerId, pushController: @escaping (ViewController) -> Void, present: @escaping (ViewController, Any?) -> Void) func presentContactsWarningSuppression(context: AccountContext, present: (ViewController, Any?) -> Void) func openWallet(context: AccountContext, walletContext: OpenWalletContext, present: @escaping (ViewController) -> Void) + func openImagePicker(context: AccountContext, completion: @escaping (UIImage) -> Void, present: @escaping (ViewController) -> Void) func navigateToCurrentCall() var hasOngoingCall: ValuePromise { get } diff --git a/submodules/LegacyComponents/LegacyComponents/TGViewController.mm b/submodules/LegacyComponents/LegacyComponents/TGViewController.mm index 9b7324e91e..8be15956c1 100644 --- a/submodules/LegacyComponents/LegacyComponents/TGViewController.mm +++ b/submodules/LegacyComponents/LegacyComponents/TGViewController.mm @@ -822,6 +822,8 @@ static id _defaultContext = nil; - (CGFloat)_currentStatusBarHeight { + if (_context.isStatusBarHidden) + return 0.0; if (_context.safeAreaInset.top > 20.0f) return _context.safeAreaInset.top; @@ -1127,7 +1129,7 @@ static id _defaultContext = nil; UIEdgeInsets safeAreaInset = [TGViewController safeAreaInsetForOrientation:orientation hasOnScreenNavigation:hasOnScreenNavigation]; CGFloat navigationBarHeight = ([self navigationBarShouldBeHidden] || [self shouldIgnoreNavigationBar]) ? 0 : [self navigationBarHeightForInterfaceOrientation:orientation]; - statusBarHeight = safeAreaInset.top > FLT_EPSILON ? safeAreaInset.top : statusBarHeight; + //statusBarHeight = safeAreaInset.top > FLT_EPSILON ? safeAreaInset.top : statusBarHeight; UIEdgeInsets edgeInset = UIEdgeInsetsMake(([self shouldIgnoreStatusBarInOrientation:orientation] ? 0.0f : statusBarHeight) + navigationBarHeight, 0, 0, 0); diff --git a/submodules/LegacyUI/Sources/LegacyController.swift b/submodules/LegacyUI/Sources/LegacyController.swift index 8868e0b5fe..1a617c6021 100644 --- a/submodules/LegacyUI/Sources/LegacyController.swift +++ b/submodules/LegacyUI/Sources/LegacyController.swift @@ -122,7 +122,7 @@ public final class LegacyControllerContext: NSObject, LegacyComponentsContext { public func isStatusBarHidden() -> Bool { if let controller = self.controller { - return controller.statusBar.isHidden + return controller.statusBar.isHidden || controller.navigationPresentation == .modal } else { return true } @@ -282,6 +282,9 @@ public final class LegacyControllerContext: NSObject, LegacyComponentsContext { if validLayout.intrinsicInsets.bottom.isEqual(to: 21.0) { safeInsets.bottom = 21.0 } + if controller.navigationPresentation == .modal { + safeInsets.top = 0.0 + } return safeInsets } return UIEdgeInsets() diff --git a/submodules/TelegramUI/TelegramUI/ChatController.swift b/submodules/TelegramUI/TelegramUI/ChatController.swift index 84f9f1ecd5..08fbf58a3a 100644 --- a/submodules/TelegramUI/TelegramUI/ChatController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatController.swift @@ -5345,7 +5345,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } strongSelf.chatDisplayNode.dismissInput() - legacyController.navigationPresentation = .modal (strongSelf.navigationController as? NavigationController)?.pushViewController(legacyController) } }) diff --git a/submodules/TelegramUI/TelegramUI/SharedAccountContext.swift b/submodules/TelegramUI/TelegramUI/SharedAccountContext.swift index 1e334c4072..025da0b0be 100644 --- a/submodules/TelegramUI/TelegramUI/SharedAccountContext.swift +++ b/submodules/TelegramUI/TelegramUI/SharedAccountContext.swift @@ -15,6 +15,8 @@ import PeerInfoUI import SettingsUI import UrlHandling import WalletUI +import LegacyMediaPickerUI +import LocalMediaResources private enum CallStatusText: Equatable { case none @@ -1056,6 +1058,38 @@ public final class SharedAccountContextImpl: SharedAccountContext { } }) } + + public func openImagePicker(context: AccountContext, completion: @escaping (UIImage) -> Void, present: @escaping (ViewController) -> Void) { + let presentationData = context.sharedContext.currentPresentationData.with { $0 } + let _ = legacyWallpaperPicker(context: context, presentationData: presentationData).start(next: { generator in + let legacyController = LegacyController(presentation: .navigation, theme: presentationData.theme) + legacyController.navigationPresentation = .modal + legacyController.statusBar.statusBarStyle = presentationData.theme.rootController.statusBarStyle.style + + let controller = generator(legacyController.context) + legacyController.bind(controller: controller) + legacyController.deferScreenEdgeGestures = [.top] + controller.selectionBlock = { [weak legacyController, weak controller] asset, _ in + if let asset = asset { + let _ = (fetchPhotoLibraryImage(localIdentifier: asset.backingAsset.localIdentifier, thumbnail: false) + |> deliverOnMainQueue).start(next: { imageAndFlag in + if let (image, _) = imageAndFlag { + completion(image) + } + }) + if let legacyController = legacyController { + legacyController.dismiss() + } + } + } + controller.dismissalBlock = { [weak legacyController] in + if let legacyController = legacyController { + legacyController.dismiss() + } + } + present(legacyController) + }) + } } private let defaultChatControllerInteraction = ChatControllerInteraction.default diff --git a/submodules/WalletUI/BUCK b/submodules/WalletUI/BUCK index 1ea4244a02..383583f827 100644 --- a/submodules/WalletUI/BUCK +++ b/submodules/WalletUI/BUCK @@ -32,5 +32,6 @@ static_library( frameworks = [ "$SDKROOT/System/Library/Frameworks/Foundation.framework", "$SDKROOT/System/Library/Frameworks/UIKit.framework", + "$SDKROOT/System/Library/Frameworks/CoreImage.framework", ], ) diff --git a/submodules/WalletUI/Sources/WalletQrScanScreen.swift b/submodules/WalletUI/Sources/WalletQrScanScreen.swift index acf8b5ae2d..8792e5e00f 100644 --- a/submodules/WalletUI/Sources/WalletQrScanScreen.swift +++ b/submodules/WalletUI/Sources/WalletQrScanScreen.swift @@ -10,6 +10,8 @@ import TelegramCore import Camera import GlassButtonNode import UrlHandling +import CoreImage +import AlertUI private func generateFrameImage() -> UIImage? { return generateImage(CGSize(width: 64.0, height: 64.0), contextGenerator: { size, context in @@ -115,6 +117,38 @@ public final class WalletQrScanScreen: ViewController { strongSelf.completion(parsedWalletUrl) } }) + + (self.displayNode as! WalletQrScanScreenNode).presentGallery = { [weak self] in + guard let strongSelf = self else { + return + } + strongSelf.context.sharedContext.openImagePicker(context: strongSelf.context, completion: { image in + let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy:CIDetectorAccuracyHigh])! + if let ciImage = CIImage(image: image) { + var options: [String: Any] + if ciImage.properties.keys.contains((kCGImagePropertyOrientation as String)) { + options = [CIDetectorImageOrientation: ciImage.properties[(kCGImagePropertyOrientation as String)] ?? 1] + } else { + options = [CIDetectorImageOrientation: 1] + } + + let features = detector.features(in: ciImage, options: options) + for case let row as CIQRCodeFeature in features { + guard let message = row.messageString else { + continue + } + if let url = URL(string: message), let parsedWalletUrl = parseWalletUrl(url) { + strongSelf.completion(parsedWalletUrl) + return + } + } + } + let controller = textAlertController(context: strongSelf.context, title: nil, text: "No valid QR code detected.", actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]) + strongSelf.present(controller, in: .window(.root)) + }, present: { [weak self] c in + self?.push(c) + }) + } } override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { @@ -144,6 +178,8 @@ private final class WalletQrScanScreenNode: ViewControllerTracingNode, UIScrollV fileprivate let focusedCode = ValuePromise(ignoreRepeated: true) private var focusedRect: CGRect? + var presentGallery: (() -> Void)? + private var validLayout: (ContainerViewLayout, CGFloat)? init(presentationData: PresentationData) { @@ -308,7 +344,7 @@ private final class WalletQrScanScreenNode: ViewControllerTracingNode, UIScrollV } @objc private func galleryPressed() { - + self.presentGallery?() } @objc private func torchPressed() {