Remove old Notification Center (#14533)

This commit is contained in:
Icaro Motta 2022-12-14 18:00:32 -03:00 committed by GitHub
parent f47bc6e40e
commit 08fb0de7b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 491 additions and 1095 deletions

View File

@ -178,13 +178,14 @@
99))
(fx/defn notifications-fetch
[{:keys [db]} {:keys [cursor filter-type filter-status reset-data?]}]
[{:keys [db]} {:keys [cursor per-page filter-type filter-status reset-data?]}]
(when-not (get-in db [:activity-center :notifications filter-type filter-status :loading?])
{:db (assoc-in db [:activity-center :notifications filter-type filter-status :loading?] true)
::json-rpc/call [{:method "wakuext_activityCenterNotificationsBy"
:params [cursor (defaults :notifications-per-page) filter-type (status filter-status)]
:on-success #(rf/dispatch [:activity-center.notifications/fetch-success filter-type filter-status reset-data? %])
:on-error #(rf/dispatch [:activity-center.notifications/fetch-error filter-type filter-status %])}]}))
(let [per-page (or per-page (defaults :notifications-per-page))]
{:db (assoc-in db [:activity-center :notifications filter-type filter-status :loading?] true)
::json-rpc/call [{:method "wakuext_activityCenterNotificationsBy"
:params [cursor per-page filter-type (status filter-status)]
:on-success #(rf/dispatch [:activity-center.notifications/fetch-success filter-type filter-status reset-data? %])
:on-error #(rf/dispatch [:activity-center.notifications/fetch-error filter-type filter-status %])}]})))
(fx/defn notifications-fetch-first-page
{:events [:activity-center.notifications/fetch-first-page]}
@ -231,6 +232,35 @@
(constantly processed)
#(concat %1 processed))))}))
(fx/defn notifications-fetch-unread-contact-requests
"Unread contact requests are, in practical terms, the same as pending contact
requests in the new Activity Center, because pending contact requests are
always marked as unread, and once the user declines/accepts the request, they
are marked as read.
If this relationship ever changes, we will probably need to change the backend
to explicitly support fetching notifications for 'pending' contact requests."
{:events [:activity-center.notifications/fetch-unread-contact-requests]}
[cofx]
(notifications-fetch cofx {:cursor start-or-end-cursor
:filter-status :unread
:filter-type types/contact-request
:per-page 20
:reset-data? true}))
(fx/defn notifications-fetch-unread-count
{:events [:activity-center.notifications/fetch-unread-count]}
[_]
{::json-rpc/call [{:method "wakuext_unreadActivityCenterNotificationsCount"
:params []
:on-success #(rf/dispatch [:activity-center.notifications/fetch-unread-count-success %])
:on-error #()}]})
(fx/defn notifications-fetch-unread-count-success
{:events [:activity-center.notifications/fetch-unread-count-success]}
[{:keys [db]} result]
{:db (assoc-in db [:activity-center :unread-count] result)})
(fx/defn notifications-fetch-error
{:events [:activity-center.notifications/fetch-error]}
[{:keys [db]} filter-type filter-status error]

View File

@ -2,12 +2,12 @@
(:require [cljs.test :refer [deftest is testing]]
[day8.re-frame.test :as rf-test]
[re-frame.core :as rf]
[status-im.activity-center.core :as activity-center]
[status-im.activity-center.notification-types :as types]
[status-im.constants :as constants]
[status-im.ethereum.json-rpc :as json-rpc]
status-im.events
[status-im.test-helpers :as h]
[status-im2.setup.config :as config]))
[status-im.test-helpers :as h]))
(def notification-id "0x1")
@ -174,345 +174,370 @@
(select-keys [:method :params])))))))
(deftest contact-verification-decline-test
(with-redefs [config/new-activity-center-enabled? true]
(testing "declines notification and reconciles"
(test-contact-verification-event
{:event [:activity-center.contact-verification/decline notification-id]
:expected-rpc-call {:method "wakuext_declineContactVerificationRequest"
:params [notification-id]}}))
(testing "logs on failure"
(test-log-on-failure
{:notification-id notification-id
:event [:activity-center.contact-verification/decline notification-id]
:action :contact-verification/decline}))))
(testing "declines notification and reconciles"
(test-contact-verification-event
{:event [:activity-center.contact-verification/decline notification-id]
:expected-rpc-call {:method "wakuext_declineContactVerificationRequest"
:params [notification-id]}}))
(testing "logs on failure"
(test-log-on-failure
{:notification-id notification-id
:event [:activity-center.contact-verification/decline notification-id]
:action :contact-verification/decline})))
(deftest contact-verification-reply-test
(with-redefs [config/new-activity-center-enabled? true]
(testing "sends reply and reconciles"
(let [reply "any answer"]
(test-contact-verification-event
{:event [:activity-center.contact-verification/reply notification-id reply]
:expected-rpc-call {:method "wakuext_acceptContactVerificationRequest"
:params [notification-id reply]}})))
(testing "logs on failure"
(test-log-on-failure
{:notification-id notification-id
:event [:activity-center.contact-verification/reply notification-id "any answer"]
:action :contact-verification/reply}))))
(testing "sends reply and reconciles"
(let [reply "any answer"]
(test-contact-verification-event
{:event [:activity-center.contact-verification/reply notification-id reply]
:expected-rpc-call {:method "wakuext_acceptContactVerificationRequest"
:params [notification-id reply]}})))
(testing "logs on failure"
(test-log-on-failure
{:notification-id notification-id
:event [:activity-center.contact-verification/reply notification-id "any answer"]
:action :contact-verification/reply})))
(deftest contact-verification-mark-as-trusted-test
(with-redefs [config/new-activity-center-enabled? true]
(testing "marks notification as trusted and reconciles"
(test-contact-verification-event
{:event [:activity-center.contact-verification/mark-as-trusted notification-id]
:expected-rpc-call {:method "wakuext_verifiedTrusted"
:params [{:id notification-id}]}}))
(testing "logs on failure"
(test-log-on-failure
{:notification-id notification-id
:event [:activity-center.contact-verification/mark-as-trusted notification-id]
:action :contact-verification/mark-as-trusted}))))
(testing "marks notification as trusted and reconciles"
(test-contact-verification-event
{:event [:activity-center.contact-verification/mark-as-trusted notification-id]
:expected-rpc-call {:method "wakuext_verifiedTrusted"
:params [{:id notification-id}]}}))
(testing "logs on failure"
(test-log-on-failure
{:notification-id notification-id
:event [:activity-center.contact-verification/mark-as-trusted notification-id]
:action :contact-verification/mark-as-trusted})))
(deftest contact-verification-mark-as-untrustworthy-test
(with-redefs [config/new-activity-center-enabled? true]
(testing "marks notification as untrustworthy and reconciles"
(test-contact-verification-event
{:event [:activity-center.contact-verification/mark-as-untrustworthy notification-id]
:expected-rpc-call {:method "wakuext_verifiedUntrustworthy"
:params [{:id notification-id}]}}))
(testing "logs on failure"
(test-log-on-failure
{:notification-id notification-id
:event [:activity-center.contact-verification/mark-as-untrustworthy notification-id]
:action :contact-verification/mark-as-untrustworthy}))))
(testing "marks notification as untrustworthy and reconciles"
(test-contact-verification-event
{:event [:activity-center.contact-verification/mark-as-untrustworthy notification-id]
:expected-rpc-call {:method "wakuext_verifiedUntrustworthy"
:params [{:id notification-id}]}}))
(testing "logs on failure"
(test-log-on-failure
{:notification-id notification-id
:event [:activity-center.contact-verification/mark-as-untrustworthy notification-id]
:action :contact-verification/mark-as-untrustworthy})))
;;;; Notification reconciliation
(deftest notifications-reconcile-test
(with-redefs [config/new-activity-center-enabled? true]
(testing "does nothing when there are no new notifications"
(rf-test/run-test-sync
(setup)
(let [notifications {types/one-to-one-chat
{:all {:cursor ""
:data [{:id "0x1"
:read true
:type types/one-to-one-chat}
{:id "0x2"
:read false
:type types/one-to-one-chat}]}
:unread {:cursor ""
:data [{:id "0x3"
:read false
:type types/one-to-one-chat}]}}
types/private-group-chat
{:unread {:cursor ""
:data [{:id "0x4"
:read false
:type types/private-group-chat}]}}}]
(rf/dispatch [:test/assoc-in [:activity-center :notifications] notifications])
(testing "does nothing when there are no new notifications"
(rf-test/run-test-sync
(setup)
(let [notifications {types/one-to-one-chat
{:all {:cursor ""
:data [{:id "0x1"
:read true
:type types/one-to-one-chat}
{:id "0x2"
:read false
:type types/one-to-one-chat}]}
:unread {:cursor ""
:data [{:id "0x3"
:read false
:type types/one-to-one-chat}]}}
types/private-group-chat
{:unread {:cursor ""
:data [{:id "0x4"
:read false
:type types/private-group-chat}]}}}]
(rf/dispatch [:test/assoc-in [:activity-center :notifications] notifications])
(rf/dispatch [:activity-center.notifications/reconcile nil])
(rf/dispatch [:activity-center.notifications/reconcile nil])
(is (= notifications (get-in (h/db) [:activity-center :notifications]))))))
(is (= notifications (get-in (h/db) [:activity-center :notifications]))))))
(testing "removes dismissed or accepted notifications"
(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}
notif-4 {:id "0x4" :read false :type types/private-group-chat}
notif-5 {:id "0x5" :read true :type types/private-group-chat}
notif-6 {:id "0x6" :read false :type types/private-group-chat}]
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
{types/one-to-one-chat
{:all {:cursor "" :data [notif-1 notif-2]}
:unread {:cursor "" :data [notif-3]}}
types/private-group-chat
{:unread {:cursor "" :data [notif-4 notif-6]}}}])
(testing "removes dismissed or accepted notifications"
(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}
notif-4 {:id "0x4" :read false :type types/private-group-chat}
notif-5 {:id "0x5" :read true :type types/private-group-chat}
notif-6 {:id "0x6" :read false :type types/private-group-chat}]
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
{types/one-to-one-chat
{:all {:cursor "" :data [notif-1 notif-2]}
:unread {:cursor "" :data [notif-3]}}
types/private-group-chat
{:unread {:cursor "" :data [notif-4 notif-6]}}}])
(rf/dispatch [:activity-center.notifications/reconcile
[(assoc notif-1 :dismissed true)
(assoc notif-3 :accepted true)
(assoc notif-4 :dismissed true)
notif-5]])
(rf/dispatch [:activity-center.notifications/reconcile
[(assoc notif-1 :dismissed true)
(assoc notif-3 :accepted true)
(assoc notif-4 :dismissed true)
notif-5]])
(is (= {types/no-type
{:all {:data [notif-5]}
:unread {:data []}}
types/one-to-one-chat
{:all {:cursor "" :data [notif-2]}
:unread {:cursor "" :data []}}
types/private-group-chat
{:all {:data [notif-5]}
:unread {:cursor "" :data [notif-6]}}}
(get-in (h/db) [:activity-center :notifications]))))))
(is (= {types/no-type
{:all {:data [notif-5]}
:unread {:data []}}
types/one-to-one-chat
{:all {:cursor "" :data [notif-2]}
:unread {:cursor "" :data []}}
types/private-group-chat
{:all {:data [notif-5]}
:unread {:cursor "" :data [notif-6]}}}
(get-in (h/db) [:activity-center :notifications]))))))
(testing "replaces old notifications with newly arrived ones"
(rf-test/run-test-sync
(setup)
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat}
notif-4 {:id "0x4" :read false :type types/private-group-chat}
notif-6 {:id "0x6" :read false :type types/private-group-chat}
new-notif-1 (assoc notif-1 :last-message {})
new-notif-4 (assoc notif-4 :author "0xabc")]
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
{types/no-type
{:all {:cursor "" :data [notif-1]}
:unread {:cursor "" :data [notif-4 notif-6]}}
types/one-to-one-chat
{:all {:cursor "" :data [notif-1]}}
types/private-group-chat
{:unread {:cursor "" :data [notif-4 notif-6]}}}])
(testing "replaces old notifications with newly arrived ones"
(rf-test/run-test-sync
(setup)
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat}
notif-4 {:id "0x4" :read false :type types/private-group-chat}
notif-6 {:id "0x6" :read false :type types/private-group-chat}
new-notif-1 (assoc notif-1 :last-message {})
new-notif-4 (assoc notif-4 :author "0xabc")]
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
{types/no-type
{:all {:cursor "" :data [notif-1]}
:unread {:cursor "" :data [notif-4 notif-6]}}
types/one-to-one-chat
{:all {:cursor "" :data [notif-1]}}
types/private-group-chat
{:unread {:cursor "" :data [notif-4 notif-6]}}}])
(rf/dispatch [:activity-center.notifications/reconcile [new-notif-1 new-notif-4 notif-6]])
(rf/dispatch [:activity-center.notifications/reconcile [new-notif-1 new-notif-4 notif-6]])
(is (= {types/no-type
{:all {:cursor "" :data [notif-6 new-notif-4 new-notif-1]}
:unread {:cursor "" :data [notif-6 new-notif-4]}}
types/one-to-one-chat
{:all {:cursor "" :data [new-notif-1]}
:unread {:data []}}
types/private-group-chat
{:all {:data [notif-6 new-notif-4]}
:unread {:cursor "" :data [notif-6 new-notif-4]}}}
(get-in (h/db) [:activity-center :notifications]))))))
(is (= {types/no-type
{:all {:cursor "" :data [notif-6 new-notif-4 new-notif-1]}
:unread {:cursor "" :data [notif-6 new-notif-4]}}
types/one-to-one-chat
{:all {:cursor "" :data [new-notif-1]}
:unread {:data []}}
types/private-group-chat
{:all {:data [notif-6 new-notif-4]}
:unread {:cursor "" :data [notif-6 new-notif-4]}}}
(get-in (h/db) [:activity-center :notifications]))))))
(testing "reconciles notifications that switched their read/unread status"
(rf-test/run-test-sync
(setup)
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat}
new-notif-1 (assoc notif-1 :read false)]
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
{types/one-to-one-chat
{:all {:cursor "" :data [notif-1]}}}])
(testing "reconciles notifications that switched their read/unread status"
(rf-test/run-test-sync
(setup)
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat}
new-notif-1 (assoc notif-1 :read false)]
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
{types/one-to-one-chat
{:all {:cursor "" :data [notif-1]}}}])
(rf/dispatch [:activity-center.notifications/reconcile [new-notif-1]])
(rf/dispatch [:activity-center.notifications/reconcile [new-notif-1]])
(is (= {types/no-type
{:all {:data [new-notif-1]}
:unread {:data [new-notif-1]}}
(is (= {types/no-type
{:all {:data [new-notif-1]}
:unread {:data [new-notif-1]}}
types/one-to-one-chat
{:all {:cursor "" :data [new-notif-1]}
:unread {:data [new-notif-1]}}}
(get-in (h/db) [:activity-center :notifications]))))))
types/one-to-one-chat
{:all {:cursor "" :data [new-notif-1]}
:unread {:data [new-notif-1]}}}
(get-in (h/db) [:activity-center :notifications]))))))
;; Sorting by timestamp and ID is compatible with what the backend does when
;; returning paginated results.
(testing "sorts notifications by timestamp and id in descending order"
(rf-test/run-test-sync
(setup)
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat :timestamp 1}
notif-2 {:id "0x2" :read true :type types/one-to-one-chat :timestamp 1}
notif-3 {:id "0x3" :read false :type types/one-to-one-chat :timestamp 50}
notif-4 {:id "0x4" :read false :type types/one-to-one-chat :timestamp 100}
notif-5 {:id "0x5" :read false :type types/one-to-one-chat :timestamp 100}
new-notif-1 (assoc notif-1 :last-message {})
new-notif-4 (assoc notif-4 :last-message {})]
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
{types/one-to-one-chat
{:all {:cursor "" :data [notif-1 notif-2]}
:unread {:cursor "" :data [notif-3 notif-4 notif-5]}}}])
;; Sorting by timestamp and ID is compatible with what the backend does when
;; returning paginated results.
(testing "sorts notifications by timestamp and id in descending order"
(rf-test/run-test-sync
(setup)
(let [notif-1 {:id "0x1" :read true :type types/one-to-one-chat :timestamp 1}
notif-2 {:id "0x2" :read true :type types/one-to-one-chat :timestamp 1}
notif-3 {:id "0x3" :read false :type types/one-to-one-chat :timestamp 50}
notif-4 {:id "0x4" :read false :type types/one-to-one-chat :timestamp 100}
notif-5 {:id "0x5" :read false :type types/one-to-one-chat :timestamp 100}
new-notif-1 (assoc notif-1 :last-message {})
new-notif-4 (assoc notif-4 :last-message {})]
(rf/dispatch [:test/assoc-in [:activity-center :notifications]
{types/one-to-one-chat
{:all {:cursor "" :data [notif-1 notif-2]}
:unread {:cursor "" :data [notif-3 notif-4 notif-5]}}}])
(rf/dispatch [:activity-center.notifications/reconcile [new-notif-1 new-notif-4]])
(rf/dispatch [:activity-center.notifications/reconcile [new-notif-1 new-notif-4]])
(is (= {types/no-type
{:all {:data [new-notif-4 new-notif-1]}
:unread {:data [new-notif-4]}}
types/one-to-one-chat
{:all {:cursor "" :data [new-notif-4 notif-2 new-notif-1]}
:unread {:cursor "" :data [notif-5 new-notif-4 notif-3]}}}
(get-in (h/db) [:activity-center :notifications]))))))))
(is (= {types/no-type
{:all {:data [new-notif-4 new-notif-1]}
:unread {:data [new-notif-4]}}
types/one-to-one-chat
{:all {:cursor "" :data [new-notif-4 notif-2 new-notif-1]}
:unread {:cursor "" :data [notif-5 new-notif-4 notif-3]}}}
(get-in (h/db) [:activity-center :notifications])))))))
;;;; Notifications fetching and pagination
(deftest notifications-fetch-test
(with-redefs [config/new-activity-center-enabled? true]
(testing "fetches first page"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/stub-fx-with-callbacks
::json-rpc/call
:on-success (constantly {:cursor "10"
:notifications [{:id "0x1"
:type types/one-to-one-chat
:read false
:chatId "0x9"}]}))
(h/spy-fx spy-queue ::json-rpc/call)
(testing "fetches first page"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/stub-fx-with-callbacks
::json-rpc/call
:on-success (constantly {:cursor "10"
:notifications [{:id "0x1"
:type types/one-to-one-chat
:read false
:chatId "0x9"}]}))
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:activity-center.notifications/fetch-first-page
{:filter-type types/one-to-one-chat}])
(rf/dispatch [:activity-center.notifications/fetch-first-page
{:filter-type types/one-to-one-chat}])
(is (= :unread (get-in (h/db) [:activity-center :filter :status])))
(is (= "" (get-in @spy-queue [0 :args 0 :params 0]))
"Should be called with empty cursor when fetching first page")
(is (= {types/one-to-one-chat
{:unread {:cursor "10"
:data [{:chat-id "0x9"
:chat-name nil
:chat-type types/one-to-one-chat
:group-chat false
:id "0x1"
:public? false
:last-message nil
:message nil
:read false
:reply-message nil
:type types/one-to-one-chat}]}}}
(get-in (h/db) [:activity-center :notifications]))))))
(is (= :unread (get-in (h/db) [:activity-center :filter :status])))
(is (= "" (get-in @spy-queue [0 :args 0 :params 0]))
"Should be called with empty cursor when fetching first page")
(is (= {types/one-to-one-chat
{:unread {:cursor "10"
:data [{:chat-id "0x9"
:chat-name nil
:chat-type types/one-to-one-chat
:group-chat false
:id "0x1"
:public? false
:last-message nil
:message nil
:read false
:reply-message nil
:type types/one-to-one-chat}]}}}
(get-in (h/db) [:activity-center :notifications]))))))
(testing "does not fetch next page when pagination cursor reached the end"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
:unread])
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
types/one-to-one-chat])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :unread :cursor]
""])
(testing "does not fetch next page when pagination cursor reached the end"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
:unread])
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
types/one-to-one-chat])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :unread :cursor]
""])
(rf/dispatch [:activity-center.notifications/fetch-next-page])
(rf/dispatch [:activity-center.notifications/fetch-next-page])
(is (= [] @spy-queue)))))
(is (= [] @spy-queue)))))
;; The cursor can be nil sometimes because the reconciliation doesn't care
;; about updating the cursor value, but we have to make sure the next page is
;; only fetched if the current cursor is valid.
(testing "does not fetch next page when cursor is nil"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
:unread])
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
types/one-to-one-chat])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :unread :cursor]
nil])
;; The cursor can be nil sometimes because the reconciliation doesn't care
;; about updating the cursor value, but we have to make sure the next page is
;; only fetched if the current cursor is valid.
(testing "does not fetch next page when cursor is nil"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
:unread])
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
types/one-to-one-chat])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :unread :cursor]
nil])
(rf/dispatch [:activity-center.notifications/fetch-next-page])
(rf/dispatch [:activity-center.notifications/fetch-next-page])
(is (= [] @spy-queue)))))
(is (= [] @spy-queue)))))
(testing "fetches next page when pagination cursor is not empty"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/stub-fx-with-callbacks
::json-rpc/call
:on-success (constantly {:cursor ""
:notifications [{:id "0x1"
:type types/mention
:read false
:chatId "0x9"}]}))
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
:unread])
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
types/mention])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/mention :unread :cursor]
"10"])
(testing "fetches next page when pagination cursor is not empty"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/stub-fx-with-callbacks
::json-rpc/call
:on-success (constantly {:cursor ""
:notifications [{:id "0x1"
:type types/mention
:read false
:chatId "0x9"}]}))
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
:unread])
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
types/mention])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/mention :unread :cursor]
"10"])
(rf/dispatch [:activity-center.notifications/fetch-next-page])
(rf/dispatch [:activity-center.notifications/fetch-next-page])
(is (= "wakuext_activityCenterNotificationsBy" (get-in @spy-queue [0 :args 0 :method])))
(is (= "10" (get-in @spy-queue [0 :args 0 :params 0]))
"Should be called with current cursor")
(is (= {types/mention
{:unread {:cursor ""
:data [{:chat-id "0x9"
:chat-name nil
:chat-type 3
:id "0x1"
:last-message nil
:message nil
:read false
:reply-message nil
:type types/mention}]}}}
(get-in (h/db) [:activity-center :notifications]))))))
(is (= "wakuext_activityCenterNotificationsBy" (get-in @spy-queue [0 :args 0 :method])))
(is (= "10" (get-in @spy-queue [0 :args 0 :params 0]))
"Should be called with current cursor")
(is (= {types/mention
{:unread {:cursor ""
:data [{:chat-id "0x9"
:chat-name nil
:chat-type 3
:id "0x1"
:last-message nil
:message nil
:read false
:reply-message nil
:type types/mention}]}}}
(get-in (h/db) [:activity-center :notifications]))))))
(testing "does not fetch next page while it is still loading"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
:all])
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
types/one-to-one-chat])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :all :cursor]
"10"])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :all :loading?]
true])
(testing "does not fetch next page while it is still loading"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
:all])
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
types/one-to-one-chat])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :all :cursor]
"10"])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :all :loading?]
true])
(rf/dispatch [:activity-center.notifications/fetch-next-page])
(rf/dispatch [:activity-center.notifications/fetch-next-page])
(is (= [] @spy-queue)))))
(is (= [] @spy-queue)))))
(testing "resets loading flag after an error"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/stub-fx-with-callbacks ::json-rpc/call :on-error (constantly :fake-error))
(h/spy-event-fx spy-queue :activity-center.notifications/fetch-error)
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
:unread])
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
types/one-to-one-chat])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :unread :cursor]
""])
(testing "resets loading flag after an error"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/stub-fx-with-callbacks ::json-rpc/call :on-error (constantly :fake-error))
(h/spy-event-fx spy-queue :activity-center.notifications/fetch-error)
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:test/assoc-in [:activity-center :filter :status]
:unread])
(rf/dispatch [:test/assoc-in [:activity-center :filter :type]
types/one-to-one-chat])
(rf/dispatch [:test/assoc-in [:activity-center :notifications types/one-to-one-chat :unread :cursor]
""])
(rf/dispatch [:activity-center.notifications/fetch-first-page])
(rf/dispatch [:activity-center.notifications/fetch-first-page])
(is (nil? (get-in (h/db) [:activity-center :notifications types/one-to-one-chat :unread :loading?])))
(is (= [:activity-center.notifications/fetch-error
types/one-to-one-chat
:unread
:fake-error]
(:args (last @spy-queue)))))))))
(is (nil? (get-in (h/db) [:activity-center :notifications types/one-to-one-chat :unread :loading?])))
(is (= [:activity-center.notifications/fetch-error
types/one-to-one-chat
:unread
:fake-error]
(:args (last @spy-queue))))))))
(deftest notifications-fetch-unread-contact-requests-test
(testing "fetches latest unread contact requests"
(let [actual (activity-center/notifications-fetch-unread-contact-requests {:db {}})
per-page 20]
(is (= {:activity-center
{:notifications
{types/contact-request
{:unread {:loading? true}}}}}
(:db actual)))
(is (= {:method "wakuext_activityCenterNotificationsBy"
:params ["" per-page types/contact-request activity-center/status-unread]}
(-> actual
::json-rpc/call
first
(select-keys [:method :params])))))))
(deftest notifications-fetch-unread-count-test
(testing "fetches total notification count and store in db"
(rf-test/run-test-sync
(setup)
(let [spy-queue (atom [])]
(h/stub-fx-with-callbacks ::json-rpc/call :on-success (constantly 9))
(h/spy-fx spy-queue ::json-rpc/call)
(rf/dispatch [:activity-center.notifications/fetch-unread-count])
(is (= "wakuext_unreadActivityCenterNotificationsCount"
(get-in @spy-queue [0 :args 0 :method])))
(is (= 9 (get-in (h/db) [:activity-center :unread-count])))))))

View File

@ -7,7 +7,7 @@
[status-im.chat.models.message-list :as message-list]
[taoensso.timbre :as log]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.notifications-center.core :as notification-center]))
[status-im.activity-center.core :as activity-center]))
(defn cursor->clock-value
[^js cursor]
@ -67,14 +67,14 @@
(fx/defn handle-mark-all-read-successful
{:events [::mark-all-read-successful]}
[cofx]
(notification-center/get-activity-center-notifications-count cofx))
(activity-center/notifications-fetch-unread-count cofx))
(fx/defn handle-mark-all-read-in-community-successful
{:events [::mark-all-read-in-community-successful]}
[{:keys [db] :as cofx} chat-ids]
(fx/merge cofx
{:db (reduce mark-chat-all-read db chat-ids)}
(notification-center/get-activity-center-notifications-count)))
(activity-center/notifications-fetch-unread-count)))
(fx/defn handle-mark-all-read
{:events [:chat.ui/mark-all-read-pressed :chat/mark-all-as-read]}

View File

@ -205,8 +205,7 @@
#(re-frame/dispatch [:chat/decrease-unviewed-count chat-id %3]))))
removed-messages)
remove-messages-fx (fn [{:keys [db]}]
{:dispatch-n [[:get-activity-center-notifications]
[:get-activity-center-notifications-count]]})]
{:dispatch [:activity-center.notifications/fetch-unread-count]})]
(apply fx/merge cofx (-> mark-as-deleted-fx
(concat mark-as-seen-fx)
(conj remove-messages-fx)))))

View File

@ -15,7 +15,7 @@
[status-im2.navigation.events :as navigation]
[status-im.utils.handlers :refer [>evt]]
[status-im.ui.components.emoji-thumbnail.styles :as emoji-thumbnail-styles]
[status-im.notifications-center.core :as notification-center]))
[status-im.activity-center.core :as activity-center]))
(def crop-size 1000)
@ -105,7 +105,7 @@
(fx/merge cofx
(handle-response cofx response-js)
(navigation/pop-to-root-tab :chat-stack)
(notification-center/get-activity-center-notifications-count)))
(activity-center/notifications-fetch-unread-count)))
(fx/defn joined
{:events [::joined ::requested-to-join]}
@ -457,7 +457,7 @@
(fx/merge cofx
(bottom-sheet/hide-bottom-sheet)
(handle-response response-js)
(notification-center/get-activity-center-notifications-count)))
(activity-center/notifications-fetch-unread-count)))
(fx/defn member-ban
{:events [::member-ban]}

View File

@ -6,7 +6,7 @@
[status-im.data-store.contacts :as contacts-store]
[status-im2.navigation.events :as navigation]
[status-im.utils.types :as types]
[status-im.notifications-center.core :as notification-center]
[status-im.activity-center.core :as activity-center]
[status-im.utils.fx :as fx]))
(fx/defn clean-up-chat
@ -47,7 +47,7 @@
(assoc-in [:contacts/contacts public-key :added] false))
:clear-message-notifications
[[public-key] (get-in db [:multiaccount :remote-push-notifications-enabled?])]}
(notification-center/get-activity-center-notifications-count)
(activity-center/notifications-fetch-unread-count)
fxs)))
(fx/defn block-contact

View File

@ -3,16 +3,13 @@
[status-im2.navigation.events :as navigation]
[status-im.utils.fx :as fx]
[status-im.chat.models :as chat]
[status-im.contact.core :as contact]
[status-im.notifications-center.core :as notification-center]))
[status-im.contact.core :as contact]))
(fx/defn send-message-pressed
{:events [:contact.ui/send-message-pressed]
:interceptors [(re-frame/inject-cofx :random-id-generator)]}
[cofx {:keys [public-key ens-name]}]
(fx/merge cofx
(chat/start-chat public-key ens-name)
(notification-center/accept-all-activity-center-notifications-from-chat public-key)))
(chat/start-chat cofx public-key ens-name))
(fx/defn contact-code-submitted
{:events [:contact.ui/contact-code-submitted]

View File

@ -48,7 +48,7 @@
(and blocked (not was-blocked))
(conj [::contact.block/contact-blocked contact chats]))))
[[:offload-messages constants/timeline-chat-id]
[:get-activity-center-notifications-count]]
[:activity-center.notifications/fetch-unread-count]]
contacts)]
(merge
{:db (update db :contacts/contacts

View File

@ -1,10 +1,8 @@
(ns status-im.data-store.activities
(:require [clojure.set :as set]
[quo.design-system.colors :as colors]
[status-im.constants :as constants]
[status-im.activity-center.notification-types :as notification-types]
[status-im.data-store.messages :as messages]
[status-im2.setup.config :as config]))
[status-im.data-store.messages :as messages]))
(defn- rpc->type [{:keys [type name] :as chat}]
(case type
@ -35,15 +33,13 @@
chat))
(defn <-rpc [item]
(cond-> (-> item
rpc->type
(set/rename-keys {:lastMessage :last-message
:replyMessage :reply-message
:chatId :chat-id
:contactVerificationStatus :contact-verification-status})
(update :last-message #(when % (messages/<-rpc %)))
(update :message #(when % (messages/<-rpc %)))
(update :reply-message #(when % (messages/<-rpc %)))
(dissoc :chatId))
(not config/new-activity-center-enabled?)
(assoc :color (rand-nth colors/chat-colors))))
(-> item
rpc->type
(set/rename-keys {:lastMessage :last-message
:replyMessage :reply-message
:chatId :chat-id
:contactVerificationStatus :contact-verification-status})
(update :last-message #(when % (messages/<-rpc %)))
(update :message #(when % (messages/<-rpc %)))
(update :reply-message #(when % (messages/<-rpc %)))
(dissoc :chatId)))

View File

@ -2,8 +2,7 @@
(:require [cljs.test :refer [deftest is testing]]
[status-im.constants :as constants]
[status-im.activity-center.notification-types :as notification-types]
[status-im.data-store.activities :as store]
[status-im2.setup.config :as config]))
[status-im.data-store.activities :as store]))
(def chat-id
"0x04c66155")
@ -19,82 +18,81 @@
:replyMessage {}})
(deftest <-rpc-test
(with-redefs [config/new-activity-center-enabled? true]
(testing "renames keys"
(is (= {:name chat-name
:chat-id chat-id
:contact-verification-status constants/contact-verification-status-pending}
(-> raw-notification
store/<-rpc
(dissoc :last-message :message :reply-message)))))
(testing "renames keys"
(is (= {:name chat-name
:chat-id chat-id
:contact-verification-status constants/contact-verification-status-pending}
(-> raw-notification
store/<-rpc
(dissoc :last-message :message :reply-message)))))
(testing "transforms messages from RPC response"
(is (= {:last-message {:quoted-message nil
:outgoing-status nil
:command-parameters nil
:content {:sticker nil
:rtl? nil
:ens-name nil
:parsed-text nil
:response-to nil
:chat-id nil
:image nil
:line-count nil
:links nil
:text nil}
:outgoing false}
:message nil
:reply-message {:quoted-message nil
:outgoing-status nil
:command-parameters nil
:content {:sticker nil
:rtl? nil
:ens-name nil
:parsed-text nil
:response-to nil
:chat-id nil
:image nil
:line-count nil
:links nil
:text nil}
:outgoing false}}
(-> raw-notification
store/<-rpc
(select-keys [:last-message :message :reply-message])))))
(testing "transforms messages from RPC response"
(is (= {:last-message {:quoted-message nil
:outgoing-status nil
:command-parameters nil
:content {:sticker nil
:rtl? nil
:ens-name nil
:parsed-text nil
:response-to nil
:chat-id nil
:image nil
:line-count nil
:links nil
:text nil}
:outgoing false}
:message nil
:reply-message {:quoted-message nil
:outgoing-status nil
:command-parameters nil
:content {:sticker nil
:rtl? nil
:ens-name nil
:parsed-text nil
:response-to nil
:chat-id nil
:image nil
:line-count nil
:links nil
:text nil}
:outgoing false}}
(-> raw-notification
store/<-rpc
(select-keys [:last-message :message :reply-message])))))
(testing "augments notification based on its type"
(is (= {:chat-name chat-name
:chat-type constants/private-group-chat-type
:name chat-name}
(-> raw-notification
(assoc :type notification-types/reply)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))
(testing "augments notification based on its type"
(is (= {:chat-name chat-name
:chat-type constants/private-group-chat-type
:name chat-name}
(-> raw-notification
(assoc :type notification-types/reply)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))
(is (= {:chat-name chat-name
:chat-type constants/private-group-chat-type
:name chat-name}
(-> raw-notification
(assoc :type notification-types/mention)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))
(is (= {:chat-name chat-name
:chat-type constants/private-group-chat-type
:name chat-name}
(-> raw-notification
(assoc :type notification-types/mention)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))
(is (= {:chat-name chat-name
:chat-type constants/private-group-chat-type
:group-chat true
:name chat-name
:public? false}
(-> raw-notification
(assoc :type notification-types/private-group-chat)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))
(is (= {:chat-name chat-name
:chat-type constants/private-group-chat-type
:group-chat true
:name chat-name
:public? false}
(-> raw-notification
(assoc :type notification-types/private-group-chat)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))
(is (= {:chat-name chat-name
:chat-type constants/one-to-one-chat-type
:group-chat false
:name chat-name
:public? false}
(-> raw-notification
(assoc :type notification-types/one-to-one-chat)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat])))))))
(is (= {:chat-name chat-name
:chat-type constants/one-to-one-chat-type
:group-chat false
:name chat-name
:public? false}
(-> raw-notification
(assoc :type notification-types/one-to-one-chat)
store/<-rpc
(select-keys [:name :chat-type :chat-name :public? :group-chat]))))))

View File

@ -32,7 +32,6 @@
status-im.multiaccounts.update.core
[status-im.native-module.core :as status]
[status-im2.navigation.events :as navigation]
status-im.notifications-center.core
status-im.activity-center.core
status-im.pairing.core
status-im.profile.core

View File

@ -9,7 +9,7 @@
[status-im.utils.fx :as fx]
[status-im.constants :as constants]
[status-im.i18n.i18n :as i18n]
[status-im.notifications-center.core :as notification-center]))
[status-im.activity-center.core :as activity-center]))
(fx/defn navigate-chat-updated
{:events [:navigate-chat-updated]}
@ -24,7 +24,7 @@
{:db (dissoc (:db cofx) :current-chat-id)
:dispatch-n [[:sanitize-messages-and-process-response response]
[:pop-to-root-tab :chat-stack]]}
(notification-center/get-activity-center-notifications-count)))
(activity-center/notifications-fetch-unread-count)))
(fx/defn handle-chat-update
{:events [:chat-updated]}
@ -62,8 +62,7 @@
(fx/defn create-from-link
[cofx {:keys [chat-id invitation-admin chat-name]}]
(if (get-in cofx [:db :chats chat-id])
{:dispatch-n [[:accept-all-activity-center-notifications-from-chat chat-id]
[:chat.ui/navigate-to-chat chat-id]]}
{:dispatch [:chat.ui/navigate-to-chat chat-id]}
{::json-rpc/call [{:method "wakuext_createGroupChatFromInvitation"
:params [chat-name chat-id invitation-admin]
:js-response true

View File

@ -32,7 +32,7 @@
[status-im.chat.models.link-preview :as link-preview]
[status-im.utils.mobile-sync :as utils.mobile-sync]
[status-im.async-storage.core :as async-storage]
[status-im.notifications-center.core :as notifications-center]
[status-im.activity-center.core :as activity-center]
[status-im2.navigation.events :as navigation]
[status-im.signing.eip1559 :as eip1559]
[status-im.data-store.chats :as data-store.chats]
@ -392,8 +392,8 @@
(get-node-config)
(communities/fetch)
(logging/set-log-level (:log-level multiaccount))
(notifications-center/get-activity-center-notifications)
(notifications-center/get-activity-center-notifications-count))))
(activity-center/notifications-fetch-unread-contact-requests)
(activity-center/notifications-fetch-unread-count))))
(re-frame/reg-fx
::open-last-chat

View File

@ -1,203 +0,0 @@
(ns status-im.notifications-center.core
(:require [status-im.utils.fx :as fx]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.activity-center.notification-types :as types]
[taoensso.timbre :as log]
[re-frame.core :as re-frame]
[status-im.data-store.activities :as data-store.activities]))
(def non-dismissable-notifications
#{types/contact-request
types/contact-request-retracted})
(fx/defn handle-activities [{:keys [db]} activities]
(let [{:keys [unread-count notifications]}
(reduce (fn [acc {:keys [read dismissed accepted chat-id] :as notification}]
(if (= "" chat-id)
;; TODO(rasom): sometimes messages come with empty `chat-id`s
;; (specifically it happens on `SyncActivityCenterRead` message).
;; In result, if notification is received with notification center
;; screen opened, and there is another paired device online, the
;; last notification disappear from the screen and is shown only
;; after reopening. It likely makes sense to fix it on status-go
;; side, but I got lost a bit.
acc
(let [index-existing (->> (map-indexed vector (:notifications acc))
(filter (fn [[idx {:keys [id]}]] (= id (:id notification))))
first
first)]
(as-> acc a
(if read
(update a :unread-count dec)
(update a :unread-count inc))
(if index-existing
(if (or dismissed accepted)
;; Remove at specific location
(assoc a :notifications
(into (subvec (:notifications a) 0 index-existing) (subvec (:notifications a) (inc index-existing))))
;; Replace element
(do
(assoc-in a [:notifications index-existing] notification)))
(update a :notifications conj notification))))))
{:unread-count (get db :activity.center/notifications-count 0)
:notifications (into [] (get-in db [:activity.center/notifications :notifications]))}
activities)]
(merge
{:db (-> db
(assoc-in [:activity.center/notifications :notifications] notifications)
(assoc :activity.center/notifications-count (max 0 unread-count)))}
(cond
(= (:view-id db) :notifications-center)
{:dispatch [:mark-all-activity-center-notifications-as-read]}
(= (:view-id db) :chat)
{:dispatch [:accept-all-activity-center-notifications-from-chat (:current-chat-id db)]}))))
(fx/defn get-activity-center-notifications-count
{:events [:get-activity-center-notifications-count]}
[_]
{::json-rpc/call [{:method "wakuext_unreadActivityCenterNotificationsCount"
:params []
:on-success #(re-frame/dispatch [:get-activity-center-notifications-count-success %])
:on-error #()}]})
(fx/defn get-activity-center-notifications-count-success
{:events [:get-activity-center-notifications-count-success]}
[{:keys [db]} result]
{:db (assoc db :activity.center/notifications-count result)})
(fx/defn dismiss-activity-center-notifications
{:events [:dismiss-activity-center-notifications]}
[{:keys [db]} ids]
{:db (update-in db [:activity.center/notifications :notifications]
(fn [items] (remove #(get ids (:id %)) items)))
::json-rpc/call [{:method "wakuext_dismissActivityCenterNotifications"
:params [ids]
:on-success #()
:on-error #()}]})
(fx/defn accept-activity-center-notifications
{:events [:accept-activity-center-notifications]}
[{:keys [db]} ids]
(when (seq ids)
{:db (update-in db [:activity.center/notifications :notifications]
(fn [items] (remove #(get ids (:id %)) items)))
::json-rpc/call [{:method "wakuext_acceptActivityCenterNotifications"
:params [ids]
:js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/info "unable to accept activity center notifications" %)}]}))
(fx/defn accept-all-activity-center-notifications-from-chat
{:events [:accept-all-activity-center-notifications-from-chat]}
[{:keys [db]} chat-id]
(let [notifications (get-in db [:activity.center/notifications :notifications])
notifications-from-chat (filter #(and
(= chat-id (:chat-id %))
(not (contains? non-dismissable-notifications (:type %))))
notifications)
notifications-from-chat-not-read (filter #(and (= chat-id (:chat-id %))
(not (:read %)))
notifications)
ids (into #{} (map :id notifications-from-chat))]
(when (seq ids)
{:db (-> db
(update-in [:activity.center/notifications :notifications]
(fn [items]
(filter
#(not (contains? ids (:id %)))
items)))
(update :activity.center/notifications-count - (min (db :activity.center/notifications-count) (count notifications-from-chat-not-read))))
::json-rpc/call [{:method "wakuext_acceptActivityCenterNotifications"
:params [ids]
:js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/info "unable to accept activity center notifications" %)}]})))
(fx/defn accept-activity-center-notification-and-open-chat
{:events [:accept-activity-center-notification-and-open-chat]}
[{:keys [db]} id]
{:db (update-in db [:activity.center/notifications :notifications]
(fn [items] (remove #(= id (:id %)) items)))
::json-rpc/call [{:method "wakuext_acceptActivityCenterNotifications"
:params [[id]]
:js-response true
:on-success #(re-frame/dispatch [:ensure-and-open-chat %])
:on-error #()}]})
(fx/defn ensure-and-open-chat
{:events [:ensure-and-open-chat]}
[{:keys [db]} response-js]
{:dispatch-n [[:sanitize-messages-and-process-response response-js]
[:chat.ui/navigate-to-chat (.-id (aget (.-chats response-js) 0))]]})
(fx/defn dismiss-all-activity-center-notifications
{:events [:dismiss-all-activity-center-notifications]}
[{:keys [db]}]
{:db (assoc-in db [:activity.center/notifications :notifications] [])
::json-rpc/call [{:method "wakuext_dismissAllActivityCenterNotifications"
:params []
:on-success #()
:on-error #()}]})
(fx/defn accept-all-activity-center-notifications
{:events [:accept-all-activity-center-notifications]}
[{:keys [db]}]
{:db (assoc-in db [:activity.center/notifications :notifications] [])
::json-rpc/call [{:method "wakuext_acceptAllActivityCenterNotifications"
:params []
:js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #()}]})
(fx/defn mark-all-activity-center-notifications-as-read
{:events [:mark-all-activity-center-notifications-as-read]}
[{:keys [db]}]
{:db (assoc db :activity.center/notifications-count 0)
::json-rpc/call [{:method "wakuext_markAllActivityCenterNotificationsRead"
:params []
:on-success #()
:on-error #()}]})
(fx/defn load-notifications [{:keys [db]} cursor]
(when-not (:activity.center/loading? db)
{:db (assoc db :activity.center/loading? true)
::json-rpc/call [{:method "wakuext_activityCenterNotifications"
:params [cursor 20]
:on-success #(re-frame/dispatch [:activity-center-notifications-success %])
:on-error #(re-frame/dispatch [:activity-center-notifications-error %])}]}))
(fx/defn clean-notifications [{:keys [db]}]
{:db (dissoc db :activity.center/notifications)})
(fx/defn get-activity-center-notifications
{:events [:get-activity-center-notifications]}
[{:keys [db] :as cofx}]
(let [{:keys [cursor]} (:activity.center/notifications db)]
(fx/merge cofx
(clean-notifications)
(load-notifications ""))))
(fx/defn load-more-activity-center-notifications
{:events [:load-more-activity-center-notifications]}
[{:keys [db] :as cofx}]
(let [{:keys [cursor]} (:activity.center/notifications db)]
(when (not= cursor "")
(load-notifications cofx cursor))))
(fx/defn activity-center-notifications-error
{:events [:activity-center-notifications-error]}
[{:keys [db]} error]
(log/warn "failed to load activity center notifications" error)
{:db (dissoc db :activity.center/loading?)})
(fx/defn activity-center-notifications-success
{:events [:activity-center-notifications-success]}
[{:keys [db]} {:keys [cursor notifications]}]
{:db (-> db
(dissoc :activity.center/loading?)
(assoc-in [:activity.center/notifications :cursor] cursor)
(update-in [:activity.center/notifications :notifications]
concat
(map data-store.activities/<-rpc notifications)))})

View File

@ -5,7 +5,6 @@
[status-im2.contexts.chat.messages.pin.events :as messages.pin]
[status-im.chat.models :as models.chat]
[status-im.chat.models.reactions :as models.reactions]
[status-im2.setup.config :as config]
[status-im.contact.core :as models.contact]
[status-im.communities.core :as models.communities]
[status-im.pairing.core :as models.pairing]
@ -22,7 +21,6 @@
[status-im.constants :as constants]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.multiaccounts.login.core :as multiaccounts.login]
[status-im.notifications-center.core :as notifications-center]
[status-im.visibility-status-updates.core :as models.visibility-status-updates]
[status-im.browser.core :as browser]
[clojure.string :as string]))
@ -72,13 +70,10 @@
(do
(js-delete response-js "activityCenterNotifications")
(fx/merge cofx
(if config/new-activity-center-enabled?
(->> activity-notifications
types/js->clj
(map data-store.activities/<-rpc)
activity-center/notifications-reconcile)
(notifications-center/handle-activities (map data-store.activities/<-rpc
(types/js->clj activity-notifications))))
(->> activity-notifications
types/js->clj
(map data-store.activities/<-rpc)
activity-center/notifications-reconcile)
(process-next response-js sync-handler)))
(seq installations)

View File

@ -157,8 +157,7 @@
{:on-press (fn []
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:chat.ui/navigate-to-chat-nav2 chat-id])
(rf/dispatch [:search/home-filter-changed nil])
(rf/dispatch [:accept-all-activity-center-notifications-from-chat chat-id]))
(rf/dispatch [:search/home-filter-changed nil]))
:on-long-press #(rf/dispatch [:bottom-sheet/show-sheet
{:content (fn []
[sheets/actions home-item])}])}])

View File

@ -133,8 +133,7 @@
(if config/new-ui-enabled?
(re-frame/dispatch [:chat.ui/navigate-to-chat-nav2 chat-id])
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id]))
(re-frame/dispatch [:search/home-filter-changed nil])
(re-frame/dispatch [:accept-all-activity-center-notifications-from-chat chat-id]))
(re-frame/dispatch [:search/home-filter-changed nil]))
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet
{:content (fn []
[sheets/actions home-item])}])}]
@ -150,8 +149,7 @@
(if config/new-ui-enabled?
(re-frame/dispatch [:chat.ui/navigate-to-chat-nav2 chat-id])
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id]))
(re-frame/dispatch [:search/home-filter-changed nil])
(re-frame/dispatch [:accept-all-activity-center-notifications-from-chat chat-id]))
(re-frame/dispatch [:search/home-filter-changed nil]))
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet
{:content (fn []
[sheets/actions home-item])}])}]
@ -248,18 +246,14 @@
:accessibility-label :new-chat-button}]))
(views/defview notifications-button []
(views/letsubs [notif-count [:activity.center/notifications-count]]
(views/letsubs [notif-count [:activity-center/unread-count]]
[react/view
[quo2.button/button {:type :grey
:size 32
:width 32
:style {:margin-left 12}
:accessibility-label :notifications-button
: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]))))}
:on-press #(re-frame/dispatch [:activity-center/open])}
[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})
@ -267,23 +261,6 @@
[react/view {:style styles/counter-public
:accessibility-label :notifications-unread-badge}]])]))
(views/defview notifications-button-old []
(views/letsubs [notif-count [:activity.center/notifications-count]]
[react/view
[quo/button {:type :icon
:style {:margin-left 10}
:accessibility-label "notifications-button"
:on-press #(do
(re-frame/dispatch [:mark-all-activity-center-notifications-as-read])
(re-frame/dispatch [:navigate-to :notifications-center]))
:theme :icon}
:main-icons/notification]
(when (pos? notif-count)
[react/view {:style (merge (styles/counter-public-container) {:top 5 :right 5})
:pointer-events :none}
[react/view {:style styles/counter-public
:accessibility-label :notifications-unread-badge}]])]))
(defn qr-button []
[quo2.button/button {:type :grey
:accessibility-label "qr-button"
@ -341,7 +318,6 @@
[topbar/topbar {:title (i18n/label :t/chat)
:navigation :none
:right-component [react/view {:flex-direction :row :margin-right 16}
[connectivity/connectivity-button]
[notifications-button-old]]}]
[connectivity/connectivity-button]]}]
[chats-list-old]
[plus-button-old]])

View File

@ -1,88 +0,0 @@
(ns status-im.ui.screens.notifications-center.styles
(:require [quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]))
(def notification-message-text
{:flex 1
:align-self :stretch
:line-height 22
:font-size 15})
(def notification-reply-text
{:line-height 20
:font-size 13
:color colors/text-gray})
(def mention-text
{:color colors/blue})
(def datetime-text
{:color colors/text-gray
:font-size 10
:text-align :right
:letter-spacing 0.4
:align-items :center
:line-height 12
:position :absolute
:top 17
:right 16})
(def group-info-container
(merge
{:height 22
:align-self :baseline
:align-items :center
:justify-content :center
:border-radius 11
:border-color colors/gray-transparent-40
:border-width 1
:margin-top 6
:margin-bottom 10
:flex-direction :row}
(:x-tiny spacing/padding-horizontal)))
(def reply-message-container
(merge
{:height 22
:align-self :baseline
:align-items :center
:border-radius 11
:border-color colors/gray-transparent-40
:border-width 1
:margin-top 6
:margin-bottom 10
:margin-right 15
:flex-direction :row}
(:x-tiny spacing/padding-horizontal)))
(defn notification-container [read]
{:min-height 64
:background-color (when-not read colors/blue-light)})
(def notification-content-container
{:flex 1})
(defn photo-container [has-header?]
{:position :absolute
:top (if has-header? 37 12)
:left 16})
(defn title-text [title-text-width]
{:margin-left 72
:margin-top 12
:margin-right 50
:width title-text-width})
(def notification-message-container
{:margin-left 72
:margin-right 16})
(def group-icon
{:margin-right 4})
(def reply-icon
{:margin-right 1})
(def community-info-container
{:flex-direction :row
:align-items :center})

View File

@ -1,126 +0,0 @@
(ns status-im.ui.screens.notifications-center.views
(:require [status-im.ui.components.react :as react]
[status-im.ui.components.topbar :as topbar]
[status-im.i18n.i18n :as i18n]
[status-im.ui.components.list.views :as list]
[re-frame.core :as re-frame]
[quo.core :as quo]
[quo.design-system.colors :as colors]
[reagent.core :as reagent]
[status-im.ui.components.toolbar :as toolbar]
[clojure.string :as string]
[status-im.constants :as constants]
[status-im.activity-center.notification-types :as types]
[status-im.ui.screens.notifications-center.views.notification :as notification]))
(def selecting (reagent/atom nil))
(def select-all (reagent/atom nil))
(def selected-items (reagent/atom #{}))
(defn render-fn [{:keys [id type] :as home-item}]
(when id
(let [selected (get @selected-items id)
on-change (fn []
(when-not (= type types/mention) (swap! selected-items #(if selected (disj % id) (conj % id)))))]
[react/view {:flex-direction :row :flex 1 :align-items :center}
(when (and @selecting (not (= type types/mention)))
[react/view {:padding-left 16}
[quo/checkbox {:value (or @select-all selected)
:disabled @select-all
:on-change on-change}]])
[react/view {:flex 1}
[notification/activity-text-item
home-item
{:on-press (fn []
(if @selecting
(on-change)
;; We don't dispatch on contact requests unless
;; accepted
(when (or (not= type types/contact-request)
(= constants/contact-request-message-state-accepted (get-in home-item [:message :contact-request-state])))
(re-frame/dispatch [:accept-activity-center-notification-and-open-chat id]))))
:on-long-press #(do (reset! selecting true)
(when-not (= type types/mention) (swap! selected-items conj id)))}]]])))
(defn filter-item []
[react/view {:padding-vertical 8 :border-bottom-width 1 :border-bottom-color colors/gray-lighter}
[react/view {:align-items :center :justify-content :space-between :padding-horizontal 16 :flex-direction :row}
(if @selecting
[react/view {:flex-direction :row}
[quo/checkbox {:value @select-all
:on-change #(do
(reset! selected-items #{})
(swap! select-all not))}]
[react/text {:style {:color colors/gray :margin-left 20}}
(str (if @select-all (i18n/label :t/all) (count @selected-items))
" " (string/lower-case (i18n/label :t/selected)))]]
[quo/button {:type :secondary
:accessibility-label :select-button-activity-center
:on-press #(reset! selecting true)}
(i18n/label :t/select)])
(when @selecting
[quo/button {:type :secondary
:on-press #(do (reset! selecting false)
(reset! select-all false)
(reset! selected-items #{}))}
(i18n/label :t/cancel)])]])
(defn reset-state []
(reset! selecting nil)
(reset! select-all nil)
(reset! selected-items #{}))
(defn toolbar-action [accept]
(if accept
(if @select-all
(re-frame/dispatch [:accept-all-activity-center-notifications])
(re-frame/dispatch [:accept-activity-center-notifications @selected-items]))
(if @select-all
(re-frame/dispatch [:dismiss-all-activity-center-notifications])
(re-frame/dispatch [:dismiss-activity-center-notifications @selected-items])))
(reset-state))
(defn center []
(reagent/create-class
{:display-name "activity-center"
:component-did-mount #(re-frame/dispatch [:get-activity-center-notifications])
:reagent-render
(fn []
(let [notifications @(re-frame/subscribe [:activity.center/notifications-grouped-by-date])]
[react/keyboard-avoiding-view {:style {:flex 1}
:ignore-offset true}
[topbar/topbar {:navigation {:on-press #(do
(reset-state)
(re-frame/dispatch [:navigate-back]))}
:title (i18n/label :t/activity)}]
(if (= (count notifications) 0)
[react/view {:style {:flex 1
:justify-content :center
:align-items :center}}
[quo/text {:color :secondary
:size :large
:align :center}
(i18n/label :t/empty-activity-center)]]
[:<>
[filter-item]
[list/section-list
{:key-fn #(str (:timestamp %) (or (:chat-id %) (:id %)))
:on-end-reached #(re-frame/dispatch [:load-more-activity-center-notifications])
:keyboard-should-persist-taps :always
:sections notifications
:render-fn render-fn
:stickySectionHeadersEnabled false
:render-section-header-fn
(fn [{:keys [title]}]
[quo/list-header title])}]
(when (or @select-all (> (count @selected-items) 0))
[toolbar/toolbar
{:show-border? true
:left [quo/button {:type :secondary
:theme :negative
:accessibility-label :reject-and-delete-activity-center
:on-press #(toolbar-action false)}
(i18n/label :t/reject-and-delete)]
:right [quo/button {:type :secondary
:accessibility-label :accept-and-add-activity-center
:on-press #(toolbar-action true)}
(i18n/label :t/accept-and-add)]}])])]))}))

View File

@ -1,137 +0,0 @@
(ns status-im.ui.screens.notifications-center.views.notification
(:require [status-im.ui.components.react :as react]
[re-frame.core :as re-frame]
[quo.core :as quo]
[quo.components.animated.pressable :as animation]
[status-im.i18n.i18n :as i18n]
[status-im.ui.screens.notifications-center.styles :as styles]
[status-im.utils.handlers :refer [<sub]]
[status-im.ui.screens.chat.photos :as photos]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.ui.components.icons.icons :as icons]
[status-im.constants :as constants]
[status-im.activity-center.notification-types :as types]
[quo.design-system.colors :as colors]
[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.styles :as chat-icon.styles]))
(defn contact-request-actions [request-id]
[react/view {:flex-direction :row}
[animation/pressable {:on-press #(re-frame/dispatch [:contact-requests.ui/accept-request request-id])
:accessibility-label :accept-cr}
[icons/icon :main-icons/checkmark-circle {:width 35
:height 35
:color colors/green}]]
[animation/pressable {:on-press #(re-frame/dispatch [:contact-requests.ui/decline-request request-id])
:accessibility-label :decline-cr}
[icons/icon :main-icons/cancel {:width 35
:height 35
:container-style {:margin-left 16}
:color colors/red}]]])
(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
message (or message last-message)
{:keys [community-id]} (<sub [:chat-by-id chat-id])
{:keys [name]} @(re-frame/subscribe [:communities/community community-id])
contact (when message @(re-frame/subscribe [:contacts/contact-by-identity (message :from)]))
title-text-width (* @(re-frame/subscribe [:dimensions/window-width]) 0.62)
sender (when message (first @(re-frame/subscribe [:contacts/contact-two-names-by-identity (message :from)])))]
[react/view
[react/touchable-opacity (merge {:style (styles/notification-container read)} opts)
[react/view {:style {:flex 1}}
(when (or
(= type types/contact-request)
(= type types/contact-request-retracted))
[react/view {:style {:padding-horizontal 20}}
[quo/text {:weight :bold}
(if
(= type types/contact-request)
(i18n/label :t/contact-request)
(i18n/label :t/removed-from-contacts))]])
(if (or
(= type types/mention)
(= type types/contact-request)
(= type types/reply))
[react/view {:style (styles/photo-container (= type types/contact-request))}
[photos/photo
(multiaccounts/displayed-photo contact)
{:size 40
:accessibility-label :current-account-photo}]]
[chat-icon.screen/chat-icon-view chat-id group-chat chat-name
{:container (styles/photo-container false)
:size 40
:chat-icon chat-icon.styles/chat-icon-chat-list
:default-chat-icon (chat-icon.styles/default-chat-icon-chat-list color)
:default-chat-icon-text (chat-icon.styles/default-chat-icon-text 40)
:accessibility-label :current-account-photo}])
[quo/text {:weight :medium
:color (when muted :secondary)
:accessibility-label :chat-name-or-sender-text
:ellipsize-mode :tail
:number-of-lines 1
:style (styles/title-text title-text-width)}
(if (or
(= type types/mention)
(= type types/contact-request)
(= type types/contact-request-retracted)
(= type types/reply))
sender
[home-item/chat-item-title chat-id muted group-chat chat-name])]
[react/text {:style styles/datetime-text
:number-of-lines 1
:accessibility-label :notification-time-text}
;;TODO (perf) move to event
(home-item/memo-timestamp timestamp)]
[react/view {:style styles/notification-message-container}
(when-not (= type types/contact-request-retracted)
[home-item/message-content-text (select-keys message [:content :content-type :community-id]) false])
(cond (= type types/mention)
[react/view {:style styles/group-info-container
:accessibility-label :chat-name-container}
[icons/icon
(if community-id :main-icons/tiny-community :main-icons/tiny-group)
{:color colors/gray
:width 16
:height 16
:container-style styles/group-icon}]
(when community-id
[react/view {:style styles/community-info-container}
[quo/text {:color :secondary
:weight :medium
:size :small}
name]
[icons/icon
:main-icons/chevron-right
{:color colors/gray
:width 16
:height 22}]])
[quo/text {:color :secondary
:weight :medium
:size :small}
(str (when community-id "#") chat-name)]]
(= type types/reply)
[react/view {:style styles/reply-message-container
:accessibility-label :reply-message-container}
[icons/icon
:main-icons/tiny-reply
{:color colors/gray
:width 18
:height 18
:container-style styles/reply-icon}]
[home-item/message-content-text (select-keys reply-message [:content :content-type :community-id]) false]])]]]
(when (= type types/contact-request)
[react/view {:style {:margin-right 20
:margin-top 10
:align-self :flex-end}}
(case (:contact-request-state message)
constants/contact-request-message-state-accepted
[quo/text {:style {:color colors/green}} (i18n/label :t/accepted)]
constants/contact-request-message-state-declined
[quo/text {:style {:color colors/red}} (i18n/label :t/declined)]
constants/contact-request-message-state-pending
[contact-request-actions (:message-id message)]
nil)])]))

View File

@ -74,7 +74,6 @@
[status-im.ui.screens.network.edit-network.views :as edit-network]
[status-im.ui.screens.network.network-details.views :as network-details]
[status-im.ui.screens.network.views :as network]
[status-im.ui.screens.notifications-center.views :as notifications-center]
[status-im.ui.screens.activity-center.views :as activity-center]
[status-im.ui.screens.notifications-settings.views :as notifications-settings]
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.views
@ -233,10 +232,6 @@
{:name :stickers-pack
:component stickers/pack}
{:name :notifications-center
;;TODO custom nav
:options {:topBar {:visible false}}
:component notifications-center/center}
{:name :activity-center
:options {:topBar {:visible false}}
:component activity-center/activity-center}

View File

@ -70,8 +70,7 @@
(fx/defn handle-community-chat [cofx {:keys [chat-id]}]
(log/info "universal-links: handling community chat" chat-id)
{:dispatch-n [[:accept-all-activity-center-notifications-from-chat chat-id]
[:chat.ui/navigate-to-chat chat-id]]})
{:dispatch [:chat.ui/navigate-to-chat chat-id]})
(fx/defn handle-public-chat [cofx {:keys [topic]}]
(log/info "universal-links: handling public chat" topic)

View File

@ -15,8 +15,7 @@
(if platform/android?
(rf/dispatch [:chat.ui/navigate-to-chat-nav2 chat-id])
(rf/dispatch [:chat.ui/navigate-to-chat chat-id]))
(rf/dispatch [:search/home-filter-changed nil])
(rf/dispatch [:accept-all-activity-center-notifications-from-chat chat-id]))))
(rf/dispatch [:search/home-filter-changed nil]))))
(defn action-icon [{:keys [public-key] :as item} {:keys [icon group added] :as extra-data}]
(let [{:keys [contacts]} group
@ -62,4 +61,3 @@
(utils.address/get-shortened-address public-key)]]
(when-not (= current-pk public-key)
[action-icon item extra-data])]))

View File

@ -5,15 +5,8 @@
[status-im2.common.plus-button.view :as components.plus-button]
[status-im2.common.home.style :as style]
[react-native.hole-view :as hole-view]
[status-im2.setup.config :as config]
[utils.re-frame :as rf]))
(defn navigate-to-activity-center []
(if config/new-activity-center-enabled?
(rf/dispatch [:activity-center/open])
(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
[rn/view {:flex 1}
@ -51,7 +44,7 @@
"
[{:keys [type open-profile style avatar hide-search]}]
(let [button-common-props (get-button-common-props type)
notif-count (rf/sub [:activity.center/notifications-count])
notif-count (rf/sub [:activity-center/unread-count])
new-notifications? (pos? notif-count)
notification-indicator :unread-dot
counter-label "0"]
@ -90,7 +83,7 @@
:else
[{:x 33 :y -7 :width 18 :height 18 :borderRadius 7}])}
[base-button :i/activity-center navigate-to-activity-center
[base-button :i/activity-center #(rf/dispatch [:activity-center/open])
:open-activity-center-button button-common-props]]
(when new-notifications?
(if (= notification-indicator :counter)

View File

@ -16,8 +16,7 @@
(fn []
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:chat.ui/navigate-to-chat-nav2 chat-id])
(rf/dispatch [:search/home-filter-changed nil])
(rf/dispatch [:accept-all-activity-center-notifications-from-chat chat-id])))
(rf/dispatch [:search/home-filter-changed nil])))
(defn truncate-literal [literal]
(when literal

View File

@ -1,6 +1,5 @@
(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]
@ -56,11 +55,9 @@
(defn contact-requests [requests]
[rn/touchable-opacity
{:active-opacity 1
:on-press #(do
(rf/dispatch [:bottom-sheet/show-sheet
{:content (fn [] [contact-requests-sheet requests])}])
(when-not config/new-activity-center-enabled?
(rf/dispatch [:mark-all-activity-center-notifications-as-read])))
:on-press (fn []
(rf/dispatch [:bottom-sheet/show-sheet
{:content (fn [] [contact-requests-sheet requests])}]))
: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)}]]

View File

@ -56,7 +56,7 @@
(defn tabs []
(let [selected-tab (reagent/atom :recent)]
(fn []
(let [contact-requests (rf/sub [:activity.center/notifications-contact-requests])]
(let [contact-requests (rf/sub [:activity-center/pending-contact-requests])]
[:<>
[quo/discover-card {:title (i18n/label :t/invite-friends-to-status)
:description (i18n/label :t/share-invite-link)}]

View File

@ -138,7 +138,3 @@
;;TODO for development only should be removed in status 2.0
(def new-ui-enabled? true)
;; TODO: Remove this (highly) temporary flag once the new Activity Center is
;; usable enough to replace the old one **in the new UI**.
(def new-activity-center-enabled? true)

View File

@ -1,10 +1,6 @@
(ns status-im2.subs.activity-center
(:require [re-frame.core :as re-frame]
[status-im.utils.datetime :as datetime]
[status-im.multiaccounts.core :as multiaccounts]
[status-im2.common.constants :as constants]
[status-im.activity-center.notification-types :as types]
[clojure.string :as string]))
[status-im.activity-center.notification-types :as types]))
(re-frame/reg-sub
:activity-center/notifications
@ -12,6 +8,12 @@
(fn [activity-center]
(:notifications activity-center)))
(re-frame/reg-sub
:activity-center/unread-count
:<- [:activity-center]
(fn [activity-center]
(:unread-count activity-center)))
(re-frame/reg-sub
:activity-center/filter-status
:<- [:activity-center]
@ -38,48 +40,8 @@
(fn [filter-status]
(= :unread filter-status)))
(defn- group-notifications-by-date
[notifications]
(->> notifications
(group-by #(datetime/timestamp->date-key (:timestamp %)))
(sort-by key >)
(map (fn [[date-key notifications]]
(let [first-notification (first notifications)]
{:title (string/capitalize (datetime/day-relative (:timestamp first-notification)))
:key date-key
:data (sort-by :timestamp > notifications)})))))
(re-frame/reg-sub
:activity.center/notifications-grouped-by-date
:<- [:activity.center/notifications]
:<- [:contacts/contacts]
(fn [[{:keys [notifications]} contacts]]
(let [supported-notifications
(filter (fn [{:keys [type last-message message]}]
(or (and (= types/one-to-one-chat type)
(not (nil? last-message)))
(and (= types/contact-request type)
(not= constants/contact-request-message-state-none
(-> contacts
(multiaccounts/contact-by-identity (:from message))
:contact-request-state)))
(= types/contact-request-retracted type)
(= types/private-group-chat type)
(= types/reply type)
(= types/mention type)))
notifications)]
(group-notifications-by-date
(map #(assoc %
:timestamp (or (:timestamp %) (:timestamp (or (:message %) (:last-message %))))
:contact (multiaccounts/contact-by-identity contacts (get-in % [:message :from])))
supported-notifications)))))
(re-frame/reg-sub
:activity.center/notifications-contact-requests
:<- [:activity.center/notifications-grouped-by-date]
:activity-center/pending-contact-requests
:<- [:activity-center/notifications]
(fn [notifications]
(reduce
(fn [acc {:keys [data]}]
(concat acc (filter #(= 1 (get-in % [:message :contact-request-state])) data)))
[]
notifications)))
(get-in notifications [types/contact-request :unread :data])))

View File

@ -228,8 +228,6 @@
(reg-root-key-sub :communities/enabled? :communities/enabled?)
(reg-root-key-sub :communities/resolve-community-info :communities/resolve-community-info)
(reg-root-key-sub :activity.center/notifications :activity.center/notifications)
(reg-root-key-sub :activity.center/notifications-count :activity.center/notifications-count)
(reg-root-key-sub :activity-center :activity-center)
(reg-root-key-sub :bug-report/description-error :bug-report/description-error)