[Fixes: #12061] Add unread mentions count
Fixes: #2061 This commit adds an unread mentions count in 3 places: 1) Public chats 2) Communities in home 3) Communities chats The logic is that if you have unread mentions, it will show you the count of messages with unread mentions, while if you have only unread messages, you will see a blue dot. Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
8926a7ad4e
commit
ef13b4d210
|
@ -143,6 +143,7 @@
|
||||||
(update-in [:chats chat-id] merge
|
(update-in [:chats chat-id] merge
|
||||||
{:last-message nil
|
{:last-message nil
|
||||||
:unviewed-messages-count 0
|
:unviewed-messages-count 0
|
||||||
|
:unviewed-mentions-count 0
|
||||||
:deleted-at-clock-value last-message-clock-value}))}))
|
:deleted-at-clock-value last-message-clock-value}))}))
|
||||||
|
|
||||||
(fx/defn clear-history-handler
|
(fx/defn clear-history-handler
|
||||||
|
|
|
@ -47,7 +47,9 @@
|
||||||
(fx/defn handle-mark-all-read-successful
|
(fx/defn handle-mark-all-read-successful
|
||||||
{:events [::mark-all-read-successful]}
|
{:events [::mark-all-read-successful]}
|
||||||
[{:keys [db]} chat-id]
|
[{:keys [db]} chat-id]
|
||||||
{:db (assoc-in db [:chats chat-id :unviewed-messages-count] 0)})
|
{:db (update-in db [:chats chat-id] assoc
|
||||||
|
:unviewed-messages-count 0
|
||||||
|
:unviewed-mentions-count 0)})
|
||||||
|
|
||||||
(fx/defn handle-mark-all-read
|
(fx/defn handle-mark-all-read
|
||||||
{:events [:chat.ui/mark-all-read-pressed :chat/mark-all-as-read]}
|
{:events [:chat.ui/mark-all-read-pressed :chat/mark-all-as-read]}
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
[{:keys [db]} {:keys [chat-id _]}]
|
[{:keys [db]} {:keys [chat-id _]}]
|
||||||
(let [{:keys [loaded-unviewed-messages-ids unviewed-messages-count]}
|
(let [{:keys [loaded-unviewed-messages-ids unviewed-messages-count]}
|
||||||
(get-in db [:chats chat-id])]
|
(get-in db [:chats chat-id])]
|
||||||
|
;; We currently only use this for private group chats and one-to-ones
|
||||||
|
;; but this method would have to be changed if we showed unviewed-mentions-count
|
||||||
|
;; in one to ones and private group chats as well
|
||||||
{:db (update-in db [:chats chat-id] assoc
|
{:db (update-in db [:chats chat-id] assoc
|
||||||
:unviewed-messages-count (subtract-seen-messages
|
:unviewed-messages-count (subtract-seen-messages
|
||||||
unviewed-messages-count
|
unviewed-messages-count
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
public-key
|
public-key
|
||||||
{:keys [chat-id
|
{:keys [chat-id
|
||||||
unviewed-messages-count
|
unviewed-messages-count
|
||||||
|
unviewed-mentions-count
|
||||||
last-message]}]
|
last-message]}]
|
||||||
(let [removed-messages-ids (keep
|
(let [removed-messages-ids (keep
|
||||||
(fn [[message-id {:keys [from]}]]
|
(fn [[message-id {:keys [from]}]]
|
||||||
|
@ -25,6 +26,7 @@
|
||||||
(update-in [:chats chat-id]
|
(update-in [:chats chat-id]
|
||||||
assoc
|
assoc
|
||||||
:unviewed-messages-count unviewed-messages-count
|
:unviewed-messages-count unviewed-messages-count
|
||||||
|
:unviewed-mentions-count unviewed-mentions-count
|
||||||
:last-message last-message))]
|
:last-message last-message))]
|
||||||
{:db (assoc-in db [:message-lists chat-id]
|
{:db (assoc-in db [:message-lists chat-id]
|
||||||
(message-list/add-many nil (vals (get-in db [:messages chat-id]))))}))
|
(message-list/add-many nil (vals (get-in db [:messages chat-id]))))}))
|
||||||
|
|
|
@ -6,16 +6,6 @@
|
||||||
[status-im.utils.fx :as fx]
|
[status-im.utils.fx :as fx]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
(defn type->rpc [{:keys [chat-type public? group-chat profile-public-key timeline?] :as chat}]
|
|
||||||
(if chat-type
|
|
||||||
(assoc chat :chatType chat-type)
|
|
||||||
(assoc chat :chatType (cond
|
|
||||||
profile-public-key constants/profile-chat-type
|
|
||||||
timeline? constants/timeline-chat-type
|
|
||||||
public? constants/public-chat-type
|
|
||||||
group-chat constants/private-group-chat-type
|
|
||||||
:else constants/one-to-one-chat-type))))
|
|
||||||
|
|
||||||
(defn rpc->type [{:keys [chatType name] :as chat}]
|
(defn rpc->type [{:keys [chatType name] :as chat}]
|
||||||
(cond
|
(cond
|
||||||
(or (= constants/public-chat-type chatType)
|
(or (= constants/public-chat-type chatType)
|
||||||
|
@ -34,15 +24,6 @@
|
||||||
:group-chat true)
|
:group-chat true)
|
||||||
:else (assoc chat :public? false :group-chat false)))
|
:else (assoc chat :public? false :group-chat false)))
|
||||||
|
|
||||||
(defn- marshal-members [{:keys [admins contacts members-joined chat-type] :as chat}]
|
|
||||||
(cond-> chat
|
|
||||||
(= chat-type constants/private-group-chat-type)
|
|
||||||
(assoc :members (map #(hash-map :id %
|
|
||||||
:admin (boolean (admins %))
|
|
||||||
:joined (boolean (members-joined %))) contacts))
|
|
||||||
:always
|
|
||||||
(dissoc :admins :contacts :members-joined)))
|
|
||||||
|
|
||||||
(defn- unmarshal-members [{:keys [members chatType] :as chat}]
|
(defn- unmarshal-members [{:keys [members chatType] :as chat}]
|
||||||
(cond
|
(cond
|
||||||
(= constants/public-chat-type chatType) (assoc chat
|
(= constants/public-chat-type chatType) (assoc chat
|
||||||
|
@ -68,26 +49,6 @@
|
||||||
:admins #{}
|
:admins #{}
|
||||||
:members-joined #{})))
|
:members-joined #{})))
|
||||||
|
|
||||||
(defn- ->rpc [chat]
|
|
||||||
(-> chat
|
|
||||||
marshal-members
|
|
||||||
(update :last-message messages/->rpc)
|
|
||||||
type->rpc
|
|
||||||
(clojure.set/rename-keys {:chat-id :id
|
|
||||||
:membership-update-events :membershipUpdateEvents
|
|
||||||
:synced-from :syncedFrom
|
|
||||||
:synced-to :syncedTo
|
|
||||||
:unviewed-messages-count :unviewedMessagesCount
|
|
||||||
:last-message :lastMessage
|
|
||||||
:community-id :communityId
|
|
||||||
:deleted-at-clock-value :deletedAtClockValue
|
|
||||||
:is-active :active
|
|
||||||
:last-clock-value :lastClockValue
|
|
||||||
:profile-public-key :profile})
|
|
||||||
(dissoc :public? :group-chat :messages
|
|
||||||
:chat-type
|
|
||||||
:contacts :admins :members-joined)))
|
|
||||||
|
|
||||||
(defn <-rpc [chat]
|
(defn <-rpc [chat]
|
||||||
(-> chat
|
(-> chat
|
||||||
rpc->type
|
rpc->type
|
||||||
|
@ -100,6 +61,7 @@
|
||||||
:deletedAtClockValue :deleted-at-clock-value
|
:deletedAtClockValue :deleted-at-clock-value
|
||||||
:chatType :chat-type
|
:chatType :chat-type
|
||||||
:unviewedMessagesCount :unviewed-messages-count
|
:unviewedMessagesCount :unviewed-messages-count
|
||||||
|
:unviewedMentionsCount :unviewed-mentions-count
|
||||||
:lastMessage :last-message
|
:lastMessage :last-message
|
||||||
:active :is-active
|
:active :is-active
|
||||||
:lastClockValue :last-clock-value
|
:lastClockValue :last-clock-value
|
||||||
|
|
|
@ -2,47 +2,6 @@
|
||||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||||
[status-im.data-store.chats :as chats]))
|
[status-im.data-store.chats :as chats]))
|
||||||
|
|
||||||
(deftest ->to-rpc
|
|
||||||
(let [chat {:public? false
|
|
||||||
:group-chat true
|
|
||||||
:color "color"
|
|
||||||
:contacts #{"a" "b" "c" "d"}
|
|
||||||
:last-clock-value 10
|
|
||||||
:chat-type 3
|
|
||||||
:admins #{"a" "b"}
|
|
||||||
:members-joined #{"a" "c"}
|
|
||||||
:name "name"
|
|
||||||
:membership-update-events :events
|
|
||||||
:unviewed-messages-count 2
|
|
||||||
:is-active true
|
|
||||||
:chat-id "chat-id"
|
|
||||||
:timestamp 2}
|
|
||||||
expected-chat {:id "chat-id"
|
|
||||||
:color "color"
|
|
||||||
:name "name"
|
|
||||||
:chatType 3
|
|
||||||
:lastMessage nil
|
|
||||||
:members #{{:id "a"
|
|
||||||
:admin true
|
|
||||||
:joined true}
|
|
||||||
{:id "b"
|
|
||||||
:admin true
|
|
||||||
:joined false}
|
|
||||||
{:id "c"
|
|
||||||
:admin false
|
|
||||||
:joined true}
|
|
||||||
{:id "d"
|
|
||||||
:admin false
|
|
||||||
:joined false}}
|
|
||||||
:lastClockValue 10
|
|
||||||
:membershipUpdateEvents :events
|
|
||||||
:unviewedMessagesCount 2
|
|
||||||
:active true
|
|
||||||
:timestamp 2}]
|
|
||||||
(testing "marshaling chat"
|
|
||||||
(is (= expected-chat (-> (#'status-im.data-store.chats/->rpc chat)
|
|
||||||
(update :members #(into #{} %))))))))
|
|
||||||
|
|
||||||
(deftest normalize-chat-test
|
(deftest normalize-chat-test
|
||||||
(let [chat {:id "chat-id"
|
(let [chat {:id "chat-id"
|
||||||
:color "color"
|
:color "color"
|
||||||
|
|
|
@ -285,6 +285,18 @@
|
||||||
0
|
0
|
||||||
chats)))
|
chats)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:communities/unviewed-counts
|
||||||
|
(fn [[_ community-id]]
|
||||||
|
[(re-frame/subscribe [:chats/by-community-id community-id])])
|
||||||
|
(fn [[chats]]
|
||||||
|
(reduce (fn [acc {:keys [unviewed-mentions-count unviewed-messages-count]}]
|
||||||
|
{:unviewed-messages-count (+ (:unviewed-messages-count acc) (or unviewed-messages-count 0))
|
||||||
|
:unviewed-mentions-count (+ (:unviewed-mentions-count acc) (or unviewed-mentions-count 0))})
|
||||||
|
{:unviewed-messages-count 0
|
||||||
|
:unviewed-mentions-count 0}
|
||||||
|
chats)))
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:communities/requests-to-join-for-community
|
:communities/requests-to-join-for-community
|
||||||
:<- [:communities/requests-to-join]
|
:<- [:communities/requests-to-join]
|
||||||
|
|
|
@ -49,8 +49,10 @@
|
||||||
(process-next response-js sync-handler)
|
(process-next response-js sync-handler)
|
||||||
(models.chat/ensure-chats (map #(-> %
|
(models.chat/ensure-chats (map #(-> %
|
||||||
(data-store.chats/<-rpc)
|
(data-store.chats/<-rpc)
|
||||||
;;TODO why here?
|
;; We dissoc this fields as they are handled by status-react and
|
||||||
(dissoc :unviewed-messages-count))
|
;; not status-go, as there might be requests in-flight that change
|
||||||
|
;; this value
|
||||||
|
(dissoc :unviewed-messages-count :unviewed-mentions-count))
|
||||||
(types/js->clj chats)))))
|
(types/js->clj chats)))))
|
||||||
|
|
||||||
(seq messages)
|
(seq messages)
|
||||||
|
@ -118,9 +120,15 @@
|
||||||
(let [chat-id (.-localChatId message-js)
|
(let [chat-id (.-localChatId message-js)
|
||||||
message-type (.-messageType message-js)
|
message-type (.-messageType message-js)
|
||||||
from (.-from message-js)
|
from (.-from message-js)
|
||||||
|
mentioned (.-mentioned message-js)
|
||||||
|
profile (models.chat/profile-chat? {:db db} chat-id)
|
||||||
new (.-new message-js)
|
new (.-new message-js)
|
||||||
current (= current-chat-id chat-id)
|
current (= current-chat-id chat-id)
|
||||||
profile (models.chat/profile-chat? {:db db} chat-id)
|
should-update-unviewed? (and (not current)
|
||||||
|
new
|
||||||
|
(not profile)
|
||||||
|
(not (= message-type constants/message-type-private-group-system-message))
|
||||||
|
(not (= from (multiaccounts.model/current-public-key {:db db}))))
|
||||||
tx-hash (and (.-commandParameters message-js) (.-commandParameters.transactionHash message-js))]
|
tx-hash (and (.-commandParameters message-js) (.-commandParameters.transactionHash message-js))]
|
||||||
(cond-> acc
|
(cond-> acc
|
||||||
current
|
current
|
||||||
|
@ -130,13 +138,13 @@
|
||||||
(update :statuses conj message-js)
|
(update :statuses conj message-js)
|
||||||
|
|
||||||
;;update counter
|
;;update counter
|
||||||
(and (not current)
|
should-update-unviewed?
|
||||||
new
|
|
||||||
(not profile)
|
|
||||||
(not (= message-type constants/message-type-private-group-system-message))
|
|
||||||
(not (= from (multiaccounts.model/current-public-key {:db db}))))
|
|
||||||
(update-in [:db :chats chat-id :unviewed-messages-count] inc)
|
(update-in [:db :chats chat-id :unviewed-messages-count] inc)
|
||||||
|
|
||||||
|
(and should-update-unviewed?
|
||||||
|
mentioned)
|
||||||
|
(update-in [:db :chats chat-id :unviewed-mentions-count] inc)
|
||||||
|
|
||||||
;;conj incoming transaction for :watch-tx
|
;;conj incoming transaction for :watch-tx
|
||||||
(not (string/blank? tx-hash))
|
(not (string/blank? tx-hash))
|
||||||
(update :transactions conj tx-hash)
|
(update :transactions conj tx-hash)
|
||||||
|
|
|
@ -124,7 +124,9 @@
|
||||||
|
|
||||||
(defn community-chat-item [{:keys [chat-id] :as home-item}]
|
(defn community-chat-item [{:keys [chat-id] :as home-item}]
|
||||||
[inner-item/home-list-item
|
[inner-item/home-list-item
|
||||||
home-item
|
;; We want communities to behave as public chats when it comes to
|
||||||
|
;; unread indicator
|
||||||
|
(assoc home-item :public? true)
|
||||||
{:on-press (fn []
|
{:on-press (fn []
|
||||||
(re-frame/dispatch [:dismiss-keyboard])
|
(re-frame/dispatch [:dismiss-keyboard])
|
||||||
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])
|
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
[status-im.ui.components.topbar :as topbar]
|
[status-im.ui.components.topbar :as topbar]
|
||||||
[status-im.ui.components.colors :as colors]
|
[status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.components.toolbar :as toolbar]
|
[status-im.ui.components.toolbar :as toolbar]
|
||||||
|
[status-im.ui.components.badge :as badge]
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.screens.communities.icon :as communities.icon]
|
[status-im.ui.screens.communities.icon :as communities.icon]
|
||||||
[quo.design-system.colors :as quo.colors]))
|
[quo.design-system.colors :as quo.colors]))
|
||||||
|
@ -20,14 +21,19 @@
|
||||||
(>evt event))
|
(>evt event))
|
||||||
|
|
||||||
(defn community-unviewed-count [id]
|
(defn community-unviewed-count [id]
|
||||||
(when-not (zero? (<sub [:communities/unviewed-count id]))
|
(let [{:keys [unviewed-messages-count unviewed-mentions-count]} (<sub [:communities/unviewed-counts id])]
|
||||||
[react/view {:style {:background-color colors/blue
|
(cond
|
||||||
:border-radius 6
|
(pos? unviewed-mentions-count)
|
||||||
:margin-right 5
|
[badge/message-counter unviewed-mentions-count]
|
||||||
:margin-top 2
|
|
||||||
:width 12
|
(pos? unviewed-messages-count)
|
||||||
:height 12}
|
[react/view {:style {:background-color colors/blue
|
||||||
:accessibility-label :unviewed-messages-public}]))
|
:border-radius 6
|
||||||
|
:margin-right 5
|
||||||
|
:margin-top 2
|
||||||
|
:width 12
|
||||||
|
:height 12}
|
||||||
|
:accessibility-label :unviewed-messages-public}])))
|
||||||
|
|
||||||
(defn community-home-list-item [{:keys [id name last?] :as community}]
|
(defn community-home-list-item [{:keys [id name last?] :as community}]
|
||||||
[react/touchable-opacity {:style (merge {:height 64}
|
[react/touchable-opacity {:style (merge {:height 64}
|
||||||
|
@ -56,6 +62,7 @@
|
||||||
name]]
|
name]]
|
||||||
[react/view {:flex-direction :row
|
[react/view {:flex-direction :row
|
||||||
:flex 1
|
:flex 1
|
||||||
|
:margin-right 15
|
||||||
:justify-content :flex-end
|
:justify-content :flex-end
|
||||||
:align-items :center}
|
:align-items :center}
|
||||||
[community-unviewed-count id]]]]])
|
[community-unviewed-count id]]]]])
|
||||||
|
|
|
@ -115,12 +115,20 @@
|
||||||
(fn [timestamp]
|
(fn [timestamp]
|
||||||
(string/upper-case (time/to-short-str timestamp)))))
|
(string/upper-case (time/to-short-str timestamp)))))
|
||||||
|
|
||||||
(defn unviewed-indicator [{:keys [unviewed-messages-count public?]}]
|
(defn unviewed-indicator [{:keys [unviewed-mentions-count
|
||||||
|
unviewed-messages-count
|
||||||
|
public?]}]
|
||||||
(when (pos? unviewed-messages-count)
|
(when (pos? unviewed-messages-count)
|
||||||
[react/view {:position :absolute :right 16 :bottom 12}
|
[react/view {:position :absolute :right 16 :bottom 12}
|
||||||
(if public?
|
(cond
|
||||||
|
(and public? (not (pos? unviewed-mentions-count)))
|
||||||
[react/view {:style styles/public-unread
|
[react/view {:style styles/public-unread
|
||||||
:accessibility-label :unviewed-messages-public}]
|
:accessibility-label :unviewed-messages-public}]
|
||||||
|
|
||||||
|
(and public? (pos? unviewed-mentions-count))
|
||||||
|
[badge/message-counter unviewed-mentions-count]
|
||||||
|
|
||||||
|
:else
|
||||||
[badge/message-counter unviewed-messages-count])]))
|
[badge/message-counter unviewed-messages-count])]))
|
||||||
|
|
||||||
(defn icon-style []
|
(defn icon-style []
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
||||||
"owner": "status-im",
|
"owner": "status-im",
|
||||||
"repo": "status-go",
|
"repo": "status-go",
|
||||||
"version": "v0.79.5",
|
"version": "v0.79.6",
|
||||||
"commit-sha1": "dfd46680879954fed29f18863354139d3d2ff34b",
|
"commit-sha1": "c74c9eedfd16ba06d6076b79f87e4401b19ab621",
|
||||||
"src-sha256": "0v5v32zvazcr1fnv8j08pknwz7567i6brhyr51x42al1an9jdkqj"
|
"src-sha256": "1g0z0inr8qp2964xkas4365d8v9shh9c8mwrbhhrkdd1yl6ggy4b"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue