diff --git a/src/status_im2/contexts/syncing/scan_sync_code/style.cljs b/src/status_im2/contexts/syncing/scan_sync_code/style.cljs index 99dee2194f..6832930132 100644 --- a/src/status_im2/contexts/syncing/scan_sync_code/style.cljs +++ b/src/status_im2/contexts/syncing/scan_sync_code/style.cljs @@ -3,6 +3,8 @@ [react-native.reanimated :as reanimated])) (def screen-padding 20) +(def flash-button-size 32) +(def flash-button-spacing 12) (def flex-spacer {:flex 1}) @@ -69,10 +71,11 @@ {:flex-direction :row :justify-content :space-between}) -(def camera-flash-button +(defn camera-flash-button + [viewfinder] {:position :absolute - :right 20 - :bottom 20}) + :top (- (+ (:y viewfinder) (:height viewfinder)) flash-button-size flash-button-spacing) + :right (+ screen-padding flash-button-spacing)}) (defn border [border1 border2 corner] diff --git a/src/status_im2/contexts/syncing/scan_sync_code/view.cljs b/src/status_im2/contexts/syncing/scan_sync_code/view.cljs index d535229afa..6d518b7e41 100644 --- a/src/status_im2/contexts/syncing/scan_sync_code/view.cljs +++ b/src/status_im2/contexts/syncing/scan_sync_code/view.cljs @@ -3,21 +3,22 @@ [oops.core :as oops] [quo2.core :as quo] [quo2.foundations.colors :as colors] + [react-native.blur :as blur] [react-native.camera-kit :as camera-kit] [react-native.core :as rn] - [react-native.blur :as blur] [react-native.hole-view :as hole-view] [react-native.permissions :as permissions] + [react-native.platform :as platform] + [react-native.reanimated :as reanimated] [react-native.safe-area :as safe-area] [reagent.core :as reagent] + [status-im2.constants :as constants] [status-im2.contexts.syncing.scan-sync-code.style :as style] + [status-im2.contexts.syncing.utils :as sync-utils] + [utils.debounce :as debounce] [utils.i18n :as i18n] [utils.re-frame :as rf] - [status-im2.contexts.syncing.utils :as sync-utils] - [status-im.utils.platform :as platform] - [react-native.reanimated :as reanimated] - [status-im2.constants :as constants] - [utils.debounce :as debounce])) + [utils.transforms :as transforms])) ;; Android allow local network access by default. So, we need this check on iOS only. (defonce preflight-check-passed? (reagent/atom (if platform/ios? false true))) @@ -175,9 +176,7 @@ [rn/view {:style style/qr-view-finder :on-layout (fn [event] - (let [layout (js->clj (oops/oget event "nativeEvent.layout") - :keywordize-keys - true) + (let [layout (transforms/js->clj (oops/oget event "nativeEvent.layout")) view-finder (assoc layout :height (:width layout))] (reset! qr-view-finder view-finder)))}]) @@ -215,15 +214,7 @@ [rn/view [border :border-bottom-width :border-right-width :border-bottom-right-radius] [border-tip {:right 0 :top -1}] - [border-tip {:left -1 :bottom 0}]]] - [quo/button - {:icon true - :type :blur-bg - :size 32 - :accessibility-label :camera-flash - :override-background-color colors/neutral-80-opa-40 - :style style/camera-flash-button} - :i/flashlight-off]] + [border-tip {:left -1 :bottom 0}]]]] [quo/text {:size :paragraph-2 :weight :regular @@ -279,7 +270,7 @@ :text (i18n/label :t/error-this-is-not-a-sync-qr-code)}])))) (defn render-camera - [show-camera? qr-view-finder camera-ref on-read-code show-holes?] + [show-camera? torch-mode qr-view-finder camera-ref on-read-code] (when (and show-camera? (:x qr-view-finder)) [:<> [rn/view {:style style/camera-container} @@ -288,16 +279,13 @@ :style style/camera-style :camera-type camera-kit/camera-type-back :zoom-mode :off - ;; https://github.com/status-im/status-mobile/issues/16243 - :torch-mode :off + :torch-mode torch-mode :scan-barcode true :on-read-code on-read-code}]] [hole-view/hole-view {:style style/hole - :holes (if show-holes? - [(merge qr-view-finder - {:borderRadius 16})] - [])} + :holes [(merge qr-view-finder + {:borderRadius 16})]} [blur/view {:style style/absolute-fill :blur-amount 10 @@ -307,13 +295,17 @@ (defn f-view [{:keys [title show-bottom-view? background animated?]}] - (let [insets (safe-area/get-insets) - active-tab (reagent/atom 1) - qr-view-finder (reagent/atom {}) - render-camera? (reagent/atom false)] + (let [insets (safe-area/get-insets) + active-tab (reagent/atom 1) + qr-view-finder (reagent/atom {}) + render-camera? (reagent/atom false) + torch? (reagent/atom false) + app-state-listener (atom nil)] (fn [] (let [camera-ref (atom nil) read-qr-once? (atom false) + torch-mode (if @torch? :on :off) + flashlight-icon (if @torch? :i/flashlight-on :i/flashlight-off) ;; The below check is to prevent scanning of any QR code ;; when the user is in syncing progress screen user-in-syncing-progress-screen? (= (rf/sub [:view-id]) :syncing-progress) @@ -328,9 +320,8 @@ scan-qr-code-tab? (= @active-tab 1) show-camera? (and scan-qr-code-tab? @camera-permission-granted? - @preflight-check-passed?) - show-holes? (and show-camera? - (boolean (not-empty @qr-view-finder))) + @preflight-check-passed? + (boolean (not-empty @qr-view-finder))) title-opacity (reanimated/use-shared-value (if animated? 0 1)) subtitle-opacity (reanimated/use-shared-value (if animated? 0 1)) content-opacity (reanimated/use-shared-value (if animated? 0 1)) @@ -361,6 +352,13 @@ 0 :easing4)) (if show-camera? 500 0)))] + (rn/use-effect (fn [] + (reset! app-state-listener + (.addEventListener rn/app-state + "change" + #(when (and (not= % "active") @torch?) + (reset! torch? false)))) + #(.remove @app-state-listener))) (when animated? (reanimated/animate-shared-value-with-delay subtitle-opacity 1 constants/onboarding-modal-animation-duration @@ -399,7 +397,7 @@ [:<> background (when (or (not animated?) @render-camera?) - [render-camera show-camera? @qr-view-finder camera-ref on-read-code show-holes?]) + [render-camera show-camera? torch-mode @qr-view-finder camera-ref on-read-code]) [rn/view {:style (style/root-container (:top insets))} [header {:active-tab active-tab @@ -419,11 +417,21 @@ :transform [{:translate-y content-translate-y}]} {})} (case @active-tab - 1 [scan-qr-code-tab qr-view-finder request-camera-permission] + 1 [scan-qr-code-tab qr-view-finder] 2 [enter-sync-code-tab] nil)] [rn/view {:style style/flex-spacer}] - (when show-bottom-view? [bottom-view insets bottom-view-translate-y])]])))) + (when show-bottom-view? [bottom-view insets bottom-view-translate-y]) + (when (and (or (not animated?) @render-camera?) show-camera?) + [quo/button + {:icon true + :type :blur-bg + :size style/flash-button-size + :accessibility-label :camera-flash + :override-background-color colors/neutral-80-opa-40 + :style (style/camera-flash-button @qr-view-finder) + :on-press #(swap! torch? not)} + flashlight-icon])]])))) (defn view [props]