Skip to content

Commit

Permalink
fixes #6596
Browse files Browse the repository at this point in the history
  • Loading branch information
tbenr committed Feb 1, 2019
1 parent 10739cd commit 240226a
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 25 deletions.
63 changes: 63 additions & 0 deletions src/status_im/extensions/camera.cljs
@@ -0,0 +1,63 @@
(ns status-im.extensions.camera
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.utils.fx :as fx]
[status-im.extensions.views :as ext-views]
[status-im.ui.components.list-selection :as list-selection]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.handlers :as handlers]))

;; Common

(handlers/register-handler-fx
:extensions/camera-cancel
(fn [_ [_ _ {{:keys [on-failure]} :data}]]
(when on-failure
(re-frame/dispatch (on-failure {:result "user cancelled"})))))

(handlers/register-handler-fx
:extensions/camera-denied
(fn [_ [_ {{:keys [on-failure]} :data}]]
(when on-failure
(re-frame/dispatch (on-failure {:result "user denied access to camera"})))))

;; Photo taker\picker

(handlers/register-handler-fx
:extensions/camera-error
(fn [cofx [_ error {:keys [on-failure]}]]
(fx/merge cofx
{:dispatch (on-failure {:result error})}
(navigation/navigate-back))))

(handlers/register-handler-fx
:extensions/camera-picture-taken
(fn [cofx [_ base64 {{:keys [on-success]} :data}]]
(fx/merge cofx
{:dispatch (on-success {:result base64})}
(navigation/navigate-back))))

(handlers/register-handler-fx
:extensions/camera-picture
(fn [{db :db} [_ _ params]]
(list-selection/show (ext-views/pick-or-take-picture-list-selection {:data params}))))

;; QR code scanner

(handlers/register-handler-fx
:extensions/camera-qr-code-scanned
(fn [cofx [_ _ qr-code {{:keys [on-success]} :data}]]
(fx/merge cofx
{:dispatch (on-success {:result qr-code})}
(navigation/navigate-back))))

(handlers/register-handler-fx
:extensions/camera-qr-code
(fn [{:keys [db] :as cofx} [_ _ {:keys [on-success on-failure]}]]
(qr-scanner/scan-qr-code cofx {:modal? false
:deny-handler :extensions/camera-denied}
{:handler :extensions/camera-qr-code-scanned
:cancel-handler :extensions/camera-cancel
:data {:on-success on-success
:on-failure on-failure}})))
11 changes: 11 additions & 0 deletions src/status_im/extensions/core.cljs
Expand Up @@ -20,6 +20,7 @@
[status-im.utils.handlers :as handlers]
[status-im.utils.fx :as fx]
status-im.extensions.ethereum
status-im.extensions.camera
[status-im.utils.ethereum.tokens :as tokens]
[status-im.utils.ethereum.core :as ethereum]
[status-im.chat.commands.sending :as commands-sending]))
Expand Down Expand Up @@ -464,6 +465,16 @@
:arguments {:values :vector
:operation {:one-of #{:plus :minus :times :divide}}
:on-result :event}}
'camera/picture
{:permissions [:read]
:value :extensions/camera-picture
:arguments {:on-success :event
:on-failure? :event}}
'camera/qr-code
{:permissions [:read]
:value :extensions/camera-qr-code
:arguments {:on-success :event
:on-failure? :event}}
'schedule/start
{:permissions [:read]
:value :extensions/schedule-start
Expand Down
66 changes: 66 additions & 0 deletions src/status_im/extensions/views.cljs
@@ -0,0 +1,66 @@
(ns status-im.extensions.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.ui.components.camera :as camera]
[status-im.ui.components.react :as react]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.toolbar.actions :as actions]
[status-im.ui.components.icons.vector-icons :as icons]
[status-im.i18n :as i18n]
[status-im.ui.screens.profile.photo-capture.styles :as styles]
[status-im.utils.image-processing :as image-processing]))

;; ensure photo taken or picked are not too big
(def max-width 1024)
(def max-height 1024)

(defn- process-image-and-finish [path context]
(let [on-success (fn [base64]
(re-frame/dispatch [:extensions/camera-picture-taken base64 context]))
on-error (fn [type error]
(re-frame/dispatch [:extensions/camera-error error context]))]
(image-processing/img->base64 path on-success on-error max-width max-height)))

(defview take-picture []
(letsubs [context [:get-screen-params]
camera-ref (reagent/atom false)]
[react/view styles/container
[status-bar/status-bar]
[toolbar/toolbar nil
[toolbar/nav-button (actions/back
#(do
(re-frame/dispatch [:extensions/camera-cancel context])
(re-frame/dispatch [:navigate-back])))]
[toolbar/content-title (i18n/label :t/extensions-camera-send-picture)]]
[camera/camera {:style {:flex 1}
:aspect (:fill camera/aspects)
:captureTarget (:disk camera/capture-targets)
:ref #(reset! camera-ref %)}]
[react/view styles/button-container
[react/view styles/button
[react/touchable-highlight {:on-press (fn []
(let [camera @camera-ref]
(-> (.capture camera)
(.then #(process-image-and-finish (.-path %) context))
(.catch #(re-frame/dispatch [:extensions/camera-error % context])))))}
[react/view
[icons/icon :icons/camera {:color :white}]]]]]]))

(defn- open-image-picker [context]
(react/show-image-picker
(fn [image]
(let [path (get (js->clj image) "path")]
(process-image-and-finish path context)))))

(defn pick-or-take-picture-list-selection [context]
{:title (i18n/label :t/extensions-camera-send-picture)
:options [{:label (i18n/label :t/image-source-gallery)
:action #(open-image-picker context)}
{:label (i18n/label :t/image-source-make-photo)
:action (fn []
(re-frame/dispatch [:request-permissions {:permissions [:camera :write-external-storage]
:on-allowed #(re-frame/dispatch [:navigate-to :take-picture context])
:on-denied #(re-frame/dispatch [:extensions/camera-denied context])}]))}]
:on-cancel #(re-frame/dispatch [:extensions/camera-cancel context])})
14 changes: 8 additions & 6 deletions src/status_im/qr_scanner/core.cljs
Expand Up @@ -5,16 +5,18 @@
[status-im.utils.fx :as fx]))

(fx/defn scan-qr-code
[{:keys [db]} {:keys [modal?] :as identifier} qr-codes]
[{:keys [db]} {:keys [modal? deny-handler] :as identifier} qr-codes]
{:db (assoc db :qr-codes qr-codes)
:request-permissions-fx {:permissions [:camera]
: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)
(i18n/label :t/camera-access-error))
50))}})
:on-denied (if (nil? deny-handler)
(fn []
(utils/set-timeout
#(utils/show-popup (i18n/label :t/error)
(i18n/label :t/camera-access-error))
50))
#(re-frame/dispatch [deny-handler qr-codes]))}})

(fx/defn set-qr-code
[{:keys [db]} context data]
Expand Down
12 changes: 7 additions & 5 deletions src/status_im/ui/components/action_sheet.cljs
Expand Up @@ -3,11 +3,13 @@
[status-im.utils.core :as utils]
[status-im.react-native.js-dependencies :as js-dependencies]))

(defn- callback [options]
(defn- callback [options on-cancel]
(fn [index]
(when (< index (count options))
(if (< index (count options))
(when-let [handler (:action (nth options index))]
(handler)))))
(handler))
(when on-cancel
(on-cancel)))))

(defn- prepare-options [title message options]
(let [destructive-opt-index (utils/first-index :destructive? options)] ;; TODO Can only be a single destructive?
Expand All @@ -18,7 +20,7 @@
(when title {:title title})
(when message {:message message})))))

(defn show [{:keys [title message options]}]
(defn show [{:keys [title message options on-cancel]}]
(.showActionSheetWithOptions (.-ActionSheetIOS js-dependencies/react-native)
(prepare-options title message options)
(callback options)))
(callback options on-cancel)))
20 changes: 12 additions & 8 deletions src/status_im/ui/components/dialog.cljs
Expand Up @@ -3,17 +3,21 @@

(def dialogs (.-default rn-dependencies/dialogs))

(defn show [{:keys [title options cancel-text]}]
(defn show [{:keys [title options cancel-text on-cancel] :as all}]
(.. dialogs
(showPicker title nil (clj->js {:items (mapv #(select-keys % [:label])
options)
:negativeText cancel-text
:positiveText nil}))
(then (fn [selected]
(when-let [label (get-in (js->clj selected :keywordize-keys true)
[:selectedItem :label])]
(when-let [action (->> options
(filter #(= label (:label %)))
first
:action)]
(action)))))))
(let [result (js->clj selected :keywordize-keys true)]
(if (not= (get result :action) "actionSelect")
(when on-cancel
(on-cancel))
(when-let [label (get-in result
[:selectedItem :label])]
(when-let [action (->> options
(filter #(= label (:label %)))
first
:action)]
(action)))))))))
1 change: 0 additions & 1 deletion src/status_im/ui/screens/profile/events.cljs
Expand Up @@ -5,7 +5,6 @@
[status-im.ui.screens.profile.models :as profile.models]
[status-im.ui.screens.profile.navigation]
[status-im.ui.components.list-selection :as list-selection]
[status-im.ui.screens.profile.models :as profile.models]
[status-im.utils.handlers :as handlers]
[status-im.utils.identicon :as identicon]
[status-im.utils.universal-links.core :as universal-links]))
Expand Down
2 changes: 1 addition & 1 deletion src/status_im/ui/screens/profile/models.cljs
Expand Up @@ -19,7 +19,7 @@
(re-frame/dispatch [callback-event base64]))
on-error (fn [type error]
(.log js/console type error))]
(image-processing/img->base64 path on-success on-error)))))
(image-processing/img->base64 path on-success on-error 150 150)))))

(defn send-transaction [chat-id {:keys [db] :as cofx}]
(let [send-command (get-in db [:id->command ["send" #{:personal-chats}]])]
Expand Down
2 changes: 1 addition & 1 deletion src/status_im/ui/screens/profile/photo_capture/views.cljs
Expand Up @@ -20,7 +20,7 @@
(re-frame/dispatch [:navigate-back]))
on-error (fn [type error]
(log/debug type error))]
(image-processing/img->base64 path on-success on-error)))
(image-processing/img->base64 path on-success on-error 150 150)))

(defn profile-photo-capture []
(let [camera-ref (reagent/atom nil)]
Expand Down
2 changes: 2 additions & 0 deletions src/status_im/ui/screens/views.cljs
Expand Up @@ -27,6 +27,7 @@
[status-im.ui.screens.profile.contact.views :as profile.contact]
[status-im.ui.screens.profile.group-chat.views :as profile.group-chat]
[status-im.ui.screens.profile.photo-capture.views :refer [profile-photo-capture]]
[status-im.extensions.views :refer [take-picture]]
[status-im.ui.screens.wallet.main.views :as wallet.main]
[status-im.ui.screens.wallet.collectibles.views :refer [collectibles-list]]
[status-im.ui.screens.wallet.send.views :refer [send-transaction send-transaction-modal sign-message-modal]]
Expand Down Expand Up @@ -160,6 +161,7 @@
:new add-new
:new-chat new-chat
:qr-scanner qr-scanner
:take-picture take-picture
:new-group new-group
:add-participants-toggle-list add-participants-toggle-list
:contact-toggle-list contact-toggle-list
Expand Down
4 changes: 2 additions & 2 deletions src/status_im/utils/image_processing.cljs
Expand Up @@ -18,12 +18,12 @@
(on-error :base64 error))]
(read-file path "base64" on-success on-error)))

(defn img->base64 [path on-success on-error]
(defn img->base64 [path on-success on-error max-width max-height]
(let [on-resized (fn [image]
(let [path (object/get image "path")]
(log/debug "Resized: " path)
(image-base64-encode path on-success on-error)))
on-error (fn [error]
(log/debug "Resized error: " error)
(on-error :resize error))]
(resize path 150 150 on-resized on-error)))
(resize path max-width max-height on-resized on-error)))
3 changes: 2 additions & 1 deletion translations/en.json
Expand Up @@ -895,5 +895,6 @@
"sticker-market": "Sticker market",
"you-dont-have-stickers": "You don’t have any stickers yet",
"get-stickers": "Get Stickers",
"recently-used-stickers": "Recently used stickers will appear here"
"recently-used-stickers": "Recently used stickers will appear here",
"extensions-camera-send-picture": "Send picture"
}

0 comments on commit 240226a

Please sign in to comment.