Add pinch to zoom deps
Add image interactions Add image preview to timeline Signed-off-by: Gheorghe Pinzaru <feross95@gmail.com>
This commit is contained in:
parent
fbb606b859
commit
13c81a34b3
|
@ -47,6 +47,7 @@
|
||||||
"react-native-haptic-feedback": "^1.9.0",
|
"react-native-haptic-feedback": "^1.9.0",
|
||||||
"react-native-image-crop-picker": "^0.31.1",
|
"react-native-image-crop-picker": "^0.31.1",
|
||||||
"react-native-image-resizer": "^1.2.3",
|
"react-native-image-resizer": "^1.2.3",
|
||||||
|
"react-native-image-viewing": "git+https://github.com/Ferossgp/react-native-image-viewing.git#v0.2.1",
|
||||||
"react-native-keychain": "git+https://github.com/status-im/react-native-keychain.git#v.3.0.0-5-status",
|
"react-native-keychain": "git+https://github.com/status-im/react-native-keychain.git#v.3.0.0-5-status",
|
||||||
"react-native-languages": "^3.0.2",
|
"react-native-languages": "^3.0.2",
|
||||||
"react-native-linear-gradient": "^2.5.6",
|
"react-native-linear-gradient": "^2.5.6",
|
||||||
|
|
|
@ -121,7 +121,7 @@
|
||||||
{:font-scale (.-fontScale window)
|
{:font-scale (.-fontScale window)
|
||||||
:height (.-height ^js window)
|
:height (.-height ^js window)
|
||||||
:scale (.-scale ^js window)
|
:scale (.-scale ^js window)
|
||||||
:width (.-window ^js window)}))
|
:width (.-width ^js window)}))
|
||||||
|
|
||||||
(def use-back-handler (.-useBackHandler hooks))
|
(def use-back-handler (.-useBackHandler hooks))
|
||||||
|
|
||||||
|
|
|
@ -1,39 +1,79 @@
|
||||||
(ns status-im.ui.screens.chat.image.preview.views
|
(ns status-im.ui.screens.chat.image.preview.views
|
||||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
|
||||||
(:require [status-im.ui.components.colors :as colors]
|
(:require [status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
|
[reagent.core :as reagent]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
|
[quo.platform :as platform]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.ui.components.icons.vector-icons :as icons]
|
[status-im.ui.components.icons.vector-icons :as icons]
|
||||||
[status-im.ui.screens.chat.sheets :as sheets]
|
[status-im.ui.screens.chat.sheets :as sheets]
|
||||||
[quo.components.safe-area :as safe-area]))
|
[quo.components.safe-area :as safe-area]
|
||||||
|
["react-native-image-viewing" :default image-viewing]))
|
||||||
|
|
||||||
(defview preview-image []
|
(defn footer-options []
|
||||||
(letsubs [{:keys [content] :as message} [:get-screen-params]
|
(let [show-sheet (reagent/atom false)]
|
||||||
{:keys [width height]} [:dimensions/window]]
|
(fn [{:keys [message on-close]}]
|
||||||
|
;; FIXME(Ferossgp): Bottom sheet doesn't work on Android because of https://github.com/software-mansion/react-native-gesture-handler/issues/139
|
||||||
|
(if platform/android?
|
||||||
|
[:<>
|
||||||
|
[react/touchable-opacity
|
||||||
|
{:on-press (fn []
|
||||||
|
(on-close)
|
||||||
|
(re-frame/dispatch [:chat.ui/save-image-to-gallery (get-in message [:content :image])]))
|
||||||
|
:style {:background-color colors/black-transparent-86
|
||||||
|
:border-radius 44
|
||||||
|
:padding 8
|
||||||
|
:position :absolute
|
||||||
|
:bottom 0
|
||||||
|
:right 0}}
|
||||||
|
[icons/icon :main-icons/download {:container-style {:width 24
|
||||||
|
:height 24}
|
||||||
|
:color colors/white-persist}]]]
|
||||||
|
[:<>
|
||||||
|
[react/touchable-opacity
|
||||||
|
{:on-press #(reset! show-sheet true)
|
||||||
|
:style {:background-color colors/black-transparent-86
|
||||||
|
:border-radius 44
|
||||||
|
:padding 8
|
||||||
|
:position :absolute
|
||||||
|
:bottom 0
|
||||||
|
:right 0}}
|
||||||
|
[icons/icon :main-icons/more {:container-style {:width 24
|
||||||
|
:height 24}
|
||||||
|
:color colors/white-persist}]]
|
||||||
|
;; NOTE(Ferossgp): If we use global bottom sheet, then it is rendered under the preview
|
||||||
|
[quo/bottom-sheet {:visible? @show-sheet
|
||||||
|
:on-cancel #(reset! show-sheet false)}
|
||||||
|
[sheets/image-long-press message #(do (reset! show-sheet false)
|
||||||
|
(on-close))]]]))))
|
||||||
|
|
||||||
|
(defn footer [{:keys [on-close] :as props}]
|
||||||
[safe-area/consumer
|
[safe-area/consumer
|
||||||
(fn [insets]
|
(fn [insets]
|
||||||
[react/view {:style {:flex 1 :justify-content :flex-end
|
[react/view {:style {:padding-horizontal 24
|
||||||
:padding-top (:top insets) :padding-bottom (:bottom insets)
|
:padding-bottom (+ (:bottom insets) 8)}}
|
||||||
:background-color colors/black-persist}}
|
[react/view {:style {:justify-content :center
|
||||||
[react/view {:flex 1 :align-items :center :justify-content :center}
|
:align-items :center}}
|
||||||
[react/image {:style (merge {:width width
|
[react/touchable-opacity {:on-press on-close
|
||||||
:height (- height 200)
|
:style {:background-color colors/black-transparent-86
|
||||||
:background-color :black})
|
:padding-horizontal 24
|
||||||
:resize-mode :contain
|
:padding-vertical 11
|
||||||
:source {:uri (:image content)}}]]
|
:border-radius 44}}
|
||||||
[react/view {:flex-direction :row :padding-horizontal 8
|
[quo/text {:style {:color colors/white-persist}}
|
||||||
:justify-content :space-between :align-items :center}
|
(i18n/label :t/close)]]
|
||||||
[react/view {:width 64}]
|
[footer-options props]]])])
|
||||||
[quo/button {:on-press #(re-frame/dispatch [:navigate-back])
|
|
||||||
:type :secondary
|
(defn preview-image [{{:keys [content] :as message} :message
|
||||||
:text-style {:color colors/white-persist}}
|
visible :visible
|
||||||
(i18n/label :t/close)]
|
on-close :on-close}]
|
||||||
[react/touchable-highlight
|
[:> image-viewing {:images #js [#js {:uri (:image content)}]
|
||||||
{:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
:on-request-close on-close
|
||||||
{:content (sheets/image-long-press message true)
|
:hide-header-on-zoom false
|
||||||
:height 64}])}
|
:hide-footer-on-zoom false
|
||||||
[icons/icon :main-icons/more {:container-style {:width 24 :height 24
|
:swipe-to-close-enabled platform/ios?
|
||||||
:margin 20}
|
:presentation-style "overFullScreen"
|
||||||
:color colors/white-persist}]]]])]))
|
:HeaderComponent #(reagent/as-element [:<>]) ; NOTE: Keep it to remove default header
|
||||||
|
:FooterComponent #(reagent/as-element [footer {:on-close on-close
|
||||||
|
:message message}])
|
||||||
|
:visible visible}])
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
[status-im.utils.contenthash :as contenthash]
|
[status-im.utils.contenthash :as contenthash]
|
||||||
[status-im.utils.security :as security]
|
[status-im.utils.security :as security]
|
||||||
[status-im.ui.screens.chat.message.reactions :as reactions]
|
[status-im.ui.screens.chat.message.reactions :as reactions]
|
||||||
|
[status-im.ui.screens.chat.image.preview.views :as preview]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.ui.screens.chat.components.reply :as components.reply]
|
[status-im.ui.screens.chat.components.reply :as components.reply]
|
||||||
|
@ -226,6 +227,7 @@
|
||||||
|
|
||||||
(defn message-content-image [{:keys [content outgoing] :as message} {:keys [on-long-press]}]
|
(defn message-content-image [{:keys [content outgoing] :as message} {:keys [on-long-press]}]
|
||||||
(let [dimensions (reagent/atom [260 260])
|
(let [dimensions (reagent/atom [260 260])
|
||||||
|
visible (reagent/atom false)
|
||||||
uri (:image content)]
|
uri (:image content)]
|
||||||
(react/image-get-size
|
(react/image-get-size
|
||||||
uri
|
uri
|
||||||
|
@ -236,9 +238,13 @@
|
||||||
style-opts {:outgoing outgoing
|
style-opts {:outgoing outgoing
|
||||||
:width (/ (first @dimensions) k)
|
:width (/ (first @dimensions) k)
|
||||||
:height (/ (second @dimensions) k)}]
|
:height (/ (second @dimensions) k)}]
|
||||||
|
[:<>
|
||||||
|
[preview/preview-image {:message message
|
||||||
|
:visible @visible
|
||||||
|
:on-close #(do (reset! visible false)
|
||||||
|
(reagent/flush))}]
|
||||||
[react/touchable-highlight {:on-press (fn []
|
[react/touchable-highlight {:on-press (fn []
|
||||||
(when (:image content)
|
(reset! visible true)
|
||||||
(re-frame/dispatch [:navigate-to :image-preview message]))
|
|
||||||
(react/dismiss-keyboard!))
|
(react/dismiss-keyboard!))
|
||||||
:on-long-press on-long-press}
|
:on-long-press on-long-press}
|
||||||
[react/view {:style (style/image-message style-opts)}
|
[react/view {:style (style/image-message style-opts)}
|
||||||
|
@ -246,7 +252,7 @@
|
||||||
:height (/ (second @dimensions) k)}
|
:height (/ (second @dimensions) k)}
|
||||||
:resize-mode :contain
|
:resize-mode :contain
|
||||||
:source {:uri uri}}]
|
:source {:uri uri}}]
|
||||||
[react/view {:style (style/image-message-border style-opts)}]]]))))
|
[react/view {:style (style/image-message-border style-opts)}]]]]))))
|
||||||
|
|
||||||
(defmulti ->message :content-type)
|
(defmulti ->message :content-type)
|
||||||
|
|
||||||
|
|
|
@ -141,8 +141,7 @@
|
||||||
:accessibility-label :delete-transaccent-button
|
:accessibility-label :delete-transaccent-button
|
||||||
:on-press #(hide-sheet-and-dispatch [:chat.ui/delete-message chat-id message-id])}]]))
|
:on-press #(hide-sheet-and-dispatch [:chat.ui/delete-message chat-id message-id])}]]))
|
||||||
|
|
||||||
(defn image-long-press [{:keys [content identicon from outgoing cant-be-replied] :as message} from-preview?]
|
(defn image-long-press [{:keys [content identicon from outgoing cant-be-replied] :as message} hide]
|
||||||
(fn []
|
|
||||||
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
|
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
|
||||||
[react/view
|
[react/view
|
||||||
(when-not outgoing
|
(when-not outgoing
|
||||||
|
@ -156,18 +155,16 @@
|
||||||
:accessibility-label :view-chat-details-button
|
:accessibility-label :view-chat-details-button
|
||||||
:chevron true
|
:chevron true
|
||||||
:on-press #(do
|
:on-press #(do
|
||||||
(when from-preview?
|
(hide)
|
||||||
(re-frame/dispatch [:navigate-back]))
|
(re-frame/dispatch [:chat.ui/show-profile from]))}])
|
||||||
(hide-sheet-and-dispatch [:chat.ui/show-profile from]))}])
|
|
||||||
(when-not cant-be-replied
|
(when-not cant-be-replied
|
||||||
[quo/list-item
|
[quo/list-item
|
||||||
{:theme :accent
|
{:theme :accent
|
||||||
:title (i18n/label :t/message-reply)
|
:title (i18n/label :t/message-reply)
|
||||||
:icon :main-icons/reply
|
:icon :main-icons/reply
|
||||||
:on-press #(do
|
:on-press #(do
|
||||||
(when from-preview?
|
(hide)
|
||||||
(re-frame/dispatch [:navigate-back]))
|
(re-frame/dispatch [:chat.ui/reply-to-message message]))}])
|
||||||
(hide-sheet-and-dispatch [:chat.ui/reply-to-message message]))}])
|
|
||||||
;; we have only base64 string for image, so we need to find a way how to copy it
|
;; we have only base64 string for image, so we need to find a way how to copy it
|
||||||
#_[quo/list-item
|
#_[quo/list-item
|
||||||
{:theme :accent
|
{:theme :accent
|
||||||
|
@ -181,7 +178,8 @@
|
||||||
:title (i18n/label :t/save)
|
:title (i18n/label :t/save)
|
||||||
:icon :main-icons/download
|
:icon :main-icons/download
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(hide-sheet-and-dispatch [:chat.ui/save-image-to-gallery (:image content)]))}]
|
(hide)
|
||||||
|
(re-frame/dispatch [:chat.ui/save-image-to-gallery (:image content)]))}]
|
||||||
;; we have only base64 string for image, so we need to find a way how to share it
|
;; we have only base64 string for image, so we need to find a way how to share it
|
||||||
#_[quo/list-item
|
#_[quo/list-item
|
||||||
{:theme :accent
|
{:theme :accent
|
||||||
|
@ -189,4 +187,4 @@
|
||||||
:icon :main-icons/share
|
:icon :main-icons/share
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(re-frame/dispatch [:bottom-sheet/hide])
|
(re-frame/dispatch [:bottom-sheet/hide])
|
||||||
(list-selection/open-share {:message (:image content)}))}]])))
|
(list-selection/open-share {:message (:image content)}))}]]))
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[quo.previews.main :as quo.preview]
|
[quo.previews.main :as quo.preview]
|
||||||
[status-im.utils.config :as config]
|
[status-im.utils.config :as config]
|
||||||
[status-im.ui.screens.chat.image.preview.views :as image-preview]
|
|
||||||
[status-im.ui.screens.profile.contact.views :as contact]
|
[status-im.ui.screens.profile.contact.views :as contact]
|
||||||
[status-im.ui.screens.notifications-settings.views :as notifications-settings]
|
[status-im.ui.screens.notifications-settings.views :as notifications-settings]
|
||||||
[status-im.ui.screens.wallet.send.views :as wallet]
|
[status-im.ui.screens.wallet.send.views :as wallet]
|
||||||
|
@ -122,9 +121,6 @@
|
||||||
{:name :qr-scanner
|
{:name :qr-scanner
|
||||||
:insets {:top false :bottom false}
|
:insets {:top false :bottom false}
|
||||||
:component qr-scanner/qr-scanner}
|
:component qr-scanner/qr-scanner}
|
||||||
{:name :image-preview
|
|
||||||
:insets {:top false :bottom false}
|
|
||||||
:component image-preview/preview-image}
|
|
||||||
{:name :notifications-settings
|
{:name :notifications-settings
|
||||||
:back-handler :noop
|
:back-handler :noop
|
||||||
:insets {:bottom true}
|
:insets {:bottom true}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
[status-im.ui.screens.status.styles :as styles]
|
[status-im.ui.screens.status.styles :as styles]
|
||||||
[status-im.ui.screens.chat.views :as chat.views]
|
[status-im.ui.screens.chat.views :as chat.views]
|
||||||
[status-im.ui.components.plus-button :as components.plus-button]
|
[status-im.ui.components.plus-button :as components.plus-button]
|
||||||
|
[status-im.ui.screens.chat.image.preview.views :as preview]
|
||||||
[status-im.ui.screens.chat.photos :as photos]
|
[status-im.ui.screens.chat.photos :as photos]
|
||||||
[status-im.ui.components.tabs :as tabs]
|
[status-im.ui.components.tabs :as tabs]
|
||||||
[status-im.utils.contenthash :as contenthash]
|
[status-im.utils.contenthash :as contenthash]
|
||||||
|
@ -53,13 +54,19 @@
|
||||||
:justify-content :center}
|
:justify-content :center}
|
||||||
[icons/icon :main-icons/close-circle {:color colors/white-persist}]]])])))
|
[icons/icon :main-icons/close-circle {:color colors/white-persist}]]])])))
|
||||||
|
|
||||||
(defn image-message [{:keys [content] :as message}]
|
(defn image-message []
|
||||||
|
(let [visible (reagent/atom false)]
|
||||||
|
(fn [{:keys [content] :as message}]
|
||||||
|
[:<>
|
||||||
|
[preview/preview-image {:message (assoc message :cant-be-replied true)
|
||||||
|
:visible @visible
|
||||||
|
:can-reply false
|
||||||
|
:on-close #(do (reset! visible false)
|
||||||
|
(reagent/flush))}]
|
||||||
[react/touchable-highlight {:on-press (fn [_]
|
[react/touchable-highlight {:on-press (fn [_]
|
||||||
(when (:image content)
|
(reset! visible true)
|
||||||
(re-frame/dispatch [:navigate-to :image-preview
|
|
||||||
(assoc message :cant-be-replied true)]))
|
|
||||||
(react/dismiss-keyboard!))}
|
(react/dismiss-keyboard!))}
|
||||||
[message-content-image (:image content) false]])
|
[message-content-image (:image content) false]]])))
|
||||||
|
|
||||||
(defn message-item [{:keys [content-type content from last-in-group? timestamp identicon outgoing] :as message} timeline? account]
|
(defn message-item [{:keys [content-type content from last-in-group? timestamp identicon outgoing] :as message} timeline? account]
|
||||||
[react/view (when last-in-group?
|
[react/view (when last-in-group?
|
||||||
|
|
|
@ -6613,6 +6613,10 @@ react-native-image-resizer@^1.2.3:
|
||||||
resolved "https://registry.yarnpkg.com/react-native-image-resizer/-/react-native-image-resizer-1.2.3.tgz#21cb2b158ff950e55a0fc01c2cb61375bd5a03ba"
|
resolved "https://registry.yarnpkg.com/react-native-image-resizer/-/react-native-image-resizer-1.2.3.tgz#21cb2b158ff950e55a0fc01c2cb61375bd5a03ba"
|
||||||
integrity sha512-RDPNJglRmWDZ/7hvu+CbpsKYl6AQmseL8cWX4UkLAHxQWNc5ZdYhP/9avC5xCfyiwkRw+Zmkmv78HO0kt0ewhQ==
|
integrity sha512-RDPNJglRmWDZ/7hvu+CbpsKYl6AQmseL8cWX4UkLAHxQWNc5ZdYhP/9avC5xCfyiwkRw+Zmkmv78HO0kt0ewhQ==
|
||||||
|
|
||||||
|
"react-native-image-viewing@git+https://github.com/Ferossgp/react-native-image-viewing.git#v0.2.1":
|
||||||
|
version "0.2.1"
|
||||||
|
resolved "git+https://github.com/Ferossgp/react-native-image-viewing.git#8ef67cdce7b7c66065a939847e45db71347c678e"
|
||||||
|
|
||||||
react-native-iphone-x-helper@^1.2.1:
|
react-native-iphone-x-helper@^1.2.1:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772"
|
resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772"
|
||||||
|
|
Loading…
Reference in New Issue