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:
Oskar Thorén 2017-09-16 09:08:47 +02:00 committed by Roman Volosovskyi
parent b889a07a86
commit b5c0b24f30
14 changed files with 119 additions and 22 deletions

View File

@ -1,6 +1,6 @@
TESTFAIRY_ENABLED=1
WALLET_WIP_ENABLED=1
NOTIFICATIONS_WIP_ENABLED=0
NOTIFICATIONS_WIP_ENABLED=1
DEBUG_LOGS_ENABLED=1
STUB_STATUS_GO=0

View File

@ -360,6 +360,26 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
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
public void recoverAccount(final String passphrase, final String password, final Callback callback) {
Log.d(TAG, "recoverAccount");

View File

@ -311,6 +311,19 @@ RCT_EXPORT_METHOD(createAccount:(NSString *)password
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
RCT_EXPORT_METHOD(recoverAccount:(NSString *)passphrase
password:(NSString *)password

View File

@ -21,6 +21,7 @@
[taoensso.timbre :refer-macros [debug] :as log]
[status-im.chat.handlers.console :as console]
[status-im.utils.types :as types]
[status-im.utils.config :as config]
[status-im.utils.clocks :as clocks]))
(defn prepare-command
@ -298,6 +299,14 @@
{:result result
: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!
(u/side-effect!
(fn [{:keys [web3 chats network-status]
@ -306,7 +315,7 @@
:as db} [_ {{:keys [message-type]
:as message} :message
chat-id :chat-id}]]
(let [{:keys [dapp?]} (get contacts chat-id)]
(let [{:keys [dapp? fcm-token]} (get contacts chat-id)]
(if dapp?
(dispatch [::send-dapp-message chat-id message])
(when message
@ -333,8 +342,9 @@
:username username)))
:else
(protocol/send-message! (assoc-in options
[:message :to] (:to message)))))))))))
(do (protocol/send-message! (assoc-in options
[:message :to] (:to message)))
(send-notification fcm-token (:message options)))))))))))
(register-handler ::send-command-protocol!
(u/side-effect!

View File

@ -13,6 +13,8 @@
[status-im.data-store.realm.schemas.account.v12.core :as v12]
[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
(def schemas [{:schema v1/schema
:schemaVersion 1

View File

@ -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}}})

View File

@ -3,7 +3,7 @@
[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.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.kv-store :as kv-store]
[status-im.data-store.realm.schemas.account.v10.message :as message]

View File

@ -114,6 +114,10 @@
true)
false))))))
(defn notify [token on-result]
(when status
(call-module #(.notify status token on-result))))
(defn recover-account [passphrase password on-result]
(when status
(call-module #(.recoverAccount status passphrase password on-result))))

View File

@ -361,8 +361,8 @@
(u/side-effect!
(fn [{:contacts/keys [contacts]} [_ {:keys [from payload]}]]
(when from
(let [{{:keys [name profile-image address status]} :contact
{:keys [public private]} :keypair} payload
(let [{{:keys [name profile-image address status fcm-token]} :contact
{:keys [public private]} :keypair} payload
existing-contact (get contacts from)
contact {:whisper-identity from
:public-key public
@ -370,7 +370,8 @@
:address address
:status status
:photo-path profile-image
:name name}
:name name
:fcm-token fcm-token}
chat {:name name
:chat-id from
:contact-info (prn-str contact)}]

View File

@ -22,6 +22,7 @@
(spec/def :contact/public-key (spec/nilable string?))
(spec/def :contact/photo-path (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-online (spec/nilable int?))
@ -46,7 +47,8 @@
:contact/status :contact/last-updated :contact/last-online :contact/pending?
:contact/unremovable? :contact/dapp? :contact/dapp-url :contact/dapp-hash
: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
(spec/def :contact-list-ui/edit? boolean?)

View File

@ -51,7 +51,8 @@
(reg-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}]
(protocol/contact-request!
{:web3 web3
@ -61,7 +62,8 @@
:payload {:contact {:name name
:profile-image photo-path
:address current-account-id
:status status}
:status status
:fcm-token fcm-token}
:keypair {:public updates-public-key
:private updates-private-key}}}})))
@ -311,10 +313,11 @@
(register-handler-fx
::send-contact-request
(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
(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 current-account [:name :photo-path :status
:updates-public-key :updates-private-key]))})))

View File

@ -33,6 +33,7 @@
:sync-state :done
:wallet {}
:prices {}
:notifications {}
:network "testnet"})
;;;;GLOBAL
@ -176,4 +177,5 @@
:discoveries/new-discover
:wallet/wallet
:prices/prices
:prices/prices-loading?]))
:prices/prices-loading?
:notifications/notifications]))

View File

@ -1,5 +1,7 @@
(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.utils :as utils]
[status-im.components.react :refer [copy-to-clipboard]]
@ -8,6 +10,11 @@
;; Work in progress namespace responsible for push notifications and interacting
;; 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.
(defn request-permissions []
(.requestPermissions (.-default rn/react-native-fcm)))
@ -16,14 +23,12 @@
(-> (.getFCMToken (aget rn/react-native-fcm "default"))
(.then (fn [x]
(when config/notifications-wip-enabled?
(log/info "FCM token" x)
(copy-to-clipboard x)
(utils/show-popup "INFO" (str "FCM Token in clipboard: " x)))))))
(log/debug "get-fcm-token: " x)
(dispatch [:update-fcm-token x]))))))
(defn on-refresh-fcm-token []
(.on (.-default rn/react-native-fcm)
(.-RefreshToken (.-FCMEvent rn/react-native-fcm))
(fn [x]
(log/info "FCM token refreshed" x)
(copy-to-clipboard x)
(utils/show-popup "INFO" (str "FCM token (refreshed) in clipboard: " x)))))
(log/debug "on-refresh-fcm-token: " x)
(dispatch [:update-fcm-token x]))))

View File

@ -283,7 +283,8 @@
(let [recieved-contact {:name "test"
:profile-image ""
:address new-contact-address
:status "test status"}
:status "test status"
:fcm-token "0xwhatever"}
recieved-contact' (merge new-contact
(dissoc recieved-contact :profile-image)
{:public-key new-contact-public-key