Images Album (2) (#14755)

* feat: images album (2)
This commit is contained in:
Omar Basem 2023-01-20 16:51:44 +04:00 committed by GitHub
parent 967c869486
commit 53495dc893
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 437 additions and 102 deletions

View File

@ -97,10 +97,10 @@
(re-frame/reg-fx (re-frame/reg-fx
::image-selected ::image-selected
(fn [[uri chat-id]] (fn [[image chat-id]]
(resize-and-call (resize-and-call
uri (:uri image)
#(re-frame/dispatch [:chat.ui/image-selected chat-id uri %])))) #(re-frame/dispatch [:chat.ui/image-selected chat-id image %]))))
(re-frame/reg-fx (re-frame/reg-fx
::camera-roll-get-photos ::camera-roll-get-photos
@ -111,9 +111,18 @@
(-> (if end-cursor (-> (if end-cursor
(.getPhotos (.getPhotos
CameraRoll 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 (.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 %)] (.then #(let [response (types/js->clj %)]
(re-frame/dispatch [:on-camera-roll-get-photos (:edges response) (re-frame/dispatch [:on-camera-roll-get-photos (:edges response)
(:page_info response) end-cursor]))) (:page_info response) end-cursor])))
@ -150,7 +159,7 @@
[{:keys [db] :as cofx} photos page-info end-cursor] [{:keys [db] :as cofx} photos page-info end-cursor]
(let [photos_x (when end-cursor (:camera-roll/photos db))] (let [photos_x (when end-cursor (:camera-roll/photos db))]
{:db (-> 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/end-cursor (:end_cursor page-info))
(assoc :camera-roll/has-next-page (:has_next_page page-info)) (assoc :camera-roll/has-next-page (:has_next_page page-info))
(assoc :camera-roll/loading-more false))})) (assoc :camera-roll/loading-more false))}))
@ -169,13 +178,14 @@
(rf/defn image-selected (rf/defn image-selected
{:events [:chat.ui/image-selected]} {:events [:chat.ui/image-selected]}
[{:keys [db]} current-chat-id original uri] [{: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 (rf/defn image-unselected
{:events [:chat.ui/image-unselected]} {:events [:chat.ui/image-unselected]}
[{:keys [db]} original] [{:keys [db]} original]
(let [current-chat-id (:current-chat-id db)] (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 (rf/defn chat-open-image-picker
{:events [:chat.ui/open-image-picker]} {:events [:chat.ui/open-image-picker]}
@ -195,15 +205,15 @@
(rf/defn camera-roll-pick (rf/defn camera-roll-pick
{:events [:chat.ui/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)) (let [current-chat-id (or chat-id (:current-chat-id db))
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])] images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
(if (get-in db [:chats current-chat-id :timeline?]) (if (get-in db [:chats current-chat-id :timeline?])
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :sending-image] {}) {: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) (when (and (< (count images) config/max-images-batch)
(not (get images uri))) (not (some #(= (:uri image) (:uri %)) images)))
{::image-selected [uri current-chat-id]})))) {::image-selected [image current-chat-id]}))))
(rf/defn save-image-to-gallery (rf/defn save-image-to-gallery
{:events [:chat.ui/save-image-to-gallery]} {:events [:chat.ui/save-image-to-gallery]}

View File

@ -147,15 +147,20 @@
:ens-name preferred-name}))) :ens-name preferred-name})))
(defn build-image-messages (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]) (let [images (get-in db [:chat/inputs chat-id :metadata :sending-image])
album-id (str (random-uuid))] album-id (str (random-uuid))]
(mapv (fn [[_ {:keys [uri]}]] (mapv (fn [[_ {:keys [uri width height]}]]
{:chat-id chat-id {:chat-id chat-id
:album-id album-id :album-id album-id
:content-type constants/content-type-image :content-type constants/content-type-image
:image-path (utils/safe-replace uri #"file://" "") :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))) images)))
(rf/defn clean-input (rf/defn clean-input
@ -181,8 +186,9 @@
(rf/defn send-messages (rf/defn send-messages
[{:keys [db] :as cofx} input-text current-chat-id] [{:keys [db] :as cofx} input-text current-chat-id]
(let [image-messages (build-image-messages cofx current-chat-id) (let [image-messages (build-image-messages cofx current-chat-id input-text)
text-message (build-text-message cofx input-text current-chat-id) text-message (when-not (seq image-messages)
(build-text-message cofx input-text current-chat-id))
messages (keep identity (conj image-messages text-message))] messages (keep identity (conj image-messages text-message))]
(when (seq messages) (when (seq messages)
(rf/merge cofx (rf/merge cofx

View File

@ -36,6 +36,8 @@
:deleted :deleted? :deleted :deleted?
:deletedForMe :deleted-for-me? :deletedForMe :deleted-for-me?
:albumId :album-id :albumId :album-id
:imageWidth :image-width
:imageHeight :image-height
:new :new?}) :new :new?})
(update :quoted-message (update :quoted-message

View File

@ -6,6 +6,8 @@
(defn build-message (defn build-message
[{:keys [chat-id [{:keys [chat-id
album-id album-id
image-width
image-height
text text
response-to response-to
ens-name ens-name
@ -17,6 +19,8 @@
content-type]}] content-type]}]
{:chatId chat-id {:chatId chat-id
:albumId album-id :albumId album-id
:imageWidth image-width
:imageHeight image-height
:text text :text text
:responseTo response-to :responseTo response-to
:ensName ens-name :ensName ens-name

View File

@ -11,10 +11,10 @@
;; so we need some magic here with paddings so close button isn't cut ;; 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/view {:padding-top 12 :padding-bottom 8 :padding-right 12}
[rn/image [rn/image
{:source {:uri (first item)} {:source {:uri (:uri (val item))}
:style style/small-image}] :style style/small-image}]
[rn/touchable-opacity [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 :style style/remove-photo-container
:hit-slop {:right 5 :hit-slop {:right 5
:left 5 :left 5

View File

@ -208,7 +208,12 @@
(def ^:const delete-message-for-me-undo-time-limit-ms 4000) (def ^:const delete-message-for-me-undo-time-limit-ms 4000)
(def ^:const album-image-sizes (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 1 146
2 146 2 146
3 146} 3 146}

View File

@ -326,3 +326,13 @@
{:events [:chat.ui/navigate-to-pinned-messages]} {:events [:chat.ui/navigate-to-pinned-messages]}
[cofx chat-id] [cofx chat-id]
(navigation/navigate-to cofx :chat-pinned-messages {:chat-id 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)})

View File

@ -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})

View File

@ -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]])]))

View File

@ -1,17 +1,24 @@
(ns status-im2.contexts.chat.messages.content.album.style (ns status-im2.contexts.chat.messages.content.album.style
(:require [quo2.foundations.colors :as colors])) (:require [quo2.foundations.colors :as colors]))
(def album-container (def max-album-height 292)
{:flex-direction :row
(defn album-container
[portrait?]
{:flex-direction (if portrait? :column :row)
:flex-wrap :wrap :flex-wrap :wrap
:overflow :hidden}) :max-height max-album-height})
(defn image (defn image
[size index] [dimensions index]
{:width size {:width (:width dimensions)
:height size :height (:height dimensions)
:margin-left (when (and (not= index 0) (not= index 2)) 1) :margin-left (when (or (and (not= index 0) (not= index 2) (not= count 3))
:margin-bottom (when (< index 2) 1)}) (= count 3)
(= index 2))
1)
:margin-bottom (when (< index 2) 1)
:align-self :flex-start})
(def overlay (def overlay
{:position :absolute {:position :absolute

View File

@ -2,50 +2,98 @@
(:require [quo2.core :as quo] (:require [quo2.core :as quo]
[quo2.foundations.colors :as colors] [quo2.foundations.colors :as colors]
[react-native.core :as rn] [react-native.core :as rn]
[react-native.fast-image :as fast-image]
[status-im2.contexts.chat.messages.content.album.style :as style] [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 max-display-count 6)
(def rectangular-style-count 3)
(defn border-tlr (defn border-tlr
[index] [index]
(when (= index 0) 12)) (when (= index 0) 12))
(defn border-trr (defn border-trr
[index] [index count album-style]
(when (= index 1) 12)) (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 (defn border-blr
[index count] [index count album-style]
(when (and (= index 2) (> count 2)) 12)) (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 (defn border-brr
[index count] [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 (defn album-message
[message] [{:keys [albumize?] :as message}]
[rn/view (let [shared-element-id (rf/sub [:shared-element-id])
{:style style/album-container} first-image (first (:album message))
(map-indexed album-style (if (> (:image-width first-image) (:image-height first-image))
(fn [index item] :landscape
(let [images-count (count (:album message)) :portrait)
images-size-key (if (< images-count 6) images-count :default) images-count (count (:album message))
size (get-in constants/album-image-sizes [images-size-key index])] ;; album images are always square, except when we have 3 images, then they must be rectangular
[rn/view {:key (:message-id item)} ;; (portrait or landscape)
[fast-image/fast-image portrait? (and (= images-count rectangular-style-count) (= album-style :portrait))]
{:style (merge (style/image size index) (if (and albumize? (> images-count 1))
{:border-top-left-radius (border-tlr index) [rn/view
:border-top-right-radius (border-trr index) {:style (style/album-container portrait?)}
:border-bottom-left-radius (border-blr index images-count) (map-indexed
:border-bottom-right-radius (border-brr index images-count)}) (fn [index item]
:source {:uri (:image (:content item))}}] (let [images-size-key (if (< images-count max-display-count) images-count :default)
(when (and (> images-count max-display-count) (= index (- max-display-count 1))) size (get-in constants/album-image-sizes [images-size-key index])
[rn/view dimensions (if (not= images-count rectangular-style-count)
{:style (merge style/overlay {:border-bottom-right-radius (border-brr index images-count)})} {:width size :height size}
[quo/text (find-size size album-style))]
{:weight :bold [rn/touchable-opacity
:size :heading-2 {:key (:message-id item)
:style {:color colors/white}} (str "+" (- images-count 5))]])])) :active-opacity 1
(:album message))]) :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))])))

View File

@ -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)}]]))))

View File

@ -11,6 +11,7 @@
[status-im2.contexts.chat.messages.content.status.view :as status] [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.system.text.view :as system.text]
[status-im2.contexts.chat.messages.content.album.view :as album] [status-im2.contexts.chat.messages.content.album.view :as album]
[status-im2.contexts.chat.messages.content.image.view :as image]
[quo2.core :as quo] [quo2.core :as quo]
[utils.re-frame :as rf] [utils.re-frame :as rf]
[status-im.ui2.screens.chat.messages.message :as old-message] [status-im.ui2.screens.chat.messages.message :as old-message]
@ -89,8 +90,7 @@
constants/content-type-sticker [not-implemented/not-implemented constants/content-type-sticker [not-implemented/not-implemented
[old-message/sticker message-data]] [old-message/sticker message-data]]
constants/content-type-image [not-implemented/not-implemented constants/content-type-image [image/image-message 0 message-data]
[old-message/message-content-image message-data]]
constants/content-type-audio [not-implemented/not-implemented constants/content-type-audio [not-implemented/not-implemented
[old-message/audio message-data]] [old-message/audio message-data]]

View File

@ -7,7 +7,7 @@
{:width "100%" {:width "100%"
:height (+ (:bottom safe-area) 65) :height (+ (:bottom safe-area) 65)
:position :absolute :position :absolute
:bottom (if platform/ios? 0 65)}) :bottom (if platform/ios? 0 33)})
(defn buttons-container (defn buttons-container
[safe-area] [safe-area]

View File

@ -63,7 +63,7 @@
(swap! selected conj item))) (swap! selected conj item)))
:accessibility-label (str "image-" index)} :accessibility-label (str "image-" index)}
[rn/image [rn/image
{:source {:uri item} {:source {:uri (:uri item)}
:style (style/image window-width index)}] :style (style/image window-width index)}]
(when (some #{item} @selected) (when (some #{item} @selected)
[rn/view {:style (style/overlay window-width)}]) [rn/view {:style (style/overlay window-width)}])
@ -77,10 +77,14 @@
[chat-id] [chat-id]
(rf/dispatch [:chat.ui/camera-roll-get-photos 20]) (rf/dispatch [:chat.ui/camera-roll-get-photos 20])
(let [selected-images (keys (rf/sub [:chats/sending-image]))] (let [selected-images (keys (rf/sub [:chats/sending-image]))]
(when selected-images
(reset! selected (vec selected-images)))
[:f> [:f>
(fn [] (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) (let [{window-height :height window-width :width} (rn/use-window-dimensions)
safe-area (safe-area/use-safe-area) safe-area (safe-area/use-safe-area)
camera-roll-photos (rf/sub [:camera-roll/photos]) camera-roll-photos (rf/sub [:camera-roll/photos])
@ -111,4 +115,3 @@
has-next-page?])}] has-next-page?])}]
[bottom-gradient chat-id selected-images]]))])) [bottom-gradient chat-id selected-images]]))]))

View File

@ -52,8 +52,8 @@
(name @state/root-comp-id) (name @state/root-comp-id)
{:component {:id comp {:component {:id comp
:name comp :name comp
:options (merge options :options (merge (status-bar-options)
(status-bar-options) options
(roots/merge-top-bar (roots/topbar-options) options))}}) (roots/merge-top-bar (roots/topbar-options) options))}})
;;if we push the screen from modal, we want to dismiss all modals ;;if we push the screen from modal, we want to dismiss all modals
(dismiss-all-modals))) (dismiss-all-modals)))
@ -209,8 +209,8 @@
(let [{:keys [options]} (get views/screens comp)] (let [{:keys [options]} (get views/screens comp)]
{:component {:id comp {:component {:id comp
:name comp :name comp
:options (merge options :options (merge (roots/status-bar-options)
(roots/status-bar-options) options
(roots/merge-top-bar (roots/topbar-options) options))}})) (roots/merge-top-bar (roots/topbar-options) options))}}))
;; SET STACK ROOT ;; SET STACK ROOT

View File

@ -8,41 +8,60 @@
[status-im2.contexts.quo-preview.main :as quo.preview] [status-im2.contexts.quo-preview.main :as quo.preview]
[status-im2.contexts.shell.view :as shell] [status-im2.contexts.shell.view :as shell]
[status-im2.contexts.syncing.view :as settings-syncing] [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 (def components
[]) [])
(defn screens (defn screens
[] []
(concat (old-screens/screens) (concat
[{:name :activity-center (old-screens/screens)
:options {:topBar {:visible false}} [{:name :activity-center
:component activity-center/view} :options {:topBar {:visible false}}
:component activity-center/view}
{:name :shell-stack {:name :shell-stack
:insets {:top false} :insets {:top false}
:component shell/shell-stack} :component shell/shell-stack}
{:name :chat {:name :chat
:options {:topBar {:visible false}} :options {:topBar {:visible false}}
:component chat/chat} :component chat/chat}
{:name :discover-communities {:name :images-horizontal
:options {:topBar {:visible false}} :insets {:top false :bottom false}
:component communities.discover/discover} :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 {:name :discover-communities
:options {:topBar {:visible false}} :options {:topBar {:visible false}}
:component communities.overview/overview} :component communities.discover/discover}
{:name :settings-syncing {:name :community-overview
:insets {:bottom true} :options {:topBar {:visible false}}
:options {:topBar {:title {:text (i18n/label :t/syncing)}}} :component communities.overview/overview}
:component settings-syncing/views}]
(when config/quo-preview-enabled? {:name :settings-syncing
quo.preview/screens) :insets {:bottom true}
:options {:topBar {:title {:text (i18n/label :t/syncing)}}}
:component settings-syncing/views}]
(when config/quo-preview-enabled? (when config/quo-preview-enabled?
quo.preview/main-screens))) quo.preview/screens)
(when config/quo-preview-enabled?
quo.preview/main-screens)))

View File

@ -111,12 +111,13 @@
(defn albumize-messages (defn albumize-messages
[messages] [messages]
(get (reduce (fn [{:keys [messages albums]} message] (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)) 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) (conj (filterv #(not= album-id (:album-id %)) messages)
{:album (get albums album-id) {:album (get albums album-id)
:album-id album-id :album-id album-id
:albumize? (:albumize? message)
:message-id album-id :message-id album-id
:content-type constants/content-type-album}) :content-type constants/content-type-album})
(conj messages message))] (conj messages message))]
@ -209,6 +210,7 @@
(fn [messages] (fn [messages]
(empty? messages))) (empty? messages)))
(re-frame/reg-sub (re-frame/reg-sub
:chats/raw-chat-messages-stream :chats/raw-chat-messages-stream
(fn [[_ chat-id] _] (fn [[_ chat-id] _]

View File

@ -7,8 +7,7 @@
[{:message-id "0x111" :album-id "abc" :albumize? true} [{:message-id "0x111" :album-id "abc" :albumize? true}
{:message-id "0x222" :album-id "abc" :albumize? true} {:message-id "0x222" :album-id "abc" :albumize? true}
{:message-id "0x333" :album-id "abc" :albumize? true} {:message-id "0x333" :album-id "abc" :albumize? true}
{:message-id "0x444" :album-id "abc" :albumize? true} {:message-id "0x444" :album-id "abc" :albumize? true}])
{:message-id "0x555" :album-id "efg" :albumize? true}])
(def messages-albumized-state (def messages-albumized-state
[{:album [{:message-id "0x444" :album-id "abc" :albumize? true} [{:album [{:message-id "0x444" :album-id "abc" :albumize? true}
@ -16,9 +15,9 @@
{:message-id "0x222" :album-id "abc" :albumize? true} {:message-id "0x222" :album-id "abc" :albumize? true}
{:message-id "0x111" :album-id "abc" :albumize? true}] {:message-id "0x111" :album-id "abc" :albumize? true}]
:album-id "abc" :album-id "abc"
:albumize? true
:message-id "abc" :message-id "abc"
:content-type constants/content-type-album} :content-type constants/content-type-album}])
{:message-id "0x555" :album-id "efg" :albumize? true}])
(deftest albumize-messages (deftest albumize-messages
(testing "Finding albums in the messages list" (testing "Finding albums in the messages list"

View File

@ -32,6 +32,8 @@
;;view ;;view
(reg-root-key-sub :view-id :view-id) (reg-root-key-sub :view-id :view-id)
(reg-root-key-sub :screen-params :navigation/screen-params) (reg-root-key-sub :screen-params :navigation/screen-params)
(reg-root-key-sub :shared-element-id :shared-element-id)
;;bottom sheet ;;bottom sheet
(reg-root-key-sub :bottom-sheet/show? :bottom-sheet/show?) (reg-root-key-sub :bottom-sheet/show? :bottom-sheet/show?)