diff --git a/resources/js/web3_init.js b/resources/js/web3_init.js index b16151dce5..9f465a24ed 100644 --- a/resources/js/web3_init.js +++ b/resources/js/web3_init.js @@ -47,6 +47,25 @@ WebViewBridge.onMessage = function (message) { } } } + + else if (data.type === "scan-qr-code-callback") + { + var id = data.data.messageId; + var callback = callbacks[id]; + if (callback) { + var result = data.result; + var regex = new RegExp(callback.regex); + if (regex.test(result)) { + if (callback.resolve) { + callback.resolve(result); + } + } else { + if (callback.reject) { + callback.reject(result); + } + } + } + } }; var StatusHttpProvider = function () {}; @@ -114,10 +133,19 @@ StatusHttpProvider.prototype.sendAsync = function (payload, callback) { messageId: messageId, payload: payload}); } - } }; +StatusHttpProvider.prototype.scanQRCode = function (regex) { + return new Promise(function (resolve, reject) { + var messageId = callbackId++; + callbacks[messageId] = {resolve: resolve, reject: reject, regex: regex}; + bridgeSend({type: 'scan-qr-code', + messageId: messageId}); + }); +}; + + StatusHttpProvider.prototype.enable = function () { return new Promise(function (resolve, reject) { setTimeout(resolve, 1000);}); }; diff --git a/src/status_im/browser/core.cljs b/src/status_im/browser/core.cljs index f849a2adc9..93f2a1dd58 100644 --- a/src/status_im/browser/core.cljs +++ b/src/status_im/browser/core.cljs @@ -7,6 +7,7 @@ [status-im.i18n :as i18n] [status-im.js-dependencies :as dependencies] [status-im.native-module.core :as status] + [status-im.qr-scanner.core :as qr-scanner] [status-im.ui.components.list-selection :as list-selection] [status-im.ui.screens.browser.default-dapps :as default-dapps] [status-im.ui.screens.navigation :as navigation] @@ -258,6 +259,12 @@ cofx) (web3-send-async payload message-id cofx)))) +(defn handle-scanned-qr-code + [data message cofx] + (handlers-macro/merge-fx cofx + (send-to-bridge (assoc message :result data)) + (navigation/navigate-back))) + (defn process-bridge-message [message {:keys [db] :as cofx}] (let [{:browser/keys [options browsers]} db @@ -279,6 +286,13 @@ (= type constants/web3-send-async-read-only) (web3-send-async-read-only dapp-name payload messageId cofx) + (= type constants/scan-qr-code) + (qr-scanner/scan-qr-code {:modal? false} + (merge {:handler :browser.bridge.callback/qr-code-scanned} + {:type constants/scan-qr-code-callback + :data data}) + cofx) + (= type constants/status-api-request) (browser.permissions/process-permissions dapp-name permissions cofx)))) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index 39e6891f39..8f6ceb5936 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -196,3 +196,5 @@ (def ^:const web3-send-async "web3-send-async") (def ^:const web3-send-async-read-only "web3-send-async-read-only") (def ^:const web3-send-async-callback "web3-send-async-callback") +(def ^:const scan-qr-code "scan-qr-code") +(def ^:const scan-qr-code-callback "scan-qr-code-callback") diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index e3e3b3826a..e853ff4abb 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -400,12 +400,19 @@ (fn [cofx [_ log-level]] (log-level/show-change-log-level-confirmation log-level cofx))) +;; Browser bridge module + +(handlers/register-handler-fx + :browser.bridge.callback/qr-code-scanned + (fn [cofx [_ _ data message]] + (browser/handle-scanned-qr-code data message cofx))) + ;; qr-scanner module (handlers/register-handler-fx :qr-scanner.ui/scan-qr-code-pressed - (fn [cofx [_ identifier handler]] - (qr-scanner/scan-qr-code identifier handler cofx))) + (fn [cofx [_ identifier handler & [opts]]] + (qr-scanner/scan-qr-code identifier (merge {:handler handler} opts) cofx))) (handlers/register-handler-fx :qr-scanner.callback/scan-qr-code-success diff --git a/src/status_im/qr_scanner/core.cljs b/src/status_im/qr_scanner/core.cljs index ee47ac91bd..e5528ae95a 100644 --- a/src/status_im/qr_scanner/core.cljs +++ b/src/status_im/qr_scanner/core.cljs @@ -4,10 +4,11 @@ [status-im.utils.utils :as utils])) (defn scan-qr-code - [identifier handler {:keys [db]}] - {:db (assoc-in db [:qr-codes identifier] handler) + [{:keys [modal?] :as identifier} qr-codes {:keys [db]}] + {:db (assoc db :qr-codes qr-codes) :request-permissions-fx {:permissions [:camera] - :on-allowed #(re-frame/dispatch [:navigate-to :qr-scanner {:current-qr-context identifier}]) + :on-allowed #(re-frame/dispatch [(if modal? :navigate-to-modal :navigate-to) + :qr-scanner {:current-qr-context identifier}]) :on-denied (fn [] (utils/set-timeout #(utils/show-popup (i18n/label :t/error) @@ -19,5 +20,5 @@ (merge {:db (-> db (update :qr-codes dissoc context) (dissoc :current-qr-context))} - (when-let [handler (get-in db [:qr-codes context])] - {:dispatch [handler context data]}))) + (when-let [qr-codes (:qr-codes db)] + {:dispatch [(:handler qr-codes) context data (dissoc qr-codes :handler)]}))) diff --git a/src/status_im/ui/screens/qr_scanner/views.cljs b/src/status_im/ui/screens/qr_scanner/views.cljs index 5eb4e853bc..4d278b5b98 100644 --- a/src/status_im/ui/screens/qr_scanner/views.cljs +++ b/src/status_im/ui/screens/qr_scanner/views.cljs @@ -2,6 +2,7 @@ (:require-macros [status-im.utils.views :refer [defview letsubs]]) (:require [reagent.core :as reagent] [re-frame.core :as re-frame] + [status-im.i18n :as i18n] [status-im.ui.components.react :as react] [status-im.ui.components.camera :as camera] [status-im.ui.components.status-bar.view :as status-bar] @@ -14,13 +15,20 @@ [status-bar/status-bar] [toolbar/simple-toolbar title]])) +(defn on-barcode-read [identifier data] + (re-frame/dispatch [:qr-scanner.callback/scan-qr-code-success identifier (camera/get-qr-code-data data)])) + (defview qr-scanner [] (letsubs [{identifier :current-qr-context} [:get-screen-params] - camera-initialized? (reagent/atom false)] - + camera-initialized? (reagent/atom false) + barcode-read? (reagent/atom false)] [react/view styles/barcode-scanner-container - [qr-scanner-toolbar (:toolbar-title identifier) (not @camera-initialized?)] - [camera/camera {:onBarCodeRead #(re-frame/dispatch [:qr-scanner.callback/scan-qr-code-success identifier (camera/get-qr-code-data %)]) + [qr-scanner-toolbar (or (:toolbar-title identifier) (i18n/label :t/scan-qr)) (not @camera-initialized?)] + [camera/camera {:onBarCodeRead #(if (:multiple? identifier) + (on-barcode-read identifier %) + (when-not @barcode-read? + (do (reset! barcode-read? true) + (on-barcode-read identifier %)))) :ref #(reset! camera-initialized? true) :captureAudio false :style styles/barcode-scanner}]