forked from status-im/status-legacy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhandlers.cljs
More file actions
128 lines (114 loc) · 4.35 KB
/
handlers.cljs
File metadata and controls
128 lines (114 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
(ns status-im.utils.handlers
(:require [cljs.spec.alpha :as spec]
[re-frame.core :as re-frame]
[re-frame.interceptor :refer [->interceptor get-coeffect get-effect]]
[status-im.multiaccounts.model :as multiaccounts.model]
[taoensso.timbre :as log]))
(def pre-event-callback (atom nil))
(defn add-pre-event-callback [callback]
(reset! pre-event-callback callback))
(defn side-effect!
"Middleware for handlers that will not affect db."
[handler]
(fn [db params]
(handler db params)
db))
(defn- pretty-print-event [ctx]
(let [[first second] (get-coeffect ctx :event)]
first))
(def debug-handlers-names
"Interceptor which logs debug information to js/console for each event."
(->interceptor
:id :debug-handlers-names
:before (fn debug-handlers-names-before
[context]
(when @pre-event-callback
(@pre-event-callback (get-coeffect context :event)))
(log/debug "Handling re-frame event: " (pretty-print-event context))
context)))
(def logged-in
"Interceptor which stops the event chain if the user is logged out"
(->interceptor
:id :logged-in
:before (fn logged-in-before
[context]
(when (multiaccounts.model/logged-in? (:coeffects context))
context))))
(defn- check-spec-msg-path-problem [problem]
(str "Spec: " (-> problem :via last) "\n"
"Predicate: " (subs (str (:pred problem)) 0 50)))
(defn- check-spec-msg-path-problems [path path-problems]
(str "Key path: " path "\n"
"Val: " (pr-str (-> path-problems first :val)) "\n\n"
"Number of problems: " (count path-problems) "\n\n"
(->> path-problems
(map check-spec-msg-path-problem)
(interpose "\n\n")
(apply str))))
(defn- check-spec-msg [event-id db]
(let [explain-data (spec/explain-data :status-im.ui.screens.db/db db)
problems (::spec/problems explain-data)
db-root-keys (->> problems (map (comp first :in)) set)
heading #(str "\n\n------\n" % "\n------\n\n")
msg (str "re-frame db spec check failed."
(heading "SUMMARY")
"After event id: " event-id "\n"
"Number of problems: " (count problems) "\n\n"
"Failing root db keys:\n"
(->> db-root-keys (interpose "\n") (apply str))
(heading "PROBLEMS")
(->> problems
(group-by :in)
(map (fn [[path path-problems]]
(check-spec-msg-path-problems path path-problems)))
(interpose "\n\n-----\n\n")
(apply str)))]
msg))
(def check-spec
"throw an exception if db doesn't match the spec"
(->interceptor
:id check-spec
:after
(fn check-handler
[context]
(let [new-db (get-effect context :db)
event-id (-> (get-coeffect context :event) first)]
(when (and new-db (not (spec/valid? :status-im.ui.screens.db/db new-db)))
(throw (ex-info (check-spec-msg event-id new-db) {})))
context))))
(def default-interceptors
[debug-handlers-names
(when js/goog.DEBUG
check-spec)
(re-frame/inject-cofx :now)])
(defn- parse-json
;; NOTE(dmitryn) Expects JSON response like:
;; {"error": "msg"} or {"result": true}
[s]
(try
(let [res (-> s
js/JSON.parse
(js->clj :keywordize-keys true))]
;; NOTE(dmitryn): AddPeer() may return {"error": ""}
;; assuming empty error is a success response
;; by transforming {"error": ""} to {:result true}
(if (and (:error res)
(= (:error res) ""))
{:result true}
res))
(catch :default e
{:error (.-message e)})))
(defn response-handler [success-fn error-fn]
(fn handle-response
([response]
(let [{:keys [error result]} (parse-json response)]
(handle-response error result)))
([error result]
(if error
(error-fn error)
(success-fn result)))))
(defn register-handler-fx
([name handler]
(register-handler-fx name nil handler))
([name interceptors handler]
(re-frame/reg-event-fx name [default-interceptors interceptors] handler)))