2019-10-21 15:09:57 +02:00
|
|
|
(ns status-im.notifications.core
|
|
|
|
(:require [re-frame.core :as re-frame]
|
2020-05-08 18:08:53 +03:00
|
|
|
[taoensso.timbre :as log]
|
|
|
|
[status-im.utils.fx :as fx]
|
2020-06-12 10:54:28 +02:00
|
|
|
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
|
|
|
["@react-native-community/push-notification-ios" :default pn-ios]
|
2020-09-25 15:35:10 +03:00
|
|
|
[status-im.notifications.android :as pn-android]
|
2020-12-07 15:10:42 +03:00
|
|
|
[status-im.notifications.local :as local]
|
2020-06-12 10:54:28 +02:00
|
|
|
[quo.platform :as platform]
|
|
|
|
[status-im.utils.config :as config]
|
2022-02-14 17:27:33 +05:30
|
|
|
[status-im.ethereum.json-rpc :as json-rpc]
|
|
|
|
[status-im.notifications.android-remote :as pn-android-remote]))
|
2020-06-12 10:54:28 +02:00
|
|
|
|
|
|
|
(def server-type-default 1)
|
|
|
|
(def server-type-custom 2)
|
|
|
|
|
|
|
|
(def apn-token-type 1)
|
|
|
|
(def firebase-token-type 2)
|
|
|
|
(def listeners-added? (atom nil))
|
|
|
|
(defn server<-rpc [{:keys [type publicKey registered]}]
|
|
|
|
{:public-key publicKey
|
|
|
|
:type type
|
|
|
|
:registered registered})
|
|
|
|
|
|
|
|
(defn add-event-listeners []
|
|
|
|
(when-not @listeners-added?
|
|
|
|
(reset! listeners-added? true)
|
|
|
|
(.addEventListener
|
|
|
|
^js pn-ios
|
|
|
|
"register"
|
|
|
|
(fn [token]
|
2022-02-14 17:27:33 +05:30
|
|
|
(re-frame/dispatch [:notifications/registered-for-push-notifications token])))
|
2020-06-12 10:54:28 +02:00
|
|
|
(.addEventListener
|
|
|
|
^js pn-ios
|
|
|
|
"registrationError"
|
|
|
|
(fn [error]
|
2022-02-14 17:27:33 +05:30
|
|
|
(re-frame/dispatch [:notifications/switch-error true error])))))
|
2020-06-12 10:54:28 +02:00
|
|
|
|
|
|
|
(defn enable-ios-notifications []
|
|
|
|
(add-event-listeners)
|
|
|
|
(-> (.requestPermissions ^js pn-ios)
|
|
|
|
(.then #())
|
|
|
|
(.catch #())))
|
|
|
|
|
|
|
|
(defn disable-ios-notifications []
|
|
|
|
(.abandonPermissions ^js pn-ios)
|
2022-02-14 17:27:33 +05:30
|
|
|
(re-frame/dispatch [:notifications/unregistered-from-push-notifications]))
|
|
|
|
|
|
|
|
(defn enable-android-notifications [remote-push-notifications-enabled?]
|
|
|
|
(if (and remote-push-notifications-enabled? (not config/google-free))
|
|
|
|
(do
|
|
|
|
(pn-android/disable-notifications)
|
|
|
|
(pn-android/clear-all-message-notifications)
|
|
|
|
(pn-android-remote/register-remote-notifications))
|
|
|
|
(do
|
|
|
|
(pn-android-remote/unregister-remote-notifications)
|
|
|
|
(pn-android/create-channel
|
|
|
|
{:channel-id "status-im-notifications"
|
|
|
|
:channel-name "Status push notifications"})
|
|
|
|
(pn-android/enable-notifications))))
|
|
|
|
|
|
|
|
(defn disable-android-notifications []
|
|
|
|
(pn-android/disable-notifications)
|
|
|
|
(pn-android-remote/unregister-remote-notifications))
|
2019-10-21 15:09:57 +02:00
|
|
|
|
2020-05-08 18:08:53 +03:00
|
|
|
;; FIXME: Repalce with request permission from audio messages PR lib
|
|
|
|
(re-frame/reg-fx
|
|
|
|
::request-permission
|
|
|
|
identity)
|
|
|
|
|
|
|
|
(fx/defn request-permission
|
|
|
|
{:events [::request-permission]}
|
|
|
|
[_]
|
|
|
|
{::request-permission true})
|
|
|
|
|
|
|
|
(re-frame/reg-fx
|
|
|
|
::local-notification
|
2020-12-07 15:10:42 +03:00
|
|
|
(fn [props]
|
|
|
|
(if platform/ios?
|
|
|
|
(local/local-push-ios props)
|
|
|
|
(local/local-push-android props))))
|
2020-05-08 18:08:53 +03:00
|
|
|
|
2019-10-21 15:09:57 +02:00
|
|
|
(re-frame/reg-fx
|
|
|
|
::enable
|
2022-02-14 17:27:33 +05:30
|
|
|
(fn [remote-push-notifications-enabled?]
|
2020-06-12 10:54:28 +02:00
|
|
|
(if platform/android?
|
2022-02-14 17:27:33 +05:30
|
|
|
(enable-android-notifications
|
|
|
|
remote-push-notifications-enabled?)
|
2020-06-12 10:54:28 +02:00
|
|
|
(enable-ios-notifications))))
|
2019-10-21 15:09:57 +02:00
|
|
|
|
|
|
|
(re-frame/reg-fx
|
|
|
|
::disable
|
|
|
|
(fn [_]
|
2020-06-12 10:54:28 +02:00
|
|
|
(if platform/android?
|
2022-02-14 17:27:33 +05:30
|
|
|
(disable-android-notifications)
|
2020-06-12 10:54:28 +02:00
|
|
|
(disable-ios-notifications))))
|
|
|
|
|
|
|
|
(re-frame/reg-fx
|
|
|
|
::logout-disable
|
|
|
|
(fn [_]
|
|
|
|
(if platform/android?
|
2021-01-18 11:01:17 +02:00
|
|
|
(pn-android/disable-notifications)
|
2020-06-12 10:54:28 +02:00
|
|
|
(.abandonPermissions ^js pn-ios))))
|
|
|
|
|
2022-04-06 23:06:17 +05:30
|
|
|
(defn clear-all-message-notifications []
|
|
|
|
(if platform/android?
|
|
|
|
(pn-android/clear-all-message-notifications)
|
|
|
|
(.removeAllDeliveredNotifications ^js pn-ios)))
|
2021-08-19 13:36:25 +03:00
|
|
|
|
2021-11-25 21:09:10 +05:30
|
|
|
(re-frame/reg-fx
|
2022-04-06 23:06:17 +05:30
|
|
|
:clear-message-notifications
|
|
|
|
(fn [[chat-ids remote-push-notifications-enabled?]]
|
|
|
|
(if remote-push-notifications-enabled?
|
|
|
|
(clear-all-message-notifications)
|
|
|
|
(when platform/android?
|
|
|
|
(doseq [chat-id chat-ids]
|
|
|
|
(pn-android/clear-message-notifications chat-id))))))
|
2021-11-25 21:09:10 +05:30
|
|
|
|
2020-06-12 10:54:28 +02:00
|
|
|
(fx/defn handle-enable-notifications-event
|
2022-02-14 17:27:33 +05:30
|
|
|
{:events [:notifications/registered-for-push-notifications]}
|
2020-06-12 10:54:28 +02:00
|
|
|
[cofx token]
|
2020-09-14 15:36:14 +03:00
|
|
|
{::json-rpc/call [{:method (json-rpc/call-ext-method "registerForPushNotifications")
|
2020-06-12 10:54:28 +02:00
|
|
|
:params [token (if platform/ios? config/apn-topic) (if platform/ios? apn-token-type firebase-token-type)]
|
|
|
|
:on-success #(log/info "[push-notifications] register-success" %)
|
2022-02-14 17:27:33 +05:30
|
|
|
:on-error #(re-frame/dispatch [:notifications/switch-error true %])}]})
|
2020-06-12 10:54:28 +02:00
|
|
|
|
|
|
|
(fx/defn handle-disable-notifications-event
|
2022-02-14 17:27:33 +05:30
|
|
|
{:events [:notifications/unregistered-from-push-notifications]}
|
2020-06-12 10:54:28 +02:00
|
|
|
[cofx]
|
2020-09-14 15:36:14 +03:00
|
|
|
{::json-rpc/call [{:method (json-rpc/call-ext-method "unregisterFromPushNotifications")
|
2020-06-12 10:54:28 +02:00
|
|
|
:params []
|
|
|
|
:on-success #(log/info "[push-notifications] unregister-success" %)
|
2022-02-14 17:27:33 +05:30
|
|
|
:on-error #(re-frame/dispatch [:notifications/switch-error false %])}]})
|
2020-06-12 10:54:28 +02:00
|
|
|
|
|
|
|
(fx/defn logout-disable
|
|
|
|
[cofx]
|
|
|
|
(merge {::logout-disable nil}
|
2022-02-14 17:27:33 +05:30
|
|
|
{::json-rpc/call [{:method (json-rpc/call-ext-method "unregisterFromPushNotifications")
|
|
|
|
:params []
|
|
|
|
:on-success #(log/info "[push-notifications] unregister-success" %)
|
|
|
|
:on-error #(log/info "[push-notifications] unregister-error" %)}]}))
|
2020-06-12 10:54:28 +02:00
|
|
|
|
|
|
|
(fx/defn notification-switch-error
|
2022-02-14 17:27:33 +05:30
|
|
|
{:events [:notifications/switch-error]}
|
2020-06-12 10:54:28 +02:00
|
|
|
[cofx enabled?]
|
2022-02-14 17:27:33 +05:30
|
|
|
(multiaccounts.update/multiaccount-update
|
2022-03-03 15:54:33 +05:30
|
|
|
cofx :remote-push-notifications-enabled? (not enabled?) {}))
|
2020-06-12 10:54:28 +02:00
|
|
|
|
|
|
|
(fx/defn notification-switch
|
|
|
|
{:events [::switch]}
|
2022-02-14 17:27:33 +05:30
|
|
|
[{:keys [db] :as cofx} enabled? remote-push-notifications?]
|
2020-06-12 10:54:28 +02:00
|
|
|
(fx/merge cofx
|
|
|
|
(if enabled?
|
2022-02-14 17:27:33 +05:30
|
|
|
{::enable remote-push-notifications?}
|
2020-06-12 10:54:28 +02:00
|
|
|
{::disable nil})
|
2022-02-14 17:27:33 +05:30
|
|
|
(multiaccounts.update/multiaccount-update
|
|
|
|
:remote-push-notifications-enabled? (and remote-push-notifications? enabled?) {})
|
|
|
|
(multiaccounts.update/multiaccount-update
|
|
|
|
:notifications-enabled? (and (not remote-push-notifications?) enabled?) {})))
|
2020-06-12 10:54:28 +02:00
|
|
|
|
|
|
|
(fx/defn notification-non-contacts-error
|
|
|
|
{:events [::non-contacts-update-error]}
|
|
|
|
[cofx enabled?]
|
|
|
|
(multiaccounts.update/optimistic cofx :push-notifications-from-contacts-only? (not (boolean enabled?))))
|
|
|
|
|
|
|
|
(fx/defn notification-block-mentions-error
|
|
|
|
{:events [::block-mentions-update-error]}
|
|
|
|
[cofx enabled?]
|
|
|
|
(multiaccounts.update/optimistic cofx :push-notifications-block-mentions? (not (boolean enabled?))))
|
|
|
|
|
|
|
|
(fx/defn notification-non-contacts
|
|
|
|
{:events [::switch-non-contacts]}
|
|
|
|
[{:keys [db] :as cofx} enabled?]
|
|
|
|
(let [method (if enabled?
|
|
|
|
"enablePushNotificationsFromContactsOnly"
|
|
|
|
"disablePushNotificationsFromContactsOnly")]
|
|
|
|
(fx/merge cofx
|
2020-09-14 15:36:14 +03:00
|
|
|
{::json-rpc/call [{:method (json-rpc/call-ext-method method)
|
2020-06-12 10:54:28 +02:00
|
|
|
:params []
|
|
|
|
:on-success #(log/info "[push-notifications] contacts-notification-success" %)
|
|
|
|
:on-error #(re-frame/dispatch [::non-contacts-update-error enabled? %])}]}
|
|
|
|
|
|
|
|
(multiaccounts.update/optimistic :push-notifications-from-contacts-only? (boolean enabled?)))))
|
|
|
|
|
|
|
|
(fx/defn notification-block-mentions
|
|
|
|
{:events [::switch-block-mentions]}
|
|
|
|
[{:keys [db] :as cofx} enabled?]
|
|
|
|
(let [method (if enabled?
|
|
|
|
"enablePushNotificationsBlockMentions"
|
|
|
|
"disablePushNotificationsBlockMentions")]
|
|
|
|
(log/info "USING METHOD" method enabled?)
|
|
|
|
(fx/merge cofx
|
2020-09-14 15:36:14 +03:00
|
|
|
{::json-rpc/call [{:method (json-rpc/call-ext-method method)
|
2020-06-12 10:54:28 +02:00
|
|
|
:params []
|
|
|
|
:on-success #(log/info "[push-notifications] block-mentions-success" %)
|
|
|
|
:on-error #(re-frame/dispatch [::block-mentions-update-error enabled? %])}]}
|
|
|
|
|
|
|
|
(multiaccounts.update/optimistic :push-notifications-block-mentions? (boolean enabled?)))))
|
|
|
|
|
|
|
|
(fx/defn switch-push-notifications-server-enabled
|
|
|
|
{:events [::switch-push-notifications-server-enabled]}
|
|
|
|
[{:keys [db] :as cofx} enabled?]
|
|
|
|
(let [method (if enabled?
|
|
|
|
"startPushNotificationsServer"
|
|
|
|
"stopPushNotificationsServer")]
|
|
|
|
(fx/merge cofx
|
2020-09-14 15:36:14 +03:00
|
|
|
{::json-rpc/call [{:method (json-rpc/call-ext-method method)
|
2020-06-12 10:54:28 +02:00
|
|
|
:params []
|
|
|
|
:on-success #(log/info "[push-notifications] switch-server-enabled successful" %)
|
|
|
|
:on-error #(re-frame/dispatch [::push-notifications-server-update-error enabled? %])}]}
|
|
|
|
|
|
|
|
(multiaccounts.update/optimistic :push-notifications-server-enabled? (boolean enabled?)))))
|
|
|
|
|
|
|
|
(fx/defn switch-send-notifications
|
|
|
|
{:events [::switch-send-push-notifications]}
|
|
|
|
[{:keys [db] :as cofx} enabled?]
|
|
|
|
(let [method (if enabled?
|
|
|
|
"enableSendingNotifications"
|
|
|
|
"disableSendingNotifications")]
|
|
|
|
(fx/merge cofx
|
2020-09-14 15:36:14 +03:00
|
|
|
{::json-rpc/call [{:method (json-rpc/call-ext-method method)
|
2020-06-12 10:54:28 +02:00
|
|
|
:params []
|
|
|
|
:on-success #(log/info "[push-notifications] switch-send-notifications successful" %)
|
|
|
|
:on-error #(re-frame/dispatch [::push-notifications-send-update-error enabled? %])}]}
|
|
|
|
|
|
|
|
(multiaccounts.update/optimistic :send-push-notifications? (boolean enabled?)))))
|
|
|
|
|
|
|
|
(fx/defn handle-add-server-error
|
|
|
|
{:events [::push-notifications-add-server-error]}
|
|
|
|
[_ public-key error]
|
|
|
|
(log/error "failed to add server", public-key, error))
|
|
|
|
|
|
|
|
(fx/defn add-server
|
|
|
|
{:events [::add-server]}
|
|
|
|
[{:keys [db] :as cofx} public-key]
|
|
|
|
(fx/merge cofx
|
2020-09-14 15:36:14 +03:00
|
|
|
{::json-rpc/call [{:method (json-rpc/call-ext-method "addPushNotificationsServer")
|
2020-06-12 10:54:28 +02:00
|
|
|
:params [public-key]
|
|
|
|
:on-success #(do
|
|
|
|
(log/info "[push-notifications] switch-send-notifications successful" %)
|
|
|
|
(re-frame/dispatch [::fetch-servers]))
|
|
|
|
:on-error #(re-frame/dispatch [::push-notifications-add-server-error public-key %])}]}))
|
|
|
|
|
|
|
|
(fx/defn handle-servers-fetched
|
|
|
|
{:events [::servers-fetched]}
|
|
|
|
[{:keys [db]} servers]
|
|
|
|
{:db (assoc db :push-notifications/servers (map server<-rpc servers))})
|
|
|
|
|
|
|
|
(fx/defn fetch-push-notifications-servers
|
|
|
|
{:events [::fetch-servers]}
|
|
|
|
[cofx]
|
2020-09-14 15:36:14 +03:00
|
|
|
{::json-rpc/call [{:method (json-rpc/call-ext-method "getPushNotificationsServers")
|
2020-06-12 10:54:28 +02:00
|
|
|
:params []
|
|
|
|
:on-success #(do
|
|
|
|
(log/info "[push-notifications] servers fetched" %)
|
|
|
|
(re-frame/dispatch [::servers-fetched %]))}]})
|
2020-09-25 15:35:10 +03:00
|
|
|
|
|
|
|
;; Wallet transactions
|
|
|
|
|
|
|
|
(fx/defn handle-preferences-load
|
|
|
|
{:events [::preferences-loaded]}
|
|
|
|
[{:keys [db]} preferences]
|
|
|
|
{:db (assoc db :push-notifications/preferences preferences)})
|
|
|
|
|
|
|
|
(fx/defn load-notification-preferences
|
|
|
|
{:events [::load-notification-preferences]}
|
|
|
|
[cofx]
|
|
|
|
{::json-rpc/call [{:method "localnotifications_notificationPreferences"
|
|
|
|
:params []
|
|
|
|
:on-success #(re-frame/dispatch [::preferences-loaded %])}]})
|
|
|
|
|
|
|
|
(defn preference= [x y]
|
|
|
|
(and (= (:service x) (:service y))
|
|
|
|
(= (:event x) (:event y))
|
|
|
|
(= (:identifier x) (:identifier y))))
|
|
|
|
|
|
|
|
(defn- update-preference [all new]
|
|
|
|
(conj (filter (comp not (partial preference= new)) all) new))
|
|
|
|
|
|
|
|
(fx/defn switch-transaction-notifications
|
|
|
|
{:events [::switch-transaction-notifications]}
|
|
|
|
[{:keys [db] :as cofx} enabled?]
|
|
|
|
{:db (update db :push-notifications/preferences update-preference {:enabled (not enabled?)
|
|
|
|
:service "wallet"
|
|
|
|
:event "transaction"
|
|
|
|
:identifier "all"})
|
|
|
|
::json-rpc/call [{:method "localnotifications_switchWalletNotifications"
|
|
|
|
:params [(not enabled?)]
|
|
|
|
:on-success #(log/info "[push-notifications] switch-transaction-notifications successful" %)
|
|
|
|
:on-error #(log/error "[push-notifications] switch-transaction-notifications error" %)}]})
|