From 9b04dc6530746cda9bffef66d5df483a7c29a2c9 Mon Sep 17 00:00:00 2001 From: yenda Date: Thu, 23 May 2019 17:30:47 +0200 Subject: [PATCH] [dev feature] extend the defn macro the defn macro knows register the function as an events under the keywords provided in the :events key of the attributes map. It also adds the interceptors provided in the :interceptors map exemple: ```clojure (fx/defn hello4 {:doc "this function is useless as well" :events [:test/valid1 :test/valid2]} [{:keys [db]} b] {:db (assoc db :a b) :b (:a db)}) ``` Signed-off-by: yenda --- src/status_im/accounts/login/core.cljs | 23 +++++++++++++++- src/status_im/events.cljs | 14 ---------- src/status_im/tribute_to_talk/core.cljs | 2 +- src/status_im/utils/fx.clj | 35 ++++++++++++++++++------- test/cljs/status_im/test/utils/fx.cljs | 12 +++++++++ 5 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/status_im/accounts/login/core.cljs b/src/status_im/accounts/login/core.cljs index 5a3d1d6f32..3c290cc9d1 100644 --- a/src/status_im/accounts/login/core.cljs +++ b/src/status_im/accounts/login/core.cljs @@ -90,7 +90,23 @@ (transactions/initialize) (ethereum.subscriptions/initialize))) -(fx/defn user-login [{:keys [db] :as cofx} create-database?] +(fx/defn user-login-without-creating-db + {:events [:accounts.login.ui/password-input-submitted]} + [{:keys [db] :as cofx}] + (let [{:keys [address password]} (accounts.db/credentials cofx)] + (fx/merge + cofx + {:db (-> db + (assoc-in [:accounts/login :processing] true) + (assoc :node/on-ready :login)) + :accounts.login/clear-web-data nil + :data-store/change-account [address + password + false + (get-in db [:accounts/accounts address :settings :fleet])]}))) + +(fx/defn user-login + [{:keys [db] :as cofx} create-database?] (let [{:keys [address password]} (accounts.db/credentials cofx)] (fx/merge cofx @@ -120,6 +136,11 @@ :dispatch [:accounts.logout.ui/logout-confirmed]})) (fx/defn user-login-callback + {:events [:accounts.login.callback/login-success] + :interceptors [(re-frame/inject-cofx :web3/get-web3) + (re-frame/inject-cofx :data-store/get-all-mailservers) + (re-frame/inject-cofx :data-store/transport) + (re-frame/inject-cofx :data-store/mailserver-topics)]} [{:keys [db web3] :as cofx} login-result] (let [data (types/json->clj login-result) error (:error data) diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index ddd2234d05..bd40019d0e 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -308,20 +308,6 @@ ;; accounts login module -(handlers/register-handler-fx - :accounts.login.ui/password-input-submitted - (fn [cofx _] - (accounts.login/user-login cofx false))) - -(handlers/register-handler-fx - :accounts.login.callback/login-success - [(re-frame/inject-cofx :web3/get-web3) - (re-frame/inject-cofx :data-store/get-all-mailservers) - (re-frame/inject-cofx :data-store/transport) - (re-frame/inject-cofx :data-store/mailserver-topics)] - (fn [cofx [_ login-result]] - (accounts.login/user-login-callback cofx login-result))) - (handlers/register-handler-fx :accounts.login.callback/verify-success (fn [cofx [_ verify-result realm-error]] diff --git a/src/status_im/tribute_to_talk/core.cljs b/src/status_im/tribute_to_talk/core.cljs index 42a1308435..d41363fcca 100644 --- a/src/status_im/tribute_to_talk/core.cljs +++ b/src/status_im/tribute_to_talk/core.cljs @@ -247,7 +247,7 @@ [:navigation/screen-params :tribute-to-talk :state] :transaction-failed)}))) -(defn remove +(fx/defn remove [{:keys [db] :as cofx}] (fx/merge cofx {:db (assoc-in db [:navigation/screen-params :tribute-to-talk] diff --git a/src/status_im/utils/fx.clj b/src/status_im/utils/fx.clj index ee6bedff57..d32c8bbf73 100644 --- a/src/status_im/utils/fx.clj +++ b/src/status_im/utils/fx.clj @@ -1,6 +1,15 @@ (ns status-im.utils.fx (:refer-clojure :exclude [defn])) +(defn- register-events + [events interceptors name args] + (mapv (fn [event] + `(status-im.utils.handlers/register-handler-fx + ~event + ~interceptors + (fn [cofx# [_# ~@args]] (~name cofx# ~@args)))) + events)) + (defmacro defn "Defines an fx producing function Takes the same arguments as the defn macro @@ -12,7 +21,8 @@ Notes: - destructuring of cofx is possible - supports docstring - - supports attr-map + - supports attr-map with optional :events key which needs to be a vector of + event keywords under which the function will be registered - TODO: add suport for `prepost-map?` (don't forget to add it to arglist) - TODO: add validation of macro parameters" {:arglists '([name doc-string? attr-map? [params*] body])} @@ -26,17 +36,24 @@ m (if (map? (first fdecl)) (conj m (first fdecl)) m) + events (get m :events []) + interceptors (get m :interceptors []) fdecl (if (map? (first fdecl)) (next fdecl) fdecl) [cofx & args] (first fdecl) fdecl (next fdecl) argsyms (take (count args) (repeatedly #(gensym "arg")))] - `(clojure.core/defn ~(with-meta name m) - ([~@argsyms] (fn [cofx#] (~name cofx# ~@argsyms))) - ([cofx# ~@args] - (if (and (map? cofx#) - (not (nil? (:db cofx#)))) - (let [~cofx cofx#] - ~@fdecl) - (throw (js/Error. (str "fx/defn expects a map of cofx as first argument got " cofx# " in function " ~name)))))))) + (if (and (sequential? events) + (every? keyword? events)) + `(do + (clojure.core/defn ~(with-meta name m) + ([~@argsyms] (fn [cofx#] (~(with-meta name m) cofx# ~@argsyms))) + ([cofx# ~@args] + (if (and (map? cofx#) + (not (nil? (:db cofx#)))) + (let [~cofx cofx#] + ~@fdecl) + (throw (js/Error. (str "fx/defn expects a map of cofx as first argument got " cofx# " in function " ~name)))))) + ~@(register-events events interceptors (with-meta name m) args)) + (throw (Exception. (str "fx/defn expects a vector of keyword as value for :events key in attr-map in function " name)))))) diff --git a/test/cljs/status_im/test/utils/fx.cljs b/test/cljs/status_im/test/utils/fx.cljs index 33ffb60b3a..82a7f4ce2c 100644 --- a/test/cljs/status_im/test/utils/fx.cljs +++ b/test/cljs/status_im/test/utils/fx.cljs @@ -17,6 +17,18 @@ [{:keys [db]} b] (identity nil)) +(fx/defn hello4 + {:doc "this function is useless as well" + :events [:test/valid1 :test/valid2]} + [{:keys [db]} b] + {:db (assoc db :a b) :b (:a db)}) + +(fx/defn hello5 + "lol lazy function does nothing" + {:events [:test]} + [{:keys [db]} b] + (identity nil)) + (deftest merge-fxs-test (testing "merge function for fxs" (let [cofx {:db {:c 2}}]