From 86219dbad8dc102c360249fa436fbac33167cefd Mon Sep 17 00:00:00 2001 From: Omar Basem Date: Tue, 27 Jun 2023 11:03:29 +0400 Subject: [PATCH] feat: save image (#16268) * feat: save image --- src/react_native/cameraroll.cljs | 7 +++++ src/status_im/chat/models/images.cljs | 31 +++++-------------- .../contexts/chat/lightbox/top_view.cljs | 25 +++++++++++++-- translations/en.json | 3 +- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/react_native/cameraroll.cljs b/src/react_native/cameraroll.cljs index 53b19f76cd..b8994df864 100644 --- a/src/react_native/cameraroll.cljs +++ b/src/react_native/cameraroll.cljs @@ -1,5 +1,6 @@ (ns react-native.cameraroll (:require ["@react-native-community/cameraroll" :as CameraRoll] + [react-native.fs :as fs] [utils.transforms :as transforms] [taoensso.timbre :as log])) @@ -14,3 +15,9 @@ (-> (.getAlbums CameraRoll (clj->js opts)) (.then #(callback (transforms/js->clj %))) (.catch #(log/warn "could not get camera roll albums" %)))) + +(defn save-image + [path] + (-> (.save CameraRoll (clj->js path)) + (.then #(fs/unlink path)) + (.catch #(fs/unlink path)))) diff --git a/src/status_im/chat/models/images.cljs b/src/status_im/chat/models/images.cljs index 7b72cdfd2b..ec9e45ed90 100644 --- a/src/status_im/chat/models/images.cljs +++ b/src/status_im/chat/models/images.cljs @@ -1,16 +1,13 @@ (ns status-im.chat.models.images - (:require ["@react-native-community/cameraroll" :as CameraRoll] - ["react-native-blob-util" :default ReactNativeBlobUtil] + (:require ["react-native-blob-util" :default ReactNativeBlobUtil] [re-frame.core :as re-frame] [react-native.share :as share] - [utils.i18n :as i18n] - [react-native.permissions :as permissions] + [react-native.cameraroll :as cameraroll] [status-im.ui.components.react :as react] [status-im2.config :as config] [react-native.fs :as fs] [utils.re-frame :as rf] [status-im.utils.platform :as platform] - [status-im.utils.utils :as utils] [taoensso.timbre :as log])) (def temp-image-url (str (fs/cache-dir) "/StatusIm_Image.jpeg")) @@ -22,7 +19,7 @@ :path temp-image-url})) (.fetch "GET" base64-uri) (.then #(on-success (.path %))) - (.catch #(log/error "could not save image")))) + (.catch #(log/error "could not download image" {:error %})))) (defn share-image [uri] @@ -33,23 +30,11 @@ #(fs/unlink downloaded-url) #(fs/unlink downloaded-url))))) -(defn save-to-gallery [path] (.save CameraRoll path)) - -(re-frame/reg-fx - ::save-image-to-gallery - (fn [base64-uri] - (if platform/ios? - (-> (download-image-http base64-uri save-to-gallery) - (.catch #(utils/show-popup (i18n/label :t/error) - (i18n/label :t/external-storage-denied)))) - (permissions/request-permissions - {:permissions [:write-external-storage] - :on-allowed #(download-image-http base64-uri save-to-gallery) - :on-denied (fn [] - (utils/set-timeout - #(utils/show-popup (i18n/label :t/error) - (i18n/label :t/external-storage-denied)) - 50))})))) +(defn save-image-to-gallery + [base64-uri on-success] + (-> (download-image-http base64-uri cameraroll/save-image) + (.then on-success) + (.catch #(log/error (str "could not save image to gallery" %))))) (re-frame/reg-fx ::chat-open-image-picker-camera diff --git a/src/status_im2/contexts/chat/lightbox/top_view.cljs b/src/status_im2/contexts/chat/lightbox/top_view.cljs index 42763aedb1..af936fdf2a 100644 --- a/src/status_im2/contexts/chat/lightbox/top_view.cljs +++ b/src/status_im2/contexts/chat/lightbox/top_view.cljs @@ -10,9 +10,10 @@ [status-im2.contexts.chat.lightbox.animations :as anim] [status-im2.contexts.chat.lightbox.style :as style] [utils.datetime :as datetime] + [utils.i18n :as i18n] [utils.re-frame :as rf] - [status-im2.contexts.chat.lightbox.constants :as c] - [status-im.chat.models.images :as images])) + [status-im.chat.models.images :as images] + [status-im2.contexts.chat.lightbox.constants :as c])) (defn animate-rotation [result screen-width screen-height insets @@ -41,6 +42,25 @@ (anim/animate top-view-width screen-width) (anim/animate top-view-bg colors/neutral-100-opa-0))))) +(defn drawer + [content] + (let [uri (http/replace-port (:image content) + (rf/sub [:mediaserver/port]))] + [quo/action-drawer + [[{:icon :i/save + :accessibility-label :save-image + :label (i18n/label :t/save-image-library) + :on-press (fn [] + (rf/dispatch [:hide-bottom-sheet]) + (images/save-image-to-gallery + uri + #(rf/dispatch [:toasts/upsert + {:id :random-id + :icon :correct + :icon-color colors/success-50 + :container-style {:bottom (when platform/android? 20)} + :text (i18n/label :t/photo-saved)}])))}]]])) + (defn top-view [messages insets index animations derived landscape? screen-width] (let [{:keys [from timestamp content]} (nth @messages @index) @@ -89,5 +109,6 @@ [quo/icon :share {:size 20 :color colors/white}]] [rn/touchable-opacity {:active-opacity 1 + :on-press #(rf/dispatch [:show-bottom-sheet {:content (fn [] [drawer content])}]) :style style/close-container} [quo/icon :options {:size 20 :color colors/white}]]]])) diff --git a/translations/en.json b/translations/en.json index 362b0aee5b..771ca9bcc2 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2244,5 +2244,6 @@ "chat-muted-till-unmuted": "Chat muted till unmuted\n (until {{duration}}) ", "until": "until", "chat-unmuted-successfully": "Chat unmuted successfully! ", - "channel-unmuted-successfully": "Channel unmuted successfully! " + "channel-unmuted-successfully": "Channel unmuted successfully! ", + "photo-saved": "Photo saved to your device" }