Skip to content

Commit

Permalink
Move contacts to status-go
Browse files Browse the repository at this point in the history
Contacts are now in status-go, no migration of contacts is provided so
all contacts will be lost upon installing this build.

I have left the initialization of filters a bit sketchy (we wait that
load-filters is called twice), as the next step will be to avoid calling
load-filters altogether, as now that both contacts & chats are in
status-go, there's no reason to call it from status-react, and can be
called directly from status-go on loading.
  • Loading branch information
cammellos committed Aug 6, 2019
1 parent 6fa482a commit 6597130
Show file tree
Hide file tree
Showing 13 changed files with 288 additions and 212 deletions.
11 changes: 6 additions & 5 deletions src/status_im/contact/block.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,15 @@
(navigation/navigate-back)))))

(fx/defn unblock-contact
[{:keys [db now]} public-key]
[{:keys [db now] :as cofx} public-key]
(let [contact (-> (get-in db [:contacts/contacts public-key])
(assoc :last-updated now)
(update :system-tags disj :contact/blocked))]
{:db (-> db
(update :contacts/blocked disj public-key)
(assoc-in [:contacts/contacts public-key] contact))
:data-store/tx [(contacts-store/save-contact-tx contact)]}))
(fx/merge cofx
{:db (-> db
(update :contacts/blocked disj public-key)
(assoc-in [:contacts/contacts public-key] contact))}
(contacts-store/save-contact-tx contact))))

(fx/defn block-contact-confirmation
[cofx public-key]
Expand Down
58 changes: 35 additions & 23 deletions src/status_im/contact/core.cljs
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
(ns status-im.contact.core
(:require [status-im.multiaccounts.model :as multiaccounts.model]
[status-im.transport.filters.core :as transport.filters]
[status-im.contact.db :as contact.db]
[status-im.contact.device-info :as device-info]
[status-im.ethereum.core :as ethereum]
[status-im.data-store.contacts :as contacts-store]
[status-im.mailserver.core :as mailserver]
[status-im.transport.message.contact :as message.contact]
[status-im.transport.message.protocol :as protocol]
[status-im.tribute-to-talk.db :as tribute-to-talk]
[status-im.tribute-to-talk.whitelist :as whitelist]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.config :as config]
[status-im.utils.fx :as fx]))
(:require
[re-frame.core :as re-frame]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.transport.filters.core :as transport.filters]
[status-im.contact.db :as contact.db]
[status-im.contact.device-info :as device-info]
[status-im.ethereum.core :as ethereum]
[status-im.data-store.contacts :as contacts-store]
[status-im.mailserver.core :as mailserver]
[status-im.transport.message.contact :as message.contact]
[status-im.transport.message.protocol :as protocol]
[status-im.tribute-to-talk.db :as tribute-to-talk]
[status-im.tribute-to-talk.whitelist :as whitelist]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.config :as config]
[status-im.utils.fx :as fx]))

(fx/defn load-contacts
[{:keys [db all-contacts]}]
{:events [::contacts-loaded]}
[{:keys [db] :as cofx} all-contacts]
(let [contacts-list (map #(vector (:public-key %) %) all-contacts)
contacts (into {} contacts-list)
tr-to-talk-enabled? (-> db tribute-to-talk/get-settings tribute-to-talk/enabled?)]
{:db (cond-> (-> db
(update :contacts/contacts #(merge contacts %))
(assoc :contacts/blocked (contact.db/get-blocked-contacts all-contacts)))
tr-to-talk-enabled?
(assoc :contacts/whitelist (whitelist/get-contact-whitelist all-contacts)))}))
(fx/merge cofx
{:db (cond-> (-> db
(update :contacts/contacts #(merge contacts %))
(assoc :contacts/blocked (contact.db/get-blocked-contacts all-contacts)))
tr-to-talk-enabled?
(assoc :contacts/whitelist (whitelist/get-contact-whitelist all-contacts)))}
;; TODO: This is currently called twice, once we load chats & when we load filters.
;; For now leaving as it is as the next step is not to have this being called from status-react
;; as both contacts & chats are in status-go, but we still need to signals the filters to
;; status-react for mailsevers/gaps, so will address separately
(transport.filters/load-filters))))

(defn build-contact
[{{:keys [chats multiaccount]
Expand All @@ -47,9 +56,9 @@
{:keys [public-key] :as contact}]
(fx/merge cofx
{:db (-> db
(update-in [:contacts/contacts public-key] merge contact))
:data-store/tx [(contacts-store/save-contact-tx contact)]}
(transport.filters/load-contact contact)))
(update-in [:contacts/contacts public-key] merge contact))}
(transport.filters/load-contact contact)
(contacts-store/save-contact-tx contact)))

(fx/defn send-contact-request
[{:keys [db] :as cofx} {:keys [public-key] :as contact}]
Expand Down Expand Up @@ -123,6 +132,9 @@
(def receive-contact-request-confirmation handle-contact-update)
(def receive-contact-update handle-contact-update)

(fx/defn initialize-contacts [cofx]
(contacts-store/fetch-contacts-rpc #(re-frame/dispatch [::contacts-loaded %])))

(fx/defn open-contact-toggle-list
[{:keys [db :as cofx]}]
(fx/merge cofx
Expand Down
91 changes: 47 additions & 44 deletions src/status_im/data_store/contacts.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,64 @@
[taoensso.timbre :as log]
[status-im.data-store.realm.core :as core]))

(defn- deserialize-contact [contact]
(defn deserialize-device-info [contact]
(update contact :deviceInfo (fn [device-info]
(reduce (fn [acc info]
(assoc acc
(:installationId info)
(clojure.set/rename-keys info {:fcmToken :fcm-token :installationId :id})))
{}
device-info))))

(defn serialize-device-info [contact]
(update contact :device-info (fn [device-info]
(map
#(clojure.set/rename-keys % {:fcm-token :fcmToken :id :installationId})
(vals device-info)))))

(defn <-rpc [contact]
(-> contact
(update :tags #(into #{} %))
(update :tribute-to-talk core/deserialize)
(update :system-tags
deserialize-device-info
(update :tributeToTalk core/deserialize)
(update :systemTags
#(reduce (fn [acc s]
(conj acc (keyword (subs s 1))))
#{}
%))))
%)) (clojure.set/rename-keys {:id :public-key
:photoPath :photo-path
:deviceInfo :device-info
:tributeToTalk :tribute-to-talk
:systemTags :system-tags
:lastUpdated :last-updated})))

(defn- serialize-contact [contact]
(defn ->rpc [contact]
(-> contact
(update :device-info #(or (vals %) []))
serialize-device-info
(update :tribute-to-talk core/serialize)
(update :system-tags #(mapv str %))
(update :tribute-to-talk core/serialize)))
(clojure.set/rename-keys {:public-key :id
:photo-path :photoPath
:device-info :deviceInfo
:tribute-to-talk :tributeToTalk
:system-tags :systemTags
:last-updated :lastUpdated})))

(defn save-contact-rpc [{:keys [public-key] :as contact}]
(json-rpc/call {:method "shhext_saveContact"
:params [(->rpc contact)]
:on-success #(log/debug "saved contact" public-key "successfuly")
:on-failure #(log/error "failed to save contact" public-key %)}))

(re-frame/reg-cofx
:data-store/get-all-contacts
(fn [coeffects _]
(assoc coeffects :all-contacts (map deserialize-contact
(-> @core/account-realm
(core/get-all :contact)
(core/all-clj :contact))))))
(defn fetch-contacts-rpc [on-success]
(json-rpc/call {:method "shhext_contacts"
:params []
:on-success #(on-success (map <-rpc %))
:on-failure #(log/error "failed to fetch contacts" %)}))

(defn save-contact-tx
"Returns tx function for saving contact"
[{:keys [public-key] :as contact}]
(fn [realm]
(core/create realm
:contact
(serialize-contact contact)
true)))

(defn save-contacts-tx
"Returns tx function for saving contacts"
[contacts]
(fn [realm]
(doseq [contact contacts]
((save-contact-tx contact) realm))))

(defn- get-contact-by-id [public-key realm]
(.objectForPrimaryKey realm "contact" public-key))
(save-contact-rpc contact))

(defn- get-messages-by-messages-ids
[message-ids]
Expand All @@ -56,26 +72,13 @@
(.objects "message")
(.filtered (str "(" (core/in-query "message-id" message-ids) ")")))))

(defn- get-chat
[public-key]
(core/single
(core/get-by-field @core/account-realm
:chat
:chat-id
public-key)))

(defn block-user-tx
"Returns tx function for deleting user messages"
[{:keys [public-key] :as contact} messages-ids]
(fn [realm]
(core/create realm :contact (serialize-contact contact) true)
(save-contact-rpc contact)
(when-let [user-messages
(get-messages-by-messages-ids messages-ids)]
(core/delete realm user-messages))
(data-store.chats/delete-chat-rpc public-key data-store.chats/one-to-one-chat-type)))

(defn delete-contact-tx
"Returns tx function for deleting contact"
[public-key]
(fn [realm]
(core/delete realm (get-contact-by-id public-key realm))))
1 change: 0 additions & 1 deletion src/status_im/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@
(handlers/register-handler-fx
:init.callback/multiaccount-change-success
[(re-frame/inject-cofx :web3/get-web3)
(re-frame/inject-cofx :data-store/get-all-contacts)
(re-frame/inject-cofx :data-store/get-all-installations)
(re-frame/inject-cofx :data-store/all-chat-requests-ranges)]
multiaccount-change-success)
Expand Down
1 change: 0 additions & 1 deletion src/status_im/init/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@
(fx/merge cofx
{:notifications/get-fcm-token nil}
(initialize-multiaccount-db address)
(contact/load-contacts)
#(when (dev-mode? %)
(models.dev-server/start))
(extensions.module/initialize)
Expand Down
2 changes: 2 additions & 0 deletions src/status_im/multiaccounts/login/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.ethereum.subscriptions :as ethereum.subscriptions]
[status-im.chat.models.loading :as chat.loading]
[status-im.contact.core :as contact]
[status-im.ethereum.transactions.core :as transactions]
[status-im.fleet.core :as fleet]
[status-im.i18n :as i18n]
Expand Down Expand Up @@ -209,6 +210,7 @@
(mobile-network/on-network-status-change)
(protocol/initialize-protocol)
(chat.loading/initialize-chats {:to -1})
(contact/initialize-contacts)
(universal-links/process-stored-event)
(chaos-mode/check-chaos-mode)
(finish-keycard-setup)
Expand Down
5 changes: 3 additions & 2 deletions src/status_im/transport/filters/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,11 @@
:topic topic})

(fx/defn set-filters-initialized [{:keys [db]}]
{:db (assoc db :filters/initialized true)})
{:db (update db :filters/initialized inc)})

;; We check that both chats & contacts have been initialized
(defn filters-initialized? [db]
(:filters/initialized db))
(>= (:filters/initialized db) 2))

(fx/defn handle-filters-added
"Called every time we load a filter from statusgo, either from explicit call
Expand Down
4 changes: 2 additions & 2 deletions src/status_im/tribute_to_talk/whitelist.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
(update :system-tags conj tag))]
(fx/merge cofx
{:db (-> db
(assoc-in [:contacts/contacts public-key] contact))
:data-store/tx [(contacts-store/save-contact-tx contact)]}
(assoc-in [:contacts/contacts public-key] contact))}
(contacts-store/save-contact-tx contact)
(add-to-whitelist public-key))))

(fx/defn mark-tribute-paid
Expand Down
68 changes: 68 additions & 0 deletions test/cljs/status_im/test/data_store/contacts.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
(ns status-im.test.data-store.contacts
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.data-store.contacts :as c]))

(deftest contact->rpc
(let [contact {:public-key "pk"
:address "address"
:name "name"
:photo-path "photo-path"
:tribute-to-talk "tribute-to-talk"
:device-info {"1" {:id "1"
:timestamp 1
:fcm-token "1"}
"2" {:id "2"
:timestamp 2
:fcm-token 3}}
:last-updated 1
:system-tags #{:a :b}}
expected-contact {:id "pk"
:address "address"
:name "name"
:photoPath "photo-path"
:tributeToTalk "[\"~#'\",\"tribute-to-talk\"]"
:deviceInfo [{:installationId "1"
:timestamp 1
:fcmToken "1"}
{:installationId "2"
:timestamp 2
:fcmToken 3}]
:lastUpdated 1
:systemTags #{":a" ":b"}}]
(testing "->rpc"
(is (= expected-contact (update
(c/->rpc contact)
:systemTags
#(into #{} %)))))))

(deftest contact<-rpc
(let [contact {:id "pk"
:address "address"
:name "name"
:photoPath "photo-path"
:tributeToTalk "[\"~#'\",\"tribute-to-talk\"]"

:deviceInfo [{:installationId "1"
:timestamp 1
:fcmToken "1"}
{:installationId "2"
:timestamp 2
:fcmToken 3}]
:lastUpdated 1
:systemTags [":a" ":b"]}
expected-contact {:public-key "pk"
:address "address"
:name "name"
:photo-path "photo-path"
:tribute-to-talk "tribute-to-talk"
:device-info {"1" {:id "1"
:timestamp 1
:fcm-token "1"}
"2" {:id "2"
:timestamp 2
:fcm-token 3}}
:last-updated 1
:system-tags #{:a :b}}]
(testing "<-rpc"
(is (= expected-contact (c/<-rpc contact))))))

Loading

0 comments on commit 6597130

Please sign in to comment.