Refactor add-contacts & add-pending-contact

We wanted to move towards having multiple functions
manipulating the data rather than relying on a chain of
dispatched events.

I have refactored ui.screens.contacts.events so that now the
functions mainly manipulate fx, passed as a first parameter.

Their responsability is to make sure their fx are merged in, so
that they can be composed more easily.

Signed-off-by: Eric Dvorsak <eric@dvorsak.fr>
This commit is contained in:
Andrea Maria Piana 2018-01-15 23:49:40 +00:00 committed by Eric Dvorsak
parent 7012125024
commit 334b15961c
No known key found for this signature in database
GPG Key ID: 932AC1CE5F05DE0C
5 changed files with 145 additions and 66 deletions

View File

@ -6,7 +6,6 @@
[status-im.utils.phone-number :as phone-number-util]
[status-im.utils.sms-listener :as sms-listener]
[status-im.ui.screens.accounts.events :as accounts-events]
[status-im.ui.screens.contacts.events :as contacts-events]
[taoensso.timbre :as log]))
;;;; Helpers fns

View File

@ -17,6 +17,8 @@
[status-im.utils.gfycat.core :refer [generate-gfy]]
[status-im.i18n :refer [label]]
[status-im.ui.screens.contacts.navigation]
[status-im.ui.screens.navigation :as navigation]
[status-im.ui.screens.discover.events :as discover-events]
[status-im.chat.console :as console-chat]
[status-im.commands.events.loading :as loading-events]
[cljs.spec.alpha :as spec]
@ -175,13 +177,19 @@
(fn [_ [on-contacts-event-creator]]
{::fetch-contacts-from-phone! on-contacts-event-creator}))
(defn watch-contact
"Takes effects map, adds effects necessary to start watching contact"
[{:keys [db] :as fx} {:keys [public-key private-key] :as contact}]
(cond-> fx
(and public-key private-key)
(assoc ::watch-contact (merge
(select-keys db [:web3])
(select-keys contact [:whisper-identity :public-key :private-key])))))
(register-handler-fx
:watch-contact
(fn [{:keys [db]} [_ {:keys [public-key private-key] :as contact}]]
(when (and public-key private-key)
{::watch-contact (merge
(select-keys db [:web3])
(select-keys contact [:whisper-identity :public-key :private-key]))})))
(fn [{:keys [db]} [_ contact]]
(watch-contact {:db db} contact)))
(register-handler-fx
:update-contact!
@ -260,7 +268,7 @@
(register-handler-fx
:load-default-contacts!
[(inject-cofx ::get-default-contacts-and-groups)]
(fn [{:keys [db default-contacts default-groups] :as cofx} _]
(fn [{:keys [db default-contacts default-groups]} _]
(let [{:contacts/keys [contacts] :group/keys [contact-groups]} db]
{:dispatch-n (concat
(prepare-default-groups-events contact-groups default-groups)
@ -305,54 +313,62 @@
:contacts/click-handler
:contacts/click-action)))
(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)
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 :fcm-token fcm-token}
(select-keys contact [:whisper-identity])
(select-keys current-account [:name :photo-path :status
:updates-public-key :updates-private-key]))})))
(defn send-contact-request
"Takes effects map, adds effects necessary to send a contact request"
[{{:accounts/keys [accounts current-account-id] :as db} :db :as fx} contact]
(let [current-account (get accounts current-account-id)
fcm-token (get-in db [:notifications :fcm-token])]
(assoc fx
::send-contact-request-fx
(merge
(select-keys db [:current-public-key :web3])
{: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])))))
(register-handler-fx
::add-new-contact
(fn [{:keys [db]} [_ {:keys [whisper-identity] :as contact}]]
{:db (-> db
(update-in [:contacts/contacts whisper-identity] merge contact)
(assoc :contacts/new-identity ""))
:dispatch [::send-contact-request contact]
::save-contact contact}))
(defn add-new-contact [fx {:keys [whisper-identity] :as contact}]
(-> fx
(send-contact-request contact)
(update-in [:db :contacts/contacts whisper-identity] merge contact)
(assoc-in [:db :contacts/new-identity] "")
(assoc ::save-contact contact)))
(register-handler-fx
:add-new-contact-and-open-chat
(fn [{:keys [db]} [_ {:keys [whisper-identity] :as contact}]]
(when-not (get-in db [:contacts/contacts whisper-identity])
(let [contact (assoc contact :address (public-key->address whisper-identity))]
{:dispatch-n [[::add-new-contact contact]
[:start-chat whisper-identity {:navigation-replace? true}]]}))))
(-> {:db db}
(add-new-contact contact)
(update :db #(navigation/navigate-to-clean % :home))
(assoc :dispatch [:start-chat whisper-identity {:navigation-replace? true}]))))))
(defn add-pending-contact [{:keys [db] :as fx} chat-or-whisper-id]
(let [{:keys [chats] :contacts/keys [contacts]} db
contact (if-let [contact-info (get-in chats [chat-or-whisper-id :contact-info])]
(read-string contact-info)
(get contacts chat-or-whisper-id))
contact' (assoc contact
:address (public-key->address chat-or-whisper-id)
:pending? false)]
(-> fx
(watch-contact contact')
(discover-events/send-portions-when-contact-exists chat-or-whisper-id)
(add-new-contact contact'))))
(register-handler-fx
:add-pending-contact
(fn [{:keys [db]} [_ chat-or-whisper-id]]
(let [{:keys [chats] :contacts/keys [contacts]} db
contact (if-let [contact-info (get-in chats [chat-or-whisper-id :contact-info])]
(read-string contact-info)
(get contacts chat-or-whisper-id))
contact' (assoc contact
:address (public-key->address chat-or-whisper-id)
:pending? false)]
{:dispatch-n [[::add-new-contact contact']
[:watch-contact contact']
[:discoveries-send-portions chat-or-whisper-id]]})))
(add-pending-contact {:db db} chat-or-whisper-id)))
(register-handler-fx
:add-pending-contact-and-open-chat
(fn [_ [_ whisper-id]]
{:dispatch-n [[:add-pending-contact whisper-id]
[:start-chat whisper-id {:navigation-replace? true}]]}))
(fn [{:keys [db]} [_ whisper-id]]
(-> {:db db}
(add-pending-contact whisper-id)
(update :db #(navigation/navigate-to-clean % :home))
(assoc :dispatch [:start-chat whisper-id {:navigation-replace? true}]))))
(register-handler-db
:set-contact-identity-from-qr
@ -428,17 +444,16 @@
:group/selected-contacts #{}
:new-chat-name "")
(assoc-in [:toolbar-search :show] nil)
(assoc-in [:toolbar-search :text] ""))
:dispatch [:navigate-to :contact-toggle-list]}))
(assoc-in [:toolbar-search :text] "")
(navigation/navigate-to-clean :contact-toggle-list))}))
(register-handler-fx
:open-chat-with-contact
(fn [_ [_ {:keys [whisper-identity dapp?] :as contact}]]
{:dispatch-n (concat
[[:navigate-to-clean :home]
[:start-chat whisper-identity]]
(when-not dapp?
[[::send-contact-request contact]]))}))
(fn [{:keys [db]} [_ {:keys [whisper-identity dapp?] :as contact}]]
(-> {:db db}
(cond-> (when-not dapp?) (send-contact-request contact))
(update :db #(navigation/navigate-to-clean % :home))
(assoc :dispatch [:start-chat whisper-identity]))))
(register-handler-fx
:add-contact-handler

View File

@ -41,15 +41,17 @@
;; HELPER-FN
(defn send-portions-when-contact-exists
[{:keys [current-public-key web3 discoveries]
:contacts/keys [contacts]}
"Takes fx map and adds send-portions if contact exists"
[{{:keys [current-public-key web3 discoveries]
:contacts/keys [contacts]} :db :as fx}
to]
(when (get contacts to)
{::send-portions {:current-public-key current-public-key
:web3 web3
:contacts contacts
:to to
:discoveries (mapv #(dissoc % :tags) (vals discoveries))}}))
(cond-> fx
(get contacts to)
(assoc ::send-portions {:current-public-key current-public-key
:web3 web3
:contacts contacts
:to to
:discoveries (mapv #(dissoc % :tags) (vals discoveries))})))
(defn add-discover [db {:keys [message-id] :as discover}]
(assoc-in db [:discoveries message-id] discover))
@ -140,12 +142,12 @@
(handlers/register-handler-fx
:discoveries-send-portions
(fn [{:keys [db]} [_ to]]
(send-portions-when-contact-exists db to)))
(send-portions-when-contact-exists {:db db} to)))
(handlers/register-handler-fx
:discoveries-request-received
(fn [{:keys [db]} [_ {:keys [from]}]]
(send-portions-when-contact-exists db from)))
(send-portions-when-contact-exists {:db db} from)))
(handlers/register-handler-fx
:discoveries-response-received

View File

@ -24,13 +24,13 @@
(defn- can-navigate-back? [db]
(not (get db :accounts/creating-account?)))
(defn- navigate-to-clean [db view-id]
;; public fns
(defn navigate-to-clean [db view-id]
(-> db
(assoc :navigation-stack (list))
(push-view view-id)))
;; public fns
(defmulti preload-data!
(fn [db [_ view-id]] (or view-id (:view-id db))))

View File

@ -154,7 +154,7 @@
load-contact-groups
load-default-contacts (add-contact-groups, add-contacts, add-contacts-to-group ;TODO add-chat, load-commands!)
add-contact-handler (add-new-contact-and-open-chat, status-im.contacts.events/add-new-contact,
status-im.contacts.events/send-contact-request, status-im.chat.events.start-chat)
status-im.contacts.events/send-contact-request ;TODO start-chat)
contact-request-received (update-contact, watch-contact ;TODO :update-chat!)
contact-update-received (update-contact ;TODO :update-chat!)
hide-contact (update-contact ;TODO :account-update-keys)
@ -169,6 +169,71 @@
add-contacts-to-group
delete-contact-group"
(testing "watch-contact"
(let [contact {:public-key "public-key"
:private-key "private-key"
:whisper-identity "whisper-identity"}
actual-fx (-> {:db {:web3 "web3"}}
(contacts-events/watch-contact contact)
::contacts-events/watch-contact)]
(testing "it adds a ::watch-contact effect"
(is (not (nil? actual-fx))))
(testing "it adds web3"
(is (= "web3" (:web3 actual-fx))))
(testing "it adds the watched-contact whisper-identity"
(is (= "whisper-identity" (:whisper-identity actual-fx))))
(testing "it adds the public key"
(is (= "public-key" (:public-key actual-fx))))
(testing "it adds the private key"
(is (= "private-key" (:private-key actual-fx))))))
(testing "send-contact-request"
(let [contact {:whisper-identity "contact-whisper-identity"}
account {:name "name"
:photo-path "photo-path"
:status "status"
:updates-public-key "updates-public-key"
:updates-private-key "updates-private-key"}
accounts {"current-account-id" account}
db {:accounts/accounts accounts
:accounts/current-account-id "current-account-id"
:web3 "web3"
:current-public-key "current-public-key"
:notifications {:fcm-token "fcm-token"}}
actual-fx (-> {:db db}
(contacts-events/send-contact-request contact)
::contacts-events/send-contact-request-fx)]
(testing "it adds a ::send-contact-request-fx effect"
(is (not (nil? actual-fx))))
(testing "it adds the current-public-key"
(is (= "current-public-key" (:current-public-key actual-fx))))
(testing "it adds web3"
(is (= "web3" (:web3 actual-fx))))
(testing "it adds the current-account-id"
(is (= "current-account-id" (:current-account-id actual-fx))))
(testing "it adds the fcm-token"
(is (= "fcm-token" (:fcm-token actual-fx))))
(testing "it adds the whisper-identity of the contact"
(is (= "contact-whisper-identity" (:whisper-identity actual-fx))))
(testing "it adds the current-account information"
(is (= account (select-keys actual-fx [:name
:photo-path
:status
:updates-public-key
:updates-private-key]))))))
(run-test-sync
(test-fixtures)
@ -246,7 +311,7 @@
;; :add-new-contact-and-open-chat
;; :status-im.contacts.events/add-new-contact
;; :status-im.contacts.events/send-contact-request
;; :status-im.chat.events/start-chat
;;TODO :start-chat
(rf/dispatch [:add-contact-handler new-contact-public-key])
@ -336,8 +401,6 @@
;; :add-pending-contact
;; :status-im.contacts.events/add-new-contact
;; :status-im.contacts.events/send-contact-request
;; :status-im.chat.events/start-chat
;;TODO :discoveries-send-portions
(rf/reg-event-db :discoveries-send-portions (fn [db _] db))