parent
edd6b8d62c
commit
ca88de162a
|
@ -323,7 +323,11 @@
|
|||
|
||||
(def react-native-permissions #js {:default #js {}})
|
||||
|
||||
(def push-notification-ios #js {:default #js {:abandonPermissions identity}})
|
||||
(def push-notification-ios
|
||||
#js
|
||||
{:default #js
|
||||
{:abandonPermissions identity
|
||||
:removeAllDeliveredNotifications identity}})
|
||||
|
||||
(def rn-emoji-keyboard
|
||||
#js {:EmojiKeyboard #js {}})
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
[utils.validators :as validators]
|
||||
[taoensso.timbre :as log]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.core :as rn]
|
||||
[utils.transforms :as types]
|
||||
[clojure.string :as string]))
|
||||
|
||||
|
@ -14,7 +13,7 @@
|
|||
|
||||
(defn init
|
||||
[handler]
|
||||
(.addListener ^js rn/device-event-emitter "gethEvent" #(handler (.-jsonEvent ^js %))))
|
||||
(.addListener ^js (.-DeviceEventEmitter ^js react-native) "gethEvent" #(handler (.-jsonEvent ^js %))))
|
||||
|
||||
(defn clear-web-data
|
||||
[]
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
(ns native-module.push-notifications
|
||||
(:require ["react-native" :as react-native]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn push-notification
|
||||
[]
|
||||
(when (exists? (.-NativeModules react-native))
|
||||
(.-PushNotification ^js (.-NativeModules react-native))))
|
||||
|
||||
(defn present-local-notification
|
||||
[opts]
|
||||
(.presentLocalNotification ^js (push-notification) (clj->js opts)))
|
||||
|
||||
(defn clear-message-notifications
|
||||
[chat-id]
|
||||
(.clearMessageNotifications ^js (push-notification) chat-id))
|
||||
|
||||
(defn clear-all-message-notifications
|
||||
[]
|
||||
(.clearAllMessageNotifications ^js (push-notification)))
|
||||
|
||||
(defn create-channel
|
||||
[{:keys [channel-id channel-name]}]
|
||||
(.createChannel ^js (push-notification)
|
||||
#js {:channelId channel-id :channelName channel-name}
|
||||
#(log/info "Notifications create channel:" %)))
|
||||
|
||||
(defn enable-notifications
|
||||
[]
|
||||
(.enableNotifications ^js (push-notification)))
|
||||
|
||||
(defn disable-notifications
|
||||
[]
|
||||
(.disableNotifications ^js (push-notification)))
|
||||
|
||||
(defn add-listener
|
||||
[event callback]
|
||||
(.addListener ^js (.-DeviceEventEmitter ^js react-native)
|
||||
event
|
||||
(fn [^js data]
|
||||
(when (and data (.-dataJSON data) callback)
|
||||
(callback (.-dataJSON data))))))
|
|
@ -0,0 +1,24 @@
|
|||
(ns react-native.push-notification-ios
|
||||
(:require ["@react-native-community/push-notification-ios" :default pn-ios]))
|
||||
|
||||
(defn present-local-notification
|
||||
[title message user-info]
|
||||
(.presentLocalNotification ^js pn-ios #js {:alertBody message :alertTitle title :userInfo user-info}))
|
||||
|
||||
(defn add-listener
|
||||
[event callback]
|
||||
(.addEventListener ^js pn-ios event callback))
|
||||
|
||||
(defn request-permissions
|
||||
[]
|
||||
(-> (.requestPermissions ^js pn-ios)
|
||||
(.then #())
|
||||
(.catch #())))
|
||||
|
||||
(defn abandon-permissions
|
||||
[]
|
||||
(.abandonPermissions ^js pn-ios))
|
||||
|
||||
(defn remove-all-delivered-notifications
|
||||
[]
|
||||
(.removeAllDeliveredNotifications ^js pn-ios))
|
|
@ -84,23 +84,25 @@
|
|||
{:events [:chat.ui/mark-all-read-pressed :chat/mark-all-as-read]}
|
||||
[{db :db} chat-id]
|
||||
{:db (mark-chat-all-read db chat-id)
|
||||
:clear-message-notifications [[chat-id]
|
||||
(get-in db [:profile/profile :remote-push-notifications-enabled?])]
|
||||
:effects/push-notifications-clear-message-notifications [chat-id]
|
||||
:json-rpc/call [{:method "wakuext_markAllRead"
|
||||
:params [chat-id]
|
||||
:on-success #(re-frame/dispatch [::mark-all-read-successful])}]})
|
||||
:on-success
|
||||
#(re-frame/dispatch
|
||||
[::mark-all-read-successful])}]})
|
||||
|
||||
(rf/defn handle-mark-mark-all-read-in-community
|
||||
{:events [:chat.ui/mark-all-read-in-community-pressed]}
|
||||
[{db :db} community-id]
|
||||
(let [community-chat-ids (map #(str community-id %)
|
||||
(keys (get-in db [:communities community-id :chats])))]
|
||||
{:clear-message-notifications [community-chat-ids
|
||||
(get-in db [:profile/profile :remote-push-notifications-enabled?])]
|
||||
{:effects/push-notifications-clear-message-notifications community-chat-ids
|
||||
:json-rpc/call [{:method "wakuext_markAllReadInCommunity"
|
||||
:params [community-id]
|
||||
:on-success #(re-frame/dispatch
|
||||
[::mark-all-read-in-community-successful %])}]}))
|
||||
:on-success
|
||||
#(re-frame/dispatch
|
||||
[::mark-all-read-in-community-successful
|
||||
%])}]}))
|
||||
|
||||
(rf/defn messages-loaded
|
||||
"Loads more messages for current chat"
|
||||
|
|
|
@ -271,18 +271,20 @@
|
|||
[{:keys [db]} community-id]
|
||||
(let [community-chat-ids (map #(str community-id %)
|
||||
(keys (get-in db [:communities community-id :chats])))]
|
||||
{:clear-message-notifications [community-chat-ids
|
||||
(get-in db [:profile/profile :remote-push-notifications-enabled?])]
|
||||
{:effects/push-notifications-clear-message-notifications community-chat-ids
|
||||
:dispatch [:shell/close-switcher-card community-id]
|
||||
:json-rpc/call [{:method "wakuext_leaveCommunity"
|
||||
:params [community-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [::left %])
|
||||
:on-success #(re-frame/dispatch [::left
|
||||
%])
|
||||
:on-error (fn [response]
|
||||
(log/error "failed to leave community"
|
||||
(log/error
|
||||
"failed to leave community"
|
||||
community-id
|
||||
response)
|
||||
(re-frame/dispatch [::failed-to-leave]))}]}))
|
||||
(re-frame/dispatch
|
||||
[::failed-to-leave]))}]}))
|
||||
|
||||
(rf/defn status-tag-pressed
|
||||
{:events [:communities/status-tag-pressed]}
|
||||
|
|
|
@ -41,15 +41,18 @@
|
|||
(map #(->> (chats-store/<-rpc %)
|
||||
(clean-up-chat public-key))
|
||||
(types/js->clj chats-js)))]
|
||||
(apply rf/merge
|
||||
(apply
|
||||
rf/merge
|
||||
cofx
|
||||
{:db (-> db
|
||||
{:db (->
|
||||
db
|
||||
(update :chats dissoc public-key)
|
||||
(update :chats-home-list disj public-key)
|
||||
(assoc-in [:contacts/contacts public-key :added?] false))
|
||||
(assoc-in [:contacts/contacts public-key
|
||||
:added?]
|
||||
false))
|
||||
:dispatch [:shell/close-switcher-card public-key]
|
||||
:clear-message-notifications
|
||||
[[public-key] (get-in db [:profile/profile :remote-push-notifications-enabled?])]}
|
||||
:effects/push-notifications-clear-message-notifications [public-key]}
|
||||
(activity-center/notifications-fetch-unread-count)
|
||||
fxs)))
|
||||
|
||||
|
|
|
@ -60,7 +60,8 @@
|
|||
status-im2.contexts.chat.home.events
|
||||
status-im2.contexts.communities.home.events
|
||||
status-im.ui.components.invite.events
|
||||
[status-im2.common.biometric.events :as biometric]))
|
||||
[status-im2.common.biometric.events :as biometric]
|
||||
status-im.ui.screens.notifications-settings.events))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:dismiss-keyboard
|
||||
|
|
|
@ -165,7 +165,6 @@
|
|||
:dapps-address (:address wallet-account)
|
||||
:latest-derived-path 0
|
||||
:signing-phrase signing-phrase
|
||||
:send-push-notifications? true
|
||||
:backup-enabled? true
|
||||
:installation-id (random-guid-generator)
|
||||
;; default mailserver (history node) setting
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
(:require [native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.notifications.core :as notifications]
|
||||
[status-im.wallet.core :as wallet]
|
||||
[status-im2.common.keychain.events :as keychain]
|
||||
[status-im2.db :as db]
|
||||
|
@ -46,14 +45,13 @@
|
|||
(rf/defn logout
|
||||
{:events [:logout :multiaccounts.logout.ui/logout-confirmed
|
||||
:multiaccounts.update.callback/save-settings-success]}
|
||||
[cofx]
|
||||
[_]
|
||||
;; we need to disable notifications before starting the logout process
|
||||
(rf/merge cofx
|
||||
{:dispatch-later [{:ms 100
|
||||
{:effects/push-notifications-disable nil
|
||||
:dispatch-later [{:ms 100
|
||||
:dispatch [::logout-method
|
||||
{:auth-method keychain/auth-method-none
|
||||
:logout? true}]}]}
|
||||
(notifications/logout-disable)))
|
||||
:logout? true}]}]})
|
||||
|
||||
(rf/defn show-logout-confirmation
|
||||
{:events [:multiaccounts.logout.ui/logout-pressed]}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
(ns status-im.notifications.android
|
||||
(:require ["react-native" :as react-native]
|
||||
[quo.platform :as platform]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn pn-android
|
||||
[]
|
||||
(when platform/android?
|
||||
(.-PushNotification ^js (.-NativeModules react-native))))
|
||||
|
||||
(defn present-local-notification
|
||||
[opts]
|
||||
(.presentLocalNotification ^js (pn-android) (clj->js opts)))
|
||||
|
||||
(defn clear-message-notifications
|
||||
[chat-id]
|
||||
(.clearMessageNotifications ^js (pn-android) chat-id))
|
||||
|
||||
(defn clear-all-message-notifications
|
||||
[]
|
||||
(.clearAllMessageNotifications ^js (pn-android)))
|
||||
|
||||
(defn create-channel
|
||||
[{:keys [channel-id channel-name]}]
|
||||
(.createChannel ^js (pn-android)
|
||||
#js
|
||||
{:channelId channel-id
|
||||
:channelName channel-name}
|
||||
#(log/info "Notifications create channel:" %)))
|
||||
|
||||
(defn enable-notifications
|
||||
[]
|
||||
(.enableNotifications ^js (pn-android)))
|
||||
|
||||
(defn disable-notifications
|
||||
[]
|
||||
(.disableNotifications ^js (pn-android)))
|
|
@ -1,313 +0,0 @@
|
|||
(ns status-im.notifications.core
|
||||
(:require ["@react-native-community/push-notification-ios" :default pn-ios]
|
||||
[quo.platform :as platform]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.notifications.android :as pn-android]
|
||||
[status-im.notifications.local :as local]
|
||||
[status-im2.config :as config]
|
||||
[utils.re-frame :as rf]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(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]
|
||||
(re-frame/dispatch [:notifications/registered-for-push-notifications token])))
|
||||
(.addEventListener
|
||||
^js pn-ios
|
||||
"registrationError"
|
||||
(fn [error]
|
||||
(re-frame/dispatch [:notifications/switch-error true error])))))
|
||||
|
||||
(defn enable-ios-notifications
|
||||
[]
|
||||
(add-event-listeners)
|
||||
(-> (.requestPermissions ^js pn-ios)
|
||||
(.then #())
|
||||
(.catch #())))
|
||||
|
||||
(defn disable-ios-notifications
|
||||
[]
|
||||
(.abandonPermissions ^js pn-ios)
|
||||
(re-frame/dispatch [:notifications/unregistered-from-push-notifications]))
|
||||
|
||||
(defn enable-android-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))
|
||||
|
||||
;; FIXME: Repalce with request permission from audio messages PR lib
|
||||
(re-frame/reg-fx
|
||||
::request-permission
|
||||
identity)
|
||||
|
||||
(rf/defn request-permission
|
||||
{:events [::request-permission]}
|
||||
[_]
|
||||
{::request-permission true})
|
||||
|
||||
(re-frame/reg-fx
|
||||
::local-notification
|
||||
(fn [props]
|
||||
(if platform/ios?
|
||||
(local/local-push-ios props)
|
||||
(local/local-push-android props))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::enable
|
||||
(fn []
|
||||
(if platform/android?
|
||||
(enable-android-notifications)
|
||||
(enable-ios-notifications))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::disable
|
||||
(fn [_]
|
||||
(if platform/android?
|
||||
(disable-android-notifications)
|
||||
(disable-ios-notifications))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::logout-disable
|
||||
(fn [_]
|
||||
(if platform/android?
|
||||
(pn-android/disable-notifications)
|
||||
(.abandonPermissions ^js pn-ios))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:clear-message-notifications
|
||||
(fn [[chat-ids] remote-push-notifications-enabled?]
|
||||
(if remote-push-notifications-enabled?
|
||||
(if platform/android?
|
||||
(pn-android/clear-all-message-notifications)
|
||||
(.removeAllDeliveredNotifications ^js pn-ios))
|
||||
(when platform/android?
|
||||
(doseq [chat-id chat-ids]
|
||||
(pn-android/clear-message-notifications chat-id))))))
|
||||
|
||||
(rf/defn handle-enable-notifications-event
|
||||
{:events [:notifications/registered-for-push-notifications]}
|
||||
[cofx token]
|
||||
{:json-rpc/call [{:method "wakuext_registerForPushNotifications"
|
||||
: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" %)
|
||||
:on-error #(re-frame/dispatch [:notifications/switch-error true %])}]})
|
||||
|
||||
(rf/defn handle-disable-notifications-event
|
||||
{:events [:notifications/unregistered-from-push-notifications]}
|
||||
[cofx]
|
||||
{:json-rpc/call [{:method "wakuext_unregisterFromPushNotifications"
|
||||
:params []
|
||||
:on-success #(log/info "[push-notifications] unregister-success" %)
|
||||
:on-error #(re-frame/dispatch [:notifications/switch-error false %])}]})
|
||||
|
||||
(rf/defn logout-disable
|
||||
[cofx]
|
||||
(merge {::logout-disable nil}
|
||||
{:json-rpc/call [{:method "wakuext_unregisterFromPushNotifications"
|
||||
:params []
|
||||
:on-success #(log/info "[push-notifications] unregister-success" %)
|
||||
:on-error #(log/info "[push-notifications] unregister-error" %)}]}))
|
||||
|
||||
(rf/defn notification-switch-error
|
||||
{:events [:notifications/switch-error]}
|
||||
[cofx enabled?]
|
||||
(multiaccounts.update/multiaccount-update
|
||||
cofx
|
||||
:remote-push-notifications-enabled?
|
||||
(not enabled?)
|
||||
{}))
|
||||
|
||||
(rf/defn notification-switch
|
||||
{:events [::switch]}
|
||||
[{:keys [db] :as cofx} enabled? remote-push-notifications?]
|
||||
(rf/merge cofx
|
||||
(if enabled?
|
||||
{::enable remote-push-notifications?}
|
||||
{::disable nil})
|
||||
(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?)
|
||||
{})))
|
||||
|
||||
(rf/defn notification-non-contacts-error
|
||||
{:events [::non-contacts-update-error]}
|
||||
[cofx enabled?]
|
||||
(multiaccounts.update/optimistic cofx
|
||||
:push-notifications-from-contacts-only?
|
||||
(not (boolean enabled?))))
|
||||
|
||||
(rf/defn notification-block-mentions-error
|
||||
{:events [::block-mentions-update-error]}
|
||||
[cofx enabled?]
|
||||
(multiaccounts.update/optimistic cofx :push-notifications-block-mentions? (not (boolean enabled?))))
|
||||
|
||||
(rf/defn notification-non-contacts
|
||||
{:events [::switch-non-contacts]}
|
||||
[{:keys [db] :as cofx} enabled?]
|
||||
(let [method (if enabled?
|
||||
"wakuext_enablePushNotificationsFromContactsOnly"
|
||||
"wakuext_disablePushNotificationsFromContactsOnly")]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:json-rpc/call [{:method method
|
||||
: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?)))))
|
||||
|
||||
(rf/defn notification-block-mentions
|
||||
{:events [::switch-block-mentions]}
|
||||
[{:keys [db] :as cofx} enabled?]
|
||||
(let [method (if enabled?
|
||||
"wakuext_enablePushNotificationsBlockMentions"
|
||||
"wakuext_disablePushNotificationsBlockMentions")]
|
||||
(log/info "USING METHOD" method enabled?)
|
||||
(rf/merge cofx
|
||||
{:json-rpc/call [{:method method
|
||||
: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?)))))
|
||||
|
||||
(rf/defn switch-push-notifications-server-enabled
|
||||
{:events [::switch-push-notifications-server-enabled]}
|
||||
[{:keys [db] :as cofx} enabled?]
|
||||
(let [method (if enabled?
|
||||
"wakuext_startPushNotificationsServer"
|
||||
"wakuext_stopPushNotificationsServer")]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:json-rpc/call [{:method method
|
||||
: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?)))))
|
||||
|
||||
(rf/defn switch-send-notifications
|
||||
{:events [::switch-send-push-notifications]}
|
||||
[{:keys [db] :as cofx} enabled?]
|
||||
(let [method (if enabled?
|
||||
"wakuext_enableSendingNotifications"
|
||||
"wakuext_disableSendingNotifications")]
|
||||
(rf/merge cofx
|
||||
{:json-rpc/call [{:method method
|
||||
: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?)))))
|
||||
|
||||
(rf/defn handle-add-server-error
|
||||
{:events [::push-notifications-add-server-error]}
|
||||
[_ public-key error]
|
||||
(log/error "failed to add server" public-key error))
|
||||
|
||||
(rf/defn add-server
|
||||
{:events [::add-server]}
|
||||
[{:keys [db] :as cofx} public-key]
|
||||
(rf/merge cofx
|
||||
{:json-rpc/call [{:method "wakuext_addPushNotificationsServer"
|
||||
: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 %])}]}))
|
||||
|
||||
(rf/defn handle-servers-fetched
|
||||
{:events [::servers-fetched]}
|
||||
[{:keys [db]} servers]
|
||||
{:db (assoc db :push-notifications/servers (map server<-rpc servers))})
|
||||
|
||||
(rf/defn fetch-push-notifications-servers
|
||||
{:events [::fetch-servers]}
|
||||
[cofx]
|
||||
{:json-rpc/call [{:method "wakuext_getPushNotificationsServers"
|
||||
:params []
|
||||
:on-success #(do
|
||||
(log/info "[push-notifications] servers fetched" %)
|
||||
(re-frame/dispatch [::servers-fetched %]))}]})
|
||||
|
||||
;; Wallet transactions
|
||||
|
||||
(rf/defn handle-preferences-load
|
||||
{:events [::preferences-loaded]}
|
||||
[{:keys [db]} preferences]
|
||||
{:db (assoc db :push-notifications/preferences preferences)})
|
||||
|
||||
(rf/defn load-notification-preferences
|
||||
{:events [::load-notification-preferences]}
|
||||
[_]
|
||||
{: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-preference]
|
||||
(conj (filter (comp not (partial preference= new-preference))
|
||||
all)
|
||||
new-preference))
|
||||
|
||||
(rf/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"
|
||||
%)}]})
|
|
@ -1,150 +0,0 @@
|
|||
(ns status-im.notifications.local
|
||||
(:require ["@react-native-community/push-notification-ios" :default pn-ios]
|
||||
[cljs-bean.core :as bean]
|
||||
[clojure.string :as string]
|
||||
[quo.platform :as platform]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.async-storage :as async-storage]
|
||||
[status-im.ethereum.decode :as decode]
|
||||
[status-im.ethereum.tokens :as tokens]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.notifications.android :as pn-android]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.money :as money]
|
||||
[status-im.utils.deprecated-types :as types]
|
||||
[status-im.utils.utils :as utils]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def default-erc20-token
|
||||
{:symbol :ERC20
|
||||
:decimals 18
|
||||
:name "ERC20"})
|
||||
|
||||
(def notification-event-ios "localNotification")
|
||||
(def notification-event-android "remoteNotificationReceived")
|
||||
|
||||
(defn local-push-ios
|
||||
[{:keys [title message user-info body-type]}]
|
||||
(when (not= body-type "message")
|
||||
(.presentLocalNotification
|
||||
pn-ios
|
||||
#js
|
||||
{:alertBody message
|
||||
:alertTitle title
|
||||
;; NOTE: Use a special type to hide in Obj-C code other notifications
|
||||
:userInfo (bean/->js (merge user-info
|
||||
{:notificationType "local-notification"}))})))
|
||||
|
||||
(defn local-push-android
|
||||
[notification]
|
||||
(pn-android/present-local-notification notification))
|
||||
|
||||
(defn handle-notification-press
|
||||
[{{deep-link :deepLink} :userInfo
|
||||
interaction :userInteraction}]
|
||||
(async-storage/set-item! (str :chat-id) nil)
|
||||
(when (and deep-link
|
||||
(or platform/ios?
|
||||
(and platform/android? interaction)))
|
||||
(re-frame/dispatch [:universal-links/handle-url deep-link])))
|
||||
|
||||
(defn listen-notifications
|
||||
[]
|
||||
(if platform/ios?
|
||||
(.addEventListener ^js pn-ios
|
||||
notification-event-ios
|
||||
(fn [notification]
|
||||
(handle-notification-press {:userInfo (bean/bean (.getData ^js
|
||||
notification))})))
|
||||
(.addListener ^js rn/device-event-emitter
|
||||
notification-event-android
|
||||
(fn [^js data]
|
||||
(when (and data (.-dataJSON data))
|
||||
(handle-notification-press (types/json->clj (.-dataJSON data))))))))
|
||||
|
||||
(defn create-transfer-notification
|
||||
[{db :db}
|
||||
{{:keys [state from to fromAccount toAccount value erc20 contract network]}
|
||||
:body
|
||||
:as notification}]
|
||||
(let [token (if erc20
|
||||
(get-in db
|
||||
[:wallet/all-tokens (string/lower-case contract)]
|
||||
default-erc20-token)
|
||||
(tokens/native-currency network))
|
||||
amount (money/wei->ether (decode/uint value))
|
||||
to (or (:name toAccount) (utils/get-shortened-address to))
|
||||
from (or (:name fromAccount) (utils/get-shortened-address from))
|
||||
title (case state
|
||||
"inbound" (i18n/label :t/push-inbound-transaction
|
||||
{:value amount
|
||||
:currency (:symbol token)})
|
||||
"outbound" (i18n/label :t/push-outbound-transaction
|
||||
{:value amount
|
||||
:currency (:symbol token)})
|
||||
"failed" (i18n/label :t/push-failed-transaction
|
||||
{:value amount
|
||||
:currency (:symbol token)})
|
||||
nil)
|
||||
description (case state
|
||||
"inbound" (i18n/label :t/push-inbound-transaction-body
|
||||
{:from from
|
||||
:to to})
|
||||
"outbound" (i18n/label :t/push-outbound-transaction-body
|
||||
{:from from
|
||||
:to to})
|
||||
"failed" (i18n/label :t/push-failed-transaction-body
|
||||
{:value amount
|
||||
:currency (:symbol token)
|
||||
:to to})
|
||||
nil)]
|
||||
{:title title
|
||||
:icon (get-in token [:icon :source])
|
||||
:deepLink (:deepLink notification)
|
||||
:user-info notification
|
||||
:message description}))
|
||||
|
||||
(defn foreground-chat?
|
||||
[{{:keys [current-chat-id view-id]} :db} chat-id]
|
||||
(and (= current-chat-id chat-id)
|
||||
(= view-id :chat)))
|
||||
|
||||
(defn show-message-pn?
|
||||
[{{:keys [app-state profile/profile]} :db :as cofx}
|
||||
notification]
|
||||
(let [chat-id (get-in notification [:body :chat :id])
|
||||
notification-author (get-in notification [:notificationAuthor :id])]
|
||||
(and
|
||||
(not= notification-author (:public-key profile))
|
||||
(or (= app-state "background")
|
||||
(not (foreground-chat? cofx chat-id))))))
|
||||
|
||||
(defn create-notification
|
||||
([notification]
|
||||
(create-notification nil notification))
|
||||
([cofx {:keys [bodyType] :as notification}]
|
||||
(assoc
|
||||
(case bodyType
|
||||
"message" (when (show-message-pn? cofx notification) notification)
|
||||
"transaction" (create-transfer-notification cofx notification)
|
||||
nil)
|
||||
:body-type
|
||||
bodyType)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::local-push-ios
|
||||
(fn [evt]
|
||||
(-> evt create-notification local-push-ios)))
|
||||
|
||||
(rf/defn local-notification-android
|
||||
{:events [::local-notification-android]}
|
||||
[cofx event]
|
||||
(some->> event
|
||||
(create-notification cofx)
|
||||
local-push-android))
|
||||
|
||||
(rf/defn process
|
||||
[cofx evt]
|
||||
(if platform/ios?
|
||||
{::local-push-ios evt}
|
||||
(local-notification-android cofx evt)))
|
|
@ -0,0 +1,83 @@
|
|||
(ns status-im.notifications.wallet
|
||||
(:require [utils.re-frame :as rf]
|
||||
[taoensso.timbre :as log]
|
||||
[clojure.string :as string]
|
||||
[status-im.ethereum.tokens :as tokens]
|
||||
[utils.money :as money]
|
||||
[status-im.ethereum.decode :as decode]
|
||||
[status-im.utils.utils :as utils]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(def default-erc20-token
|
||||
{:symbol :ERC20
|
||||
:decimals 18
|
||||
:name "ERC20"})
|
||||
|
||||
(defn preference=
|
||||
[x y]
|
||||
(and (= (:service x) (:service y))
|
||||
(= (:event x) (:event y))
|
||||
(= (:identifier x) (:identifier y))))
|
||||
|
||||
(defn- update-preference
|
||||
[all new-preference]
|
||||
(conj (filter (comp not (partial preference= new-preference))
|
||||
all)
|
||||
new-preference))
|
||||
|
||||
(rf/defn switch-transaction-notifications
|
||||
{:events [:push-notifications.wallet/switch-transactions]}
|
||||
[{:keys [db]} enabled?]
|
||||
{:db (update db
|
||||
:push-notifications/preferences
|
||||
update-preference
|
||||
{:enabled? enabled?
|
||||
:service "wallet"
|
||||
:event "transaction"
|
||||
:identifier "all"})
|
||||
:json-rpc/call [{:method "localnotifications_switchWalletNotifications"
|
||||
:params [enabled?]
|
||||
:on-success #(log/info "[push-notifications] switch-transaction successful" %)
|
||||
:on-error #(log/error "[push-notifications] switch-transaction error" %)}]})
|
||||
|
||||
(defn create-transfer-notification
|
||||
[{db :db}
|
||||
{{:keys [state from to fromAccount toAccount value erc20 contract network]}
|
||||
:body
|
||||
:as notification}]
|
||||
(let [token (if erc20
|
||||
(get-in db
|
||||
[:wallet/all-tokens (string/lower-case contract)]
|
||||
default-erc20-token)
|
||||
(tokens/native-currency network))
|
||||
amount (money/wei->ether (decode/uint value))
|
||||
to (or (:name toAccount) (utils/get-shortened-address to))
|
||||
from (or (:name fromAccount) (utils/get-shortened-address from))
|
||||
title (case state
|
||||
"inbound" (i18n/label :t/push-inbound-transaction
|
||||
{:value amount
|
||||
:currency (:symbol token)})
|
||||
"outbound" (i18n/label :t/push-outbound-transaction
|
||||
{:value amount
|
||||
:currency (:symbol token)})
|
||||
"failed" (i18n/label :t/push-failed-transaction
|
||||
{:value amount
|
||||
:currency (:symbol token)})
|
||||
nil)
|
||||
description (case state
|
||||
"inbound" (i18n/label :t/push-inbound-transaction-body
|
||||
{:from from
|
||||
:to to})
|
||||
"outbound" (i18n/label :t/push-outbound-transaction-body
|
||||
{:from from
|
||||
:to to})
|
||||
"failed" (i18n/label :t/push-failed-transaction-body
|
||||
{:value amount
|
||||
:currency (:symbol token)
|
||||
:to to})
|
||||
nil)]
|
||||
{:title title
|
||||
:icon (get-in token [:icon :source])
|
||||
:deepLink (:deepLink notification)
|
||||
:user-info notification
|
||||
:message description}))
|
|
@ -2,7 +2,7 @@
|
|||
(:require [status-im.chat.models.message :as models.message]
|
||||
[status-im.ethereum.subscriptions :as ethereum.subscriptions]
|
||||
[status-im.mailserver.core :as mailserver]
|
||||
[status-im.notifications.local :as local-notifications]
|
||||
[status-im2.contexts.push-notifications.local.events :as local-notifications]
|
||||
[status-im.transport.message.core :as transport.message]
|
||||
[status-im.visibility-status-updates.core :as visibility-status-updates]
|
||||
[utils.re-frame :as rf]
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
(ns status-im.ui.screens.notifications-settings.events
|
||||
(:require [status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[utils.re-frame :as rf]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(rf/defn notification-non-contacts-error
|
||||
{:events [:push-notifications/non-contacts-update-error]}
|
||||
[cofx enabled?]
|
||||
(multiaccounts.update/optimistic cofx
|
||||
:push-notifications-from-contacts-only?
|
||||
(not (boolean enabled?))))
|
||||
|
||||
(rf/defn notification-block-mentions-error
|
||||
{:events [:push-notifications/block-mentions-update-error]}
|
||||
[cofx enabled?]
|
||||
(multiaccounts.update/optimistic cofx :push-notifications-block-mentions? (not (boolean enabled?))))
|
||||
|
||||
(rf/defn notification-non-contacts
|
||||
{:events [:push-notifications/switch-non-contacts]}
|
||||
[{:keys [db] :as cofx} enabled?]
|
||||
(let [method (if enabled?
|
||||
"wakuext_enablePushNotificationsFromContactsOnly"
|
||||
"wakuext_disablePushNotificationsFromContactsOnly")]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:json-rpc/call [{:method method
|
||||
:params []
|
||||
:on-success #(log/info "[push-notifications] contacts-notification-success" %)
|
||||
:on-error #(log/info "[push-notifications] contacts-notification-error" %)}]}
|
||||
(multiaccounts.update/optimistic :push-notifications-from-contacts-only? (boolean enabled?)))))
|
||||
|
||||
(rf/defn notification-block-mentions
|
||||
{:events [:push-notifications/switch-block-mentions]}
|
||||
[{:keys [db] :as cofx} enabled?]
|
||||
(let [method (if enabled?
|
||||
"wakuext_enablePushNotificationsBlockMentions"
|
||||
"wakuext_disablePushNotificationsBlockMentions")]
|
||||
(rf/merge cofx
|
||||
{:json-rpc/call [{:method method
|
||||
:params []
|
||||
:on-success #(log/info "[push-notifications] block-mentions-success" %)
|
||||
:on-error #(rf/dispatch
|
||||
[:push-notifications/block-mentions-update-error enabled?
|
||||
%])}]}
|
||||
|
||||
(multiaccounts.update/optimistic :push-notifications-block-mentions? (boolean enabled?)))))
|
||||
|
||||
(rf/defn notification-switch
|
||||
{:events [:push-notifications/switch]}
|
||||
[{:keys [db] :as cofx} enabled?]
|
||||
(rf/merge cofx
|
||||
(if enabled?
|
||||
{:effects/push-notifications-enable nil}
|
||||
{:effects/push-notifications-disable nil})
|
||||
(multiaccounts.update/multiaccount-update :notifications-enabled? enabled? {})))
|
|
@ -1,19 +1,15 @@
|
|||
(ns status-im.ui.screens.notifications-settings.views
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||
(:require [quo.core :as quo]
|
||||
[quo.design-system.colors :as quo-colors]
|
||||
[quo.platform :as platform]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.notifications.core :as notifications]
|
||||
[status-im.ui.components.react :as react]))
|
||||
|
||||
(defonce server (reagent/atom ""))
|
||||
[status-im.ui.components.react :as react]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn local-notifications
|
||||
[]
|
||||
(let [{:keys [enabled]} @(re-frame/subscribe [:notifications/wallet-transactions])]
|
||||
(let [{:keys [enabled?]} (rf/sub [:push-notifications/wallet-transactions])
|
||||
{:keys [notifications-enabled?]} (rf/sub [:profile/profile])]
|
||||
[:<>
|
||||
[quo/separator
|
||||
{:color (:ui-02 @quo-colors/theme)
|
||||
|
@ -23,25 +19,24 @@
|
|||
{:size :small
|
||||
:title (i18n/label :t/notifications-transactions)
|
||||
:accessibility-label :notifications-button
|
||||
:active enabled
|
||||
:on-press #(re-frame/dispatch
|
||||
[::notifications/switch-transaction-notifications enabled])
|
||||
:active (and notifications-enabled? enabled?)
|
||||
:on-press #(rf/dispatch [:push-notifications.wallet/switch-transactions
|
||||
(not enabled?)])
|
||||
:accessory :switch}]]))
|
||||
|
||||
(defn notifications-settings-ios
|
||||
[]
|
||||
(let [{:keys [remote-push-notifications-enabled?
|
||||
(let [{:keys [notifications-enabled?
|
||||
push-notifications-block-mentions?
|
||||
push-notifications-from-contacts-only?]}
|
||||
@(re-frame/subscribe [:profile/profile])]
|
||||
(rf/sub [:profile/profile])]
|
||||
[:<>
|
||||
[quo/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/show-notifications)
|
||||
:accessibility-label :notifications-button
|
||||
:active remote-push-notifications-enabled?
|
||||
:on-press #(re-frame/dispatch [::notifications/switch
|
||||
(not remote-push-notifications-enabled?) true])
|
||||
:active notifications-enabled?
|
||||
:on-press #(rf/dispatch [:push-notifications/switch (not notifications-enabled?)])
|
||||
:accessory :switch}]
|
||||
[quo/separator
|
||||
{:color (:ui-02 @quo-colors/theme)
|
||||
|
@ -51,35 +46,34 @@
|
|||
{:size :small
|
||||
:title (i18n/label :t/notifications-non-contacts)
|
||||
:accessibility-label :notifications-button
|
||||
:active (and remote-push-notifications-enabled?
|
||||
:active (and notifications-enabled?
|
||||
(not push-notifications-from-contacts-only?))
|
||||
:on-press #(re-frame/dispatch
|
||||
[::notifications/switch-non-contacts
|
||||
:on-press #(rf/dispatch
|
||||
[:push-notifications/switch-non-contacts
|
||||
(not push-notifications-from-contacts-only?)])
|
||||
:accessory :switch}]
|
||||
[quo/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/allow-mention-notifications)
|
||||
:accessibility-label :notifications-button
|
||||
:active (and remote-push-notifications-enabled?
|
||||
:active (and notifications-enabled?
|
||||
(not push-notifications-block-mentions?))
|
||||
:on-press #(re-frame/dispatch
|
||||
[::notifications/switch-block-mentions
|
||||
:on-press #(rf/dispatch
|
||||
[:push-notifications/switch-block-mentions
|
||||
(not push-notifications-block-mentions?)])
|
||||
:accessory :switch}]
|
||||
[local-notifications]]))
|
||||
|
||||
(defn notifications-settings-android
|
||||
[]
|
||||
(let [{:keys [notifications-enabled?]} @(re-frame/subscribe [:profile/profile])]
|
||||
(let [{:keys [notifications-enabled?]} (rf/sub [:profile/profile])]
|
||||
[:<>
|
||||
[quo/list-item
|
||||
{:title (i18n/label :t/local-notifications)
|
||||
:accessibility-label :local-notifications-settings-button
|
||||
:subtitle (i18n/label :t/local-notifications-subtitle)
|
||||
:active notifications-enabled?
|
||||
:on-press #(re-frame/dispatch
|
||||
[::notifications/switch (not notifications-enabled?) false])
|
||||
:on-press #(rf/dispatch [:push-notifications/switch (not notifications-enabled?)])
|
||||
:accessory :switch}]
|
||||
[local-notifications]]))
|
||||
|
||||
|
@ -91,81 +85,3 @@
|
|||
(if platform/ios?
|
||||
[notifications-settings-ios]
|
||||
[notifications-settings-android])])
|
||||
|
||||
(defn notifications-advanced-settings
|
||||
[]
|
||||
(let [{:keys [remote-push-notifications-enabled?
|
||||
send-push-notifications?
|
||||
push-notifications-server-enabled?]}
|
||||
@(re-frame/subscribe [:profile/profile])]
|
||||
[react/scroll-view
|
||||
{:style {:flex 1}
|
||||
:content-container-style {:padding-vertical 8}}
|
||||
[quo/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/send-push-notifications)
|
||||
:accessibility-label :send-push-notifications-button
|
||||
:active send-push-notifications?
|
||||
:on-press #(re-frame/dispatch
|
||||
[::notifications/switch-send-push-notifications
|
||||
(not send-push-notifications?)])
|
||||
:accessory :switch}]
|
||||
[quo/list-footer
|
||||
(i18n/label :t/send-push-notifications-description)]
|
||||
[quo/separator {:style {:margin-vertical 8}}]
|
||||
[quo/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/push-notifications-server-enabled)
|
||||
:accessibility-label :send-push-notifications-button
|
||||
:active (and remote-push-notifications-enabled?
|
||||
push-notifications-server-enabled?)
|
||||
:on-press #(re-frame/dispatch
|
||||
[::notifications/switch-push-notifications-server-enabled
|
||||
(not push-notifications-server-enabled?)])
|
||||
:accessory :switch}]
|
||||
[quo/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/push-notifications-servers)
|
||||
:accessibility-label :send-push-notifications-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch
|
||||
[:navigate-to :notifications-servers])}]]))
|
||||
|
||||
(defn server-view
|
||||
[{:keys [public-key type registered]}]
|
||||
[quo/list-item
|
||||
{:size :small
|
||||
:title (str (subs public-key 0 8)
|
||||
" "
|
||||
(if (= type notifications/server-type-custom)
|
||||
(i18n/label :t/custom)
|
||||
(i18n/label :t/default))
|
||||
" "
|
||||
(if registered
|
||||
(i18n/label :t/registered)
|
||||
(i18n/label :t/not-registered)))}])
|
||||
|
||||
(defview notifications-servers
|
||||
[]
|
||||
(letsubs [servers [:push-notifications/servers]]
|
||||
{:component-did-mount #(re-frame/dispatch [::notifications/fetch-servers])}
|
||||
[react/scroll-view
|
||||
{:style {:flex 1}
|
||||
:content-container-style {:padding-vertical 8}}
|
||||
(map server-view servers)
|
||||
[react/keyboard-avoiding-view {}
|
||||
[react/view {:style {:padding-horizontal 20}}
|
||||
[quo/text-input
|
||||
{:label (i18n/label :t/server)
|
||||
:placeholder (i18n/label :t/specify-server-public-key)
|
||||
:value @server
|
||||
:on-change-text #(reset! server %)
|
||||
:auto-focus true}]]
|
||||
[quo/button
|
||||
{:type :secondary
|
||||
:after :main-icon/next
|
||||
:disabled (empty? @server)
|
||||
:on-press #(do
|
||||
(re-frame/dispatch [::notifications/add-server @server])
|
||||
(reset! server ""))}
|
||||
(i18n/label :t/save)]]]))
|
||||
|
|
|
@ -312,10 +312,6 @@
|
|||
:options {:topBar {:title {:text (i18n/label :t/notification-settings)}}
|
||||
:insets {:top? true}}
|
||||
:component notifications-settings/notifications-settings}
|
||||
{:name :notifications-servers
|
||||
:options {:topBar {:title {:text (i18n/label :t/notifications-servers)}}
|
||||
:insets {:top? true}}
|
||||
:component notifications-settings/notifications-servers}
|
||||
{:name :sync-settings
|
||||
:options {:topBar {:title {:text (i18n/label :t/sync-settings)}}
|
||||
:insets {:top? true}}
|
||||
|
@ -475,17 +471,6 @@
|
|||
:top? true}}
|
||||
:component notifications-settings/notifications-settings}
|
||||
|
||||
;;TODO WHY MODAL?
|
||||
;[Profile] Notifications Advanced settings
|
||||
{:name :notifications-advanced-settings
|
||||
:options {:topBar {:title {:text (i18n/label :t/notification-settings)}}
|
||||
:popGesture false
|
||||
:hardwareBackButton {:dismissModalOnPress false
|
||||
:popStackOnPress false}
|
||||
:insets {:bottom? true
|
||||
:top? true}}
|
||||
:component notifications-settings/notifications-advanced-settings}
|
||||
|
||||
;[Wallet] Prepare Transaction
|
||||
{:name :prepare-send-transaction
|
||||
:on-dissmiss [:wallet/cancel-transaction-command]
|
||||
|
|
|
@ -109,9 +109,7 @@
|
|||
(update :chats #(apply dissoc % removed-chats))
|
||||
(update :chats-home-list set/difference removed-chats))
|
||||
:fx [(when (not-empty removed-chats)
|
||||
[:clear-message-notifications
|
||||
[removed-chats
|
||||
(get-in db [:profile/profile :remote-push-notifications-enabled?])]])
|
||||
[:effects/push-notifications-clear-message-notifications removed-chats])
|
||||
[:dispatch [:chat/leave-removed-chat]]]}))
|
||||
|
||||
(re-frame/reg-event-fx :chat/ensure-chats ensure-chats)
|
||||
|
@ -286,9 +284,9 @@
|
|||
{:events [:chat.ui/remove-chat]}
|
||||
[{:keys [db now] :as cofx} chat-id]
|
||||
(rf/merge cofx
|
||||
{:clear-message-notifications
|
||||
[[chat-id] (get-in db [:profile/profile :remote-push-notifications-enabled?])]
|
||||
:dispatch [:shell/close-switcher-card chat-id]}
|
||||
{:effects/push-notifications-clear-message-notifications [chat-id]
|
||||
:dispatch [:shell/close-switcher-card
|
||||
chat-id]}
|
||||
(deactivate-chat chat-id)
|
||||
(offload-messages chat-id)))
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.notifications.core :as notifications]
|
||||
[status-im2.contexts.onboarding.enable-notifications.style :as style]
|
||||
[status-im2.contexts.shell.jump-to.utils :as shell.utils]
|
||||
[utils.i18n :as i18n]
|
||||
|
@ -25,7 +24,7 @@
|
|||
[quo/button
|
||||
{:on-press (fn []
|
||||
(shell.utils/change-selected-stack-id :communities-stack true nil)
|
||||
(rf/dispatch [::notifications/switch true platform/ios?])
|
||||
(rf/dispatch [:push-notifications/switch true platform/ios?])
|
||||
(rf/dispatch [:navigate-to-within-stack
|
||||
[:welcome :enable-notifications]]))
|
||||
:type :primary
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
[status-im2.common.biometric.events :as biometric]
|
||||
[status-im2.contexts.profile.config :as profile.config]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.notifications.core :as notifications]
|
||||
[status-im2.config :as config]
|
||||
[status-im.data-store.settings :as data-store.settings]
|
||||
[status-im.communities.core :as communities]
|
||||
|
@ -25,7 +24,8 @@
|
|||
[status-im.data-store.visibility-status-updates :as visibility-status-updates-store]
|
||||
[status-im.data-store.switcher-cards :as switcher-cards-store]
|
||||
[status-im.browser.core :as browser]
|
||||
[status-im.group-chats.core :as group-chats]))
|
||||
[status-im.group-chats.core :as group-chats]
|
||||
[status-im2.contexts.push-notifications.events :as notifications]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::login
|
||||
|
@ -77,7 +77,7 @@
|
|||
:networks/current-network current-network
|
||||
:networks/networks (merge networks config/default-networks-by-id)
|
||||
:profile/profile (merge profile settings))}
|
||||
(notifications/load-notification-preferences)
|
||||
(notifications/load-preferences)
|
||||
(data-store.chats/fetch-chats-preview
|
||||
{:on-success
|
||||
#(do (re-frame/dispatch [:chats-list/load-success %])
|
||||
|
@ -98,12 +98,10 @@
|
|||
{:events [:profile.login/get-chats-callback]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [{:networks/keys [current-network networks]} db
|
||||
notifications-enabled? (get-in db [:profile/profile :notifications-enabled?])
|
||||
{:keys [notifications-enabled?]} (:profile/profile db)
|
||||
current-network-config (get networks current-network)
|
||||
network-id (str (get-in networks
|
||||
[current-network :config :NetworkId]))
|
||||
remote-push-notifications-enabled?
|
||||
(get-in db [:profile/profile :remote-push-notifications-enabled?])]
|
||||
[current-network :config :NetworkId]))]
|
||||
(rf/merge cofx
|
||||
(cond-> {:wallet/initialize-transactions-management-enabled nil
|
||||
:wallet/initialize-wallet
|
||||
|
@ -114,8 +112,8 @@
|
|||
accounts tokens custom-tokens favourites]))]
|
||||
:check-eip1559-activation {:network-id network-id}
|
||||
:chat/open-last-chat (get-in db [:profile/profile :key-uid])}
|
||||
(or notifications-enabled? remote-push-notifications-enabled?)
|
||||
(assoc ::notifications/enable remote-push-notifications-enabled?))
|
||||
notifications-enabled?
|
||||
(assoc :effects/push-notifications-enable nil))
|
||||
(transport/start-messenger)
|
||||
(contacts/initialize-contacts)
|
||||
(browser/initialize-browser)
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
(ns status-im2.contexts.push-notifications.effects
|
||||
(:require [react-native.push-notification-ios :as pn-ios]
|
||||
[utils.re-frame :as rf]
|
||||
[native-module.push-notifications :as native-module.pn]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(def ios-listeners-added? (atom nil))
|
||||
|
||||
(defn enable-ios-notifications
|
||||
[]
|
||||
(when-not @ios-listeners-added?
|
||||
(reset! ios-listeners-added? true)
|
||||
(pn-ios/add-listener
|
||||
"register"
|
||||
(fn [token]
|
||||
(rf/dispatch [:push-notifications/registered-for-push-notifications token])))
|
||||
(pn-ios/add-listener
|
||||
"registrationError"
|
||||
(fn [error]
|
||||
(rf/dispatch [:push-notifications/switch-error true error]))))
|
||||
(pn-ios/request-permissions))
|
||||
|
||||
(defn disable-ios-notifications
|
||||
[]
|
||||
(pn-ios/abandon-permissions)
|
||||
(rf/dispatch [:push-notifications/unregistered-from-push-notifications]))
|
||||
|
||||
(defn enable-android-notifications
|
||||
[]
|
||||
(native-module.pn/create-channel
|
||||
{:channel-id "status-im-notifications"
|
||||
:channel-name "Status push notifications"})
|
||||
(native-module.pn/enable-notifications))
|
||||
|
||||
(defn disable-android-notifications
|
||||
[]
|
||||
(native-module.pn/disable-notifications))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects/push-notifications-enable
|
||||
(fn []
|
||||
(if platform/android?
|
||||
(enable-android-notifications)
|
||||
(enable-ios-notifications))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects/push-notifications-disable
|
||||
(fn []
|
||||
(if platform/android?
|
||||
(disable-android-notifications)
|
||||
(disable-ios-notifications))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects/push-notifications-clear-message-notifications
|
||||
(fn [chat-ids]
|
||||
(if platform/android?
|
||||
(doseq [chat-id chat-ids]
|
||||
(native-module.pn/clear-message-notifications chat-id))
|
||||
(pn-ios/remove-all-delivered-notifications))))
|
|
@ -0,0 +1,60 @@
|
|||
(ns status-im2.contexts.push-notifications.events
|
||||
(:require [react-native.push-notification-ios :as pn-ios]
|
||||
[native-module.push-notifications :as native-module.pn]
|
||||
[status-im2.config :as config]
|
||||
[utils.re-frame :as rf]
|
||||
[taoensso.timbre :as log]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.async-storage :as async-storage]
|
||||
[utils.transforms :as transforms]
|
||||
[cljs-bean.core :as bean]
|
||||
status-im2.contexts.push-notifications.effects))
|
||||
|
||||
(def server-type-default 1)
|
||||
(def server-type-custom 2)
|
||||
|
||||
(def apn-token-type 1)
|
||||
(def firebase-token-type 2)
|
||||
|
||||
(defn handle-notification-press
|
||||
[{{deep-link :deepLink} :userInfo
|
||||
interaction :userInteraction}]
|
||||
(async-storage/set-item! (str :chat-id) nil)
|
||||
(when (and deep-link (or platform/ios? (and platform/android? interaction)))
|
||||
(rf/dispatch [:universal-links/handle-url deep-link])))
|
||||
|
||||
(defn listen-notifications
|
||||
[]
|
||||
(if platform/ios?
|
||||
(pn-ios/add-listener "localNotification"
|
||||
#(handle-notification-press {:userInfo (bean/bean (.getData ^js %))}))
|
||||
(native-module.pn/add-listener "remoteNotificationReceived"
|
||||
#(handle-notification-press (transforms/json->clj %)))))
|
||||
|
||||
(rf/defn handle-enable-notifications-event
|
||||
{:events [:push-notifications/registered-for-push-notifications]}
|
||||
[_ token]
|
||||
{:json-rpc/call [{:method "wakuext_registerForPushNotifications"
|
||||
: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" %)
|
||||
:on-error #(log/info "[push-notifications] register-error" %)}]})
|
||||
|
||||
(rf/defn handle-disable-notifications-event
|
||||
{:events [:push-notifications/unregistered-from-push-notifications]}
|
||||
[_]
|
||||
{:json-rpc/call [{:method "wakuext_unregisterFromPushNotifications"
|
||||
:params []
|
||||
:on-success #(log/info "[push-notifications] unregister-success" %)
|
||||
:on-error #(log/info "[push-notifications] unregister-error" %)}]})
|
||||
|
||||
(rf/defn handle-preferences-load
|
||||
{:events [:push-notifications/preferences-loaded]}
|
||||
[{:keys [db]} preferences]
|
||||
{:db (assoc db :push-notifications/preferences preferences)})
|
||||
|
||||
(rf/defn load-preferences
|
||||
[_]
|
||||
{:json-rpc/call [{:method "localnotifications_notificationPreferences"
|
||||
:params []
|
||||
:on-success #(rf/dispatch [:push-notifications/preferences-loaded %])}]})
|
|
@ -0,0 +1,18 @@
|
|||
(ns status-im2.contexts.push-notifications.local.effects
|
||||
(:require [react-native.push-notification-ios :as pn-ios]
|
||||
[cljs-bean.core :as bean]
|
||||
[native-module.push-notifications :as native-module.pn]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-fx :effects/push-notifications-local-present-ios
|
||||
(fn [{:keys [title message user-info body-type]}]
|
||||
(when (not= body-type "message")
|
||||
(pn-ios/present-local-notification title
|
||||
message
|
||||
(bean/->js (merge user-info
|
||||
{:notificationType
|
||||
"local-notification"}))))))
|
||||
|
||||
(rf/reg-fx :effects/push-notifications-local-present-android
|
||||
(fn [notification]
|
||||
(native-module.pn/present-local-notification notification)))
|
|
@ -0,0 +1,36 @@
|
|||
(ns status-im2.contexts.push-notifications.local.events
|
||||
(:require [quo.platform :as platform]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im.notifications.wallet :as notifications.wallet]
|
||||
status-im2.contexts.push-notifications.local.effects))
|
||||
|
||||
(defn foreground-chat?
|
||||
[{{:keys [current-chat-id view-id]} :db} chat-id]
|
||||
(and (= current-chat-id chat-id)
|
||||
(= view-id :chat)))
|
||||
|
||||
(defn show-message-pn?
|
||||
[{{:keys [app-state profile/profile]} :db :as cofx}
|
||||
notification]
|
||||
(let [chat-id (get-in notification [:body :chat :id])
|
||||
notification-author (get-in notification [:notificationAuthor :id])]
|
||||
(and
|
||||
(not= notification-author (:public-key profile))
|
||||
(or (= app-state "background")
|
||||
(not (foreground-chat? cofx chat-id))))))
|
||||
|
||||
(defn create-notification
|
||||
[cofx {:keys [bodyType] :as notification}]
|
||||
(assoc
|
||||
(case bodyType
|
||||
"message" (when (show-message-pn? cofx notification) notification)
|
||||
"transaction" (notifications.wallet/create-transfer-notification cofx notification)
|
||||
nil)
|
||||
:body-type
|
||||
bodyType))
|
||||
|
||||
(rf/defn process
|
||||
[cofx event]
|
||||
(if platform/ios?
|
||||
{:effects/push-notifications-local-present-ios (create-notification nil event)}
|
||||
{:effects/push-notifications-local-present-android (create-notification cofx event)}))
|
|
@ -18,12 +18,12 @@
|
|||
[status-im2.setup.interceptors :as interceptors]
|
||||
[react-native.async-storage :as async-storage]
|
||||
[native-module.core :as native-module]
|
||||
[status-im.notifications.local :as notifications]
|
||||
[status-im.utils.universal-links.core :as utils.universal-links]
|
||||
status-im.events
|
||||
status-im2.events
|
||||
status-im2.navigation.core
|
||||
status-im2.subs.root))
|
||||
status-im2.subs.root
|
||||
[status-im2.contexts.push-notifications.events :as notifications]))
|
||||
|
||||
;;;; re-frame RN setup
|
||||
(set! interop/next-tick js/setTimeout)
|
||||
|
|
|
@ -236,7 +236,6 @@
|
|||
(reg-root-key-sub :delete-profile/keep-keys-on-keycard? :delete-profile/keep-keys-on-keycard?)
|
||||
|
||||
;; push notifications
|
||||
(reg-root-key-sub :push-notifications/servers :push-notifications/servers)
|
||||
(reg-root-key-sub :push-notifications/preferences :push-notifications/preferences)
|
||||
|
||||
(reg-root-key-sub :buy-crypto/on-ramps :buy-crypto/on-ramps)
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.ethereum.transactions.core :as transactions]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im.notifications.core :as notifications]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.money :as money]
|
||||
[status-im.wallet.db :as wallet.db]
|
||||
[status-im.wallet.utils :as wallet.utils]))
|
||||
[status-im.wallet.utils :as wallet.utils]
|
||||
[status-im.notifications.wallet :as notifications.wallet]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:wallet/accounts
|
||||
|
@ -236,10 +236,10 @@
|
|||
(* 100 (/ confirmations transactions/confirmations-count-threshold)))))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:notifications/wallet-transactions
|
||||
:push-notifications/wallet-transactions
|
||||
:<- [:push-notifications/preferences]
|
||||
(fn [pref]
|
||||
(first (filter #(notifications/preference= %
|
||||
(first (filter #(notifications.wallet/preference= %
|
||||
{:service "wallet"
|
||||
:event "transaction"
|
||||
:identifier "all"})
|
||||
|
|
|
@ -78,3 +78,5 @@
|
|||
(def sub (comp deref re-frame/subscribe))
|
||||
|
||||
(def dispatch re-frame/dispatch)
|
||||
|
||||
(def reg-fx re-frame/reg-fx)
|
||||
|
|
Loading…
Reference in New Issue