parent
967c869486
commit
53495dc893
|
@ -97,10 +97,10 @@
|
|||
|
||||
(re-frame/reg-fx
|
||||
::image-selected
|
||||
(fn [[uri chat-id]]
|
||||
(fn [[image chat-id]]
|
||||
(resize-and-call
|
||||
uri
|
||||
#(re-frame/dispatch [:chat.ui/image-selected chat-id uri %]))))
|
||||
(:uri image)
|
||||
#(re-frame/dispatch [:chat.ui/image-selected chat-id image %]))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::camera-roll-get-photos
|
||||
|
@ -111,9 +111,18 @@
|
|||
(-> (if end-cursor
|
||||
(.getPhotos
|
||||
CameraRoll
|
||||
#js {:first num :after end-cursor :assetType "Photos" :groupTypes "All"})
|
||||
#js
|
||||
{:first num
|
||||
:after end-cursor
|
||||
:assetType "Photos"
|
||||
:groupTypes "All"
|
||||
:include (clj->js ["imageSize"])})
|
||||
(.getPhotos CameraRoll
|
||||
#js {:first num :assetType "Photos" :groupTypes "All"}))
|
||||
#js
|
||||
{:first num
|
||||
:assetType "Photos"
|
||||
:groupTypes "All"
|
||||
:include (clj->js ["imageSize"])}))
|
||||
(.then #(let [response (types/js->clj %)]
|
||||
(re-frame/dispatch [:on-camera-roll-get-photos (:edges response)
|
||||
(:page_info response) end-cursor])))
|
||||
|
@ -150,7 +159,7 @@
|
|||
[{:keys [db] :as cofx} photos page-info end-cursor]
|
||||
(let [photos_x (when end-cursor (:camera-roll/photos db))]
|
||||
{:db (-> db
|
||||
(assoc :camera-roll/photos (concat photos_x (map #(get-in % [:node :image :uri]) photos)))
|
||||
(assoc :camera-roll/photos (concat photos_x (map #(get-in % [:node :image]) photos)))
|
||||
(assoc :camera-roll/end-cursor (:end_cursor page-info))
|
||||
(assoc :camera-roll/has-next-page (:has_next_page page-info))
|
||||
(assoc :camera-roll/loading-more false))}))
|
||||
|
@ -169,13 +178,14 @@
|
|||
(rf/defn image-selected
|
||||
{:events [:chat.ui/image-selected]}
|
||||
[{:keys [db]} current-chat-id original uri]
|
||||
{:db (update-in db [:chat/inputs current-chat-id :metadata :sending-image original] merge {:uri uri})})
|
||||
{:db
|
||||
(update-in db [:chat/inputs current-chat-id :metadata :sending-image uri] merge original {:uri uri})})
|
||||
|
||||
(rf/defn image-unselected
|
||||
{:events [:chat.ui/image-unselected]}
|
||||
[{:keys [db]} original]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
{:db (update-in db [:chat/inputs current-chat-id :metadata :sending-image] dissoc original)}))
|
||||
{:db (update-in db [:chat/inputs current-chat-id :metadata :sending-image] dissoc (:uri original))}))
|
||||
|
||||
(rf/defn chat-open-image-picker
|
||||
{:events [:chat.ui/open-image-picker]}
|
||||
|
@ -195,15 +205,15 @@
|
|||
|
||||
(rf/defn camera-roll-pick
|
||||
{:events [:chat.ui/camera-roll-pick]}
|
||||
[{:keys [db]} uri chat-id]
|
||||
[{:keys [db]} image chat-id]
|
||||
(let [current-chat-id (or chat-id (:current-chat-id db))
|
||||
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
|
||||
(if (get-in db [:chats current-chat-id :timeline?])
|
||||
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :sending-image] {})
|
||||
::image-selected [uri current-chat-id]}
|
||||
::image-selected [image current-chat-id]}
|
||||
(when (and (< (count images) config/max-images-batch)
|
||||
(not (get images uri)))
|
||||
{::image-selected [uri current-chat-id]}))))
|
||||
(not (some #(= (:uri image) (:uri %)) images)))
|
||||
{::image-selected [image current-chat-id]}))))
|
||||
|
||||
(rf/defn save-image-to-gallery
|
||||
{:events [:chat.ui/save-image-to-gallery]}
|
||||
|
|
|
@ -147,15 +147,20 @@
|
|||
:ens-name preferred-name})))
|
||||
|
||||
(defn build-image-messages
|
||||
[{db :db} chat-id]
|
||||
[{db :db} chat-id input-text]
|
||||
(let [images (get-in db [:chat/inputs chat-id :metadata :sending-image])
|
||||
album-id (str (random-uuid))]
|
||||
(mapv (fn [[_ {:keys [uri]}]]
|
||||
(mapv (fn [[_ {:keys [uri width height]}]]
|
||||
{:chat-id chat-id
|
||||
:album-id album-id
|
||||
:content-type constants/content-type-image
|
||||
:image-path (utils/safe-replace uri #"file://" "")
|
||||
:text (i18n/label :t/update-to-see-image {"locale" "en"})})
|
||||
:image-width width
|
||||
:image-height height
|
||||
;; TODO: message not received if text field is
|
||||
;; nil or empty, issue:
|
||||
;; https://github.com/status-im/status-mobile/issues/14754
|
||||
:text (or input-text "placeholder")})
|
||||
images)))
|
||||
|
||||
(rf/defn clean-input
|
||||
|
@ -181,8 +186,9 @@
|
|||
|
||||
(rf/defn send-messages
|
||||
[{:keys [db] :as cofx} input-text current-chat-id]
|
||||
(let [image-messages (build-image-messages cofx current-chat-id)
|
||||
text-message (build-text-message cofx input-text current-chat-id)
|
||||
(let [image-messages (build-image-messages cofx current-chat-id input-text)
|
||||
text-message (when-not (seq image-messages)
|
||||
(build-text-message cofx input-text current-chat-id))
|
||||
messages (keep identity (conj image-messages text-message))]
|
||||
(when (seq messages)
|
||||
(rf/merge cofx
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
:deleted :deleted?
|
||||
:deletedForMe :deleted-for-me?
|
||||
:albumId :album-id
|
||||
:imageWidth :image-width
|
||||
:imageHeight :image-height
|
||||
:new :new?})
|
||||
|
||||
(update :quoted-message
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
(defn build-message
|
||||
[{:keys [chat-id
|
||||
album-id
|
||||
image-width
|
||||
image-height
|
||||
text
|
||||
response-to
|
||||
ens-name
|
||||
|
@ -17,6 +19,8 @@
|
|||
content-type]}]
|
||||
{:chatId chat-id
|
||||
:albumId album-id
|
||||
:imageWidth image-width
|
||||
:imageHeight image-height
|
||||
:text text
|
||||
:responseTo response-to
|
||||
:ensName ens-name
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
;; so we need some magic here with paddings so close button isn't cut
|
||||
[rn/view {:padding-top 12 :padding-bottom 8 :padding-right 12}
|
||||
[rn/image
|
||||
{:source {:uri (first item)}
|
||||
{:source {:uri (:uri (val item))}
|
||||
:style style/small-image}]
|
||||
[rn/touchable-opacity
|
||||
{:on-press #(rf/dispatch [:chat.ui/image-unselected (first item)])
|
||||
{:on-press (fn [] (rf/dispatch [:chat.ui/image-unselected (val item)]))
|
||||
:style style/remove-photo-container
|
||||
:hit-slop {:right 5
|
||||
:left 5
|
||||
|
|
|
@ -208,7 +208,12 @@
|
|||
(def ^:const delete-message-for-me-undo-time-limit-ms 4000)
|
||||
|
||||
(def ^:const album-image-sizes
|
||||
{4 {0 146
|
||||
{2 {0 146
|
||||
1 146}
|
||||
3 {0 [292 194]
|
||||
1 [145 97]
|
||||
2 [145 97]}
|
||||
4 {0 146
|
||||
1 146
|
||||
2 146
|
||||
3 146}
|
||||
|
|
|
@ -326,3 +326,13 @@
|
|||
{:events [:chat.ui/navigate-to-pinned-messages]}
|
||||
[cofx chat-id]
|
||||
(navigation/navigate-to cofx :chat-pinned-messages {:chat-id chat-id}))
|
||||
|
||||
(rf/defn navigate-to-horizontal-images
|
||||
{:events [:chat.ui/navigate-to-horizontal-images]}
|
||||
[cofx messages index]
|
||||
(navigation/navigate-to cofx :images-horizontal {:messages messages :index index}))
|
||||
|
||||
(rf/defn update-shared-element-id
|
||||
{:events [:chat.ui/update-shared-element-id]}
|
||||
[{:keys [db]} shared-element-id]
|
||||
{:db (assoc db :shared-element-id shared-element-id)})
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
(ns status-im2.contexts.chat.images-horizontal.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn container-view
|
||||
[padding-top]
|
||||
{:background-color :black
|
||||
:height "100%"
|
||||
:padding-top padding-top})
|
||||
|
||||
(defn top-view-container
|
||||
[top-inset]
|
||||
{:position :absolute
|
||||
:left 20
|
||||
:top (+ 12 top-inset)
|
||||
:z-index 1
|
||||
:flex-direction :row
|
||||
:width "100%"})
|
||||
|
||||
(def close-container
|
||||
{:width 32
|
||||
:height 32
|
||||
:border-radius 12
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:background-color colors/neutral-80-opa-40})
|
||||
|
||||
(def top-right-buttons
|
||||
{:position :absolute
|
||||
:right 20
|
||||
:flex-direction :row})
|
||||
|
||||
(defn gradient-container
|
||||
[insets]
|
||||
{:width "100%"
|
||||
;:height (+ (:bottom insets) 65)
|
||||
:position :absolute
|
||||
:bottom (:bottom insets)})
|
||||
|
||||
(def text-style
|
||||
{:color colors/white
|
||||
:align-self :center
|
||||
:margin-horizontal 20
|
||||
:margin-vertical 12})
|
|
@ -0,0 +1,138 @@
|
|||
(ns status-im2.contexts.chat.images-horizontal.view
|
||||
(:require [quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[utils.re-frame :as rf]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[oops.core :as oops]
|
||||
[status-im2.contexts.chat.images-horizontal.style :as style]
|
||||
[utils.datetime :as datetime]
|
||||
[react-native.linear-gradient :as linear-gradient]))
|
||||
|
||||
(def flat-list-ref (atom nil))
|
||||
(def small-list-ref (atom nil))
|
||||
(def small-image-size 40)
|
||||
|
||||
(defn image
|
||||
[message]
|
||||
(let [shared-element-id (rf/sub [:shared-element-id])
|
||||
window-width (:width (rn/get-window))
|
||||
height (* (or (:image-height message) 1000)
|
||||
(/ window-width (or (:image-width message) 1000)))]
|
||||
[rn/image
|
||||
{:source {:uri (:image (:content message))}
|
||||
:style {:width window-width
|
||||
:height height
|
||||
:border-radius 12}
|
||||
:native-ID (when (= shared-element-id (:message-id message)) :shared-element)}]))
|
||||
|
||||
(defn get-item-layout
|
||||
[_ index]
|
||||
(let [window-width (:width (rn/get-window))]
|
||||
#js {:length window-width :offset (* window-width index) :index index}))
|
||||
|
||||
(defn get-small-item-layout
|
||||
[_ index]
|
||||
#js {:length small-image-size :offset (* (+ small-image-size 8) index) :index index})
|
||||
|
||||
(defn on-viewable-items-changed
|
||||
[e]
|
||||
(let [changed (-> e (oops/oget :changed) first)]
|
||||
(.scrollToIndex ^js @small-list-ref #js {:animated true :index (oops/oget changed :index)})
|
||||
(rf/dispatch [:chat.ui/update-shared-element-id (:message-id (oops/oget changed :item))])))
|
||||
|
||||
(defn top-view
|
||||
[{:keys [from timestamp]} insets]
|
||||
(let [display-name (first (rf/sub [:contacts/contact-two-names-by-identity from]))]
|
||||
[rn/view
|
||||
{:style (style/top-view-container (:top insets))}
|
||||
[rn/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:style style/close-container}
|
||||
[quo/icon :close {:size 20 :color colors/white}]]
|
||||
[rn/view {:style {:margin-left 12}}
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-1
|
||||
:style {:color colors/white}} display-name]
|
||||
[quo/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style {:color colors/neutral-40}} (datetime/to-short-str timestamp)]]
|
||||
[rn/view {:style style/top-right-buttons}
|
||||
[rn/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:on-press #(js/alert "to be implemented")
|
||||
:style (merge style/close-container {:margin-right 12})}
|
||||
[quo/icon :share {:size 20 :color colors/white}]]
|
||||
[rn/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:on-press #(js/alert "to be implemented")
|
||||
:style style/close-container}
|
||||
[quo/icon :options {:size 20 :color colors/white}]]]]))
|
||||
|
||||
|
||||
|
||||
(defn small-image
|
||||
[item]
|
||||
[rn/image
|
||||
{:source {:uri (:image (:content item))}
|
||||
:style {:width small-image-size
|
||||
:height small-image-size
|
||||
:border-radius 10}}])
|
||||
|
||||
(defn bottom-view
|
||||
[messages insets]
|
||||
(let [text (get-in (first messages) [:content :text])
|
||||
padding-horizontal (- (/ (:width (rn/get-window)) 2) (/ small-image-size 2))]
|
||||
[linear-gradient/linear-gradient
|
||||
{:colors [:black :transparent]
|
||||
:start {:x 0 :y 1}
|
||||
:end {:x 0 :y 0}
|
||||
:style (style/gradient-container insets)}
|
||||
[rn/text
|
||||
{:style style/text-style} text]
|
||||
[rn/flat-list
|
||||
{:ref #(reset! small-list-ref %)
|
||||
:key-fn :message-id
|
||||
:data messages
|
||||
:render-fn small-image
|
||||
:horizontal true
|
||||
:get-item-layout get-small-item-layout
|
||||
:separator [rn/view {:style {:width 8}}]
|
||||
:content-container-style {:padding-vertical 12
|
||||
:padding-horizontal padding-horizontal}}]]))
|
||||
|
||||
(defn images-horizontal
|
||||
[]
|
||||
(let [{:keys [messages index]} (rf/sub [:get-screen-params])
|
||||
;; The initial value of data is the image that was pressed (and not the whole album) in order for
|
||||
;; the transition animation to execute properly, otherwise it would animate towards outside the
|
||||
;; screen (even if we have `initialScrollIndex` set).
|
||||
data (reagent/atom [(nth messages index)])]
|
||||
(reset! data messages)
|
||||
;; We use setTimeout to enqueue `scrollToIndex` until the `data` has been updated.
|
||||
(js/setTimeout #(do
|
||||
(.scrollToIndex ^js @flat-list-ref #js {:animated false :index index})
|
||||
(.scrollToIndex ^js @small-list-ref #js {:animated false :index index}))
|
||||
0)
|
||||
[safe-area/consumer
|
||||
(fn [insets]
|
||||
[rn/view
|
||||
{:style (style/container-view (:top insets))}
|
||||
[top-view (first messages) insets]
|
||||
[rn/flat-list
|
||||
{:ref #(reset! flat-list-ref %)
|
||||
:key-fn :message-id
|
||||
:data @data
|
||||
:render-fn image
|
||||
:horizontal true
|
||||
:paging-enabled true
|
||||
:get-item-layout get-item-layout
|
||||
:viewability-config {:view-area-coverage-percent-threshold 50}
|
||||
:on-viewable-items-changed on-viewable-items-changed
|
||||
:content-container-style {:justify-content :center
|
||||
:align-items :center}}]
|
||||
[bottom-view messages insets]])]))
|
|
@ -1,17 +1,24 @@
|
|||
(ns status-im2.contexts.chat.messages.content.album.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def album-container
|
||||
{:flex-direction :row
|
||||
(def max-album-height 292)
|
||||
|
||||
(defn album-container
|
||||
[portrait?]
|
||||
{:flex-direction (if portrait? :column :row)
|
||||
:flex-wrap :wrap
|
||||
:overflow :hidden})
|
||||
:max-height max-album-height})
|
||||
|
||||
(defn image
|
||||
[size index]
|
||||
{:width size
|
||||
:height size
|
||||
:margin-left (when (and (not= index 0) (not= index 2)) 1)
|
||||
:margin-bottom (when (< index 2) 1)})
|
||||
[dimensions index]
|
||||
{:width (:width dimensions)
|
||||
:height (:height dimensions)
|
||||
:margin-left (when (or (and (not= index 0) (not= index 2) (not= count 3))
|
||||
(= count 3)
|
||||
(= index 2))
|
||||
1)
|
||||
:margin-bottom (when (< index 2) 1)
|
||||
:align-self :flex-start})
|
||||
|
||||
(def overlay
|
||||
{:position :absolute
|
||||
|
|
|
@ -2,50 +2,98 @@
|
|||
(:require [quo2.core :as quo]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[status-im2.contexts.chat.messages.content.album.style :as style]
|
||||
[status-im2.constants :as constants]))
|
||||
|
||||
[status-im2.constants :as constants]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.chat.messages.content.image.view :as image]))
|
||||
(def max-display-count 6)
|
||||
|
||||
(def rectangular-style-count 3)
|
||||
|
||||
(defn border-tlr
|
||||
[index]
|
||||
(when (= index 0) 12))
|
||||
|
||||
(defn border-trr
|
||||
[index]
|
||||
(when (= index 1) 12))
|
||||
[index count album-style]
|
||||
(when (or (and (= index 1) (not= count rectangular-style-count))
|
||||
(and (= index 0) (= count rectangular-style-count) (= album-style :landscape))
|
||||
(and (= index 1) (= count rectangular-style-count) (= album-style :portrait)))
|
||||
12))
|
||||
|
||||
(defn border-blr
|
||||
[index count]
|
||||
(when (and (= index 2) (> count 2)) 12))
|
||||
[index count album-style]
|
||||
(when (or (and (= index 0) (< count rectangular-style-count))
|
||||
(and (= index 2) (> count rectangular-style-count))
|
||||
(and (= index 1) (= count rectangular-style-count) (= album-style :landscape))
|
||||
(and (= index 0) (= count rectangular-style-count) (= album-style :portrait)))
|
||||
12))
|
||||
|
||||
(defn border-brr
|
||||
[index count]
|
||||
(when (and (= index (- (min count max-display-count) 1)) (> count 2)) 12))
|
||||
(when (or (and (= index 1) (< count rectangular-style-count))
|
||||
(and (= index (- (min count max-display-count) 1)) (> count 2)))
|
||||
12))
|
||||
|
||||
(defn find-size
|
||||
[size-arr album-style]
|
||||
(if (= album-style :landscape)
|
||||
{:width (first size-arr) :height (second size-arr) :album-style album-style}
|
||||
{:width (second size-arr) :height (first size-arr) :album-style album-style}))
|
||||
|
||||
(defn album-message
|
||||
[message]
|
||||
[rn/view
|
||||
{:style style/album-container}
|
||||
(map-indexed
|
||||
(fn [index item]
|
||||
(let [images-count (count (:album message))
|
||||
images-size-key (if (< images-count 6) images-count :default)
|
||||
size (get-in constants/album-image-sizes [images-size-key index])]
|
||||
[rn/view {:key (:message-id item)}
|
||||
[fast-image/fast-image
|
||||
{:style (merge (style/image size index)
|
||||
{:border-top-left-radius (border-tlr index)
|
||||
:border-top-right-radius (border-trr index)
|
||||
:border-bottom-left-radius (border-blr index images-count)
|
||||
:border-bottom-right-radius (border-brr index images-count)})
|
||||
:source {:uri (:image (:content item))}}]
|
||||
(when (and (> images-count max-display-count) (= index (- max-display-count 1)))
|
||||
[rn/view
|
||||
{:style (merge style/overlay {:border-bottom-right-radius (border-brr index images-count)})}
|
||||
[quo/text
|
||||
{:weight :bold
|
||||
:size :heading-2
|
||||
:style {:color colors/white}} (str "+" (- images-count 5))]])]))
|
||||
(:album message))])
|
||||
[{:keys [albumize?] :as message}]
|
||||
(let [shared-element-id (rf/sub [:shared-element-id])
|
||||
first-image (first (:album message))
|
||||
album-style (if (> (:image-width first-image) (:image-height first-image))
|
||||
:landscape
|
||||
:portrait)
|
||||
images-count (count (:album message))
|
||||
;; album images are always square, except when we have 3 images, then they must be rectangular
|
||||
;; (portrait or landscape)
|
||||
portrait? (and (= images-count rectangular-style-count) (= album-style :portrait))]
|
||||
(if (and albumize? (> images-count 1))
|
||||
[rn/view
|
||||
{:style (style/album-container portrait?)}
|
||||
(map-indexed
|
||||
(fn [index item]
|
||||
(let [images-size-key (if (< images-count max-display-count) images-count :default)
|
||||
size (get-in constants/album-image-sizes [images-size-key index])
|
||||
dimensions (if (not= images-count rectangular-style-count)
|
||||
{:width size :height size}
|
||||
(find-size size album-style))]
|
||||
[rn/touchable-opacity
|
||||
{:key (:message-id item)
|
||||
:active-opacity 1
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:chat.ui/update-shared-element-id (:message-id item)])
|
||||
(js/setTimeout #(rf/dispatch [:chat.ui/navigate-to-horizontal-images
|
||||
(:album message) index])
|
||||
100))}
|
||||
[rn/image
|
||||
{:style (merge
|
||||
(style/image dimensions index)
|
||||
{:border-top-left-radius (border-tlr index)
|
||||
:border-top-right-radius (border-trr index images-count album-style)
|
||||
:border-bottom-left-radius (border-blr index images-count album-style)
|
||||
:border-bottom-right-radius (border-brr index images-count)})
|
||||
:source {:uri (:image (:content item))}
|
||||
:native-ID (when (and (= shared-element-id (:message-id item))
|
||||
(< index max-display-count))
|
||||
:shared-element)}]
|
||||
(when (and (> images-count max-display-count) (= index (- max-display-count 1)))
|
||||
[rn/view
|
||||
{:style (merge style/overlay
|
||||
{:border-bottom-right-radius (border-brr index images-count)})}
|
||||
[quo/text
|
||||
{:weight :bold
|
||||
:size :heading-2
|
||||
:style {:color colors/white}}
|
||||
(str "+" (- images-count (dec max-display-count)))]])]))
|
||||
(:album message))
|
||||
]
|
||||
[:<>
|
||||
(map-indexed
|
||||
(fn [index item]
|
||||
[image/image-message index item])
|
||||
(:album message))])))
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
(ns status-im2.contexts.chat.messages.content.image.view
|
||||
(:require [react-native.core :as rn]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn calculate-dimensions
|
||||
[width height]
|
||||
(let [max-width (if (> width height) 320 190)
|
||||
max-height (if (> width height) 190 320)]
|
||||
(if (> height width)
|
||||
(let [calculated-height (* (min height max-height) (/ (max width max-width) width))
|
||||
calculated-width (* (max width max-width) (/ (min height max-height) height))]
|
||||
{:width calculated-width :height calculated-height})
|
||||
(let [calculated-height (* (max height max-height) (/ (min width max-width) width))
|
||||
calculated-width (* (min width max-width) (/ (max height max-height) height))]
|
||||
{:width calculated-width :height calculated-height}))))
|
||||
|
||||
(defn image-message
|
||||
[index {:keys [content image-width image-height message-id] :as message}]
|
||||
(let [dimensions (calculate-dimensions (or image-width 1000) (or image-height 1000))
|
||||
text (:text content)]
|
||||
(fn []
|
||||
(let [shared-element-id (rf/sub [:shared-element-id])]
|
||||
[rn/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:style {:margin-top (when (> index 0) 20)}
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:chat.ui/update-shared-element-id message-id])
|
||||
(js/setTimeout #(rf/dispatch [:chat.ui/navigate-to-horizontal-images
|
||||
[message] 0])
|
||||
100))}
|
||||
;; This text comp is temporary. Should later use
|
||||
;; `status-im2.contexts.chat.messages.content.text.view`
|
||||
(when (and (not= text "placeholder") (= index 0)) [rn/text text])
|
||||
[rn/image
|
||||
{:source {:uri (:image content)}
|
||||
:style (merge dimensions {:border-radius 12})
|
||||
:native-ID (when (= shared-element-id message-id) :shared-element)}]]))))
|
|
@ -11,6 +11,7 @@
|
|||
[status-im2.contexts.chat.messages.content.status.view :as status]
|
||||
[status-im2.contexts.chat.messages.content.system.text.view :as system.text]
|
||||
[status-im2.contexts.chat.messages.content.album.view :as album]
|
||||
[status-im2.contexts.chat.messages.content.image.view :as image]
|
||||
[quo2.core :as quo]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.ui2.screens.chat.messages.message :as old-message]
|
||||
|
@ -89,8 +90,7 @@
|
|||
constants/content-type-sticker [not-implemented/not-implemented
|
||||
[old-message/sticker message-data]]
|
||||
|
||||
constants/content-type-image [not-implemented/not-implemented
|
||||
[old-message/message-content-image message-data]]
|
||||
constants/content-type-image [image/image-message 0 message-data]
|
||||
|
||||
constants/content-type-audio [not-implemented/not-implemented
|
||||
[old-message/audio message-data]]
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
{:width "100%"
|
||||
:height (+ (:bottom safe-area) 65)
|
||||
:position :absolute
|
||||
:bottom (if platform/ios? 0 65)})
|
||||
:bottom (if platform/ios? 0 33)})
|
||||
|
||||
(defn buttons-container
|
||||
[safe-area]
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
(swap! selected conj item)))
|
||||
:accessibility-label (str "image-" index)}
|
||||
[rn/image
|
||||
{:source {:uri item}
|
||||
{:source {:uri (:uri item)}
|
||||
:style (style/image window-width index)}]
|
||||
(when (some #{item} @selected)
|
||||
[rn/view {:style (style/overlay window-width)}])
|
||||
|
@ -77,10 +77,14 @@
|
|||
[chat-id]
|
||||
(rf/dispatch [:chat.ui/camera-roll-get-photos 20])
|
||||
(let [selected-images (keys (rf/sub [:chats/sending-image]))]
|
||||
(when selected-images
|
||||
(reset! selected (vec selected-images)))
|
||||
[:f>
|
||||
(fn []
|
||||
(rn/use-effect-once
|
||||
(fn []
|
||||
(if selected-images
|
||||
(reset! selected (vec selected-images))
|
||||
(reset! selected []))
|
||||
js/undefined))
|
||||
(let [{window-height :height window-width :width} (rn/use-window-dimensions)
|
||||
safe-area (safe-area/use-safe-area)
|
||||
camera-roll-photos (rf/sub [:camera-roll/photos])
|
||||
|
@ -111,4 +115,3 @@
|
|||
has-next-page?])}]
|
||||
[bottom-gradient chat-id selected-images]]))]))
|
||||
|
||||
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
(name @state/root-comp-id)
|
||||
{:component {:id comp
|
||||
:name comp
|
||||
:options (merge options
|
||||
(status-bar-options)
|
||||
:options (merge (status-bar-options)
|
||||
options
|
||||
(roots/merge-top-bar (roots/topbar-options) options))}})
|
||||
;;if we push the screen from modal, we want to dismiss all modals
|
||||
(dismiss-all-modals)))
|
||||
|
@ -209,8 +209,8 @@
|
|||
(let [{:keys [options]} (get views/screens comp)]
|
||||
{:component {:id comp
|
||||
:name comp
|
||||
:options (merge options
|
||||
(roots/status-bar-options)
|
||||
:options (merge (roots/status-bar-options)
|
||||
options
|
||||
(roots/merge-top-bar (roots/topbar-options) options))}}))
|
||||
|
||||
;; SET STACK ROOT
|
||||
|
|
|
@ -8,41 +8,60 @@
|
|||
[status-im2.contexts.quo-preview.main :as quo.preview]
|
||||
[status-im2.contexts.shell.view :as shell]
|
||||
[status-im2.contexts.syncing.view :as settings-syncing]
|
||||
[status-im2.config :as config]))
|
||||
[status-im2.contexts.chat.images-horizontal.view :as images-horizontal]
|
||||
[status-im2.config :as config]
|
||||
[quo.design-system.colors :as colors]))
|
||||
|
||||
(def components
|
||||
[])
|
||||
|
||||
(defn screens
|
||||
[]
|
||||
(concat (old-screens/screens)
|
||||
[{:name :activity-center
|
||||
:options {:topBar {:visible false}}
|
||||
:component activity-center/view}
|
||||
(concat
|
||||
(old-screens/screens)
|
||||
[{:name :activity-center
|
||||
:options {:topBar {:visible false}}
|
||||
:component activity-center/view}
|
||||
|
||||
{:name :shell-stack
|
||||
:insets {:top false}
|
||||
:component shell/shell-stack}
|
||||
{:name :shell-stack
|
||||
:insets {:top false}
|
||||
:component shell/shell-stack}
|
||||
|
||||
{:name :chat
|
||||
:options {:topBar {:visible false}}
|
||||
:component chat/chat}
|
||||
{:name :chat
|
||||
:options {:topBar {:visible false}}
|
||||
:component chat/chat}
|
||||
|
||||
{:name :discover-communities
|
||||
:options {:topBar {:visible false}}
|
||||
:component communities.discover/discover}
|
||||
{:name :images-horizontal
|
||||
:insets {:top false :bottom false}
|
||||
:options {:topBar {:visible false}
|
||||
:statusBar {:backgroundColor colors/black-persist
|
||||
:style :light
|
||||
:animate true}
|
||||
:navigationBar {:backgroundColor colors/black-persist}
|
||||
:animations {:push {:sharedElementTransitions [{:fromId :shared-element
|
||||
:toId :shared-element
|
||||
:interpolation {:type :decelerate}}]}
|
||||
:pop {:sharedElementTransitions [{:fromId :shared-element
|
||||
:toId :shared-element
|
||||
:interpolation {:type
|
||||
:decelerate}}]}}}
|
||||
:component images-horizontal/images-horizontal}
|
||||
|
||||
{:name :community-overview
|
||||
:options {:topBar {:visible false}}
|
||||
:component communities.overview/overview}
|
||||
{:name :discover-communities
|
||||
:options {:topBar {:visible false}}
|
||||
:component communities.discover/discover}
|
||||
|
||||
{:name :settings-syncing
|
||||
:insets {:bottom true}
|
||||
:options {:topBar {:title {:text (i18n/label :t/syncing)}}}
|
||||
:component settings-syncing/views}]
|
||||
{:name :community-overview
|
||||
:options {:topBar {:visible false}}
|
||||
:component communities.overview/overview}
|
||||
|
||||
(when config/quo-preview-enabled?
|
||||
quo.preview/screens)
|
||||
{:name :settings-syncing
|
||||
:insets {:bottom true}
|
||||
:options {:topBar {:title {:text (i18n/label :t/syncing)}}}
|
||||
:component settings-syncing/views}]
|
||||
|
||||
(when config/quo-preview-enabled?
|
||||
quo.preview/main-screens)))
|
||||
(when config/quo-preview-enabled?
|
||||
quo.preview/screens)
|
||||
|
||||
(when config/quo-preview-enabled?
|
||||
quo.preview/main-screens)))
|
||||
|
|
|
@ -111,12 +111,13 @@
|
|||
(defn albumize-messages
|
||||
[messages]
|
||||
(get (reduce (fn [{:keys [messages albums]} message]
|
||||
(let [album-id (when (:albumize? message) (:album-id message))
|
||||
(let [album-id (:album-id message)
|
||||
albums (cond-> albums album-id (update album-id conj message))
|
||||
messages (if (and album-id (> (count (get albums album-id)) 3))
|
||||
messages (if album-id
|
||||
(conj (filterv #(not= album-id (:album-id %)) messages)
|
||||
{:album (get albums album-id)
|
||||
:album-id album-id
|
||||
:albumize? (:albumize? message)
|
||||
:message-id album-id
|
||||
:content-type constants/content-type-album})
|
||||
(conj messages message))]
|
||||
|
@ -209,6 +210,7 @@
|
|||
(fn [messages]
|
||||
(empty? messages)))
|
||||
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/raw-chat-messages-stream
|
||||
(fn [[_ chat-id] _]
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
[{:message-id "0x111" :album-id "abc" :albumize? true}
|
||||
{:message-id "0x222" :album-id "abc" :albumize? true}
|
||||
{:message-id "0x333" :album-id "abc" :albumize? true}
|
||||
{:message-id "0x444" :album-id "abc" :albumize? true}
|
||||
{:message-id "0x555" :album-id "efg" :albumize? true}])
|
||||
{:message-id "0x444" :album-id "abc" :albumize? true}])
|
||||
|
||||
(def messages-albumized-state
|
||||
[{:album [{:message-id "0x444" :album-id "abc" :albumize? true}
|
||||
|
@ -16,9 +15,9 @@
|
|||
{:message-id "0x222" :album-id "abc" :albumize? true}
|
||||
{:message-id "0x111" :album-id "abc" :albumize? true}]
|
||||
:album-id "abc"
|
||||
:albumize? true
|
||||
:message-id "abc"
|
||||
:content-type constants/content-type-album}
|
||||
{:message-id "0x555" :album-id "efg" :albumize? true}])
|
||||
:content-type constants/content-type-album}])
|
||||
|
||||
(deftest albumize-messages
|
||||
(testing "Finding albums in the messages list"
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
;;view
|
||||
(reg-root-key-sub :view-id :view-id)
|
||||
(reg-root-key-sub :screen-params :navigation/screen-params)
|
||||
(reg-root-key-sub :shared-element-id :shared-element-id)
|
||||
|
||||
|
||||
;;bottom sheet
|
||||
(reg-root-key-sub :bottom-sheet/show? :bottom-sheet/show?)
|
||||
|
|
Loading…
Reference in New Issue