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
::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]}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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
(: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

View File

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

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.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]]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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"

View File

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