feat: images album

This commit is contained in:
Omar Basem
2022-12-29 07:07:06 +04:00
parent 9c0361adef
commit f201ebc09f
9 changed files with 310 additions and 180 deletions
+10 -2
View File
@@ -101,6 +101,7 @@
:on-success #(re-frame/dispatch
[::mark-all-read-in-community-successful %])}]}))
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
(rf/defn messages-loaded
@@ -122,6 +123,14 @@
=======
>>>>>>> c341585dd... updates
=======
(defn mark-albums [messages]
(let [new-messages (atom [])]
(doseq [message messages]
(swap! new-messages conj (if (:album-id message) (assoc message :albumize true) message)))
@new-messages))
>>>>>>> 669c096c4... feat: images album
(fx/defn messages-loaded
>>>>>>> 86fbedba6... updates
"Loads more messages for current chat"
@@ -152,8 +161,7 @@
messages)
current-clock-value (get-in db [:pagination-info chat-id :cursor-clock-value])
clock-value (when cursor (cursor->clock-value cursor))
;all-messages (find-albums all-messages)
]
new-messages (mark-albums new-messages)]
{:dispatch [:chat/add-senders-to-chat-users (vals senders)]
:db (-> db
(update-in [:pagination-info chat-id :cursor-clock-value]
+47 -45
View File
@@ -20,19 +20,21 @@
from
outgoing
whisper-timestamp
deleted-for-me?]}]
deleted-for-me?
albumize]}]
(-> {:whisper-timestamp whisper-timestamp
:from from
:one-to-one? (= constants/message-type-one-to-one message-type)
:system-message? (boolean
(or
(= constants/message-type-private-group-system-message
message-type)
deleted-for-me?))
(or
(= constants/message-type-private-group-system-message
message-type)
deleted-for-me?))
:clock-value clock-value
:type :message
:message-id message-id
:outgoing (boolean outgoing)}
:outgoing (boolean outgoing)
:albumize albumize}
add-datemark
add-timestamp))
@@ -44,18 +46,18 @@
We check the time, and the author"
[a b]
(and
(not (:system-message? a))
(not (:system-message? b))
(= (:from a) (:from b))
(<= (js/Math.abs (- (:whisper-timestamp a) (:whisper-timestamp b))) group-ms)))
(not (:system-message? a))
(not (:system-message? b))
(= (:from a) (:from b))
(<= (js/Math.abs (- (:whisper-timestamp a) (:whisper-timestamp b))) group-ms)))
(defn display-photo?
"We display photos for other users, and not in 1-to-1 chats"
[{:keys [system-message? one-to-one? outgoing]}]
(or system-message?
(and
(not outgoing)
(not one-to-one?))))
(not outgoing)
(not one-to-one?))))
(defn compare-fn
"Compare two messages, first compare by clock-value, and break ties by message-id,
@@ -79,33 +81,33 @@
(let [last-in-group? (or (nil? next-message)
(not (same-group? current-message next-message)))]
(assoc current-message
:first? (nil? previous-message)
:first-outgoing? (and outgoing
(not outgoing-seen?))
:outgoing-seen? (or outgoing-seen?
outgoing)
:first-in-group? (or (nil? previous-message)
(not (same-group? current-message previous-message)))
:last-in-group? last-in-group?
:display-username? (and last-in-group?
(not system-message?)
(not outgoing)
(not one-to-one?))
:display-photo? (display-photo? current-message))))
:first? (nil? previous-message)
:first-outgoing? (and outgoing
(not outgoing-seen?))
:outgoing-seen? (or outgoing-seen?
outgoing)
:first-in-group? (or (nil? previous-message)
(not (same-group? current-message previous-message)))
:last-in-group? last-in-group?
:display-username? (and last-in-group?
(not system-message?)
(not outgoing)
(not one-to-one?))
:display-photo? (display-photo? current-message))))
(defn update-next-message
"Update next message in the list, we set :first? to false, and check if it
:first-outgoing? state has changed because of the insertion"
[current-message next-message]
(assoc
next-message
:first? false
:first-outgoing? (and
(not (:first-outgoing? current-message))
(:first-outgoing? next-message))
:outgoing-seen? (:outgoing-seen? current-message)
:first-in-group?
(not (same-group? current-message next-message))))
next-message
:first? false
:first-outgoing? (and
(not (:first-outgoing? current-message))
(:first-outgoing? next-message))
:outgoing-seen? (:outgoing-seen? current-message)
:first-in-group?
(not (same-group? current-message next-message))))
(defn update-previous-message
"If this is a new group, we mark the previous as the last one in the group"
@@ -116,11 +118,11 @@
:as previous-message}]
(let [last-in-group? (not (same-group? current-message previous-message))]
(assoc previous-message
:display-username? (and last-in-group?
(not system-message?)
(not outgoing)
(not one-to-one?))
:last-in-group? last-in-group?)))
:display-username? (and last-in-group?
(not system-message?)
(not outgoing)
(not one-to-one?))
:last-in-group? last-in-group?)))
(defn get-prev-element
"Get previous item in the iterator, and wind it back to the initial state"
@@ -148,14 +150,14 @@
(get-next-element iter))
^js message-with-pos-data (add-group-info message previous-message next-message)]
(cond-> (.update iter message-with-pos-data)
next-message
(-> ^js (.find next-message)
(.update (update-next-message message-with-pos-data next-message)))
next-message
(-> ^js (.find next-message)
(.update (update-next-message message-with-pos-data next-message)))
(and previous-message
(not= :datemark (:type previous-message)))
(-> ^js (.find previous-message)
(.update (update-previous-message message-with-pos-data previous-message))))))
(and previous-message
(not= :datemark (:type previous-message)))
(-> ^js (.find previous-message)
(.update (update-previous-message message-with-pos-data previous-message))))))
(defn remove-message
"Remove a message in the list"
+1 -1
View File
@@ -35,6 +35,7 @@
:audioDurationMs :audio-duration-ms
:deleted :deleted?
:deletedForMe :deleted-for-me?
:albumId :album-id
:new :new?})
(update :quoted-message
@@ -48,7 +49,6 @@
(assoc :content {:chat-id (:chatId message)
:text (:text message)
:image (:image message)
:album-id (:albumId message)
:sticker (:sticker message)
:ens-name (:ensName message)
:line-count (:lineCount message)
@@ -1,4 +1,5 @@
(ns status-im.ui2.screens.chat.messages.message
<<<<<<< HEAD
(:require
[quo.design-system.colors :as quo.colors]
[quo.react-native :as rn]
@@ -32,6 +33,45 @@
[status-im2.contexts.chat.messages.delete-message.events]
[utils.re-frame :as rf]
[quo2.core :as quo])
=======
(:require [quo.design-system.colors :as quo.colors]
[quo.react-native :as rn]
[quo2.components.avatars.user-avatar :as user-avatar]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.foundations.typography :as typography]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.constants :as constants]
[status-im.i18n.i18n :as i18n]
[status-im.react-native.resources :as resources]
[status-im.ui.components.fast-image :as fast-image]
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.image.preview.views :as preview]
[status-im.ui.screens.chat.message.audio :as message.audio]
[status-im.ui.screens.chat.message.command :as message.command]
[status-im.ui.screens.chat.message.gap :as message.gap]
[status-im.ui.screens.chat.message.link-preview :as link-preview]
[status-im.ui.screens.chat.sheets :as sheets]
[status-im.ui.screens.chat.styles.message.message :as style]
[status-im.ui.screens.chat.utils :as chat.utils]
[status-im.ui.screens.communities.icon :as communities.icon]
[status-im.ui2.screens.chat.components.reply :as components.reply]
[status-im.utils.config :as config]
[status-im.utils.datetime :as time]
[status-im.utils.utils :as utils]
[status-im2.contexts.chat.home.chat-list-item.view :as home.chat-list-item]
[status-im2.contexts.chat.messages.delete-message-for-me.events]
[status-im2.contexts.chat.messages.delete-message.events]
[utils.re-frame :as rf]
<<<<<<< HEAD
[quo2.core :as quo])
=======
[utils.security.core :as security]
[status-im2.contexts.chat.messages.album.view :as album])
>>>>>>> b640f2420... feat: images album
>>>>>>> bcb0fd54e... feat: images album
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(def edited-at-text (str " ⌫ " (i18n/label :t/edited)))
@@ -433,11 +473,9 @@
reaction-picker]))
(defmethod ->message constants/content-type-album
[{:keys [album-id] :as message}
{:keys [on-long-press modal ref] :as reaction-picker}]
(println "MAMA" (get message album-id))
[rn/view
[rn/text "FUCKING ALBUM!!!!"]])
[message reaction-picker]
[message-content-wrapper message
[album/album-message message reaction-picker]])
(defmethod ->message constants/content-type-image
[{:keys [content in-popover? outgoing] :as message}
@@ -0,0 +1,10 @@
(ns status-im2.contexts.chat.messages.album.style
(:require [quo2.foundations.colors :as colors]))
(def overlay
{:position :absolute
:width 73
:height 73
:background-color colors/neutral-80-opa-60
:justify-content :center
:align-items :center})
@@ -0,0 +1,69 @@
(ns status-im2.contexts.chat.messages.album.view
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
[reagent.core :as reagent]
[status-im2.contexts.chat.messages.album.style :as style]))
(def image-max-width 260)
(def image-max-height 192)
(def image-sizes
{4 {0 146
1 146
2 146
3 146}
5 {0 146
1 146
2 97
3 97
4 97}
:default {0 146
1 146
2 72.5
3 72.5
4 72.5
5 72.5}})
(defn image-set-size
[dimensions]
(fn [evt]
(let [width (.-width (.-nativeEvent evt))
height (.-height (.-nativeEvent evt))]
(if (< width height)
;; if width less than the height we reduce width proportionally to height
(let [k (/ height image-max-height)]
(when (not= (/ width k) (first @dimensions))
(reset! dimensions {:width (/ width k) :height image-max-height :loaded true})))
(swap! dimensions assoc :loaded true)))))
(defn album-message
[message]
(let [dimensions (reagent/atom {:width image-max-width :height image-max-height :loaded false})]
[rn/view
{:style {:flex-direction :row
:flex-wrap :wrap
:border-radius 12
:width 293
:overflow :hidden}}
(map-indexed (fn [index item]
(let [images-count (count (:album message))
images-size-key (if (< images-count 6) images-count :default)
size (get-in image-sizes [images-size-key index])]
[rn/view {:key (str index)}
[fast-image/fast-image
{:style {:width size
:height size
:margin-left (when (and (not= index 0) (not= index 2)) 1)
:margin-bottom (when (or (= index 0) (= index 1)) 1)}
:on-load (image-set-size dimensions)
:on-error #(swap! dimensions assoc :error true)
:source {:uri (:image (:content item))}}]
(when (and (> images-count 6) (= index 5))
[rn/view {:style style/overlay}
[quo/text
{:weight :bold
:size :heading-2
:style {:color colors/white}} (str "+" (- images-count 5))]])]))
(:album message))]))
@@ -18,7 +18,7 @@
(defonce messages-list-ref (atom nil))
(defonce list-key-fn #(or (:message-id %) (:value %) :nil))
(defonce list-key-fn #(or (:message-id %) (:value %)))
(defonce list-ref #(reset! messages-list-ref %))
(defn scroll-to-bottom
@@ -133,7 +133,7 @@
[message/message-with-reactions message-data context])]))])
=======
(defn render-fn
[{:keys [outgoing type album-id] :as message}
[{:keys [outgoing type] :as message}
idx
_
{:keys [group-chat public? community? current-public-key
@@ -147,7 +147,6 @@
[gap/gap message idx messages-list-ref false chat-id]
; message content
[message/chat-message
(if-not album-id
(assoc message
:incoming-group (and group-chat (not outgoing))
:group-chat group-chat
@@ -158,9 +157,13 @@
:message-pin-enabled message-pin-enabled
:edit-enabled edit-enabled
:can-delete-message-for-everyone? can-delete-message-for-everyone?)
<<<<<<< HEAD
(assoc message
:content-type 12))]))])
>>>>>>> ef5639b77... updates
=======
]))])
>>>>>>> b640f2420... feat: images album
(defn messages-list
[{:keys [chat
+2 -2
View File
@@ -4,12 +4,12 @@
[utils.re-frame :as rf]))
;; Ignore all logs, because there are lots of temporary warnings when developing and hot reloading
(.ignoreAllLogs LogBox)
;(.ignoreAllLogs LogBox)
;; Only ignore warnings/errors that cannot be fixed for the time being.
;; When you add a warning to be ignored explain below why it is ignored and how it can be fixed.
;; When a warning is fixed make sure to remove it from here.
#_(.ignoreLogs ^js LogBox
(.ignoreLogs ^js LogBox
(clj->js ["undefined is not an object (evaluating 'e.message')"
"Cannot read property 'message' of undefined"
"InternalError Metro has encountered an error"
+122 -122
View File
@@ -4,82 +4,83 @@
[status-im.chat.models.message-list :as models.message-list]
[status-im.chat.models.reactions :as models.reactions]
[status-im.utils.datetime :as datetime]
[status-im2.common.constants :as constants]))
[status-im2.common.constants :as constants]
[status-im.constants]))
(re-frame/reg-sub
:chats/chat-messages
:<- [:messages/messages]
(fn [messages [_ chat-id]]
(get messages chat-id {})))
:chats/chat-messages
:<- [:messages/messages]
(fn [messages [_ chat-id]]
(get messages chat-id {})))
(re-frame/reg-sub
:chats/pinned
(fn [[_ chat-id] _]
[(re-frame/subscribe [:messages/pin-messages])
(re-frame/subscribe [:chats/chat-messages chat-id])])
(fn [[pin-messages messages] [_ chat-id]]
(let [pin-messages (get pin-messages chat-id {})]
(reduce-kv (fn [acc message-id message]
(let [{:keys [deleted? deleted-for-me?]} (get messages message-id)]
(if (or deleted? deleted-for-me?)
acc
(assoc acc message-id message))))
{}
pin-messages))))
:chats/pinned
(fn [[_ chat-id] _]
[(re-frame/subscribe [:messages/pin-messages])
(re-frame/subscribe [:chats/chat-messages chat-id])])
(fn [[pin-messages messages] [_ chat-id]]
(let [pin-messages (get pin-messages chat-id {})]
(reduce-kv (fn [acc message-id message]
(let [{:keys [deleted? deleted-for-me?]} (get messages message-id)]
(if (or deleted? deleted-for-me?)
acc
(assoc acc message-id message))))
{}
pin-messages))))
(re-frame/reg-sub
:chats/pinned-sorted-list
(fn [[_ chat-id] _]
(re-frame/subscribe [:chats/pinned chat-id]))
(fn [pin-messages _]
(->> pin-messages
vals
(sort-by :pinned-at <))))
:chats/pinned-sorted-list
(fn [[_ chat-id] _]
(re-frame/subscribe [:chats/pinned chat-id]))
(fn [pin-messages _]
(->> pin-messages
vals
(sort-by :pinned-at <))))
(re-frame/reg-sub
:chats/pin-modal
:<- [:messages/pin-modal]
(fn [pin-modal [_ chat-id]]
(get pin-modal chat-id)))
:chats/pin-modal
:<- [:messages/pin-modal]
(fn [pin-modal [_ chat-id]]
(get pin-modal chat-id)))
(re-frame/reg-sub
:chats/message-reactions
:<- [:multiaccount/public-key]
:<- [:messages/reactions]
(fn [[current-public-key reactions] [_ message-id chat-id]]
(models.reactions/message-reactions
current-public-key
(get-in reactions [chat-id message-id]))))
:chats/message-reactions
:<- [:multiaccount/public-key]
:<- [:messages/reactions]
(fn [[current-public-key reactions] [_ message-id chat-id]]
(models.reactions/message-reactions
current-public-key
(get-in reactions [chat-id message-id]))))
(re-frame/reg-sub
:chats/all-loaded?
:<- [:messages/pagination-info]
(fn [pagination-info [_ chat-id]]
(get-in pagination-info [chat-id :all-loaded?])))
:chats/all-loaded?
:<- [:messages/pagination-info]
(fn [pagination-info [_ chat-id]]
(get-in pagination-info [chat-id :all-loaded?])))
(re-frame/reg-sub
:chats/loading-messages?
:<- [:messages/pagination-info]
(fn [pagination-info [_ chat-id]]
(get-in pagination-info [chat-id :loading-messages?])))
:chats/loading-messages?
:<- [:messages/pagination-info]
(fn [pagination-info [_ chat-id]]
(get-in pagination-info [chat-id :loading-messages?])))
(re-frame/reg-sub
:chats/loading-pin-messages?
:<- [:messages/pagination-info]
(fn [pagination-info [_ chat-id]]
(get-in pagination-info [chat-id :loading-pin-messages?])))
:chats/loading-pin-messages?
:<- [:messages/pagination-info]
(fn [pagination-info [_ chat-id]]
(get-in pagination-info [chat-id :loading-pin-messages?])))
(re-frame/reg-sub
:chats/message-list
:<- [:messages/message-lists]
(fn [message-lists [_ chat-id]]
(get message-lists chat-id)))
:chats/message-list
:<- [:messages/message-lists]
(fn [message-lists [_ chat-id]]
(get message-lists chat-id)))
(re-frame/reg-sub
:chats/pin-message-list
:<- [:messages/pin-message-lists]
(fn [pin-message-lists [_ chat-id]]
(get pin-message-lists chat-id)))
:chats/pin-message-list
:<- [:messages/pin-message-lists]
(fn [pin-message-lists [_ chat-id]]
(get pin-message-lists chat-id)))
(defn hydrate-messages
"Pull data from messages and add it to the sorted list"
@@ -96,83 +97,82 @@
message-list)))
(re-frame/reg-sub
:chats/chat-no-messages?
(fn [[_ chat-id] _]
(re-frame/subscribe [:chats/chat-messages chat-id]))
(fn [messages]
(empty? messages)))
:chats/chat-no-messages?
(fn [[_ chat-id] _]
(re-frame/subscribe [:chats/chat-messages chat-id]))
(fn [messages]
(empty? messages)))
(defn find-albums [messages]
(let [new-messages (atom {})]
(let [all-messages (atom [])
albums (atom {})]
(doseq [message messages]
(let [album-id (or (:album-id (:content message)) :all-messages)]
(if (get @new-messages album-id)
(swap! new-messages update-in [album-id] #(conj % message))
(swap! new-messages assoc-in [album-id] [message]))
;)
(when (and (not= album-id :all-messages) (> (count (get @new-messages album-id)) 3))
(swap! new-messages update-in [:all-messages] #(conj % {album-id (get @new-messages album-id)
:album-id album-id})))
))
;(println "asdfasdf" (:all-messages @new-messages))
(:all-messages @new-messages))
;messages
)
(let [album-id (when (:albumize message) (:album-id message))]
(if (and album-id (get @albums album-id))
(swap! albums update-in [album-id] #(conj % message))
(swap! albums assoc-in [album-id] [message]))
(swap! all-messages conj message)
(when (and album-id (> (count (get @albums album-id)) 3))
(do
(swap! all-messages (fn [data] (filterv #(not= album-id (:album-id %)) data)))
(swap! all-messages conj {:album (get @albums album-id)
:album-id album-id
:message-id album-id
:content-type status-im.constants/content-type-album})))))
@all-messages))
(re-frame/reg-sub
:chats/raw-chat-messages-stream
(fn [[_ chat-id] _]
[(re-frame/subscribe [:chats/message-list chat-id])
(re-frame/subscribe [:chats/chat-messages chat-id])
(re-frame/subscribe [:chats/pinned chat-id])
(re-frame/subscribe [:chats/loading-messages? chat-id])
(re-frame/subscribe [:chats/synced-from chat-id])
(re-frame/subscribe [:chats/chat-type chat-id])
(re-frame/subscribe [:chats/joined chat-id])])
(fn [[message-list messages pin-messages loading-messages? synced-from chat-type joined] [_ chat-id]]
;;TODO (perf)
;(js/console.log "LLL" message-list)
(let [message-list-seq (models.message-list/->seq message-list)]
; Don't show gaps if that's the case as we are still loading messages
(if (and (empty? message-list-seq) loading-messages?)
[]
(-> message-list-seq
(chat.db/add-datemarks)
(hydrate-messages messages pin-messages)
(chat.db/collapse-gaps chat-id
synced-from
(datetime/timestamp)
chat-type
joined
loading-messages?)
(find-albums)
)))))
:chats/raw-chat-messages-stream
(fn [[_ chat-id] _]
[(re-frame/subscribe [:chats/message-list chat-id])
(re-frame/subscribe [:chats/chat-messages chat-id])
(re-frame/subscribe [:chats/pinned chat-id])
(re-frame/subscribe [:chats/loading-messages? chat-id])
(re-frame/subscribe [:chats/synced-from chat-id])
(re-frame/subscribe [:chats/chat-type chat-id])
(re-frame/subscribe [:chats/joined chat-id])])
(fn [[message-list messages pin-messages loading-messages? synced-from chat-type joined] [_ chat-id]]
;;TODO (perf)
(let [message-list-seq (models.message-list/->seq message-list)]
; Don't show gaps if that's the case as we are still loading messages
(if (and (empty? message-list-seq) loading-messages?)
[]
(-> message-list-seq
(chat.db/add-datemarks)
(hydrate-messages messages pin-messages)
(chat.db/collapse-gaps chat-id
synced-from
(datetime/timestamp)
chat-type
joined
loading-messages?)
(find-albums))))))
;;we want to keep data unchanged so react doesn't change component when we leave screen
(def memo-profile-messages-stream (atom nil))
(re-frame/reg-sub
:chats/profile-messages-stream
(fn [[_ chat-id] _]
[(re-frame/subscribe [:chats/raw-chat-messages-stream chat-id])
(re-frame/subscribe [:chats/chat-no-messages? chat-id])
(re-frame/subscribe [:view-id])])
(fn [[messages empty view-id]]
(when (or (= view-id :profile) empty)
(reset! memo-profile-messages-stream messages))
@memo-profile-messages-stream))
:chats/profile-messages-stream
(fn [[_ chat-id] _]
[(re-frame/subscribe [:chats/raw-chat-messages-stream chat-id])
(re-frame/subscribe [:chats/chat-no-messages? chat-id])
(re-frame/subscribe [:view-id])])
(fn [[messages empty view-id]]
(when (or (= view-id :profile) empty)
(reset! memo-profile-messages-stream messages))
@memo-profile-messages-stream))
(def memo-timeline-messages-stream (atom nil))
(re-frame/reg-sub
:chats/timeline-messages-stream
:<- [:chats/message-list constants/timeline-chat-id]
:<- [:chats/chat-messages constants/timeline-chat-id]
:<- [:view-id]
(fn [[message-list messages view-id]]
(if (= view-id :status)
(let [res (-> (models.message-list/->seq message-list)
(hydrate-messages messages))]
(reset! memo-timeline-messages-stream res)
res)
@memo-timeline-messages-stream)))
:chats/timeline-messages-stream
:<- [:chats/message-list constants/timeline-chat-id]
:<- [:chats/chat-messages constants/timeline-chat-id]
:<- [:view-id]
(fn [[message-list messages view-id]]
(if (= view-id :status)
(let [res (-> (models.message-list/->seq message-list)
(hydrate-messages messages))]
(reset! memo-timeline-messages-stream res)
res)
@memo-timeline-messages-stream)))