[slow sign in] Denorlmalize last message
The last messages of the chats are necessary to properly show the chat list, which is shown right after signing in. Before this commit, the last message was retrieved as one of 20 last messages fetched for each chat. Implementation: - `:last-message-content` and `:last-message-type` fields were added to `chat` entity - both fields are updated when messages are received/sent - loading of the last 20 messages for each chat was removed as initialization step
This commit is contained in:
parent
07e8f6908d
commit
c440b7a3a7
|
@ -66,42 +66,15 @@
|
|||
message-id)))
|
||||
statuses))
|
||||
|
||||
(fx/defn load-chats-messages
|
||||
[{:keys [db get-stored-messages get-stored-user-statuses get-referenced-messages]
|
||||
:as cofx}]
|
||||
(let [chats (:chats db)
|
||||
public-key (accounts.db/current-public-key cofx)]
|
||||
(fx/merge
|
||||
cofx
|
||||
{:db (assoc
|
||||
db :chats
|
||||
(reduce
|
||||
(fn [chats chat-id]
|
||||
(let [{:keys [messages]} (get-stored-messages chat-id)
|
||||
chat-messages (index-messages messages)
|
||||
message-ids (keys chat-messages)
|
||||
statuses (get-stored-user-statuses chat-id message-ids)
|
||||
unviewed-messages-ids (get-unviewed-messages-ids statuses public-key)]
|
||||
(update
|
||||
chats
|
||||
chat-id
|
||||
assoc
|
||||
|
||||
:messages chat-messages
|
||||
:message-statuses statuses
|
||||
:loaded-unviewed-messages-ids unviewed-messages-ids
|
||||
:referenced-messages (into {}
|
||||
(get-referenced-messages
|
||||
(get-referenced-ids chat-messages))))))
|
||||
chats
|
||||
(keys chats)))}
|
||||
(group-messages))))
|
||||
|
||||
(fx/defn initialize-chats
|
||||
"Initialize all persisted chats on startup"
|
||||
[{:keys [db default-dapps all-stored-chats] :as cofx}]
|
||||
(let [chats (reduce (fn [acc {:keys [chat-id] :as chat}]
|
||||
(assoc acc chat-id chat))
|
||||
(assoc acc chat-id
|
||||
(assoc chat
|
||||
:messages-initialized? false
|
||||
:referenced-messages {}
|
||||
:messages empty-message-map)))
|
||||
{}
|
||||
all-stored-chats)]
|
||||
(fx/merge cofx
|
||||
|
@ -154,6 +127,7 @@
|
|||
loaded-unviewed-messages (get-unviewed-messages-ids new-statuses public-key)]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:chats current-chat-id :messages-initialized?] true)
|
||||
(update-in [:chats current-chat-id :messages] merge indexed-messages)
|
||||
(update-in [:chats current-chat-id :message-statuses] merge new-statuses)
|
||||
(update-in [:chats current-chat-id :referenced-messages]
|
||||
|
|
|
@ -266,6 +266,26 @@
|
|||
(= from current-public-key))
|
||||
messages))))))
|
||||
|
||||
(defn- update-last-message [all-chats chat-id]
|
||||
(let [{:keys [messages message-groups]}
|
||||
(get all-chats chat-id)
|
||||
{:keys [content message-type]}
|
||||
(->> (chat.db/sort-message-groups message-groups messages)
|
||||
first
|
||||
second
|
||||
last
|
||||
:message-id
|
||||
(get messages))]
|
||||
(chat-model/upsert-chat
|
||||
{:chat-id chat-id
|
||||
:last-message-content content
|
||||
:last-message-type message-type})))
|
||||
|
||||
(fx/defn update-last-messages
|
||||
[{:keys [db] :as cofx} chat-ids]
|
||||
(apply fx/merge cofx
|
||||
(map (partial update-last-message (:chats db)) chat-ids)))
|
||||
|
||||
(fx/defn receive-many
|
||||
[{:keys [now] :as cofx} messages]
|
||||
(let [valid-messages (keep #(when-let [chat-id (extract-chat-id cofx %)]
|
||||
|
@ -293,7 +313,8 @@
|
|||
messages-fx-fns
|
||||
groups-fx-fns
|
||||
(when platform/desktop?
|
||||
[(chat-model/update-dock-badge-label)])))))
|
||||
[(chat-model/update-dock-badge-label)])
|
||||
[(update-last-messages chat-ids)]))))
|
||||
|
||||
(defn system-message [{:keys [now] :as cofx} {:keys [clock-value chat-id content from]}]
|
||||
(let [{:keys [last-clock-value]} (get-in cofx [:db :chats chat-id])
|
||||
|
@ -347,8 +368,11 @@
|
|||
:raw-payload-hash (transport.utils/sha3 raw-payload))]
|
||||
|
||||
(fx/merge cofx
|
||||
(chat-model/upsert-chat {:chat-id chat-id
|
||||
:timestamp now})
|
||||
(chat-model/upsert-chat
|
||||
{:chat-id chat-id
|
||||
:timestamp now
|
||||
:last-message-content (:content message)
|
||||
:last-message-type (:message-type message)})
|
||||
(add-message false message-with-id true)
|
||||
(add-own-status chat-id message-id :sending)
|
||||
(send chat-id message-id wrapped-record))))
|
||||
|
|
|
@ -221,18 +221,6 @@
|
|||
(when (= id (:public-key account))
|
||||
(:photo-path account)))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/last-message
|
||||
(fn [[_ chat-id]]
|
||||
(re-frame/subscribe [:chats/chat chat-id]))
|
||||
(fn [{:keys [messages message-groups]}]
|
||||
(->> (chat.db/sort-message-groups message-groups messages)
|
||||
first
|
||||
second
|
||||
last
|
||||
:message-id
|
||||
(get messages))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/unread-messages-number
|
||||
:<- [:chats/active-chats]
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
(ns status-im.data-store.chats
|
||||
(:require [goog.object :as object]
|
||||
[cljs.core.async :as async]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.utils.ethereum.core :as utils.ethereum]
|
||||
[status-im.utils.clocks :as utils.clocks]
|
||||
[status-im.data-store.realm.core :as core]))
|
||||
[status-im.data-store.realm.core :as core]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im.utils.core :as utils]
|
||||
[cljs.tools.reader.edn :as edn]))
|
||||
|
||||
(defn remove-empty-vals
|
||||
"Remove key/value when empty seq or nil"
|
||||
|
@ -60,7 +62,9 @@
|
|||
(update :tags #(into #{} %))
|
||||
(update :membership-updates (partial unmarshal-membership-updates chat-id))
|
||||
;; We cap the clock value to a safe value in case the db has been polluted
|
||||
(assoc :last-clock-value (get-last-clock-value chat-id))))
|
||||
(assoc :last-clock-value (get-last-clock-value chat-id))
|
||||
(update :last-message-type keyword)
|
||||
(update :last-message-content edn/read-string)))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:data-store/all-chats
|
||||
|
@ -73,12 +77,14 @@
|
|||
|
||||
(defn save-chat-tx
|
||||
"Returns tx function for saving chat"
|
||||
[{:keys [chat-id] :as chat}]
|
||||
[chat]
|
||||
(fn [realm]
|
||||
(core/create
|
||||
realm
|
||||
:chat
|
||||
(update chat :membership-updates marshal-membership-updates)
|
||||
(-> chat
|
||||
(update :membership-updates marshal-membership-updates)
|
||||
(utils/update-if-present :last-message-content messages/prepare-content))
|
||||
true)))
|
||||
|
||||
;; Only used in debug mode
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
(fn [cofx _]
|
||||
(assoc cofx :get-referenced-messages get-references-by-ids)))
|
||||
|
||||
(defn- prepare-content [content]
|
||||
(defn prepare-content [content]
|
||||
(if (string? content)
|
||||
content
|
||||
(pr-str content)))
|
||||
|
|
|
@ -223,3 +223,10 @@
|
|||
:tags {:type "string[]"}
|
||||
:unviewed-messages-count {:type :int
|
||||
:default 0}}})
|
||||
|
||||
(def v10
|
||||
(update v9 :properties merge
|
||||
{:last-message-content {:type :string
|
||||
:optional true}
|
||||
:last-message-type {:type :string
|
||||
:optional true}}))
|
||||
|
|
|
@ -291,6 +291,19 @@
|
|||
browser/v8
|
||||
dapp-permissions/v9])
|
||||
|
||||
(def v28 [chat/v10
|
||||
transport/v7
|
||||
contact/v3
|
||||
message/v9
|
||||
mailserver/v11
|
||||
mailserver-topic/v1
|
||||
user-status/v2
|
||||
membership-update/v1
|
||||
installation/v2
|
||||
local-storage/v1
|
||||
browser/v8
|
||||
dapp-permissions/v9])
|
||||
|
||||
;; put schemas ordered by version
|
||||
(def schemas [{:schema v1
|
||||
:schemaVersion 1
|
||||
|
@ -372,4 +385,7 @@
|
|||
:migration migrations/v26}
|
||||
{:schema v27
|
||||
:schemaVersion 27
|
||||
:migration migrations/v27}])
|
||||
:migration migrations/v27}
|
||||
{:schema v28
|
||||
:schemaVersion 28
|
||||
:migration migrations/v28}])
|
||||
|
|
|
@ -298,3 +298,21 @@
|
|||
|
||||
(doseq [status @statuses-to-be-deleted]
|
||||
(.delete new-realm status))))
|
||||
|
||||
(defn get-last-message [realm chat-id]
|
||||
(->
|
||||
(.objects realm "message")
|
||||
(.filtered (str "chat-id=\"" chat-id "\""))
|
||||
(.sorted "timestamp" true)
|
||||
(aget 0)))
|
||||
|
||||
(defn v28 [old-realm new-realm]
|
||||
(let [chats (.objects new-realm "chat")]
|
||||
(dotimes [i (.-length chats)]
|
||||
(let [chat (aget chats i)
|
||||
chat-id (aget chat "chat-id")]
|
||||
(when-let [last-message (get-last-message new-realm chat-id)]
|
||||
(let [content (aget last-message "content")
|
||||
message-type (aget last-message "message-type")]
|
||||
(aset chat "last-message-content" content)
|
||||
(aset chat "last-message-type" message-type)))))))
|
||||
|
|
|
@ -91,14 +91,6 @@
|
|||
(fn [cofx [_ encryption-key error]]
|
||||
(init/handle-init-store-error cofx encryption-key)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:load-chats-messages
|
||||
[(re-frame/inject-cofx :data-store/get-messages)
|
||||
(re-frame/inject-cofx :data-store/get-referenced-messages)
|
||||
(re-frame/inject-cofx :data-store/get-user-statuses)]
|
||||
(fn [cofx]
|
||||
(chat-loading/load-chats-messages cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:init-chats
|
||||
[(re-frame/inject-cofx :web3/get-web3)
|
||||
|
|
|
@ -114,13 +114,18 @@
|
|||
[react/text {:style style/empty-chat-text-name} (:name contact)]]
|
||||
(i18n/label :t/empty-chat-description))]])))
|
||||
|
||||
(defview messages-view [group-chat modal?]
|
||||
(defview messages-view [chat group-chat modal?]
|
||||
(letsubs [messages [:chats/current-chat-messages-stream]
|
||||
chat [:chats/current-chat]
|
||||
current-public-key [:account/public-key]]
|
||||
{:component-did-mount #(re-frame/dispatch [:chat.ui/set-chat-ui-props {:messages-focused? true
|
||||
:input-focused? false}])}
|
||||
(if (empty? messages)
|
||||
{:component-did-mount
|
||||
(fn [args]
|
||||
(when-not (:messages-initialized? (second (.-argv (.-props args))))
|
||||
(re-frame/dispatch [:chat.ui/load-more-messages]))
|
||||
(re-frame/dispatch [:chat.ui/set-chat-ui-props
|
||||
{:messages-focused? true
|
||||
:input-focused? false}]))}
|
||||
(if (and (empty? messages)
|
||||
(:messages-initialized? chat))
|
||||
[empty-chat-container chat]
|
||||
[list/flat-list {:data messages
|
||||
:key-fn #(or (:message-id %) (:value %))
|
||||
|
@ -134,6 +139,10 @@
|
|||
:enableEmptySections true
|
||||
:keyboardShouldPersistTaps :handled}])))
|
||||
|
||||
(defview messages-view-wrapper [group-chat modal?]
|
||||
(letsubs [chat [:chats/current-chat]]
|
||||
[messages-view chat group-chat modal?]))
|
||||
|
||||
(defview chat-root [modal?]
|
||||
(letsubs [{:keys [group-chat public?]} [:chats/current-chat]
|
||||
show-bottom-info? [:chats/current-chat-ui-prop :show-bottom-info?]
|
||||
|
@ -151,7 +160,7 @@
|
|||
[chat-toolbar public? modal?]
|
||||
(if (or (= :chat current-view) modal?)
|
||||
[messages-view-animation
|
||||
[messages-view group-chat modal?]]
|
||||
[messages-view-wrapper group-chat modal?]]
|
||||
[react/view style/message-view-preview])
|
||||
[input/container]
|
||||
(when show-bottom-info?
|
||||
|
|
|
@ -19,13 +19,18 @@
|
|||
[status-im.ui.components.action-button.action-button :as action-button]
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(views/defview chat-list-item-inner-view [{:keys [chat-id name group-chat color public? public-key] :as chat-item}]
|
||||
(views/defview chat-list-item-inner-view [{:keys [chat-id name group-chat
|
||||
color public? public-key
|
||||
last-message-content
|
||||
last-message-type]
|
||||
:as chat-item}]
|
||||
(views/letsubs [photo-path [:contacts/chat-photo chat-id]
|
||||
unviewed-messages-count [:chats/unviewed-messages-count chat-id]
|
||||
chat-name [:chats/chat-name chat-id]
|
||||
current-chat-id [:chats/current-chat-id]
|
||||
{:keys [content] :as last-message} [:chats/last-message chat-id]]
|
||||
(let [name (or chat-name
|
||||
current-chat-id [:chats/current-chat-id]]
|
||||
(let [last-message {:content last-message-content
|
||||
:message-type last-message-type}
|
||||
name (or chat-name
|
||||
(gfycat/generate-gfy public-key))
|
||||
[unviewed-messages-label large?] [(utils/unread-messages-count unviewed-messages-count) true]
|
||||
current? (= current-chat-id chat-id)]
|
||||
|
@ -52,7 +57,7 @@
|
|||
:style styles/chat-last-message}
|
||||
(if (= constants/content-type-command (:content-type last-message))
|
||||
[chat-item/command-short-preview last-message]
|
||||
(or (:text content)
|
||||
(or (:text last-message-content)
|
||||
(i18n/label :no-messages-yet)))]]
|
||||
[react/view {:style styles/timestamp}
|
||||
[chat-item/message-timestamp (:timestamp last-message)]
|
||||
|
@ -140,14 +145,7 @@
|
|||
(fn [this]
|
||||
(let [[_ loading?] (.. this -props -argv)]
|
||||
(when loading?
|
||||
(re-frame/dispatch [:init-chats]))))
|
||||
|
||||
:component-did-update
|
||||
(fn [this [_ old-loading?]]
|
||||
(let [[_ loading?] (.. this -props -argv)]
|
||||
(when (and (false? loading?)
|
||||
(true? old-loading?))
|
||||
(re-frame/dispatch [:load-chats-messages]))))}
|
||||
(re-frame/dispatch [:init-chats]))))}
|
||||
[react/view {:style styles/chat-list-view}
|
||||
[react/view {:style styles/chat-list-header}
|
||||
[search-input search-filter]
|
||||
|
|
|
@ -100,14 +100,7 @@
|
|||
(when loading?
|
||||
(utils/set-timeout
|
||||
#(re-frame/dispatch [:init-chats])
|
||||
100))))
|
||||
|
||||
:component-did-update
|
||||
(fn [this [_ old-loading?]]
|
||||
(let [[_ loading?] (.. this -props -argv)]
|
||||
(when (and (false? loading?)
|
||||
(true? old-loading?))
|
||||
(re-frame/dispatch [:load-chats-messages]))))}
|
||||
100))))}
|
||||
[react/view styles/container
|
||||
[toolbar show-welcome? (and network-initialized? (not rpc-network?)) sync-state latest-block-number]
|
||||
(cond show-welcome?
|
||||
|
|
|
@ -88,9 +88,10 @@
|
|||
(defview home-list-chat-item-inner-view [{:keys [chat-id name color online
|
||||
group-chat public?
|
||||
public-key
|
||||
timestamp]}]
|
||||
(letsubs [last-message [:chats/last-message chat-id]
|
||||
chat-name [:chats/chat-name chat-id]]
|
||||
timestamp
|
||||
last-message-content
|
||||
last-message-type]}]
|
||||
(letsubs [chat-name [:chats/chat-name chat-id]]
|
||||
(let [truncated-chat-name (utils/truncate-str chat-name 30)]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])}
|
||||
[react/view styles/chat-container
|
||||
|
@ -100,10 +101,10 @@
|
|||
[react/view styles/item-upper-container
|
||||
[chat-list-item-name truncated-chat-name group-chat public? public-key]
|
||||
[react/view styles/message-status-container
|
||||
[message-timestamp (or (:timestamp last-message)
|
||||
timestamp)]]]
|
||||
[message-timestamp timestamp]]]
|
||||
[react/view styles/item-lower-container
|
||||
[message-content-text last-message]
|
||||
[message-content-text {:content last-message-content
|
||||
:content-type last-message-type}]
|
||||
[unviewed-indicator chat-id]]]]])))
|
||||
|
||||
(defn home-list-browser-item-inner-view [{:keys [dapp url name browser-id] :as browser}]
|
||||
|
|
|
@ -10,9 +10,14 @@
|
|||
:admins #{4}
|
||||
:contacts #{2}
|
||||
:tags #{}
|
||||
:membership-updates []}
|
||||
(chats/normalize-chat {:admins [4]
|
||||
:contacts [2]})))))
|
||||
:membership-updates []
|
||||
:last-message-type :message-type
|
||||
:last-message-content {:foo "bar"}}
|
||||
(chats/normalize-chat
|
||||
{:admins [4]
|
||||
:contacts [2]
|
||||
:last-message-type "message-type"
|
||||
:last-message-content "{:foo \"bar\"}"})))))
|
||||
(testing "membership-updates"
|
||||
(with-redefs [chats/get-last-clock-value (constantly 42)]
|
||||
(let [raw-events {"1" {:id "1" :type "members-added" :clock-value 10 :members [1 2] :signature "a" :from "id-1"}
|
||||
|
|
Loading…
Reference in New Issue