chats list performance

Signed-off-by: andrey <motor4ik@gmail.com>
This commit is contained in:
andrey 2021-09-03 09:45:57 +02:00
parent 6387bba9f5
commit 82b640abe1
No known key found for this signature in database
GPG Key ID: 89B67245FD2F0272
22 changed files with 351 additions and 461 deletions

View File

@ -15,7 +15,8 @@
[status-im.utils.types :as types] [status-im.utils.types :as types]
[status-im.add-new.db :as new-public-chat.db] [status-im.add-new.db :as new-public-chat.db]
[status-im.chat.models.loading :as loading] [status-im.chat.models.loading :as loading]
[status-im.ui.screens.chat.state :as chat.state])) [status-im.ui.screens.chat.state :as chat.state]
[clojure.set :as set]))
(defn chats [] (defn chats []
(:chats (types/json->clj (js/require "./chats.js")))) (:chats (types/json->clj (js/require "./chats.js"))))
@ -44,11 +45,8 @@
([cofx chat-id] ([cofx chat-id]
(community-chat? (get-chat cofx chat-id)))) (community-chat? (get-chat cofx chat-id))))
(defn active-chat? (defn active-chat? [cofx chat-id]
([chat] (not (nil? (get-chat cofx chat-id))))
(:is-active chat))
([cofx chat-id]
(active-chat? (get-chat cofx chat-id))))
(defn foreground-chat? (defn foreground-chat?
[{{:keys [current-chat-id view-id]} :db} chat-id] [{{:keys [current-chat-id view-id]} :db} chat-id]
@ -87,22 +85,10 @@
:color (rand-nth colors/chat-colors) :color (rand-nth colors/chat-colors)
:chat-type constants/one-to-one-chat-type :chat-type constants/one-to-one-chat-type
:group-chat false :group-chat false
:is-active true
:timestamp now :timestamp now
:contacts #{chat-id} :contacts #{chat-id}
:last-clock-value 0})) :last-clock-value 0}))
(fx/defn ensure-chat
"Add chat to db and update"
[{:keys [db] :as cofx} {:keys [chat-id timeline?] :as chat-props}]
(let [chat (merge
(or (get (:chats db) chat-id)
(create-new-chat chat-id cofx))
chat-props)
new? (not (get-in db [:chats chat-id]))
public? (public-chat? chat)]
{:db (update-in db [:chats chat-id] merge chat)}))
(defn map-chats [{:keys [db] :as cofx}] (defn map-chats [{:keys [db] :as cofx}]
(fn [val] (fn [val]
(assoc (assoc
@ -119,13 +105,24 @@
(fx/defn ensure-chats (fx/defn ensure-chats
"Add chats to db and update" "Add chats to db and update"
[{:keys [db] :as cofx} chats] [{:keys [db] :as cofx} chats]
(let [chats (map (map-chats cofx) chats) (let [{:keys [all-chats chats-home-list removed-chats]}
filtered-chats (filter (filter-chats db) chats)] (reduce (fn [acc {:keys [chat-id profile-public-key timeline? community-id active] :as chat}]
{:db (update db :chats #(reduce (if (not active)
(fn [acc {:keys [chat-id] :as chat}] (update acc :removed-chats conj chat-id)
(update acc chat-id merge chat)) (cond-> acc
% (and (not profile-public-key) (not timeline?) (not community-id))
chats))})) (update :chats-home-list conj chat-id)
:always
(assoc-in [:all-chats chat-id] chat))))
{:all-chats {}
:chats-home-list #{}
:removed-chats #{}}
(map (map-chats cofx) chats))]
{:db (-> db
(update :chats merge all-chats)
(update :chats-home-list set/union chats-home-list)
(update :chats #(apply dissoc % removed-chats))
(update :chats-home-list set/difference removed-chats))}))
(fx/defn clear-history (fx/defn clear-history
"Clears history of the particular chat" "Clears history of the particular chat"
@ -165,6 +162,7 @@
cofx cofx
{:db (-> db {:db (-> db
(assoc-in [:chats chat-id :is-active] false) (assoc-in [:chats chat-id :is-active] false)
(update :chats-home-list disj chat-id)
(assoc-in [:current-chat-id] nil)) (assoc-in [:current-chat-id] nil))
::json-rpc/call [{:method "wakuext_deactivateChat" ::json-rpc/call [{:method "wakuext_deactivateChat"
:params [{:id chat-id}] :params [{:id chat-id}]
@ -202,10 +200,16 @@
(when (not (= (:view-id db) :home)) (when (not (= (:view-id db) :home))
(navigation/pop-to-root-tab :chat-stack)))) (navigation/pop-to-root-tab :chat-stack))))
(fx/defn show-more-chats
{:events [:chat.ui/show-more-chats]}
[{:keys [db]}]
(when (< (:home-items-show-number db) (count (:chats db)))
{:db (update db :home-items-show-number + 40)}))
(fx/defn preload-chat-data (fx/defn preload-chat-data
"Takes chat-id and coeffects map, returns effects necessary when navigating to chat" "Takes chat-id and coeffects map, returns effects necessary when navigating to chat"
{:events [:chat.ui/preload-chat-data]} {:events [:chat.ui/preload-chat-data]}
[{:keys [db] :as cofx} chat-id] [cofx chat-id]
(loading/load-messages cofx chat-id)) (loading/load-messages cofx chat-id))
(fx/defn navigate-to-chat (fx/defn navigate-to-chat
@ -217,6 +221,8 @@
(fn [{:keys [db]}] (fn [{:keys [db]}]
{:db (assoc db :current-chat-id chat-id :ignore-close-chat true)}) {:db (assoc db :current-chat-id chat-id :ignore-close-chat true)})
(preload-chat-data chat-id) (preload-chat-data chat-id)
#(when (group-chat? cofx chat-id)
(loading/load-chat % chat-id))
#(when-not dont-reset? #(when-not dont-reset?
(navigation/change-tab % :chat)) (navigation/change-tab % :chat))
#(when-not dont-reset? #(when-not dont-reset?
@ -225,7 +231,7 @@
(fx/defn handle-clear-history-response (fx/defn handle-clear-history-response
{:events [::history-cleared]} {:events [::history-cleared]}
[{:keys [db] :as cofx} chat-id response] [{:keys [db]} chat-id response]
(let [chat (chats-store/<-rpc (first (:chats response)))] (let [chat (chats-store/<-rpc (first (:chats response)))]
{:db (assoc-in db [:chats chat-id] chat)})) {:db (assoc-in db [:chats chat-id] chat)}))
@ -233,7 +239,9 @@
{:events [::one-to-one-chat-created]} {:events [::one-to-one-chat-created]}
[{:keys [db]} chat-id response] [{:keys [db]} chat-id response]
(let [chat (chats-store/<-rpc (first (:chats response)))] (let [chat (chats-store/<-rpc (first (:chats response)))]
{:db (assoc-in db [:chats chat-id] chat) {:db (-> db
(assoc-in [:chats chat-id] chat)
(update :chats-home-list conj chat-id))
:dispatch [:chat.ui/navigate-to-chat chat-id]})) :dispatch [:chat.ui/navigate-to-chat chat-id]}))
(fx/defn navigate-to-user-pinned-messages (fx/defn navigate-to-user-pinned-messages
@ -261,14 +269,16 @@
(fx/defn handle-public-chat-created (fx/defn handle-public-chat-created
{:events [::public-chat-created]} {:events [::public-chat-created]}
[{:keys [db] :as cofx} chat-id {:keys [dont-navigate?]} response] [{:keys [db]} chat-id {:keys [dont-navigate?]} response]
(let [chat (chats-store/<-rpc (first (:chats response))) (let [chat (chats-store/<-rpc (first (:chats response)))
db-with-chat {:db (assoc-in db [:chats chat-id] chat)}] db-with-chat {:db (-> db
(assoc-in [:chats chat-id] chat)
(update :chats-home-list conj chat-id))}]
(if dont-navigate? (if dont-navigate?
db-with-chat db-with-chat
(assoc db-with-chat :dispatch [:chat.ui/navigate-to-chat chat-id])))) (assoc db-with-chat :dispatch [:chat.ui/navigate-to-chat chat-id]))))
(fx/defn create-public-chat-go [cofx chat-id opts] (fx/defn create-public-chat-go [_ chat-id opts]
{::json-rpc/call [{:method "wakuext_createPublicChat" {::json-rpc/call [{:method "wakuext_createPublicChat"
:params [{:id chat-id}] :params [{:id chat-id}]
:on-success #(re-frame/dispatch [::public-chat-created chat-id opts %]) :on-success #(re-frame/dispatch [::public-chat-created chat-id opts %])

View File

@ -21,22 +21,35 @@
(fx/defn update-chats-in-app-db (fx/defn update-chats-in-app-db
{:events [:chats-list/load-success]} {:events [:chats-list/load-success]}
[{:keys [db]} new-chats] [{:keys [db]} ^js new-chats-js]
(let [old-chats (:chats db) (let [{:keys [all-chats chats-home-list]}
chats (reduce (fn [acc {:keys [chat-id] :as chat}] (reduce (fn [acc ^js chat-js]
(assoc acc chat-id chat)) (let [{:keys [chat-id profile-public-key timeline? community-id] :as chat}
{} (data-store.chats/<-rpc-js chat-js)]
new-chats) (cond-> acc
chats (merge old-chats chats)] (and (not profile-public-key) (not timeline?) (not community-id))
{:db (assoc db :chats chats (update :chats-home-list conj chat-id)
:always
(assoc-in [:all-chats chat-id] chat))))
{:all-chats {}
:chats-home-list #{}}
new-chats-js)]
{:db (assoc db :chats all-chats
:chats-home-list chats-home-list
:chats/loading? false)})) :chats/loading? false)}))
(fx/defn initialize-chats (fx/defn load-chat-success
"Initialize persisted chats on startup" {:events [:chats-list/load-chat-success]}
[cofx] [{:keys [db]} ^js chat]
(data-store.chats/fetch-chats-rpc cofx {:on-success (let [{:keys [chat-id] :as chat} (data-store.chats/<-rpc chat)]
#(re-frame/dispatch {:db (update-in db [:chats chat-id] merge chat)}))
[:chats-list/load-success %])}))
(fx/defn load-chat
[_ chat-id]
{::json-rpc/call [{:method (json-rpc/call-ext-method "chat")
:params [chat-id]
:on-success #(re-frame/dispatch [:chats-list/load-chat-success %])
:on-failure #(log/error "failed to fetch chats" 0 -1 %)}]})
(fx/defn handle-failed-loading-messages (fx/defn handle-failed-loading-messages
{:events [::failed-loading-messages]} {:events [::failed-loading-messages]}

View File

@ -50,10 +50,7 @@
(is (= nil (get-in actual [:db :messages chat-id]))))) (is (= nil (get-in actual [:db :messages chat-id])))))
(testing "it sets a deleted-at-clock-value equal to the last message clock-value" (testing "it sets a deleted-at-clock-value equal to the last message clock-value"
(let [actual (chat/remove-chat cofx chat-id)] (let [actual (chat/remove-chat cofx chat-id)]
(is (= 10 (get-in actual [:db :chats chat-id :deleted-at-clock-value]))))) (is (= 10 (get-in actual [:db :chats chat-id :deleted-at-clock-value])))))))
(testing "it sets the chat as inactive"
(let [actual (chat/remove-chat cofx chat-id)]
(is (= false (get-in actual [:db :chats chat-id :is-active])))))))
(deftest multi-user-chat? (deftest multi-user-chat?
(let [chat-id "1"] (let [chat-id "1"]

View File

@ -6,32 +6,25 @@
[status-im.utils.fx :as fx] [status-im.utils.fx :as fx]
[taoensso.timbre :as log])) [taoensso.timbre :as log]))
(defn rpc->type [{:keys [chatType name] :as chat}] (defn rpc->type [{:keys [chat-type name] :as chat}]
(cond (cond
(or (= constants/public-chat-type chatType) (or (= constants/public-chat-type chat-type)
(= constants/profile-chat-type chatType) (= constants/profile-chat-type chat-type)
(= constants/timeline-chat-type chatType)) (assoc chat (= constants/timeline-chat-type chat-type)) (assoc chat
:chat-name (str "#" name) :chat-name (str "#" name)
:public? true :public? true
:group-chat true :group-chat true
:timeline? (= constants/timeline-chat-type chatType)) :timeline? (= constants/timeline-chat-type chat-type))
(= constants/community-chat-type chatType) (assoc chat (= constants/community-chat-type chat-type) (assoc chat
:chat-name name :chat-name name
:group-chat true) :group-chat true)
(= constants/private-group-chat-type chatType) (assoc chat (= constants/private-group-chat-type chat-type) (assoc chat
:chat-name name :chat-name name
:public? false :public? false
:group-chat true) :group-chat true)
:else (assoc chat :public? false :group-chat false))) :else (assoc chat :public? false :group-chat false)))
(defn- unmarshal-members [{:keys [members chatType] :as chat}] (defn members-reducer [acc member]
(cond
(= constants/public-chat-type chatType) (assoc chat
:contacts #{}
:admins #{}
:members-joined #{})
(= constants/private-group-chat-type chatType) (merge chat
(reduce (fn [acc member]
(cond-> acc (cond-> acc
(:admin member) (:admin member)
(update :admins conj (:id member)) (update :admins conj (:id member))
@ -39,6 +32,15 @@
(update :members-joined conj (:id member)) (update :members-joined conj (:id member))
:always :always
(update :contacts conj (:id member)))) (update :contacts conj (:id member))))
(defn- unmarshal-members [{:keys [members chat-type] :as chat}]
(cond
(= constants/public-chat-type chat-type) (assoc chat
:contacts #{}
:admins #{}
:members-joined #{})
(= constants/private-group-chat-type chat-type) (merge chat
(reduce members-reducer
{:admins #{} {:admins #{}
:members-joined #{} :members-joined #{}
:contacts #{}} :contacts #{}}
@ -51,8 +53,6 @@
(defn <-rpc [chat] (defn <-rpc [chat]
(-> chat (-> chat
rpc->type
unmarshal-members
(clojure.set/rename-keys {:id :chat-id (clojure.set/rename-keys {:id :chat-id
:communityId :community-id :communityId :community-id
:syncedFrom :synced-from :syncedFrom :synced-from
@ -63,15 +63,42 @@
:unviewedMessagesCount :unviewed-messages-count :unviewedMessagesCount :unviewed-messages-count
:unviewedMentionsCount :unviewed-mentions-count :unviewedMentionsCount :unviewed-mentions-count
:lastMessage :last-message :lastMessage :last-message
:active :is-active
:lastClockValue :last-clock-value :lastClockValue :last-clock-value
:invitationAdmin :invitation-admin :invitationAdmin :invitation-admin
:profile :profile-public-key}) :profile :profile-public-key})
rpc->type
unmarshal-members
(update :last-message #(when % (messages/<-rpc %))) (update :last-message #(when % (messages/<-rpc %)))
(dissoc :members))) (dissoc :members)))
(fx/defn fetch-chats-rpc [cofx {:keys [on-success]}] (defn <-rpc-js [^js chat]
{::json-rpc/call [{:method (json-rpc/call-ext-method "chats") (-> {:name (.-name chat)
:description (.-description chat)
:color (.-color chat)
:timestamp (.-timestamp chat)
:alias (.-alias chat)
:identicon (.-identicon chat)
:muted (.-muted chat)
:joined (.-joined chat)
:chat-id (.-id chat)
:community-id (.-communityId chat)
:synced-from (.-syncedFrom chat)
:synced-to (.-syncedTo chat)
:deleted-at-clock-value (.-deletedAtClockValue chat)
:chat-type (.-chatType chat)
:unviewed-messages-count (.-unviewedMessagesCount chat)
:unviewed-mentions-count (.-unviewedMentionsCount chat)
:last-message {:content {:text (.-text chat)}
:content-type (.-contentType chat)}
:last-clock-value (.-lastClockValue chat)
:profile-public-key (.-profile chat)}
rpc->type
unmarshal-members))
(fx/defn fetch-chats-rpc [_ {:keys [on-success]}]
{::json-rpc/call [{:method (json-rpc/call-ext-method "chatsPreview")
:params [] :params []
:on-success #(on-success (map <-rpc %)) :js-response true
:on-success #(on-success ^js %)
:on-failure #(log/error "failed to fetch chats" 0 -1 %)}]}) :on-failure #(log/error "failed to fetch chats" 0 -1 %)}]})

View File

@ -22,7 +22,6 @@
:lastClockValue 10 :lastClockValue 10
:membershipUpdateEvents :events :membershipUpdateEvents :events
:unviewedMessagesCount 2 :unviewedMessagesCount 2
:active true
:timestamp 2} :timestamp 2}
expected-chat {:public? false expected-chat {:public? false
:group-chat true :group-chat true
@ -37,7 +36,6 @@
:name "name" :name "name"
:membership-update-events :events :membership-update-events :events
:unviewed-messages-count 2 :unviewed-messages-count 2
:is-active true
:chat-id "chat-id" :chat-id "chat-id"
:timestamp 2}] :timestamp 2}]
(testing "from-rpc" (testing "from-rpc"

View File

@ -33,14 +33,14 @@
:nickname :localNickname}))) :nickname :localNickname})))
(fx/defn fetch-contacts-rpc (fx/defn fetch-contacts-rpc
[cofx on-success] [_ on-success]
{::json-rpc/call [{:method (json-rpc/call-ext-method "contacts") {::json-rpc/call [{:method (json-rpc/call-ext-method "contacts")
:params [] :params []
:on-success #(on-success (map <-rpc %)) :on-success #(on-success (map <-rpc %))
:on-failure #(log/error "failed to fetch contacts" %)}]}) :on-failure #(log/error "failed to fetch contacts" %)}]})
(fx/defn save-contact (fx/defn save-contact
[cofx {:keys [public-key] :as contact} on-success] [_ {:keys [public-key] :as contact} on-success]
{::json-rpc/call [{:method (json-rpc/call-ext-method "saveContact") {::json-rpc/call [{:method (json-rpc/call-ext-method "saveContact")
:params [(->rpc contact)] :params [(->rpc contact)]
:on-success #(do :on-success #(do
@ -49,7 +49,7 @@
(on-success))) (on-success)))
:on-failure #(log/error "failed to save contact" public-key %)}]}) :on-failure #(log/error "failed to save contact" public-key %)}]})
(fx/defn block [cofx contact on-success] (fx/defn block [_ contact on-success]
{::json-rpc/call [{:method (json-rpc/call-ext-method "blockContact") {::json-rpc/call [{:method (json-rpc/call-ext-method "blockContact")
:params [(->rpc contact)] :params [(->rpc contact)]
:on-success on-success :on-success on-success

View File

@ -27,6 +27,8 @@
:chat/cooldown-enabled? false :chat/cooldown-enabled? false
:chat/last-outgoing-message-sent-at 0 :chat/last-outgoing-message-sent-at 0
:chat/spam-messages-frequency 0 :chat/spam-messages-frequency 0
:chats-home-list #{}
:home-items-show-number 20
:tooltips {} :tooltips {}
:dimensions/window (dimensions/window) :dimensions/window (dimensions/window)
:registry {} :registry {}

View File

@ -72,8 +72,9 @@
"wakuext_removeFilters" {} "wakuext_removeFilters" {}
"wakuext_sendContactUpdate" {} "wakuext_sendContactUpdate" {}
"wakuext_sendContactUpdates" {} "wakuext_sendContactUpdates" {}
"wakuext_chats" {} "wakuext_chatsPreview" {}
"wakuext_activeChats" {} "wakuext_activeChats" {}
"wakuext_chat" {}
"wakuext_addSystemMessages" {} "wakuext_addSystemMessages" {}
"wakuext_deleteMessagesFrom" {} "wakuext_deleteMessagesFrom" {}
"wakuext_deleteMessagesByChatID" {} "wakuext_deleteMessagesByChatID" {}

View File

@ -13,7 +13,7 @@
(fx/defn navigate-chat-updated (fx/defn navigate-chat-updated
{:events [:navigate-chat-updated]} {:events [:navigate-chat-updated]}
[cofx chat-id] [cofx chat-id]
(when (get-in cofx [:db :chats chat-id :is-active]) (when (get-in cofx [:db :chats chat-id])
(fx/merge cofx (fx/merge cofx
{:dispatch-later [{:ms 1000 :dispatch [:chat.ui/navigate-to-chat chat-id]}]} {:dispatch-later [{:ms 1000 :dispatch [:chat.ui/navigate-to-chat chat-id]}]}
(navigation/pop-to-root-tab :chat-stack)))) (navigation/pop-to-root-tab :chat-stack))))
@ -59,7 +59,7 @@
(fx/defn create-from-link (fx/defn create-from-link
[cofx {:keys [chat-id invitation-admin chat-name]}] [cofx {:keys [chat-id invitation-admin chat-name]}]
(if (get-in cofx [:db :chats chat-id :is-active]) (if (get-in cofx [:db :chats chat-id])
{:dispatch-n [[:accept-all-activity-center-notifications-from-chat chat-id] {:dispatch-n [[:accept-all-activity-center-notifications-from-chat chat-id]
[:chat.ui/navigate-to-chat chat-id false]]} [:chat.ui/navigate-to-chat chat-id false]]}
{::json-rpc/call [{:method (json-rpc/call-ext-method "createGroupChatFromInvitation") {::json-rpc/call [{:method (json-rpc/call-ext-method "createGroupChatFromInvitation")

View File

@ -1,7 +1,6 @@
(ns status-im.multiaccounts.login.core (ns status-im.multiaccounts.login.core
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[status-im.anon-metrics.core :as anon-metrics] [status-im.anon-metrics.core :as anon-metrics]
[status-im.chat.models.loading :as chat.loading]
[status-im.contact.core :as contact] [status-im.contact.core :as contact]
[status-im.utils.config :as config] [status-im.utils.config :as config]
[status-im.data-store.settings :as data-store.settings] [status-im.data-store.settings :as data-store.settings]
@ -37,7 +36,8 @@
[status-im.async-storage.core :as async-storage] [status-im.async-storage.core :as async-storage]
[status-im.notifications-center.core :as notifications-center] [status-im.notifications-center.core :as notifications-center]
[status-im.navigation :as navigation] [status-im.navigation :as navigation]
[status-im.signing.eip1559 :as eip1559])) [status-im.signing.eip1559 :as eip1559]
[status-im.data-store.chats :as data-store.chats]))
(re-frame/reg-fx (re-frame/reg-fx
::initialize-communities-enabled ::initialize-communities-enabled
@ -250,10 +250,19 @@
(.catch (fn [_] (.catch (fn [_]
(log/error "Failed to initialize wallet")))))) (log/error "Failed to initialize wallet"))))))
(fx/defn initialize-browser [_]
{::json-rpc/call
[{:method "browsers_getBrowsers"
:on-success #(re-frame/dispatch [::initialize-browsers %])}
{:method "browsers_getBookmarks"
:on-success #(re-frame/dispatch [::initialize-bookmarks %])}
{:method "permissions_getDappPermissions"
:on-success #(re-frame/dispatch [::initialize-dapp-permissions %])}]})
(fx/defn initialize-appearance [cofx] (fx/defn initialize-appearance [cofx]
{::multiaccounts/switch-theme (get-in cofx [:db :multiaccount :appearance])}) {::multiaccounts/switch-theme (get-in cofx [:db :multiaccount :appearance])})
(fx/defn get-group-chat-invitations [cofx] (fx/defn get-group-chat-invitations [_]
{::json-rpc/call {::json-rpc/call
[{:method (json-rpc/call-ext-method "getGroupChatInvitations") [{:method (json-rpc/call-ext-method "getGroupChatInvitations")
:on-success #(re-frame/dispatch [::initialize-invitations %])}]}) :on-success #(re-frame/dispatch [::initialize-invitations %])}]})
@ -279,19 +288,36 @@
(fx/defn get-settings-callback (fx/defn get-settings-callback
{:events [::get-settings-callback]} {:events [::get-settings-callback]}
[{:keys [db] :as cofx} settings] [{:keys [db] :as cofx} settings]
(let [{:keys [notifications-enabled?] (let [{:networks/keys [current-network networks]
:networks/keys [current-network networks]
:as settings} :as settings}
(data-store.settings/rpc->settings settings) (data-store.settings/rpc->settings settings)
multiaccount (dissoc settings :networks/current-network :networks/networks) multiaccount (dissoc settings :networks/current-network :networks/networks)]
network-id (str (get-in networks [current-network :config :NetworkId]))]
(fx/merge cofx (fx/merge cofx
(cond-> {:db (-> db {:db (-> db
(dissoc :multiaccounts/login) (dissoc :multiaccounts/login)
(assoc :networks/current-network current-network (assoc :networks/current-network current-network
:networks/networks networks :networks/networks networks
:multiaccount multiaccount)) :multiaccount multiaccount))}
::eip1559/check-eip1559-activation (data-store.chats/fetch-chats-rpc
{:on-success
#(do (re-frame/dispatch [:chats-list/load-success %])
(re-frame/dispatch [::get-chats-callback settings]))})
(acquisition/login)
(initialize-appearance)
(initialize-communities-enabled)
(get-node-config)
(communities/fetch)
(logging/set-log-level (:log-level multiaccount))
(notifications-center/get-activity-center-notifications-count))))
(fx/defn get-chats-callback
{:events [::get-chats-callback]}
[{:keys [db] :as cofx} settings]
(let [{:keys [notifications-enabled?]
:networks/keys [current-network networks]} settings
network-id (str (get-in networks [current-network :config :NetworkId]))]
(fx/merge cofx
(cond-> {::eip1559/check-eip1559-activation
{:network-id network-id {:network-id network-id
:on-enabled #(log/info "eip1550 is activated") :on-enabled #(log/info "eip1550 is activated")
:on-disabled #(log/info "eip1559 is not activated")} :on-disabled #(log/info "eip1559 is not activated")}
@ -301,24 +327,17 @@
accounts custom-tokens favourites]))} accounts custom-tokens favourites]))}
notifications-enabled? notifications-enabled?
(assoc ::notifications/enable nil)) (assoc ::notifications/enable nil))
(acquisition/login)
(initialize-appearance)
(transport/start-messenger) (transport/start-messenger)
(initialize-communities-enabled)
(initialize-transactions-management-enabled) (initialize-transactions-management-enabled)
(check-network-version network-id) (check-network-version network-id)
(chat.loading/initialize-chats)
(get-node-config)
(communities/fetch)
(contact/initialize-contacts) (contact/initialize-contacts)
(stickers/init-stickers-packs) (stickers/init-stickers-packs)
(initialize-browser)
(mobile-network/on-network-status-change) (mobile-network/on-network-status-change)
(get-group-chat-invitations) (get-group-chat-invitations)
(logging/set-log-level (:log-level multiaccount))
(multiaccounts/get-profile-picture) (multiaccounts/get-profile-picture)
(multiaccounts/switch-preview-privacy-mode-flag) (multiaccounts/switch-preview-privacy-mode-flag)
(link-preview/request-link-preview-whitelist) (link-preview/request-link-preview-whitelist))))
(notifications-center/get-activity-center-notifications-count))))
(defn get-new-auth-method [auth-method save-password?] (defn get-new-auth-method [auth-method save-password?]
(when save-password? (when save-password?
@ -358,13 +377,7 @@
(fx/merge cofx (fx/merge cofx
{:db (assoc db :chats/loading? true) {:db (assoc db :chats/loading? true)
::json-rpc/call ::json-rpc/call
[{:method "browsers_getBrowsers" [{:method "settings_getSettings"
:on-success #(re-frame/dispatch [::initialize-browsers %])}
{:method "browsers_getBookmarks"
:on-success #(re-frame/dispatch [::initialize-bookmarks %])}
{:method "permissions_getDappPermissions"
:on-success #(re-frame/dispatch [::initialize-dapp-permissions %])}
{:method "settings_getSettings"
:on-success #(do (re-frame/dispatch [::get-settings-callback %]) :on-success #(do (re-frame/dispatch [::get-settings-callback %])
(redirect-to-root db))}]} (redirect-to-root db))}]}
(notifications/load-notification-preferences) (notifications/load-notification-preferences)
@ -384,7 +397,7 @@
(fx/merge cofx (fx/merge cofx
{:db (-> db {:db (-> db
(dissoc :multiaccounts/login) (dissoc :multiaccounts/login)
(assoc :tos/next-root :onboarding-notification) (assoc :tos/next-root :onboarding-notification :chats/loading? false)
(assoc-in [:multiaccount :multiaccounts/first-account] first-account?)) (assoc-in [:multiaccount :multiaccounts/first-account] first-account?))
:dispatch-later [{:ms 2000 :dispatch [::initialize-wallet :dispatch-later [{:ms 2000 :dispatch [::initialize-wallet
accounts nil nil accounts nil nil
@ -392,8 +405,9 @@
true]}]} true]}]}
(finish-keycard-setup) (finish-keycard-setup)
(transport/start-messenger) (transport/start-messenger)
(chat.loading/initialize-chats)
(communities/fetch) (communities/fetch)
(data-store.chats/fetch-chats-rpc
{:on-success #(re-frame/dispatch [:chats-list/load-success %])})
(initialize-communities-enabled) (initialize-communities-enabled)
(multiaccounts/switch-preview-privacy-mode-flag) (multiaccounts/switch-preview-privacy-mode-flag)
(link-preview/request-link-preview-whitelist) (link-preview/request-link-preview-whitelist)
@ -407,6 +421,22 @@
(defn- keycard-setup? [cofx] (defn- keycard-setup? [cofx]
(boolean (get-in cofx [:db :keycard :flow]))) (boolean (get-in cofx [:db :keycard :flow])))
(defn on-login-update-db [db login-only? now]
(-> db
(dissoc :connectivity/ui-status-properties)
(update :keycard dissoc :from-key-storage-and-migration?)
(update :keycard dissoc
:on-card-read
:card-read-in-progress?
:pin
:multiaccount)
(assoc :tos-accept-next-root
(if login-only?
:chat-stack
:onboarding-notification))
(assoc :logged-in-since now)
(assoc :view-id :home)))
(fx/defn multiaccount-login-success (fx/defn multiaccount-login-success
[{:keys [db now] :as cofx}] [{:keys [db now] :as cofx}]
(let [{:keys [key-uid password save-password? creating?]} (let [{:keys [key-uid password save-password? creating?]}
@ -424,20 +454,7 @@
"login-only?" login-only? "login-only?" login-only?
"recovered-account?" recovered-account?) "recovered-account?" recovered-account?)
(fx/merge cofx (fx/merge cofx
{:db (-> db {:db (on-login-update-db db login-only? now)
(dissoc :connectivity/ui-status-properties)
(update :keycard dissoc :from-key-storage-and-migration?)
(update :keycard dissoc
:on-card-read
:card-read-in-progress?
:pin
:multiaccount)
(assoc :tos-accept-next-root
(if login-only?
:chat-stack
:onboarding-notification))
(assoc :logged-in-since now)
(assoc :view-id :home))
::json-rpc/call ::json-rpc/call
[{:method "web3_clientVersion" [{:method "web3_clientVersion"
:on-success #(re-frame/dispatch [::initialize-web3-client-version %])}]} :on-success #(re-frame/dispatch [::initialize-web3-client-version %])}]}

View File

@ -29,7 +29,6 @@
:membership-updates () :membership-updates ()
:unviewed-messages-count 0 :unviewed-messages-count 0
:last-message-content-type "text/plain" :last-message-content-type "text/plain"
:is-active true
:last-message-content {:chat-id "status" :text "darn typos...! "} :last-message-content {:chat-id "status" :text "darn typos...! "}
:debug? false :debug? false
:group-chat true :group-chat true
@ -48,7 +47,6 @@
:membership-updates () :membership-updates ()
:unviewed-messages-count 0 :unviewed-messages-count 0
:last-message-content-type "text/plain" :last-message-content-type "text/plain"
:is-active true
:last-message-content {:chat-id "0x04173f7cdea0076a7998abb674cc79fe61337c42db77043c01d5b0f3e3ac1e5a45bca0c93bb9f3c3d38b7cc9a7337cd64f9f9b2114fe4bbdfe1ae2633ba14d8c9c" :last-message-content {:chat-id "0x04173f7cdea0076a7998abb674cc79fe61337c42db77043c01d5b0f3e3ac1e5a45bca0c93bb9f3c3d38b7cc9a7337cd64f9f9b2114fe4bbdfe1ae2633ba14d8c9c"
:text "Hey"} :text "Hey"}
:debug? false :debug? false
@ -68,7 +66,6 @@
:membership-updates () :membership-updates ()
:unviewed-messages-count 0 :unviewed-messages-count 0
:last-message-content-type "text/plain" :last-message-content-type "text/plain"
:is-active true
:last-message-content {:chat-id "0x04173f7cdea0076a7998abb674cc79fe61337c42db77043c01d5b0f3e3ac1e5a45bca0c93bb9f3c3d38b7cc9a7337cd64f9f9b2114fe4bbdfe1ae2633ba14d8c9c" :last-message-content {:chat-id "0x04173f7cdea0076a7998abb674cc79fe61337c42db77043c01d5b0f3e3ac1e5a45bca0c93bb9f3c3d38b7cc9a7337cd64f9f9b2114fe4bbdfe1ae2633ba14d8c9c"
:text "Djndjd"} :text "Djndjd"}
:debug? false :debug? false

View File

@ -68,6 +68,7 @@
{:id :tabs-stack {:id :tabs-stack
:options (merge (default-root) :options (merge (default-root)
{:bottomTabs {:titleDisplayMode :alwaysHide {:bottomTabs {:titleDisplayMode :alwaysHide
:tabsAttachMode :onSwitchToTab
:backgroundColor colors/white}}) :backgroundColor colors/white}})
:children [;CHAT STACK :children [;CHAT STACK
{:stack {:id :chat-stack {:stack {:id :chat-stack

View File

@ -82,6 +82,7 @@
(reg-root-key-sub :logged-in-since :logged-in-since) (reg-root-key-sub :logged-in-since :logged-in-since)
(reg-root-key-sub :link-previews-whitelist :link-previews-whitelist) (reg-root-key-sub :link-previews-whitelist :link-previews-whitelist)
(reg-root-key-sub :app-state :app-state) (reg-root-key-sub :app-state :app-state)
(reg-root-key-sub :home-items-show-number :home-items-show-number)
;;NOTE this one is not related to ethereum network ;;NOTE this one is not related to ethereum network
;; it is about cellular network/ wifi network ;; it is about cellular network/ wifi network
@ -120,6 +121,8 @@
(reg-root-key-sub :group-chat/invitations :group-chat/invitations) (reg-root-key-sub :group-chat/invitations :group-chat/invitations)
(reg-root-key-sub :chats/mention-suggestions :chats/mention-suggestions) (reg-root-key-sub :chats/mention-suggestions :chats/mention-suggestions)
(reg-root-key-sub :chat/inputs-with-mentions :chat/inputs-with-mentions) (reg-root-key-sub :chat/inputs-with-mentions :chat/inputs-with-mentions)
(reg-root-key-sub :chats-home-list :chats-home-list)
;;browser ;;browser
(reg-root-key-sub :browsers :browser/browsers) (reg-root-key-sub :browsers :browser/browsers)
(reg-root-key-sub :browser/options :browser/options) (reg-root-key-sub :browser/options :browser/options)
@ -771,17 +774,17 @@
(re-frame/reg-sub (re-frame/reg-sub
:chats/chat :chats/chat
:<- [:chats/active-chats] :<- [::chats]
(fn [chats [_ chat-id]] (fn [chats [_ chat-id]]
(get chats chat-id))) (get chats chat-id)))
(re-frame/reg-sub (re-frame/reg-sub
:chats/by-community-id :chats/by-community-id
:<- [:chats/active-chats] :<- [::chats]
(fn [chats [_ community-id]] (fn [chats [_ community-id]]
(->> chats (->> chats
(keep (fn [[_ chat]] (keep (fn [[_ chat]]
(when (= (:community-id chat) community-id) (when (and (= (:community-id chat) community-id))
chat))) chat)))
(sort-by :timestamp >)))) (sort-by :timestamp >))))
@ -840,15 +843,11 @@
(get ui-props prop))) (get ui-props prop)))
(re-frame/reg-sub (re-frame/reg-sub
:chats/active-chats :chats/home-list-chats
:<- [::chats] :<- [::chats]
(fn [chats] :<- [:chats-home-list]
(reduce-kv (fn [acc id {:keys [is-active profile-public-key timeline?] :as chat}] (fn [[chats active-chats]]
(if (and is-active (not profile-public-key) (not timeline?)) (map #(get chats %) active-chats)))
(assoc acc id chat)
acc))
{}
chats)))
(re-frame/reg-sub (re-frame/reg-sub
:chat-by-id :chat-by-id
@ -1180,9 +1179,9 @@
(re-frame/reg-sub (re-frame/reg-sub
:chats/unread-messages-number :chats/unread-messages-number
:<- [:chats/active-chats] :<- [:chats/home-list-chats]
(fn [chats _] (fn [chats _]
(reduce-kv (fn [{:keys [public other]} _ {:keys [unviewed-messages-count public?] :as chat}] (reduce (fn [{:keys [public other]} {:keys [unviewed-messages-count public?] :as chat}]
(if (or public? (chat.models/community-chat? chat)) (if (or public? (chat.models/community-chat? chat))
{:public (+ public unviewed-messages-count) {:public (+ public unviewed-messages-count)
:other other} :other other}
@ -1497,7 +1496,8 @@
:<- [:search/filtered-chats] :<- [:search/filtered-chats]
:<- [:communities/communities] :<- [:communities/communities]
:<- [:view-id] :<- [:view-id]
(fn [[search-filter filtered-chats communities view-id]] :<- [:home-items-show-number]
(fn [[search-filter filtered-chats communities view-id home-items-show-number]]
(if (= view-id :home) (if (= view-id :home)
(let [communities-count (count communities) (let [communities-count (count communities)
chats-count (count filtered-chats) chats-count (count filtered-chats)
@ -1511,7 +1511,7 @@
assoc :last? true) assoc :last? true)
communities) communities)
res {:search-filter search-filter res {:search-filter search-filter
:items (concat communities-with-separator filtered-chats)}] :items (concat communities-with-separator (take home-items-show-number filtered-chats))}]
(reset! memo-home-items res) (reset! memo-home-items res)
res) res)
;;we want to keep data unchanged so react doesn't change component when we leave screen ;;we want to keep data unchanged so react doesn't change component when we leave screen
@ -1843,17 +1843,18 @@
(re-frame/reg-sub (re-frame/reg-sub
:activity.center/notifications-grouped-by-date :activity.center/notifications-grouped-by-date
:<- [:activity.center/notifications] :<- [:activity.center/notifications]
:<- [::chats] (fn [{:keys [notifications]}]
(fn [[{:keys [notifications]} chats]] (let [supported-notifications
(let [supported-notifications (filter (fn [{:keys [type chat-id last-message]}] (filter (fn [{:keys [type last-message]}]
(and
(or (and (= constants/activity-center-notification-type-one-to-one-chat type) (or (and (= constants/activity-center-notification-type-one-to-one-chat type)
(not (nil? last-message))) (not (nil? last-message)))
(= constants/activity-center-notification-type-private-group-chat type) (= constants/activity-center-notification-type-private-group-chat type)
(= constants/activity-center-notification-type-reply type) (= constants/activity-center-notification-type-reply type)
(= constants/activity-center-notification-type-mention type)) (= constants/activity-center-notification-type-mention type)))
(get chats chat-id))) notifications)] notifications)]
(group-notifications-by-date (map #(assoc % :timestamp (or (:timestamp %) (:timestamp (or (:message %) (:last-message %))))) supported-notifications))))) (group-notifications-by-date
(map #(assoc % :timestamp (or (:timestamp %) (:timestamp (or (:message %) (:last-message %)))))
supported-notifications)))))
;;WALLET TRANSACTIONS ================================================================================================== ;;WALLET TRANSACTIONS ==================================================================================================
@ -2458,7 +2459,7 @@
(re-frame/reg-sub (re-frame/reg-sub
:search/filtered-chats :search/filtered-chats
:<- [:chats/active-chats] :<- [:chats/home-list-chats]
:<- [:contacts/contacts] :<- [:contacts/contacts]
:<- [:search/home-filter] :<- [:search/home-filter]
(fn [[chats contacts search-filter]] (fn [[chats contacts search-filter]]
@ -2468,13 +2469,9 @@
(partial filter-chat (partial filter-chat
contacts contacts
(string/lower-case search-filter)) (string/lower-case search-filter))
(vals chats)) chats)
(vals chats))] chats)]
(sort-by :timestamp > filtered-chats))))
(sort-by :timestamp > (filter (fn [{:keys [community-id]}]
;; Ignore communities
(not community-id))
filtered-chats)))))
(defn extract-currency-attributes [currency] (defn extract-currency-attributes [currency]
(let [{:keys [code display-name]} (val currency)] (let [{:keys [code display-name]} (val currency)]

View File

@ -235,11 +235,9 @@
(defn button [] (defn button []
(if-not @(re-frame/subscribe [::invite.events/enabled]) (if-not @(re-frame/subscribe [::invite.events/enabled])
[rn/view {:style {:align-items :center}}
[rn/view {:style (:tiny spacing/padding-vertical)}
[quo/button {:on-press #(re-frame/dispatch [::invite.events/share-link nil]) [quo/button {:on-press #(re-frame/dispatch [::invite.events/share-link nil])
:accessibility-label :invite-friends-button} :accessibility-label :invite-friends-button}
(i18n/label :t/invite-friends)]]] (i18n/label :t/invite-friends)]
(let [pack @(re-frame/subscribe [::invite.events/default-reward]) (let [pack @(re-frame/subscribe [::invite.events/default-reward])
tokens (transform-tokens pack)] tokens (transform-tokens pack)]
[rn/view {:style {:align-items :center [rn/view {:style {:align-items :center

View File

@ -35,12 +35,12 @@
:error error}]) :error error}])
(defn render-topic [topic] (defn render-topic [topic]
^{:key topic}
[react/touchable-highlight {:on-press #(start-chat topic) [react/touchable-highlight {:on-press #(start-chat topic)
:accessibility-label :chat-item} :accessibility-label :chat-item}
[react/view {:padding-right 8 :padding-vertical 8} [react/view {:border-color colors/gray-lighter :border-radius 36 :border-width 1 :padding-horizontal 8
[react/view {:border-color colors/gray-lighter :border-radius 36 :border-width 1 :padding-horizontal 8 :padding-vertical 5} :padding-vertical 5 :margin-right 8 :margin-vertical 8}
[react/text {:style {:color colors/blue :typography :main-medium}} (str "#" topic)]]]]) [react/text {:style {:color colors/blue :typography :main-medium}}
(str "#" topic)]]])
(def lang-names {"es" "status-espanol" (def lang-names {"es" "status-espanol"
"pt" "statusbrasil" "pt" "statusbrasil"

View File

@ -36,6 +36,7 @@
(def no-chats-text (def no-chats-text
{:margin-top 50 {:margin-top 50
:margin-bottom 8
:margin-horizontal 16 :margin-horizontal 16
:line-height 22 :line-height 22
:text-align :center}) :text-align :center})

View File

@ -29,42 +29,40 @@
(defn home-tooltip-view [] (defn home-tooltip-view []
[react/view (styles/chat-tooltip) [react/view (styles/chat-tooltip)
[react/view {:style {:flex-direction :row}}
[react/view {:flex 1}
[react/view {:style styles/empty-chats-header-container}
[react/view {:style {:width 66 :position :absolute :top -6 :background-color colors/white [react/view {:style {:width 66 :position :absolute :top -6 :background-color colors/white
:align-items :center}} :align-items :center}}
[react/image {:source (resources/get-image :empty-chats-header) [react/image {:source (resources/get-image :empty-chats-header)
:style {:width 50 :height 50}}]]] :style {:width 50 :height 50}}]]
[react/touchable-highlight [react/touchable-highlight
{:style {:position :absolute :right 0 :top 0 {:style {:position :absolute :right 0 :top 0
:width 44 :height 44 :align-items :center :justify-content :center} :width 44 :height 44 :align-items :center :justify-content :center}
:on-press #(re-frame/dispatch [:multiaccounts.ui/hide-home-tooltip]) :on-press #(re-frame/dispatch [:multiaccounts.ui/hide-home-tooltip])
:accessibility-label :hide-home-button} :accessibility-label :hide-home-button}
[icons/icon :main-icons/close-circle {:color colors/gray}]]]] [icons/icon :main-icons/close-circle {:color colors/gray}]]
[react/view [react/i18n-text {:style styles/no-chats-text :key :chat-and-transact}]
[react/i18n-text {:style styles/no-chats-text :key :chat-and-transact}]]
[invite/button] [invite/button]
[react/view {:align-items :center} [react/view {:align-items :center :margin-bottom 16}
[react/view {:style (styles/hr-wrapper)}] [react/view {:style (styles/hr-wrapper)}]
[react/i18n-text {:style (styles/or-text) :key :or}]] [react/i18n-text {:style (styles/or-text) :key :or}]]
[react/view {:margin-top 16}
[react/i18n-text {:style {:margin-horizontal 16 [react/i18n-text {:style {:margin-horizontal 16
:text-align :center} :text-align :center}
:key :follow-your-interests}] :key :follow-your-interests}]
[react/view {:style styles/tags-wrapper} [react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center
[react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center} :margin-top 10
:margin-bottom 18}
(for [chat (new-public-chat/featured-public-chats)] (for [chat (new-public-chat/featured-public-chats)]
(new-public-chat/render-topic chat))]] ^{:key chat}
[new-public-chat/render-topic chat])]
(when @(re-frame/subscribe [:communities/enabled?]) (when @(re-frame/subscribe [:communities/enabled?])
[react/view [:<>
[react/i18n-text {:style {:margin-horizontal 16 [react/i18n-text {:style {:margin-horizontal 16
:text-align :center} :text-align :center}
:key :join-a-community}] :key :join-a-community}]
[react/view {:style styles/tags-wrapper} [react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center
[react/view {:flex-direction :row :flex-wrap :wrap :justify-content :center} :margin-top 10
:margin-bottom 18}
(for [community communities/featured] (for [community communities/featured]
(communities.views/render-featured-community community))]]])]]) [communities.views/render-featured-community community])]])])
(defn welcome-blank-page [] (defn welcome-blank-page []
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}} [react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}}
@ -150,7 +148,7 @@
[list/flat-list [list/flat-list
{:key-fn chat-list-key-fn {:key-fn chat-list-key-fn
:getItemLayout get-item-layout :getItemLayout get-item-layout
:initialNumToRender 5 :on-end-reached #(re-frame/dispatch [:chat.ui/show-more-chats])
:keyboard-should-persist-taps :always :keyboard-should-persist-taps :always
:data items :data items
:render-fn render-fn :render-fn render-fn

View File

@ -10,105 +10,37 @@
[status-im.ui.components.react :as react] [status-im.ui.components.react :as react]
[status-im.ui.screens.home.styles :as styles] [status-im.ui.screens.home.styles :as styles]
[status-im.ui.components.icons.icons :as icons] [status-im.ui.components.icons.icons :as icons]
[status-im.utils.contenthash :as contenthash]
[status-im.utils.core :as utils] [status-im.utils.core :as utils]
[status-im.utils.datetime :as time] [status-im.utils.datetime :as time]
[status-im.ui.components.chat-icon.styles :as chat-icon.styles])) [status-im.ui.components.chat-icon.styles :as chat-icon.styles]))
(defn mention-element [from] (defn preview-label [label-key]
@(re-frame/subscribe [:contacts/contact-name-by-identity from])) [react/text {:style styles/last-message-text
:accessibility-label :no-messages-text}
(i18n/label label-key)])
;; if truncated subheader text is too short we won't get ellipsize at the end of text (defn message-content-text [{:keys [content content-type]} absolute]
(def max-subheader-length 100) [react/view (when absolute {:position :absolute :left 72 :top 32 :right 80})
(cond
(not (and content content-type))
[preview-label :t/no-messages]
(defn truncate-literal [literal] (and (= constants/content-type-text content-type)
(let [size (min max-subheader-length (.-length literal))] (not (string/blank? (:text content))))
{:components (.substring literal 0 size)
:length size}))
(defn add-parsed-to-subheader [acc {:keys [type destination literal children]}]
(let [result (case type
"paragraph"
(reduce
(fn [{:keys [_ length] :as acc-paragraph} parsed-child]
(if (>= length max-subheader-length)
(reduced acc-paragraph)
(add-parsed-to-subheader acc-paragraph parsed-child)))
{:components [react/text-class]
:length 0}
children)
"mention"
{:components [react/text-class [mention-element literal]]
:length 4} ;; we can't predict name length so take the smallest possible
"status-tag"
(truncate-literal (str "#" literal))
"link"
(truncate-literal destination)
(truncate-literal literal))]
{:components (conj (:components acc) (:components result))
:length (+ (:length acc) (:length result))}))
(def subheader-wrapper
[react/text-class {:style styles/last-message-text [react/text-class {:style styles/last-message-text
:number-of-lines 1 :number-of-lines 1
:ellipsize-mode :tail :ellipsize-mode :tail
:accessibility-label :chat-message-text}]) :accessibility-label :chat-message-text}
(:text content)]
(defn render-subheader
"Render the preview of a last message to a maximum of max-subheader-length characters"
[parsed-text]
(let [result
(reduce
(fn [{:keys [_ length] :as acc-text} new-text-chunk]
(if (>= length max-subheader-length)
(reduced acc-text)
(add-parsed-to-subheader acc-text new-text-chunk)))
{:components subheader-wrapper
:length 0}
parsed-text)]
(:components result)))
(defn message-content-text [{:keys [content content-type community-id]}]
[react/view {:position :absolute :left 72 :top 32 :right 80}
(cond
(not (and content content-type))
[react/text {:style styles/last-message-text
:accessibility-label :no-messages-text}
(i18n/label :t/no-messages)]
(= constants/content-type-sticker content-type) (= constants/content-type-sticker content-type)
[react/image {:style {:margin 1 :width 20 :height 20} [preview-label :t/sticker]
;;TODO (perf) move to event
:source {:uri (contenthash/url (-> content :sticker :hash))}}]
(= constants/content-type-image content-type) (= constants/content-type-image content-type)
[react/text {:style styles/last-message-text [preview-label :t/image]
:accessibility-label :no-messages-text}
(i18n/label :t/image)]
(= constants/content-type-audio content-type) (= constants/content-type-audio content-type)
[react/text {:style styles/last-message-text [preview-label :t/audio])])
:accessibility-label :no-messages-text}
(i18n/label :t/audio)]
(= constants/content-type-community content-type)
(let [{:keys [name]}
@(re-frame/subscribe [:communities/community community-id])]
[react/text {:style styles/last-message-text
:accessibility-label :no-messages-text}
(i18n/label :t/community-message-preview {:community-name name})])
(string/blank? (:text content))
[react/text {:style styles/last-message-text}
""]
(:text content)
(render-subheader (:parsed-text content)))])
(def memo-timestamp (def memo-timestamp
(memoize (memoize
@ -186,5 +118,5 @@
(memo-timestamp (if (pos? (:whisper-timestamp last-message)) (memo-timestamp (if (pos? (:whisper-timestamp last-message))
(:whisper-timestamp last-message) (:whisper-timestamp last-message)
timestamp))] timestamp))]
[message-content-text (select-keys last-message [:content :content-type :community-id])] [message-content-text (select-keys last-message [:content :content-type]) true]
[unviewed-indicator home-item]]])) [unviewed-indicator home-item]]]))

View File

@ -78,7 +78,8 @@
(reagent/create-class (reagent/create-class
{:display-name "activity-center" {:display-name "activity-center"
:component-did-mount #(re-frame/dispatch [:get-activity-center-notifications]) :component-did-mount #(re-frame/dispatch [:get-activity-center-notifications])
:reagent-render (fn [] :reagent-render
(fn []
(let [notifications @(re-frame/subscribe [:activity.center/notifications-grouped-by-date])] (let [notifications @(re-frame/subscribe [:activity.center/notifications-grouped-by-date])]
[react/keyboard-avoiding-view {:style {:flex 1} [react/keyboard-avoiding-view {:style {:flex 1}
:ignore-offset true} :ignore-offset true}

View File

@ -2,118 +2,17 @@
(:require [status-im.ui.components.react :as react] (:require [status-im.ui.components.react :as react]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[quo.core :as quo] [quo.core :as quo]
[clojure.string :as string]
[status-im.i18n.i18n :as i18n]
[status-im.ui.screens.notifications-center.styles :as styles] [status-im.ui.screens.notifications-center.styles :as styles]
[status-im.utils.handlers :refer [<sub]] [status-im.utils.handlers :refer [<sub]]
[status-im.ui.screens.chat.photos :as photos] [status-im.ui.screens.chat.photos :as photos]
[status-im.multiaccounts.core :as multiaccounts] [status-im.multiaccounts.core :as multiaccounts]
[status-im.ui.components.icons.icons :as icons] [status-im.ui.components.icons.icons :as icons]
[status-im.utils.contenthash :as contenthash]
[status-im.constants :as constants] [status-im.constants :as constants]
[quo.design-system.colors :as colors] [quo.design-system.colors :as colors]
[status-im.ui.screens.home.views.inner-item :as home-item] [status-im.ui.screens.home.views.inner-item :as home-item]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen] [status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.chat-icon.styles :as chat-icon.styles])) [status-im.ui.components.chat-icon.styles :as chat-icon.styles]))
(defn mention-element [from]
(let [contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity from])]
(str (when-not (= (subs contact-name 0 1) "@") "@") contact-name)))
(def max-notification-length 160)
(def max-notification-lines 2)
(def max-reply-lines 1)
(defn add-parsed-to-message [acc style text-weight {:keys [type destination literal children]}]
(let [result (case type
"paragraph"
(reduce
(fn [{:keys [_ length] :as acc-paragraph} parsed-child]
(if (>= length max-notification-length)
(reduced acc-paragraph)
(add-parsed-to-message acc-paragraph style text-weight parsed-child)))
{:components [quo/text {:style style
:weight text-weight}]
:length 0}
children)
"mention"
{:components [quo/text {:style (merge style styles/mention-text)} [mention-element literal]]
:length 4} ;; we can't predict name length so take the smallest possible
"status-tag"
(home-item/truncate-literal (str "#" literal))
"link"
(home-item/truncate-literal destination)
(home-item/truncate-literal (string/replace literal #"\n" " ")))]
{:components (conj (:components acc) (:components result))
:length (+ (:length acc) (:length result))}))
(defn message-wrapper
([] (message-wrapper 1 styles/notification-reply-text))
([number-of-lines style]
[react/text-class {:style style
:number-of-lines number-of-lines
:ellipsize-mode :tail
:accessibility-label :chat-message-text}]))
(defn render-message
"Render the preview of a message with a maximum length, maximum lines, style and font weight"
([parsed-text] (render-message parsed-text max-notification-length max-notification-lines styles/notification-message-text :regular))
([parsed-text max-length number-of-lines style text-weight]
(let [result
(reduce
(fn [{:keys [_ length] :as acc-text} new-text-chunk]
(if (>= length max-length)
(reduced acc-text)
(add-parsed-to-message acc-text style text-weight new-text-chunk)))
{:components (message-wrapper number-of-lines style)
:length 0}
parsed-text)]
(:components result))))
(defn message-content-text [{:keys [content content-type community-id]} max-number-of-lines style text-weight]
[react/view
(cond
(not (and content content-type))
[react/text {:style (merge
style
{:color colors/gray})
:accessibility-label :no-messages-text}
(i18n/label :t/no-messages)]
(= constants/content-type-sticker content-type)
[react/image {:style {:margin 1 :width 20 :height 20}
;;TODO (perf) move to event
:source {:uri (contenthash/url (-> content :sticker :hash))}}]
(= constants/content-type-image content-type)
[react/text {:style style
:accessibility-label :no-messages-text}
(i18n/label :t/image)]
(= constants/content-type-audio content-type)
[react/text {:style style
:accessibility-label :no-messages-text}
(i18n/label :t/audio)]
(= constants/content-type-community content-type)
(let [{:keys [name]}
@(re-frame/subscribe [:communities/community community-id])]
[react/text {:style style
:accessibility-label :no-messages-text}
(i18n/label :t/community-message-preview {:community-name name})])
(string/blank? (:text content))
[react/text {:style style}
""]
(:text content)
(render-message (:parsed-text content) max-notification-length max-number-of-lines style text-weight))])
(defn activity-text-item [home-item opts] (defn activity-text-item [home-item opts]
(let [{:keys [chat-id chat-name message last-message reply-message muted read group-chat timestamp type color]} home-item (let [{:keys [chat-id chat-name message last-message reply-message muted read group-chat timestamp type color]} home-item
message (or message last-message) message (or message last-message)
@ -155,7 +54,7 @@
;;TODO (perf) move to event ;;TODO (perf) move to event
(home-item/memo-timestamp timestamp)] (home-item/memo-timestamp timestamp)]
[react/view {:style styles/notification-message-container} [react/view {:style styles/notification-message-container}
[message-content-text (select-keys message [:content :content-type :community-id]) max-notification-lines styles/notification-message-text] [home-item/message-content-text (select-keys message [:content :content-type]) false]
(cond (= type constants/activity-center-notification-type-mention) (cond (= type constants/activity-center-notification-type-mention)
[react/view {:style styles/group-info-container [react/view {:style styles/group-info-container
:accessibility-label :chat-name-container} :accessibility-label :chat-name-container}
@ -190,4 +89,4 @@
:width 18 :width 18
:height 18 :height 18
:container-style styles/reply-icon}] :container-style styles/reply-icon}]
[message-content-text (select-keys reply-message [:content :content-type :community-id]) max-reply-lines styles/notification-reply-text :medium]])]]])) [home-item/message-content-text (select-keys reply-message [:content :content-type]) false]])]]]))

View File

@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>", "_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im", "owner": "status-im",
"repo": "status-go", "repo": "status-go",
"version": "v0.87.0", "version": "v0.87.1",
"commit-sha1": "fb218761d9d1620916ae7e8b19b9b4a03f92c767", "commit-sha1": "59eeed94368c1f0ee9d603e313a13f178e644514",
"src-sha256": "073qgjfn2cn1li6g4r38xizkifsl4xd1sm51784jmy7kq6gqs1gr" "src-sha256": "1pnyb4vw88nx5b8np0ajhfyjblfkxr8bl40vhilz5gpz1g1a9l3c"
} }

View File

@ -1157,6 +1157,7 @@
"status-not-sent-click": "Not confirmed. Click for options", "status-not-sent-click": "Not confirmed. Click for options",
"step-i-of-n": "Step {{step}} of {{number}}", "step-i-of-n": "Step {{step}} of {{number}}",
"sticker-market": "Sticker market", "sticker-market": "Sticker market",
"sticker": "Sticker",
"submit": "Submit", "submit": "Submit",
"submit-bug": "Submit a bug", "submit-bug": "Submit a bug",
"success": "Success", "success": "Success",