From c65ca5c92eb87172801aac7df8a277ca8bdb2c01 Mon Sep 17 00:00:00 2001 From: Andrey Shovkoplyas Date: Wed, 22 Apr 2020 12:18:52 +0200 Subject: [PATCH] start loading messages earlier Signed-off-by: Andrey Shovkoplyas --- src/status_im/chat/db.cljs | 1 - src/status_im/chat/models.cljs | 63 +++---------------- src/status_im/chat/models/loading.cljs | 15 ++--- src/status_im/chat/models/message_seen.cljs | 52 +++++++++++++++ src/status_im/events.cljs | 3 +- src/status_im/group_chats/db.cljs | 10 +-- src/status_im/multiaccounts/login/core.cljs | 10 +-- .../ui/screens/routing/chat_stack.cljs | 1 - test/cljs/status_im/test/chat/models.cljs | 9 +-- 9 files changed, 80 insertions(+), 84 deletions(-) create mode 100644 src/status_im/chat/models/message_seen.cljs diff --git a/src/status_im/chat/db.cljs b/src/status_im/chat/db.cljs index 495ca866a9..36c920da4f 100644 --- a/src/status_im/chat/db.cljs +++ b/src/status_im/chat/db.cljs @@ -1,6 +1,5 @@ (ns status-im.chat.db (:require [clojure.set :as clojure.set] - [clojure.string :as string] [status-im.multiaccounts.core :as multiaccounts] [status-im.contact.db :as contact.db] [status-im.group-chats.db :as group-chats.db] diff --git a/src/status_im/chat/models.cljs b/src/status_im/chat/models.cljs index 73bdd6c269..cee254f82f 100644 --- a/src/status_im/chat/models.cljs +++ b/src/status_im/chat/models.cljs @@ -10,17 +10,15 @@ [status-im.ethereum.json-rpc :as json-rpc] [status-im.i18n :as i18n] [status-im.mailserver.core :as mailserver] - [status-im.transport.message.protocol :as transport.protocol] [status-im.ui.components.colors :as colors] [status-im.ui.components.react :as react] [status-im.ui.screens.navigation :as navigation] [status-im.utils.clocks :as utils.clocks] - [status-im.utils.config :as config] [status-im.utils.fx :as fx] - [status-im.utils.gfycat.core :as gfycat] [status-im.utils.platform :as platform] [status-im.utils.utils :as utils] - [taoensso.timbre :as log])) + [status-im.chat.models.message-seen :as message-seen] + [status-im.chat.models.loading :as loading])) (defn- get-chat [cofx chat-id] (get-in cofx [:db :chats chat-id])) @@ -218,54 +216,6 @@ (when (not (= (:view-id db) :home)) (navigation/navigate-to-cofx :home {})))) -(defn- unread-messages-number [chats] - (apply + (map :unviewed-messages-count chats))) - -(fx/defn update-dock-badge-label - [cofx] - (let [chats (get-in cofx [:db :chats]) - active-chats (filter :is-active (vals chats)) - private-chats (filter (complement :public?) active-chats) - public-chats (filter :public? active-chats) - private-chats-unread-count (unread-messages-number private-chats) - public-chats-unread-count (unread-messages-number public-chats) - label (cond - (pos? private-chats-unread-count) private-chats-unread-count - (pos? public-chats-unread-count) "•" - :else nil)] - {:set-dock-badge-label label})) - -(defn subtract-seen-messages - [old-count new-seen-messages-ids] - (max 0 (- old-count (count new-seen-messages-ids)))) - -(fx/defn update-chats-unviewed-messages-count - [{:keys [db] :as cofx} {:keys [chat-id loaded-unviewed-messages-ids]}] - (let [{:keys [loaded-unviewed-messages-ids unviewed-messages-count]} - (get-in db [:chats chat-id])] - {:db (update-in db [:chats chat-id] assoc - :unviewed-messages-count (subtract-seen-messages - unviewed-messages-count - loaded-unviewed-messages-ids) - :loaded-unviewed-messages-ids #{})})) - -(fx/defn mark-messages-seen - "Marks all unviewed loaded messages as seen in particular chat" - [{:keys [db] :as cofx} chat-id] - (let [loaded-unviewed-ids (get-in db [:chats chat-id :loaded-unviewed-messages-ids])] - (when (seq loaded-unviewed-ids) - (fx/merge cofx - {:db (reduce (fn [acc message-id] - (assoc-in acc [:chats chat-id :messages - message-id :seen] - true)) - db - loaded-unviewed-ids)} - (messages-store/mark-messages-seen chat-id loaded-unviewed-ids nil) - (update-chats-unviewed-messages-count {:chat-id chat-id}) - (when platform/desktop? - (update-dock-badge-label)))))) - (fx/defn offload-all-messages {:events [::offload-all-messages]} [{:keys [db] :as cofx}] @@ -295,16 +245,17 @@ (when-not (group-chat? cofx chat-id) (transport.filters/load-chat chat-id)) (when platform/desktop? - (mark-messages-seen chat-id)) + (message-seen/mark-messages-seen chat-id)) (when (and (one-to-one-chat? cofx chat-id) (not (contact.db/contact-exists? db chat-id))) - (contact.core/create-contact chat-id))))) + (contact.core/create-contact chat-id)) + (loading/load-messages)))) (fx/defn navigate-to-chat "Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data" [cofx chat-id] (fx/merge cofx - (navigation/navigate-to-cofx :chat {}) - (preload-chat-data chat-id))) + (preload-chat-data chat-id) + (navigation/navigate-to-cofx :chat {}))) (fx/defn start-chat "Start a chat, making sure it exists" diff --git a/src/status_im/chat/models/loading.cljs b/src/status_im/chat/models/loading.cljs index a420c014e7..c7d0523dbd 100644 --- a/src/status_im/chat/models/loading.cljs +++ b/src/status_im/chat/models/loading.cljs @@ -6,14 +6,11 @@ [status-im.data-store.chats :as data-store.chats] [status-im.data-store.messages :as data-store.messages] [status-im.transport.filters.core :as filters] - [status-im.chat.models :as chat-model] - [status-im.ethereum.json-rpc :as json-rpc] [status-im.mailserver.core :as mailserver] - [status-im.utils.config :as config] - [status-im.utils.datetime :as time] [status-im.utils.fx :as fx] [status-im.chat.models.message-list :as message-list] - [taoensso.timbre :as log])) + [taoensso.timbre :as log] + [status-im.chat.models.message-seen :as message-seen])) (defn cursor->clock-value [cursor] (js/parseInt (.substring cursor 51 64))) @@ -121,7 +118,7 @@ (assoc-in [:chats current-chat-id :cursor] cursor) (assoc-in [:chats current-chat-id :all-loaded?] (empty? cursor)))} - (chat-model/mark-messages-seen current-chat-id))))) + (message-seen/mark-messages-seen current-chat-id))))) (fx/defn load-more-messages [{:keys [db] :as cofx}] @@ -142,7 +139,6 @@ (mailserver/load-gaps-fx current-chat-id))))))) (fx/defn load-messages - {:events [::load-messages]} [{:keys [db now] :as cofx}] (when-let [current-chat-id (:current-chat-id db)] (if-not (get-in db [:chats current-chat-id :messages-initialized?]) @@ -155,8 +151,7 @@ ;; which will be reset only if we hit home (assoc :loaded-chat-id current-chat-id) (assoc-in [:chats current-chat-id :messages-initialized?] now))} - (chat-model/mark-messages-seen current-chat-id) + (message-seen/mark-messages-seen current-chat-id) (load-more-messages))) ;; We mark messages as seen in case we received them while on a different tab - (chat-model/mark-messages-seen cofx current-chat-id)))) - + (message-seen/mark-messages-seen cofx current-chat-id)))) diff --git a/src/status_im/chat/models/message_seen.cljs b/src/status_im/chat/models/message_seen.cljs new file mode 100644 index 0000000000..c387ba61f3 --- /dev/null +++ b/src/status_im/chat/models/message_seen.cljs @@ -0,0 +1,52 @@ +(ns status-im.chat.models.message-seen + (:require [status-im.utils.fx :as fx] + [status-im.data-store.messages :as messages-store] + [status-im.utils.platform :as platform])) + +(defn- unread-messages-number [chats] + (apply + (map :unviewed-messages-count chats))) + +(fx/defn update-dock-badge-label + [cofx] + (let [chats (get-in cofx [:db :chats]) + active-chats (filter :is-active (vals chats)) + private-chats (filter (complement :public?) active-chats) + public-chats (filter :public? active-chats) + private-chats-unread-count (unread-messages-number private-chats) + public-chats-unread-count (unread-messages-number public-chats) + label (cond + (pos? private-chats-unread-count) private-chats-unread-count + (pos? public-chats-unread-count) "•" + :else nil)] + {:set-dock-badge-label label})) + +(defn subtract-seen-messages + [old-count new-seen-messages-ids] + (max 0 (- old-count (count new-seen-messages-ids)))) + +(fx/defn update-chats-unviewed-messages-count + [{:keys [db] :as cofx} {:keys [chat-id loaded-unviewed-messages-ids]}] + (let [{:keys [loaded-unviewed-messages-ids unviewed-messages-count]} + (get-in db [:chats chat-id])] + {:db (update-in db [:chats chat-id] assoc + :unviewed-messages-count (subtract-seen-messages + unviewed-messages-count + loaded-unviewed-messages-ids) + :loaded-unviewed-messages-ids #{})})) + +(fx/defn mark-messages-seen + "Marks all unviewed loaded messages as seen in particular chat" + [{:keys [db] :as cofx} chat-id] + (let [loaded-unviewed-ids (get-in db [:chats chat-id :loaded-unviewed-messages-ids])] + (when (seq loaded-unviewed-ids) + (fx/merge cofx + {:db (reduce (fn [acc message-id] + (assoc-in acc [:chats chat-id :messages + message-id :seen] + true)) + db + loaded-unviewed-ids)} + (messages-store/mark-messages-seen chat-id loaded-unviewed-ids nil) + (update-chats-unviewed-messages-count {:chat-id chat-id}) + (when platform/desktop? + (update-dock-badge-label)))))) \ No newline at end of file diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 7f118cfb52..3dfaec2b11 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -66,6 +66,7 @@ [status-im.wallet.db :as wallet.db] [taoensso.timbre :as log] [status-im.utils.money :as money] + [status-im.chat.models.message-seen :as message-seen] status-im.hardwallet.core status-im.popover.core)) @@ -555,7 +556,7 @@ (defn- mark-messages-seen [{:keys [db] :as cofx}] (let [{:keys [current-chat-id]} db] - (chat/mark-messages-seen cofx current-chat-id))) + (message-seen/mark-messages-seen cofx current-chat-id))) (handlers/register-handler-fx :chat.ui/mark-messages-seen diff --git a/src/status_im/group_chats/db.cljs b/src/status_im/group_chats/db.cljs index 50d04c0d8d..26d594854c 100644 --- a/src/status_im/group_chats/db.cljs +++ b/src/status_im/group_chats/db.cljs @@ -1,6 +1,5 @@ (ns status-im.group-chats.db - (:require [status-im.chat.models :as models.chat] - [status-im.multiaccounts.core :as multiaccounts])) + (:require [status-im.multiaccounts.core :as multiaccounts])) (def members-added-type 3) @@ -22,11 +21,14 @@ from))) first)) +(defn group-chat? [chat] + (and (:group-chat chat) (not (:public? chat)))) + (defn get-pending-invite-inviter-name "when the chat is a private group chat in which the user has been invited and didn't accept the invitation yet, return inviter-name" [contacts chat my-public-key] - (when (and (models.chat/group-chat? chat) + (when (and (group-chat? chat) (invited? my-public-key chat) (not (joined? my-public-key chat))) (let [inviter-pk (get-inviter-pk my-public-key chat)] @@ -36,6 +38,6 @@ "when the chat is a private group chat in which the user has been invited and didn't accept the invitation yet, return inviter-name" [contacts chat my-public-key] - (when (models.chat/group-chat? chat) + (when (group-chat? chat) (let [inviter-pk (get-inviter-pk my-public-key chat)] (multiaccounts/displayed-name (or (get contacts inviter-pk) {:public-key inviter-pk}))))) diff --git a/src/status_im/multiaccounts/login/core.cljs b/src/status_im/multiaccounts/login/core.cljs index 1d5f7c3173..e6d15b4708 100644 --- a/src/status_im/multiaccounts/login/core.cljs +++ b/src/status_im/multiaccounts/login/core.cljs @@ -1,13 +1,9 @@ (ns status-im.multiaccounts.login.core (:require [re-frame.core :as re-frame] - [status-im.chaos-mode.core :as chaos-mode] - [status-im.chat.models :as chat-model] [status-im.chat.models.loading :as chat.loading] - [status-im.constants :as constants] [status-im.contact.core :as contact] [status-im.ethereum.core :as ethereum] [status-im.ethereum.json-rpc :as json-rpc] - [status-im.ethereum.transactions.core :as transactions] [status-im.fleet.core :as fleet] [status-im.i18n :as i18n] [status-im.native-module.core :as status] @@ -32,10 +28,10 @@ [status-im.utils.identicon :as identicon] [status-im.ethereum.eip55 :as eip55] [status-im.popover.core :as popover] - [status-im.hardwallet.nfc :as nfc] [status-im.multiaccounts.core :as multiaccounts] [status-im.data-store.settings :as data-store.settings] - [status-im.wallet.prices :as prices])) + [status-im.wallet.prices :as prices] + [status-im.chat.models.message-seen :as message-seen])) (def rpc-endpoint "https://goerli.infura.io/v3/f315575765b14720b32382a61a89341a") (def contract-address "0xfbf4c8e2B41fAfF8c616a0E49Fb4365a5355Ffaf") @@ -249,7 +245,7 @@ (keychain/save-user-password key-uid password)) (keychain/save-auth-method key-uid (or new-auth-method auth-method)) (when platform/desktop? - (chat-model/update-dock-badge-label))))) + (message-seen/update-dock-badge-label))))) (fx/defn create-only-events [{:keys [db] :as cofx}] diff --git a/src/status_im/ui/screens/routing/chat_stack.cljs b/src/status_im/ui/screens/routing/chat_stack.cljs index fd42efc569..8f3809e39c 100644 --- a/src/status_im/ui/screens/routing/chat_stack.cljs +++ b/src/status_im/ui/screens/routing/chat_stack.cljs @@ -22,7 +22,6 @@ :style {:padding-bottom tabbar.styles/tabs-diff} :component home/home} {:name :chat - :on-focus [::chat.loading/load-messages] :component chat/chat} {:name :profile :component profile.contact/profile} diff --git a/test/cljs/status_im/test/chat/models.cljs b/test/cljs/status_im/test/chat/models.cljs index d7c15806f4..b48a1710fb 100644 --- a/test/cljs/status_im/test/chat/models.cljs +++ b/test/cljs/status_im/test/chat/models.cljs @@ -4,7 +4,8 @@ [status-im.utils.identicon :as identicon] [status-im.ethereum.json-rpc :as json-rpc] [status-im.utils.clocks :as utils.clocks] - [status-im.chat.models :as chat])) + [status-im.chat.models :as chat] + [status-im.chat.models.message-seen :as message-seen])) (deftest upsert-chat-test (testing "upserting a non existing chat" @@ -156,7 +157,7 @@ (deftest update-dock-badge-label (testing "When user has unseen private messages" (is (= {:set-dock-badge-label 3} - (chat/update-dock-badge-label + (message-seen/update-dock-badge-label {:db {:chats {"0x0" {:is-active true :public? false :unviewed-messages-count 3 @@ -167,7 +168,7 @@ :loaded-unviewed-messages-ids #{1 2}}}}})))) (testing "When user has unseen public messages and no unseen private messages" (is (= {:set-dock-badge-label "•"} - (chat/update-dock-badge-label + (message-seen/update-dock-badge-label {:db {:chats {"0x0" {:is-active true :public? false :unviewed-messages-count 0 @@ -178,7 +179,7 @@ :loaded-unviewed-messages-ids #{1 2}}}}})))) (testing "When user has no unseen messages" (is (= {:set-dock-badge-label nil} - (chat/update-dock-badge-label + (message-seen/update-dock-badge-label {:db {:chats {"0x0" {:is-active true :public? false :unviewed-messages-count 0