mirror of
https://github.com/status-im/status-mobile.git
synced 2025-01-12 01:34:31 +00:00
Push notifications: end to end v1
- Send notification when sending message in 1on1 chat - Add notify FFI with binds for ObjC and Java - Add fcm-token to contacts in spec and realm - Add notifications to db - Include fcm-token in contact request - Update fcm-token when it arrives and put it in DB - Disable copy-paste hijacking and popup - Turn on notifications flag in Jenkins build
This commit is contained in:
parent
b889a07a86
commit
b5c0b24f30
@ -1,6 +1,6 @@
|
|||||||
TESTFAIRY_ENABLED=1
|
TESTFAIRY_ENABLED=1
|
||||||
WALLET_WIP_ENABLED=1
|
WALLET_WIP_ENABLED=1
|
||||||
NOTIFICATIONS_WIP_ENABLED=0
|
NOTIFICATIONS_WIP_ENABLED=1
|
||||||
DEBUG_LOGS_ENABLED=1
|
DEBUG_LOGS_ENABLED=1
|
||||||
STUB_STATUS_GO=0
|
STUB_STATUS_GO=0
|
||||||
|
|
||||||
|
@ -360,6 +360,26 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
|||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
public void notify(final String token, final Callback callback) {
|
||||||
|
Log.d(TAG, "notify");
|
||||||
|
if (!checkAvailability()) {
|
||||||
|
callback.invoke(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread thread = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
String res = Statusgo.Notify(token);
|
||||||
|
|
||||||
|
callback.invoke(res);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void recoverAccount(final String passphrase, final String password, final Callback callback) {
|
public void recoverAccount(final String passphrase, final String password, final Callback callback) {
|
||||||
Log.d(TAG, "recoverAccount");
|
Log.d(TAG, "recoverAccount");
|
||||||
|
@ -311,6 +311,19 @@ RCT_EXPORT_METHOD(createAccount:(NSString *)password
|
|||||||
callback(@[[NSString stringWithUTF8String: result]]);
|
callback(@[[NSString stringWithUTF8String: result]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
#pragma mark - Notify method
|
||||||
|
//////////////////////////////////////////////////////////////////// notify
|
||||||
|
RCT_EXPORT_METHOD(notify:(NSString *)token
|
||||||
|
callback:(RCTResponseSenderBlock)callback) {
|
||||||
|
char * result = Notify((char *) [token UTF8String]);
|
||||||
|
callback(@[[NSString stringWithUTF8String: result]]);
|
||||||
|
#if DEBUG
|
||||||
|
NSLog(@"Notify() method called");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////// recoverAccount
|
//////////////////////////////////////////////////////////////////// recoverAccount
|
||||||
RCT_EXPORT_METHOD(recoverAccount:(NSString *)passphrase
|
RCT_EXPORT_METHOD(recoverAccount:(NSString *)passphrase
|
||||||
password:(NSString *)password
|
password:(NSString *)password
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
[taoensso.timbre :refer-macros [debug] :as log]
|
[taoensso.timbre :refer-macros [debug] :as log]
|
||||||
[status-im.chat.handlers.console :as console]
|
[status-im.chat.handlers.console :as console]
|
||||||
[status-im.utils.types :as types]
|
[status-im.utils.types :as types]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
[status-im.utils.clocks :as clocks]))
|
[status-im.utils.clocks :as clocks]))
|
||||||
|
|
||||||
(defn prepare-command
|
(defn prepare-command
|
||||||
@ -298,6 +299,14 @@
|
|||||||
{:result result
|
{:result result
|
||||||
:chat-id chat-id}])))))
|
:chat-id chat-id}])))))
|
||||||
|
|
||||||
|
(defn send-notification [fcm-token message]
|
||||||
|
(if (and fcm-token config/notifications-wip-enabled?)
|
||||||
|
(do (log/debug "send-notification fcm-token: " fcm-token)
|
||||||
|
(log/debug "send-notification message: " message)
|
||||||
|
(status/notify fcm-token (fn [res]
|
||||||
|
(log/debug "send-notification cb result: " res))))
|
||||||
|
(log/debug "send-notification message not sending because fcm-token is unavailable or notification flag is off")))
|
||||||
|
|
||||||
(register-handler ::send-message!
|
(register-handler ::send-message!
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
(fn [{:keys [web3 chats network-status]
|
(fn [{:keys [web3 chats network-status]
|
||||||
@ -306,7 +315,7 @@
|
|||||||
:as db} [_ {{:keys [message-type]
|
:as db} [_ {{:keys [message-type]
|
||||||
:as message} :message
|
:as message} :message
|
||||||
chat-id :chat-id}]]
|
chat-id :chat-id}]]
|
||||||
(let [{:keys [dapp?]} (get contacts chat-id)]
|
(let [{:keys [dapp? fcm-token]} (get contacts chat-id)]
|
||||||
(if dapp?
|
(if dapp?
|
||||||
(dispatch [::send-dapp-message chat-id message])
|
(dispatch [::send-dapp-message chat-id message])
|
||||||
(when message
|
(when message
|
||||||
@ -333,8 +342,9 @@
|
|||||||
:username username)))
|
:username username)))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(protocol/send-message! (assoc-in options
|
(do (protocol/send-message! (assoc-in options
|
||||||
[:message :to] (:to message)))))))))))
|
[:message :to] (:to message)))
|
||||||
|
(send-notification fcm-token (:message options)))))))))))
|
||||||
|
|
||||||
(register-handler ::send-command-protocol!
|
(register-handler ::send-command-protocol!
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
[status-im.data-store.realm.schemas.account.v12.core :as v12]
|
[status-im.data-store.realm.schemas.account.v12.core :as v12]
|
||||||
[status-im.data-store.realm.schemas.account.v13.core :as v13]))
|
[status-im.data-store.realm.schemas.account.v13.core :as v13]))
|
||||||
|
|
||||||
|
;; TODO(oskarth): Add failing test if directory vXX exists but isn't in schemas.
|
||||||
|
|
||||||
;; put schemas ordered by version
|
;; put schemas ordered by version
|
||||||
(def schemas [{:schema v1/schema
|
(def schemas [{:schema v1/schema
|
||||||
:schemaVersion 1
|
:schemaVersion 1
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
(ns status-im.data-store.realm.schemas.account.v13.contact
|
||||||
|
(:require [taoensso.timbre :as log]))
|
||||||
|
|
||||||
|
(def schema {:name :contact
|
||||||
|
:primaryKey :whisper-identity
|
||||||
|
:properties {:address {:type :string :optional true}
|
||||||
|
:whisper-identity :string
|
||||||
|
:name {:type :string :optional true}
|
||||||
|
:photo-path {:type :string :optional true}
|
||||||
|
:last-updated {:type :int :default 0}
|
||||||
|
:last-online {:type :int :default 0}
|
||||||
|
:pending? {:type :bool :default false}
|
||||||
|
:status {:type :string :optional true}
|
||||||
|
:fcm-token {:type :string :optional true}
|
||||||
|
:public-key {:type :string
|
||||||
|
:optional true}
|
||||||
|
:private-key {:type :string
|
||||||
|
:optional true}
|
||||||
|
:dapp? {:type :bool
|
||||||
|
:default false}
|
||||||
|
:dapp-url {:type :string
|
||||||
|
:optional true}
|
||||||
|
:bot-url {:type :string
|
||||||
|
:optional true}
|
||||||
|
:global-command {:type :command
|
||||||
|
:optional true}
|
||||||
|
:commands {:type :list
|
||||||
|
:objectType :command}
|
||||||
|
:responses {:type :list
|
||||||
|
:objectType :command}
|
||||||
|
:dapp-hash {:type :int
|
||||||
|
:optional true}
|
||||||
|
:debug? {:type :bool
|
||||||
|
:default false}}})
|
@ -3,7 +3,7 @@
|
|||||||
[status-im.data-store.realm.schemas.account.v1.chat-contact :as chat-contact]
|
[status-im.data-store.realm.schemas.account.v1.chat-contact :as chat-contact]
|
||||||
[status-im.data-store.realm.schemas.account.v6.command :as command]
|
[status-im.data-store.realm.schemas.account.v6.command :as command]
|
||||||
[status-im.data-store.realm.schemas.account.v9.command-parameter :as command-parameter]
|
[status-im.data-store.realm.schemas.account.v9.command-parameter :as command-parameter]
|
||||||
[status-im.data-store.realm.schemas.account.v7.contact :as contact]
|
[status-im.data-store.realm.schemas.account.v13.contact :as contact]
|
||||||
[status-im.data-store.realm.schemas.account.v1.discover :as discover]
|
[status-im.data-store.realm.schemas.account.v1.discover :as discover]
|
||||||
[status-im.data-store.realm.schemas.account.v1.kv-store :as kv-store]
|
[status-im.data-store.realm.schemas.account.v1.kv-store :as kv-store]
|
||||||
[status-im.data-store.realm.schemas.account.v10.message :as message]
|
[status-im.data-store.realm.schemas.account.v10.message :as message]
|
||||||
|
@ -114,6 +114,10 @@
|
|||||||
true)
|
true)
|
||||||
false))))))
|
false))))))
|
||||||
|
|
||||||
|
(defn notify [token on-result]
|
||||||
|
(when status
|
||||||
|
(call-module #(.notify status token on-result))))
|
||||||
|
|
||||||
(defn recover-account [passphrase password on-result]
|
(defn recover-account [passphrase password on-result]
|
||||||
(when status
|
(when status
|
||||||
(call-module #(.recoverAccount status passphrase password on-result))))
|
(call-module #(.recoverAccount status passphrase password on-result))))
|
||||||
|
@ -361,8 +361,8 @@
|
|||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
(fn [{:contacts/keys [contacts]} [_ {:keys [from payload]}]]
|
(fn [{:contacts/keys [contacts]} [_ {:keys [from payload]}]]
|
||||||
(when from
|
(when from
|
||||||
(let [{{:keys [name profile-image address status]} :contact
|
(let [{{:keys [name profile-image address status fcm-token]} :contact
|
||||||
{:keys [public private]} :keypair} payload
|
{:keys [public private]} :keypair} payload
|
||||||
existing-contact (get contacts from)
|
existing-contact (get contacts from)
|
||||||
contact {:whisper-identity from
|
contact {:whisper-identity from
|
||||||
:public-key public
|
:public-key public
|
||||||
@ -370,7 +370,8 @@
|
|||||||
:address address
|
:address address
|
||||||
:status status
|
:status status
|
||||||
:photo-path profile-image
|
:photo-path profile-image
|
||||||
:name name}
|
:name name
|
||||||
|
:fcm-token fcm-token}
|
||||||
chat {:name name
|
chat {:name name
|
||||||
:chat-id from
|
:chat-id from
|
||||||
:contact-info (prn-str contact)}]
|
:contact-info (prn-str contact)}]
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
(spec/def :contact/public-key (spec/nilable string?))
|
(spec/def :contact/public-key (spec/nilable string?))
|
||||||
(spec/def :contact/photo-path (spec/nilable string?))
|
(spec/def :contact/photo-path (spec/nilable string?))
|
||||||
(spec/def :contact/status (spec/nilable string?))
|
(spec/def :contact/status (spec/nilable string?))
|
||||||
|
(spec/def :contact/fcm-token (spec/nilable string?))
|
||||||
|
|
||||||
(spec/def :contact/last-updated (spec/nilable int?))
|
(spec/def :contact/last-updated (spec/nilable int?))
|
||||||
(spec/def :contact/last-online (spec/nilable int?))
|
(spec/def :contact/last-online (spec/nilable int?))
|
||||||
@ -46,7 +47,8 @@
|
|||||||
:contact/status :contact/last-updated :contact/last-online :contact/pending?
|
:contact/status :contact/last-updated :contact/last-online :contact/pending?
|
||||||
:contact/unremovable? :contact/dapp? :contact/dapp-url :contact/dapp-hash
|
:contact/unremovable? :contact/dapp? :contact/dapp-url :contact/dapp-hash
|
||||||
:contact/bot-url :contact/global-command :contact/commands-loaded?
|
:contact/bot-url :contact/global-command :contact/commands-loaded?
|
||||||
:contact/commands :contact/responses :contact/debug? :contact/subscriptions]))
|
:contact/commands :contact/responses :contact/debug? :contact/subscriptions
|
||||||
|
:contact/fcm-token]))
|
||||||
|
|
||||||
;;Contact list ui props
|
;;Contact list ui props
|
||||||
(spec/def :contact-list-ui/edit? boolean?)
|
(spec/def :contact-list-ui/edit? boolean?)
|
||||||
|
@ -51,7 +51,8 @@
|
|||||||
|
|
||||||
(reg-fx
|
(reg-fx
|
||||||
::send-contact-request-fx
|
::send-contact-request-fx
|
||||||
(fn [{:keys [web3 current-public-key name whisper-identity photo-path current-account-id status
|
(fn [{:keys [web3 current-public-key name whisper-identity
|
||||||
|
photo-path current-account-id status fcm-token
|
||||||
updates-public-key updates-private-key] :as params}]
|
updates-public-key updates-private-key] :as params}]
|
||||||
(protocol/contact-request!
|
(protocol/contact-request!
|
||||||
{:web3 web3
|
{:web3 web3
|
||||||
@ -61,7 +62,8 @@
|
|||||||
:payload {:contact {:name name
|
:payload {:contact {:name name
|
||||||
:profile-image photo-path
|
:profile-image photo-path
|
||||||
:address current-account-id
|
:address current-account-id
|
||||||
:status status}
|
:status status
|
||||||
|
:fcm-token fcm-token}
|
||||||
:keypair {:public updates-public-key
|
:keypair {:public updates-public-key
|
||||||
:private updates-private-key}}}})))
|
:private updates-private-key}}}})))
|
||||||
|
|
||||||
@ -311,10 +313,11 @@
|
|||||||
(register-handler-fx
|
(register-handler-fx
|
||||||
::send-contact-request
|
::send-contact-request
|
||||||
(fn [{{:accounts/keys [accounts current-account-id] :as db} :db} [_ contact]]
|
(fn [{{:accounts/keys [accounts current-account-id] :as db} :db} [_ contact]]
|
||||||
(let [current-account (get accounts current-account-id)]
|
(let [current-account (get accounts current-account-id)
|
||||||
|
fcm-token (get-in db [:notifications :fcm-token])]
|
||||||
{::send-contact-request-fx (merge
|
{::send-contact-request-fx (merge
|
||||||
(select-keys db [:current-public-key :web3])
|
(select-keys db [:current-public-key :web3])
|
||||||
{:current-account-id current-account-id}
|
{:current-account-id current-account-id :fcm-token fcm-token}
|
||||||
(select-keys contact [:whisper-identity])
|
(select-keys contact [:whisper-identity])
|
||||||
(select-keys current-account [:name :photo-path :status
|
(select-keys current-account [:name :photo-path :status
|
||||||
:updates-public-key :updates-private-key]))})))
|
:updates-public-key :updates-private-key]))})))
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
:sync-state :done
|
:sync-state :done
|
||||||
:wallet {}
|
:wallet {}
|
||||||
:prices {}
|
:prices {}
|
||||||
|
:notifications {}
|
||||||
:network "testnet"})
|
:network "testnet"})
|
||||||
|
|
||||||
;;;;GLOBAL
|
;;;;GLOBAL
|
||||||
@ -176,4 +177,5 @@
|
|||||||
:discoveries/new-discover
|
:discoveries/new-discover
|
||||||
:wallet/wallet
|
:wallet/wallet
|
||||||
:prices/prices
|
:prices/prices
|
||||||
:prices/prices-loading?]))
|
:prices/prices-loading?
|
||||||
|
:notifications/notifications]))
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
(ns status-im.utils.notifications
|
(ns status-im.utils.notifications
|
||||||
(:require [status-im.react-native.js-dependencies :as rn]
|
(:require [re-frame.core :as re-frame :refer [dispatch reg-fx]]
|
||||||
|
[status-im.utils.handlers :as handlers]
|
||||||
|
[status-im.react-native.js-dependencies :as rn]
|
||||||
[status-im.utils.config :as config]
|
[status-im.utils.config :as config]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[status-im.components.react :refer [copy-to-clipboard]]
|
[status-im.components.react :refer [copy-to-clipboard]]
|
||||||
@ -8,6 +10,11 @@
|
|||||||
;; Work in progress namespace responsible for push notifications and interacting
|
;; Work in progress namespace responsible for push notifications and interacting
|
||||||
;; with Firebase Cloud Messaging.
|
;; with Firebase Cloud Messaging.
|
||||||
|
|
||||||
|
(handlers/register-handler-db
|
||||||
|
:update-fcm-token
|
||||||
|
(fn [db [_ fcm-token]]
|
||||||
|
(assoc-in db [:notifications :fcm-token] fcm-token)))
|
||||||
|
|
||||||
;; NOTE: Only need to explicitly request permissions on iOS.
|
;; NOTE: Only need to explicitly request permissions on iOS.
|
||||||
(defn request-permissions []
|
(defn request-permissions []
|
||||||
(.requestPermissions (.-default rn/react-native-fcm)))
|
(.requestPermissions (.-default rn/react-native-fcm)))
|
||||||
@ -16,14 +23,12 @@
|
|||||||
(-> (.getFCMToken (aget rn/react-native-fcm "default"))
|
(-> (.getFCMToken (aget rn/react-native-fcm "default"))
|
||||||
(.then (fn [x]
|
(.then (fn [x]
|
||||||
(when config/notifications-wip-enabled?
|
(when config/notifications-wip-enabled?
|
||||||
(log/info "FCM token" x)
|
(log/debug "get-fcm-token: " x)
|
||||||
(copy-to-clipboard x)
|
(dispatch [:update-fcm-token x]))))))
|
||||||
(utils/show-popup "INFO" (str "FCM Token in clipboard: " x)))))))
|
|
||||||
|
|
||||||
(defn on-refresh-fcm-token []
|
(defn on-refresh-fcm-token []
|
||||||
(.on (.-default rn/react-native-fcm)
|
(.on (.-default rn/react-native-fcm)
|
||||||
(.-RefreshToken (.-FCMEvent rn/react-native-fcm))
|
(.-RefreshToken (.-FCMEvent rn/react-native-fcm))
|
||||||
(fn [x]
|
(fn [x]
|
||||||
(log/info "FCM token refreshed" x)
|
(log/debug "on-refresh-fcm-token: " x)
|
||||||
(copy-to-clipboard x)
|
(dispatch [:update-fcm-token x]))))
|
||||||
(utils/show-popup "INFO" (str "FCM token (refreshed) in clipboard: " x)))))
|
|
||||||
|
@ -283,7 +283,8 @@
|
|||||||
(let [recieved-contact {:name "test"
|
(let [recieved-contact {:name "test"
|
||||||
:profile-image ""
|
:profile-image ""
|
||||||
:address new-contact-address
|
:address new-contact-address
|
||||||
:status "test status"}
|
:status "test status"
|
||||||
|
:fcm-token "0xwhatever"}
|
||||||
recieved-contact' (merge new-contact
|
recieved-contact' (merge new-contact
|
||||||
(dissoc recieved-contact :profile-image)
|
(dissoc recieved-contact :profile-image)
|
||||||
{:public-key new-contact-public-key
|
{:public-key new-contact-public-key
|
||||||
|
Loading…
x
Reference in New Issue
Block a user