feat: save image (#16268)

* feat: save image
This commit is contained in:
Omar Basem 2023-06-27 11:03:29 +04:00 committed by GitHub
parent cd32806c96
commit 86219dbad8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 26 deletions

View File

@ -1,5 +1,6 @@
(ns react-native.cameraroll (ns react-native.cameraroll
(:require ["@react-native-community/cameraroll" :as CameraRoll] (:require ["@react-native-community/cameraroll" :as CameraRoll]
[react-native.fs :as fs]
[utils.transforms :as transforms] [utils.transforms :as transforms]
[taoensso.timbre :as log])) [taoensso.timbre :as log]))
@ -14,3 +15,9 @@
(-> (.getAlbums CameraRoll (clj->js opts)) (-> (.getAlbums CameraRoll (clj->js opts))
(.then #(callback (transforms/js->clj %))) (.then #(callback (transforms/js->clj %)))
(.catch #(log/warn "could not get camera roll albums" %)))) (.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))))

View File

@ -1,16 +1,13 @@
(ns status-im.chat.models.images (ns status-im.chat.models.images
(:require ["@react-native-community/cameraroll" :as CameraRoll] (:require ["react-native-blob-util" :default ReactNativeBlobUtil]
["react-native-blob-util" :default ReactNativeBlobUtil]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[react-native.share :as share] [react-native.share :as share]
[utils.i18n :as i18n] [react-native.cameraroll :as cameraroll]
[react-native.permissions :as permissions]
[status-im.ui.components.react :as react] [status-im.ui.components.react :as react]
[status-im2.config :as config] [status-im2.config :as config]
[react-native.fs :as fs] [react-native.fs :as fs]
[utils.re-frame :as rf] [utils.re-frame :as rf]
[status-im.utils.platform :as platform] [status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]
[taoensso.timbre :as log])) [taoensso.timbre :as log]))
(def temp-image-url (str (fs/cache-dir) "/StatusIm_Image.jpeg")) (def temp-image-url (str (fs/cache-dir) "/StatusIm_Image.jpeg"))
@ -22,7 +19,7 @@
:path temp-image-url})) :path temp-image-url}))
(.fetch "GET" base64-uri) (.fetch "GET" base64-uri)
(.then #(on-success (.path %))) (.then #(on-success (.path %)))
(.catch #(log/error "could not save image")))) (.catch #(log/error "could not download image" {:error %}))))
(defn share-image (defn share-image
[uri] [uri]
@ -33,23 +30,11 @@
#(fs/unlink downloaded-url) #(fs/unlink downloaded-url)
#(fs/unlink downloaded-url))))) #(fs/unlink downloaded-url)))))
(defn save-to-gallery [path] (.save CameraRoll path)) (defn save-image-to-gallery
[base64-uri on-success]
(re-frame/reg-fx (-> (download-image-http base64-uri cameraroll/save-image)
::save-image-to-gallery (.then on-success)
(fn [base64-uri] (.catch #(log/error (str "could not save image to gallery" %)))))
(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))}))))
(re-frame/reg-fx (re-frame/reg-fx
::chat-open-image-picker-camera ::chat-open-image-picker-camera

View File

@ -10,9 +10,10 @@
[status-im2.contexts.chat.lightbox.animations :as anim] [status-im2.contexts.chat.lightbox.animations :as anim]
[status-im2.contexts.chat.lightbox.style :as style] [status-im2.contexts.chat.lightbox.style :as style]
[utils.datetime :as datetime] [utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf] [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 (defn animate-rotation
[result screen-width screen-height insets [result screen-width screen-height insets
@ -41,6 +42,25 @@
(anim/animate top-view-width screen-width) (anim/animate top-view-width screen-width)
(anim/animate top-view-bg colors/neutral-100-opa-0))))) (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 (defn top-view
[messages insets index animations derived landscape? screen-width] [messages insets index animations derived landscape? screen-width]
(let [{:keys [from timestamp content]} (nth @messages @index) (let [{:keys [from timestamp content]} (nth @messages @index)
@ -89,5 +109,6 @@
[quo/icon :share {:size 20 :color colors/white}]] [quo/icon :share {:size 20 :color colors/white}]]
[rn/touchable-opacity [rn/touchable-opacity
{:active-opacity 1 {:active-opacity 1
:on-press #(rf/dispatch [:show-bottom-sheet {:content (fn [] [drawer content])}])
:style style/close-container} :style style/close-container}
[quo/icon :options {:size 20 :color colors/white}]]]])) [quo/icon :options {:size 20 :color colors/white}]]]]))

View File

@ -2244,5 +2244,6 @@
"chat-muted-till-unmuted": "Chat muted till unmuted\n (until {{duration}}) ", "chat-muted-till-unmuted": "Chat muted till unmuted\n (until {{duration}}) ",
"until": "until", "until": "until",
"chat-unmuted-successfully": "Chat unmuted successfully! ", "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"
} }