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-image-crop-picker": "^0.31.1",
|
||||
"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-languages": "^3.0.2",
|
||||
"react-native-linear-gradient": "^2.5.6",
|
||||
|
|
|
@ -121,7 +121,7 @@
|
|||
{:font-scale (.-fontScale window)
|
||||
:height (.-height ^js window)
|
||||
:scale (.-scale ^js window)
|
||||
:width (.-window ^js window)}))
|
||||
:width (.-width ^js window)}))
|
||||
|
||||
(def use-back-handler (.-useBackHandler hooks))
|
||||
|
||||
|
|
|
@ -1,39 +1,79 @@
|
|||
(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]
|
||||
[status-im.ui.components.react :as react]
|
||||
[reagent.core :as reagent]
|
||||
[re-frame.core :as re-frame]
|
||||
[quo.core :as quo]
|
||||
[quo.platform :as platform]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.icons.vector-icons :as icons]
|
||||
[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 []
|
||||
(letsubs [{:keys [content] :as message} [:get-screen-params]
|
||||
{:keys [width height]} [:dimensions/window]]
|
||||
[safe-area/consumer
|
||||
(fn [insets]
|
||||
[react/view {:style {:flex 1 :justify-content :flex-end
|
||||
:padding-top (:top insets) :padding-bottom (:bottom insets)
|
||||
:background-color colors/black-persist}}
|
||||
[react/view {:flex 1 :align-items :center :justify-content :center}
|
||||
[react/image {:style (merge {:width width
|
||||
:height (- height 200)
|
||||
:background-color :black})
|
||||
:resize-mode :contain
|
||||
:source {:uri (:image content)}}]]
|
||||
[react/view {:flex-direction :row :padding-horizontal 8
|
||||
:justify-content :space-between :align-items :center}
|
||||
[react/view {:width 64}]
|
||||
[quo/button {:on-press #(re-frame/dispatch [:navigate-back])
|
||||
:type :secondary
|
||||
:text-style {:color colors/white-persist}}
|
||||
(i18n/label :t/close)]
|
||||
[react/touchable-highlight
|
||||
{:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (sheets/image-long-press message true)
|
||||
:height 64}])}
|
||||
[icons/icon :main-icons/more {:container-style {:width 24 :height 24
|
||||
:margin 20}
|
||||
:color colors/white-persist}]]]])]))
|
||||
(defn footer-options []
|
||||
(let [show-sheet (reagent/atom false)]
|
||||
(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
|
||||
(fn [insets]
|
||||
[react/view {:style {:padding-horizontal 24
|
||||
:padding-bottom (+ (:bottom insets) 8)}}
|
||||
[react/view {:style {:justify-content :center
|
||||
:align-items :center}}
|
||||
[react/touchable-opacity {:on-press on-close
|
||||
:style {:background-color colors/black-transparent-86
|
||||
:padding-horizontal 24
|
||||
:padding-vertical 11
|
||||
:border-radius 44}}
|
||||
[quo/text {:style {:color colors/white-persist}}
|
||||
(i18n/label :t/close)]]
|
||||
[footer-options props]]])])
|
||||
|
||||
(defn preview-image [{{:keys [content] :as message} :message
|
||||
visible :visible
|
||||
on-close :on-close}]
|
||||
[:> image-viewing {:images #js [#js {:uri (:image content)}]
|
||||
:on-request-close on-close
|
||||
:hide-header-on-zoom false
|
||||
:hide-footer-on-zoom false
|
||||
:swipe-to-close-enabled platform/ios?
|
||||
:presentation-style "overFullScreen"
|
||||
: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.security :as security]
|
||||
[status-im.ui.screens.chat.message.reactions :as reactions]
|
||||
[status-im.ui.screens.chat.image.preview.views :as preview]
|
||||
[quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[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]}]
|
||||
(let [dimensions (reagent/atom [260 260])
|
||||
visible (reagent/atom false)
|
||||
uri (:image content)]
|
||||
(react/image-get-size
|
||||
uri
|
||||
|
@ -236,17 +238,21 @@
|
|||
style-opts {:outgoing outgoing
|
||||
:width (/ (first @dimensions) k)
|
||||
:height (/ (second @dimensions) k)}]
|
||||
[react/touchable-highlight {:on-press (fn []
|
||||
(when (:image content)
|
||||
(re-frame/dispatch [:navigate-to :image-preview message]))
|
||||
(react/dismiss-keyboard!))
|
||||
:on-long-press on-long-press}
|
||||
[react/view {:style (style/image-message style-opts)}
|
||||
[react/image {:style {:width (/ (first @dimensions) k)
|
||||
:height (/ (second @dimensions) k)}
|
||||
:resize-mode :contain
|
||||
:source {:uri uri}}]
|
||||
[react/view {:style (style/image-message-border style-opts)}]]]))))
|
||||
[:<>
|
||||
[preview/preview-image {:message message
|
||||
:visible @visible
|
||||
:on-close #(do (reset! visible false)
|
||||
(reagent/flush))}]
|
||||
[react/touchable-highlight {:on-press (fn []
|
||||
(reset! visible true)
|
||||
(react/dismiss-keyboard!))
|
||||
:on-long-press on-long-press}
|
||||
[react/view {:style (style/image-message style-opts)}
|
||||
[react/image {:style {:width (/ (first @dimensions) k)
|
||||
:height (/ (second @dimensions) k)}
|
||||
:resize-mode :contain
|
||||
:source {:uri uri}}]
|
||||
[react/view {:style (style/image-message-border style-opts)}]]]]))))
|
||||
|
||||
(defmulti ->message :content-type)
|
||||
|
||||
|
|
|
@ -141,52 +141,50 @@
|
|||
:accessibility-label :delete-transaccent-button
|
||||
: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?]
|
||||
(fn []
|
||||
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
|
||||
[react/view
|
||||
(when-not outgoing
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo {:identicon identicon
|
||||
:public-key from})]
|
||||
:title contact-name
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
:chevron true
|
||||
:on-press #(do
|
||||
(when from-preview?
|
||||
(re-frame/dispatch [:navigate-back]))
|
||||
(hide-sheet-and-dispatch [:chat.ui/show-profile from]))}])
|
||||
(when-not cant-be-replied
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/message-reply)
|
||||
:icon :main-icons/reply
|
||||
:on-press #(do
|
||||
(when from-preview?
|
||||
(re-frame/dispatch [:navigate-back]))
|
||||
(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
|
||||
#_[quo/list-item
|
||||
{:theme :accent
|
||||
:title :t/sharing-copy-to-clipboard
|
||||
:icon :main-icons/copy
|
||||
:on-press (fn []
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(react/copy-to-clipboard (:image content)))}]
|
||||
(defn image-long-press [{:keys [content identicon from outgoing cant-be-replied] :as message} hide]
|
||||
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
|
||||
[react/view
|
||||
(when-not outgoing
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo {:identicon identicon
|
||||
:public-key from})]
|
||||
:title contact-name
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
:chevron true
|
||||
:on-press #(do
|
||||
(hide)
|
||||
(re-frame/dispatch [:chat.ui/show-profile from]))}])
|
||||
(when-not cant-be-replied
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/save)
|
||||
:icon :main-icons/download
|
||||
:title (i18n/label :t/message-reply)
|
||||
:icon :main-icons/reply
|
||||
:on-press #(do
|
||||
(hide)
|
||||
(re-frame/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
|
||||
#_[quo/list-item
|
||||
{:theme :accent
|
||||
:title :t/sharing-copy-to-clipboard
|
||||
:icon :main-icons/copy
|
||||
:on-press (fn []
|
||||
(hide-sheet-and-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
|
||||
#_[quo/list-item
|
||||
{:theme :accent
|
||||
:title :t/sharing-share
|
||||
:icon :main-icons/share
|
||||
:on-press (fn []
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(list-selection/open-share {:message (:image content)}))}]])))
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(react/copy-to-clipboard (:image content)))}]
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:title (i18n/label :t/save)
|
||||
:icon :main-icons/download
|
||||
:on-press (fn []
|
||||
(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
|
||||
#_[quo/list-item
|
||||
{:theme :accent
|
||||
:title :t/sharing-share
|
||||
:icon :main-icons/share
|
||||
:on-press (fn []
|
||||
(re-frame/dispatch [:bottom-sheet/hide])
|
||||
(list-selection/open-share {:message (:image content)}))}]]))
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
[status-im.utils.platform :as platform]
|
||||
[quo.previews.main :as quo.preview]
|
||||
[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.notifications-settings.views :as notifications-settings]
|
||||
[status-im.ui.screens.wallet.send.views :as wallet]
|
||||
|
@ -122,9 +121,6 @@
|
|||
{:name :qr-scanner
|
||||
:insets {:top false :bottom false}
|
||||
:component qr-scanner/qr-scanner}
|
||||
{:name :image-preview
|
||||
:insets {:top false :bottom false}
|
||||
:component image-preview/preview-image}
|
||||
{:name :notifications-settings
|
||||
:back-handler :noop
|
||||
:insets {:bottom true}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[status-im.ui.screens.status.styles :as styles]
|
||||
[status-im.ui.screens.chat.views :as chat.views]
|
||||
[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.components.tabs :as tabs]
|
||||
[status-im.utils.contenthash :as contenthash]
|
||||
|
@ -53,13 +54,19 @@
|
|||
:justify-content :center}
|
||||
[icons/icon :main-icons/close-circle {:color colors/white-persist}]]])])))
|
||||
|
||||
(defn image-message [{:keys [content] :as message}]
|
||||
[react/touchable-highlight {:on-press (fn [_]
|
||||
(when (:image content)
|
||||
(re-frame/dispatch [:navigate-to :image-preview
|
||||
(assoc message :cant-be-replied true)]))
|
||||
(react/dismiss-keyboard!))}
|
||||
[message-content-image (:image content) false]])
|
||||
(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 [_]
|
||||
(reset! visible true)
|
||||
(react/dismiss-keyboard!))}
|
||||
[message-content-image (:image content) false]]])))
|
||||
|
||||
(defn message-item [{:keys [content-type content from last-in-group? timestamp identicon outgoing] :as message} timeline? account]
|
||||
[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"
|
||||
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:
|
||||
version "1.2.1"
|
||||
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