Mark notifications as read based on call to action (#14439)
This commit is contained in:
parent
3d71fdba98
commit
42de2a6384
|
@ -6,6 +6,14 @@
|
|||
[status-im.utils.fx :as fx]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def defaults
|
||||
{:filter-status :unread
|
||||
:filter-type types/no-type
|
||||
;; Choose the maximum number of notifications that *usually/safely* fit on
|
||||
;; most screens, so that the UI doesn't have to needlessly render
|
||||
;; notifications.
|
||||
:notifications-per-page 8})
|
||||
|
||||
;;;; Navigation
|
||||
|
||||
(fx/defn open-activity-center
|
||||
|
@ -75,6 +83,35 @@
|
|||
(map data-store.activities/<-rpc)
|
||||
(notifications-reconcile cofx)))
|
||||
|
||||
;;;; Mark notifications as read
|
||||
|
||||
(defn- get-notification
|
||||
[db notification-id]
|
||||
(->> (get-in db [:activity-center
|
||||
:notifications
|
||||
(get-in db [:activity-center :filter :type])
|
||||
(get-in db [:activity-center :filter :status])
|
||||
:data])
|
||||
(filter #(= notification-id (:id %)))
|
||||
first))
|
||||
|
||||
(fx/defn mark-as-read
|
||||
{:events [:activity-center.notifications/mark-as-read]}
|
||||
[{:keys [db]} notification-id]
|
||||
(when-let [notification (get-notification db notification-id)]
|
||||
{::json-rpc/call [{:method "wakuext_markActivityCenterNotificationsRead"
|
||||
:params [[notification-id]]
|
||||
:on-success #(rf/dispatch [:activity-center.notifications/mark-as-read-success notification])
|
||||
:on-error #(rf/dispatch [:activity-center/process-notification-failure
|
||||
notification-id
|
||||
:notification/mark-as-read
|
||||
%])}]}))
|
||||
|
||||
(fx/defn mark-as-read-success
|
||||
{:events [:activity-center.notifications/mark-as-read-success]}
|
||||
[cofx notification]
|
||||
(notifications-reconcile cofx [(assoc notification :read true)]))
|
||||
|
||||
;;;; Contact verification
|
||||
|
||||
(fx/defn contact-verification-decline
|
||||
|
@ -123,14 +160,6 @@
|
|||
|
||||
;;;; Notifications fetching and pagination
|
||||
|
||||
(def defaults
|
||||
{:filter-status :unread
|
||||
:filter-type types/no-type
|
||||
;; Choose the maximum number of notifications that *usually/safely* fit on
|
||||
;; most screens, so that the UI doesn't have to needlessly render
|
||||
;; notifications.
|
||||
:notifications-per-page 8})
|
||||
|
||||
(def start-or-end-cursor
|
||||
"")
|
||||
|
||||
|
|
|
@ -9,13 +9,105 @@
|
|||
[status-im.test-helpers :as h]
|
||||
[status-im2.setup.config :as config]))
|
||||
|
||||
(def notification-id "0x1")
|
||||
|
||||
(defn setup []
|
||||
(h/register-helper-events)
|
||||
(rf/dispatch [:setup/app-started]))
|
||||
|
||||
;;;; Contact verification
|
||||
(defn test-log-on-failure
|
||||
[{:keys [before-test notification-id event action]}]
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(h/using-log-test-appender
|
||||
(fn [logs]
|
||||
(when before-test
|
||||
(before-test))
|
||||
(h/stub-fx-with-callbacks ::json-rpc/call :on-error (constantly :fake-error))
|
||||
|
||||
(def notification-id 24)
|
||||
(rf/dispatch event)
|
||||
|
||||
(is (= {:args [(str "Failed to " action)
|
||||
{:notification-id notification-id
|
||||
:error :fake-error}]
|
||||
:level :warn}
|
||||
(last @logs)))))))
|
||||
|
||||
;;;; Misc
|
||||
|
||||
(deftest mark-as-read-test
|
||||
(testing "does nothing if the notification ID cannot be found in the app db"
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [spy-queue (atom [])]
|
||||
(h/spy-fx spy-queue ::json-rpc/call)
|
||||
(let [notifications {types/one-to-one-chat
|
||||
{:all {:cursor "" :data [{:id notification-id
|
||||
:read false
|
||||
:type types/one-to-one-chat}]}
|
||||
:unread {:cursor "" :data []}}}]
|
||||
(rf/dispatch [:test/assoc-in [:activity-center]
|
||||
{:notifications notifications
|
||||
:filter {:type types/one-to-one-chat
|
||||
:status :all}}])
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read "0x666"])
|
||||
|
||||
(is (= [] @spy-queue))
|
||||
(is (= notifications (get-in (h/db) [:activity-center :notifications])))))))
|
||||
|
||||
(testing "marks notifications as read and updates app db"
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat}
|
||||
notif-2 {:id "0x2" :read false :type types/one-to-one-chat}
|
||||
notif-3 {:id "0x3" :read false :type types/one-to-one-chat}
|
||||
new-notif-3 (assoc notif-3 :read true)
|
||||
new-notif-2 (assoc notif-2 :read true)]
|
||||
(h/stub-fx-with-callbacks ::json-rpc/call :on-success (constantly nil))
|
||||
(rf/dispatch [:test/assoc-in [:activity-center]
|
||||
{:notifications {types/one-to-one-chat
|
||||
{:all {:cursor "" :data [notif-3 notif-2 notif-1]}
|
||||
:unread {:cursor "" :data [notif-3 notif-2]}}}
|
||||
:filter {:type types/one-to-one-chat
|
||||
:status :unread}}])
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read (:id notif-2)])
|
||||
(is (= {types/one-to-one-chat
|
||||
{:all {:cursor "" :data [notif-3 new-notif-2 notif-1]}
|
||||
:unread {:cursor "" :data [notif-3]}}
|
||||
|
||||
types/no-type
|
||||
{:all {:data [new-notif-2]}
|
||||
:unread {:data []}}}
|
||||
(get-in (h/db) [:activity-center :notifications])))
|
||||
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read (:id notif-3)])
|
||||
(is (= {types/one-to-one-chat
|
||||
{:all {:cursor "" :data [new-notif-3 new-notif-2 notif-1]}
|
||||
:unread {:cursor "" :data []}}
|
||||
|
||||
types/no-type
|
||||
{:all {:data [new-notif-3 new-notif-2]}
|
||||
:unread {:data []}}}
|
||||
(get-in (h/db) [:activity-center :notifications]))))))
|
||||
|
||||
(testing "logs on failure"
|
||||
(test-log-on-failure
|
||||
{:notification-id notification-id
|
||||
:event [:activity-center.notifications/mark-as-read notification-id]
|
||||
:action :notification/mark-as-read
|
||||
:before-test (fn []
|
||||
(rf/dispatch [:test/assoc-in [:activity-center]
|
||||
{:notifications {types/one-to-one-chat
|
||||
{:all {:cursor "" :data [{:id notification-id
|
||||
:read false
|
||||
:type types/one-to-one-chat}]}
|
||||
:unread {:cursor "" :data []}}}
|
||||
:filter {:type types/one-to-one-chat
|
||||
:status :all}}]))})))
|
||||
|
||||
;;;; Contact verification
|
||||
|
||||
(def contact-verification-rpc-response
|
||||
{:activityCenterNotifications
|
||||
|
@ -59,22 +151,6 @@
|
|||
:timestamp 1666647286000
|
||||
:type types/contact-verification})
|
||||
|
||||
(defn test-log-on-failure
|
||||
[{:keys [notification-id event action]}]
|
||||
(rf-test/run-test-sync
|
||||
(setup)
|
||||
(h/using-log-test-appender
|
||||
(fn [logs]
|
||||
(h/stub-fx-with-callbacks ::json-rpc/call :on-error (constantly :fake-error))
|
||||
|
||||
(rf/dispatch event)
|
||||
|
||||
(is (= {:args [(str "Failed to " action)
|
||||
{:notification-id notification-id
|
||||
:error :fake-error}]
|
||||
:level :warn}
|
||||
(last @logs)))))))
|
||||
|
||||
(defn test-contact-verification-event
|
||||
[{:keys [event expected-rpc-call]}]
|
||||
(rf-test/run-test-sync
|
||||
|
|
|
@ -51,9 +51,13 @@
|
|||
{:button-1 {:label (i18n/label :t/decline)
|
||||
:accessibility-label :decline-contact-request
|
||||
:type :danger
|
||||
:on-press #(rf/dispatch [:contact-requests.ui/decline-request id])}
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:contact-requests.ui/decline-request id])
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read id]))}
|
||||
:button-2 {:label (i18n/label :t/accept)
|
||||
:accessibility-label :accept-contact-request
|
||||
:type :positive
|
||||
:on-press #(rf/dispatch [:contact-requests.ui/accept-request id])}}
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:contact-requests.ui/accept-request id])
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read id]))}}
|
||||
nil))])))
|
||||
|
|
|
@ -85,21 +85,29 @@
|
|||
{:button-1 {:label (i18n/label :t/untrustworthy)
|
||||
:accessibility-label :mark-contact-verification-as-untrustworthy
|
||||
:type :danger
|
||||
:on-press #(rf/dispatch [:activity-center.contact-verification/mark-as-untrustworthy id])}
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:activity-center.contact-verification/mark-as-untrustworthy id])
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read id]))}
|
||||
:button-2 {:label (i18n/label :t/accept)
|
||||
:accessibility-label :mark-contact-verification-as-trusted
|
||||
:type :positive
|
||||
:on-press #(rf/dispatch [:activity-center.contact-verification/mark-as-trusted id])}})
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:activity-center.contact-verification/mark-as-trusted id])
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read id]))}})
|
||||
(when (= contact-verification-status constants/contact-verification-status-pending)
|
||||
{:button-1 {:label (i18n/label :t/decline)
|
||||
:accessibility-label :decline-contact-verification
|
||||
:type :danger
|
||||
:on-press #(hide-bottom-sheet-and-dispatch [:activity-center.contact-verification/decline id])}
|
||||
:on-press (fn []
|
||||
(hide-bottom-sheet-and-dispatch [:activity-center.contact-verification/decline id])
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read id]))}
|
||||
:button-2 (if replying?
|
||||
{:label (i18n/label :t/send-reply)
|
||||
:accessibility-label :reply-to-contact-verification
|
||||
:type :primary
|
||||
:on-press #(hide-bottom-sheet-and-dispatch [:activity-center.contact-verification/reply id @reply])}
|
||||
:on-press (fn []
|
||||
(hide-bottom-sheet-and-dispatch [:activity-center.contact-verification/reply id @reply])
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read id]))}
|
||||
{:label (i18n/label :t/message-reply)
|
||||
:accessibility-label :send-reply-to-contact-verification
|
||||
:type :primary
|
||||
|
|
|
@ -256,11 +256,11 @@
|
|||
:width 32
|
||||
:style {:margin-left 12}
|
||||
:accessibility-label :notifications-button
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [:mark-all-activity-center-notifications-as-read])
|
||||
(if config/new-activity-center-enabled?
|
||||
(re-frame/dispatch [:activity-center/open])
|
||||
(re-frame/dispatch [:navigate-to :notifications-center])))}
|
||||
:on-press #(do (if config/new-activity-center-enabled?
|
||||
(re-frame/dispatch [:activity-center/open])
|
||||
(do
|
||||
(re-frame/dispatch [:mark-all-activity-center-notifications-as-read])
|
||||
(re-frame/dispatch [:navigate-to :notifications-center]))))}
|
||||
[icons/icon :main-icons/notification2 {:color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white)}]]
|
||||
(when (pos? notif-count)
|
||||
[react/view {:style (merge (styles/counter-public-container) {:top 5 :right 5})
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn navigate-to-activity-center []
|
||||
(rf/dispatch [:mark-all-activity-center-notifications-as-read])
|
||||
(if config/new-activity-center-enabled?
|
||||
(rf/dispatch [:activity-center/open])
|
||||
(rf/dispatch [:navigate-to :notifications-center])))
|
||||
(do (rf/dispatch [:mark-all-activity-center-notifications-as-read])
|
||||
(rf/dispatch [:navigate-to :notifications-center]))))
|
||||
|
||||
(defn title-column [{:keys [label handler accessibility-label]}]
|
||||
[rn/view style/title-column
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
(ns status-im2.contexts.chat.home.contact-request.view
|
||||
(:require [react-native.core :as rn]
|
||||
[status-im2.setup.config :as config]
|
||||
[quo2.core :as quo]
|
||||
[i18n.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
|
@ -58,7 +59,8 @@
|
|||
:on-press #(do
|
||||
(rf/dispatch [:bottom-sheet/show-sheet
|
||||
{:content (fn [] [contact-requests-sheet requests])}])
|
||||
(rf/dispatch [:mark-all-activity-center-notifications-as-read]))
|
||||
(when-not config/new-activity-center-enabled?
|
||||
(rf/dispatch [:mark-all-activity-center-notifications-as-read])))
|
||||
:style style/contact-requests}
|
||||
[rn/view {:style (style/contact-requests-icon)}
|
||||
[quo/icon :i/pending-user {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]]
|
||||
|
|
Loading…
Reference in New Issue