[ISSUE #3537] Added mixpanel support
Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
parent
581d4f04a5
commit
f1e41cc7ab
1
.env
1
.env
|
@ -13,3 +13,4 @@ RN_BRIDGE_THRESHOLD_WARNINGS=0
|
||||||
COMPILE_VIEWS_ENABLED=0
|
COMPILE_VIEWS_ENABLED=0
|
||||||
POW_TARGET=0.001
|
POW_TARGET=0.001
|
||||||
POW_TIME=1
|
POW_TIME=1
|
||||||
|
MIXPANEL_TOKEN=3f2e1a8970f159aa2a3d5dc5d65eab38
|
||||||
|
|
|
@ -11,5 +11,6 @@ QUEUE_MESSAGE_ENABLED=1
|
||||||
MANY_WHISPER_TOPICS_ENABLED=0
|
MANY_WHISPER_TOPICS_ENABLED=0
|
||||||
RN_BRIDGE_THRESHOLD_WARNINGS=0
|
RN_BRIDGE_THRESHOLD_WARNINGS=0
|
||||||
COMPILE_VIEWS_ENABLED=0
|
COMPILE_VIEWS_ENABLED=0
|
||||||
|
MIXPANEL_TOKEN=3f2e1a8970f159aa2a3d5dc5d65eab38
|
||||||
POW_TARGET=0.001
|
POW_TARGET=0.001
|
||||||
POW_TIME=1
|
POW_TIME=1
|
||||||
|
|
|
@ -11,5 +11,6 @@ QUEUE_MESSAGE_ENABLED=0
|
||||||
MANY_WHISPER_TOPICS_ENABLED=0
|
MANY_WHISPER_TOPICS_ENABLED=0
|
||||||
RN_BRIDGE_THRESHOLD_WARNINGS=0
|
RN_BRIDGE_THRESHOLD_WARNINGS=0
|
||||||
COMPILE_VIEWS_ENABLED=0
|
COMPILE_VIEWS_ENABLED=0
|
||||||
|
MIXPANEL_TOKEN=2584e00100d319d12e538cc4d0fa9fc1
|
||||||
POW_TARGET=0.2
|
POW_TARGET=0.2
|
||||||
POW_TIME=1
|
POW_TIME=1
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
(defn- generate-context
|
(defn- generate-context
|
||||||
"Generates context for jail call"
|
"Generates context for jail call"
|
||||||
[current-account-id chat-id to group-id]
|
[current-account-id chat-id to group-id]
|
||||||
(merge {:platform platform/platform
|
(merge {:platform platform/os
|
||||||
:from current-account-id
|
:from current-account-id
|
||||||
:to to
|
:to to
|
||||||
:chat {:chat-id chat-id
|
:chat {:chat-id chat-id
|
||||||
|
|
|
@ -109,7 +109,7 @@
|
||||||
::account-created
|
::account-created
|
||||||
[re-frame/trim-v (re-frame/inject-cofx :get-new-keypair!)
|
[re-frame/trim-v (re-frame/inject-cofx :get-new-keypair!)
|
||||||
(re-frame/inject-cofx ::get-signing-phrase) (re-frame/inject-cofx ::get-status)]
|
(re-frame/inject-cofx ::get-signing-phrase) (re-frame/inject-cofx ::get-status)]
|
||||||
(fn [{:keys [keypair signing-phrase status db] :as cofx} [{:keys [pubkey address mnemonic]} password]]
|
(fn [{:keys [keypair signing-phrase status db]} [{:keys [pubkey address mnemonic]} password]]
|
||||||
(let [normalized-address (utils.hex/normalize-hex address)
|
(let [normalized-address (utils.hex/normalize-hex address)
|
||||||
account {:public-key pubkey
|
account {:public-key pubkey
|
||||||
:address normalized-address
|
:address normalized-address
|
||||||
|
@ -208,6 +208,12 @@
|
||||||
:dispatch [:navigate-to-clean :usage-data]}
|
:dispatch [:navigate-to-clean :usage-data]}
|
||||||
(account-update {:name (:name create)}))))
|
(account-update {:name (:name create)}))))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:account-finalized
|
||||||
|
(fn [{db :db} _]
|
||||||
|
{:db db
|
||||||
|
:dispatch [:navigate-to-clean :home]}))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:update-sign-in-time
|
:update-sign-in-time
|
||||||
(fn [{db :db now :now} _]
|
(fn [{db :db now :now} _]
|
||||||
|
|
|
@ -120,13 +120,14 @@
|
||||||
|
|
||||||
(register-handler-fx
|
(register-handler-fx
|
||||||
:change-account-handler
|
:change-account-handler
|
||||||
(fn [{{:keys [view-id] :as db} :db} [_ error address]]
|
(fn [{{:keys [accounts/accounts view-id] :as db} :db} [_ error address]]
|
||||||
(if (nil? error)
|
(if (nil? error)
|
||||||
{:db (cond-> (dissoc db :accounts/login)
|
{:db (cond-> (dissoc db :accounts/login)
|
||||||
(= view-id :create-account)
|
(= view-id :create-account)
|
||||||
(assoc-in [:accounts/create :step] :enter-name))
|
(assoc-in [:accounts/create :step] :enter-name))
|
||||||
:dispatch-n (concat
|
:dispatch-n (concat
|
||||||
[[:stop-debugging]
|
[[:stop-debugging]
|
||||||
|
(when (:sharing-usage-data? (accounts address)) [:register-mixpanel-tracking address])
|
||||||
[:initialize-account address
|
[:initialize-account address
|
||||||
(when (not= view-id :create-account)
|
(when (not= view-id :create-account)
|
||||||
[[:navigate-to-clean :home]])]])}
|
[[:navigate-to-clean :home]])]])}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
[clojure.string :as s]
|
[clojure.string :as s]
|
||||||
[status-im.protocol.core :as protocol]
|
[status-im.protocol.core :as protocol]
|
||||||
[status-im.utils.contacts :as utils.contacts]
|
[status-im.utils.contacts :as utils.contacts]
|
||||||
[status-im.utils.utils :refer [http-post]]
|
|
||||||
[status-im.utils.random :as random]
|
[status-im.utils.random :as random]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[cljs.reader :refer [read-string]]
|
[cljs.reader :refer [read-string]]
|
||||||
|
|
|
@ -34,12 +34,15 @@
|
||||||
[status-im.js-dependencies :as dependencies]
|
[status-im.js-dependencies :as dependencies]
|
||||||
[status-im.ui.screens.db :refer [app-db]]
|
[status-im.ui.screens.db :refer [app-db]]
|
||||||
[status-im.utils.datetime :as time]
|
[status-im.utils.datetime :as time]
|
||||||
|
[status-im.utils.ethereum.core :as ethereum]
|
||||||
[status-im.utils.random :as random]
|
[status-im.utils.random :as random]
|
||||||
[status-im.utils.config :as config]
|
[status-im.utils.config :as config]
|
||||||
[status-im.utils.crypt :as crypt]
|
[status-im.utils.crypt :as crypt]
|
||||||
[status-im.utils.notifications :as notifications]
|
[status-im.utils.notifications :as notifications]
|
||||||
[status-im.utils.handlers :as handlers]
|
[status-im.utils.handlers :as handlers]
|
||||||
|
[status-im.utils.http :as http]
|
||||||
[status-im.utils.instabug :as inst]
|
[status-im.utils.instabug :as inst]
|
||||||
|
[status-im.utils.mixpanel :as mixpanel]
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[status-im.utils.types :as types]
|
[status-im.utils.types :as types]
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
|
@ -113,14 +116,14 @@
|
||||||
(let [on-success #(re-frame/dispatch (success-event-creator %))
|
(let [on-success #(re-frame/dispatch (success-event-creator %))
|
||||||
on-error #(re-frame/dispatch (failure-event-creator %))
|
on-error #(re-frame/dispatch (failure-event-creator %))
|
||||||
opts {:timeout-ms timeout-ms}]
|
opts {:timeout-ms timeout-ms}]
|
||||||
(utils/http-post action data on-success on-error opts))))
|
(http/post action data on-success on-error opts))))
|
||||||
|
|
||||||
(defn- http-get [{:keys [url response-validator success-event-creator failure-event-creator timeout-ms]}]
|
(defn- http-get [{:keys [url response-validator success-event-creator failure-event-creator timeout-ms]}]
|
||||||
(let [on-success #(re-frame/dispatch (success-event-creator %))
|
(let [on-success #(re-frame/dispatch (success-event-creator %))
|
||||||
on-error #(re-frame/dispatch (failure-event-creator %))
|
on-error #(re-frame/dispatch (failure-event-creator %))
|
||||||
opts {:valid-response? response-validator
|
opts {:valid-response? response-validator
|
||||||
:timeout-ms timeout-ms}]
|
:timeout-ms timeout-ms}]
|
||||||
(utils/http-get url on-success on-error opts)))
|
(http/get url on-success on-error opts)))
|
||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
:http-get
|
:http-get
|
||||||
|
@ -204,7 +207,6 @@
|
||||||
:close-application
|
:close-application
|
||||||
(fn [] (status/close-application)))
|
(fn [] (status/close-application)))
|
||||||
|
|
||||||
|
|
||||||
;;;; Handlers
|
;;;; Handlers
|
||||||
|
|
||||||
(handlers/register-handler-db
|
(handlers/register-handler-db
|
||||||
|
@ -250,8 +252,7 @@
|
||||||
status-module-initialized? status-node-started?
|
status-module-initialized? status-node-started?
|
||||||
inbox/wnode]
|
inbox/wnode]
|
||||||
:or [network (get app-db :network)
|
:or [network (get app-db :network)
|
||||||
wnode (get app-db :inbox/wnode)]
|
wnode (get app-db :inbox/wnode)]} [_ address]]
|
||||||
:as db} [_ address]]
|
|
||||||
(let [console-contact (get contacts console-chat-id)]
|
(let [console-contact (get contacts console-chat-id)]
|
||||||
(cond-> (assoc app-db
|
(cond-> (assoc app-db
|
||||||
:access-scope->commands-responses access-scope->commands-responses
|
:access-scope->commands-responses access-scope->commands-responses
|
||||||
|
@ -332,6 +333,25 @@
|
||||||
(fn [_ _]
|
(fn [_ _]
|
||||||
{::get-fcm-token-fx nil}))
|
{::get-fcm-token-fx nil}))
|
||||||
|
|
||||||
|
(defn- track [id event]
|
||||||
|
(let [anonid (ethereum/sha3 id)]
|
||||||
|
(doseq [{:keys [label properties]} (mixpanel/matching-events event mixpanel/event-by-trigger)]
|
||||||
|
(mixpanel/track anonid label properties))))
|
||||||
|
|
||||||
|
(def hook-id :mixpanel-callback)
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:register-mixpanel-tracking
|
||||||
|
(fn [_ [_ id]]
|
||||||
|
(re-frame/add-post-event-callback hook-id #(track id %))
|
||||||
|
nil))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:unregister-mixpanel-tracking
|
||||||
|
(fn []
|
||||||
|
(re-frame/remove-post-event-callback hook-id)
|
||||||
|
nil))
|
||||||
|
|
||||||
;; Because we send command to jail in params and command `:ref` is a lookup vector with
|
;; Because we send command to jail in params and command `:ref` is a lookup vector with
|
||||||
;; keyword in it (for example `["transactor" :command 51 "send"]`), we lose that keyword
|
;; keyword in it (for example `["transactor" :command 51 "send"]`), we lose that keyword
|
||||||
;; information in the process of converting to/from JSON, and we need to restore it
|
;; information in the process of converting to/from JSON, and we need to restore it
|
||||||
|
|
|
@ -107,20 +107,22 @@
|
||||||
:icon-content [components.common/counter {:size 22} 1]}]
|
:icon-content [components.common/counter {:size 22} 1]}]
|
||||||
[profile.components/settings-item-separator]])])
|
[profile.components/settings-item-separator]])])
|
||||||
|
|
||||||
(defn navigate-to-accounts []
|
(defn navigate-to-accounts [sharing-usage-data?]
|
||||||
;; TODO(rasom): probably not the best place for this call
|
;; TODO(rasom): probably not the best place for this call
|
||||||
(protocol/stop-whisper!)
|
(protocol/stop-whisper!)
|
||||||
(re-frame/dispatch [:navigate-to :accounts]))
|
(re-frame/dispatch [:navigate-to :accounts])
|
||||||
|
(when sharing-usage-data?
|
||||||
|
(re-frame/dispatch [:unregister-mixpanel-tracking])))
|
||||||
|
|
||||||
(defn handle-logout []
|
(defn handle-logout [sharing-usage-data?]
|
||||||
(utils/show-confirmation (i18n/label :t/logout-title)
|
(utils/show-confirmation (i18n/label :t/logout-title)
|
||||||
(i18n/label :t/logout-are-you-sure)
|
(i18n/label :t/logout-are-you-sure)
|
||||||
(i18n/label :t/logout) navigate-to-accounts))
|
(i18n/label :t/logout) #(navigate-to-accounts sharing-usage-data?)))
|
||||||
|
|
||||||
(defn logout []
|
(defn logout [sharing-usage-data?]
|
||||||
[react/view {}
|
[react/view {}
|
||||||
[react/touchable-highlight
|
[react/touchable-highlight
|
||||||
{:on-press handle-logout
|
{:on-press #(handle-logout sharing-usage-data?)
|
||||||
:accessibility-label :log-out-button}
|
:accessibility-label :log-out-button}
|
||||||
[react/view profile.components.styles/settings-item
|
[react/view profile.components.styles/settings-item
|
||||||
[react/text {:style styles/logout-text
|
[react/text {:style styles/logout-text
|
||||||
|
@ -159,7 +161,7 @@
|
||||||
:action-fn #(re-frame/dispatch [:switch-dev-mode %])}]])]))
|
:action-fn #(re-frame/dispatch [:switch-dev-mode %])}]])]))
|
||||||
|
|
||||||
(defview my-profile []
|
(defview my-profile []
|
||||||
(letsubs [{:keys [public-key] :as current-account} [:get-current-account]
|
(letsubs [{:keys [public-key sharing-usage-data?] :as current-account} [:get-current-account]
|
||||||
editing? [:get :my-profile/editing?]
|
editing? [:get :my-profile/editing?]
|
||||||
changed-account [:get :my-profile/profile]]
|
changed-account [:get :my-profile/profile]]
|
||||||
(let [shown-account (merge current-account changed-account)]
|
(let [shown-account (merge current-account changed-account)]
|
||||||
|
@ -174,5 +176,5 @@
|
||||||
[share-contact-code current-account public-key]]
|
[share-contact-code current-account public-key]]
|
||||||
[react/view styles/my-profile-info-container
|
[react/view styles/my-profile-info-container
|
||||||
[my-profile-settings current-account]]
|
[my-profile-settings current-account]]
|
||||||
[logout]
|
[logout sharing-usage-data?]
|
||||||
[advanced shown-account]]])))
|
[advanced shown-account]]])))
|
|
@ -1,16 +1,13 @@
|
||||||
(ns status-im.ui.screens.qr-scanner.styles
|
(ns status-im.ui.screens.qr-scanner.styles
|
||||||
(:require [status-im.ui.components.styles :refer [color-white]]
|
(:require [status-im.ui.components.colors :as colors]
|
||||||
[status-im.ui.components.toolbar.styles :as toolbar.styles]
|
[status-im.ui.components.toolbar.styles :as toolbar.styles]))
|
||||||
[status-im.utils.platform :as p]))
|
|
||||||
|
|
||||||
(def barcode-scanner-container
|
(def barcode-scanner-container
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:background-color :white})
|
:background-color :white})
|
||||||
|
|
||||||
(def barcode-scanner
|
(def barcode-scanner
|
||||||
{:flex 1
|
{:flex 1})
|
||||||
:justify-content :flex-end
|
|
||||||
:align-items :center})
|
|
||||||
|
|
||||||
(def rectangle-container
|
(def rectangle-container
|
||||||
{:position :absolute
|
{:position :absolute
|
||||||
|
@ -73,5 +70,5 @@
|
||||||
(def import-text
|
(def import-text
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:flex-direction :column
|
:flex-direction :column
|
||||||
:color color-white
|
:color colors/white
|
||||||
:margin-left 8})
|
:margin-left 8})
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:help-improve-handler
|
:help-improve-handler
|
||||||
(fn [{db :db} [_ yes?]]
|
(fn [{db :db} [_ yes? address]]
|
||||||
(merge (when yes?
|
(merge (when yes?
|
||||||
(accounts/account-update {:db db} {:sharing-usage-data? true}))
|
(accounts/account-update {:db db} {:sharing-usage-data? true}))
|
||||||
{:dispatch [:navigate-to-clean :home]})))
|
{:dispatch-n [(when yes? [:register-mixpanel-tracking address])
|
||||||
|
[:account-finalized]]})))
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(ns status-im.ui.screens.usage-data.views
|
(ns status-im.ui.screens.usage-data.views
|
||||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
(:require-macros [status-im.utils.views :as views])
|
||||||
(:require [status-im.ui.components.react :as react]
|
(:require [status-im.ui.components.react :as react]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.react-native.resources :as resources]
|
[status-im.react-native.resources :as resources]
|
||||||
|
@ -8,7 +8,8 @@
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.ui.components.status-bar.view :as status-bar]))
|
[status-im.ui.components.status-bar.view :as status-bar]))
|
||||||
|
|
||||||
(defview usage-data []
|
(views/defview usage-data []
|
||||||
|
(views/letsubs [account [:get-current-account]]
|
||||||
[react/view {:style styles/usage-data-view}
|
[react/view {:style styles/usage-data-view}
|
||||||
[status-bar/status-bar {:flat? true}]
|
[status-bar/status-bar {:flat? true}]
|
||||||
[react/view {:style styles/logo-container}
|
[react/view {:style styles/logo-container}
|
||||||
|
@ -22,9 +23,9 @@
|
||||||
(i18n/label :t/help-improve-description)]]
|
(i18n/label :t/help-improve-description)]]
|
||||||
[react/view styles/buttons-container
|
[react/view styles/buttons-container
|
||||||
[components.common/button {:style {:flex-direction :row}
|
[components.common/button {:style {:flex-direction :row}
|
||||||
:on-press #(re-frame/dispatch [:help-improve-handler true])
|
:on-press #(re-frame/dispatch [:help-improve-handler true (:address account)])
|
||||||
:label (i18n/label :t/share-usage-data)}]
|
:label (i18n/label :t/share-usage-data)}]
|
||||||
[react/view styles/bottom-button-container
|
[react/view styles/bottom-button-container
|
||||||
[components.common/button {:on-press #(re-frame/dispatch [:help-improve-handler false])
|
[components.common/button {:on-press #(re-frame/dispatch [:help-improve-handler false (:address account)])
|
||||||
:label (i18n/label :t/dont-want-to-share)
|
:label (i18n/label :t/dont-want-to-share)
|
||||||
:background? false}]]]])
|
:background? false}]]]]))
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
(ns status-im.utils.build
|
(ns status-im.utils.build
|
||||||
(:require [cljs.analyzer :as analyzer]))
|
(:require [cljs.analyzer :as analyzer]
|
||||||
|
[clojure.java.shell :as shell]))
|
||||||
|
|
||||||
;; Some warnings are unavoidable due to dependencies. For example, reagent 0.6.0
|
;; Some warnings are unavoidable due to dependencies. For example, reagent 0.6.0
|
||||||
;; has a warning in its util.cljs namespace. Adjust this as is necessary and
|
;; has a warning in its util.cljs namespace. Adjust this as is necessary and
|
||||||
;; unavoidable warnings arise.
|
;; unavoidable warnings arise.
|
||||||
(def acceptable-warning?
|
(def acceptable-warning?
|
||||||
#{
|
#{"Protocol IFn implements method -invoke with variadic signature (&)"}) ;; reagent 0.6.0 reagent/impl/util.cljs:61
|
||||||
"Protocol IFn implements method -invoke with variadic signature (&)" ;; reagent 0.6.0 reagent/impl/util.cljs:61
|
|
||||||
})
|
|
||||||
|
|
||||||
(defn nil-acceptable-warning [s]
|
(defn nil-acceptable-warning [s]
|
||||||
(when-not (acceptable-warning? s)
|
(when-not (acceptable-warning? s)
|
||||||
|
@ -19,3 +18,6 @@
|
||||||
(binding [*out* *err*]
|
(binding [*out* *err*]
|
||||||
(println (analyzer/message env (str "\u001B[31mWARNING\u001B[0m: " s))))
|
(println (analyzer/message env (str "\u001B[31mWARNING\u001B[0m: " s))))
|
||||||
(System/exit 1))))
|
(System/exit 1))))
|
||||||
|
|
||||||
|
(defmacro git-short-version []
|
||||||
|
(:out (shell/sh "bash" "-c" "git describe --always")))
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
(ns status-im.utils.build
|
||||||
|
(:require-macros [status-im.utils.build :refer [git-short-version]]))
|
||||||
|
|
||||||
|
(def version (git-short-version))
|
|
@ -33,6 +33,7 @@
|
||||||
(def many-whisper-topics-enabled? (enabled? (get-config :MANY_WHISPER_TOPICS_ENABLED 0)))
|
(def many-whisper-topics-enabled? (enabled? (get-config :MANY_WHISPER_TOPICS_ENABLED 0)))
|
||||||
(def rn-bridge-threshold-warnings-enabled? (enabled? (get-config :RN_BRIDGE_THRESHOLD_WARNINGS 0)))
|
(def rn-bridge-threshold-warnings-enabled? (enabled? (get-config :RN_BRIDGE_THRESHOLD_WARNINGS 0)))
|
||||||
(def compile-views-enabled? (enabled? (get-config :COMPILE_VIEWS_ENABLED 0)))
|
(def compile-views-enabled? (enabled? (get-config :COMPILE_VIEWS_ENABLED 0)))
|
||||||
|
(def mixpanel-token (get-config :MIXPANEL_TOKEN))
|
||||||
|
|
||||||
(def pow-target (js/parseFloat (get-config :POW_TARGET "0.001")))
|
(def pow-target (js/parseFloat (get-config :POW_TARGET "0.001")))
|
||||||
(def pow-time (js/parseInt (get-config :POW_TIME "1")))
|
(def pow-time (js/parseInt (get-config :POW_TIME "1")))
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
(handler db params)
|
(handler db params)
|
||||||
db))
|
db))
|
||||||
|
|
||||||
|
(defn- pretty-print-event [ctx]
|
||||||
|
(let [[first second] (get-coeffect ctx :event)]
|
||||||
|
(if (map? second)
|
||||||
|
first
|
||||||
|
(str first " " second))))
|
||||||
|
|
||||||
(def debug-handlers-names
|
(def debug-handlers-names
|
||||||
"Interceptor which logs debug information to js/console for each event."
|
"Interceptor which logs debug information to js/console for each event."
|
||||||
(->interceptor
|
(->interceptor
|
||||||
|
@ -26,13 +32,12 @@
|
||||||
[context]
|
[context]
|
||||||
(when @pre-event-callback
|
(when @pre-event-callback
|
||||||
(@pre-event-callback (get-coeffect context :event)))
|
(@pre-event-callback (get-coeffect context :event)))
|
||||||
(log/debug "Handling re-frame event: " (first (get-coeffect context :event)))
|
(log/debug "Handling re-frame event: " (pretty-print-event context))
|
||||||
context)))
|
context)))
|
||||||
|
|
||||||
(defn- check-spec-msg-path-problem [problem]
|
(defn- check-spec-msg-path-problem [problem]
|
||||||
(let [pred (:pred problem)]
|
|
||||||
(str "Spec: " (-> problem :via last) "\n"
|
(str "Spec: " (-> problem :via last) "\n"
|
||||||
"Predicate: " (subs (str (:pred problem)) 0 50))))
|
"Predicate: " (subs (str (:pred problem)) 0 50)))
|
||||||
|
|
||||||
(defn- check-spec-msg-path-problems [path path-problems]
|
(defn- check-spec-msg-path-problems [path path-problems]
|
||||||
(str "Key path: " path "\n"
|
(str "Key path: " path "\n"
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
(ns status-im.utils.http
|
||||||
|
(:require [status-im.constants :as const]
|
||||||
|
[status-im.utils.utils :as utils]
|
||||||
|
[status-im.react-native.js-dependencies :as rn-dependencies])
|
||||||
|
(:refer-clojure :exclude [get]))
|
||||||
|
|
||||||
|
;; Default HTTP request timeout ms
|
||||||
|
(def http-request-default-timeout-ms 3000)
|
||||||
|
|
||||||
|
(defn post
|
||||||
|
"Performs an HTTP POST request"
|
||||||
|
([action data on-success]
|
||||||
|
(post action data on-success nil))
|
||||||
|
([action data on-success on-error]
|
||||||
|
(post action data on-success on-error nil))
|
||||||
|
([action data on-success on-error {:keys [timeout-ms]}]
|
||||||
|
(-> (rn-dependencies/fetch (str const/server-address action)
|
||||||
|
(clj->js {:method "POST"
|
||||||
|
:headers {:accept "application/json"
|
||||||
|
:content-type "application/json"}
|
||||||
|
:body (.stringify js/JSON (clj->js data))
|
||||||
|
:timeout (or timeout-ms http-request-default-timeout-ms)}))
|
||||||
|
(.then (fn [response]
|
||||||
|
(.text response)))
|
||||||
|
(.then (fn [text]
|
||||||
|
(let [json (.parse js/JSON text)
|
||||||
|
obj (js->clj json :keywordize-keys true)]
|
||||||
|
(on-success obj))))
|
||||||
|
(.catch (or on-error
|
||||||
|
(fn [error]
|
||||||
|
(utils/show-popup "Error" (str error))))))))
|
||||||
|
|
||||||
|
(defn get
|
||||||
|
"Performs an HTTP GET request"
|
||||||
|
([url] (get url nil))
|
||||||
|
([url on-success] (get url on-success nil))
|
||||||
|
([url on-success on-error]
|
||||||
|
(get url on-success on-error nil))
|
||||||
|
([url on-success on-error {:keys [valid-response? timeout-ms]}]
|
||||||
|
(-> (rn-dependencies/fetch url
|
||||||
|
(clj->js {:method "GET"
|
||||||
|
:headers {"Cache-Control" "no-cache"}
|
||||||
|
:timeout (or timeout-ms http-request-default-timeout-ms)}))
|
||||||
|
(.then (fn [response]
|
||||||
|
(let [ok? (.-ok response)
|
||||||
|
ok?' (if valid-response?
|
||||||
|
(and ok? (valid-response? response))
|
||||||
|
ok?)]
|
||||||
|
[(.-_bodyText response) ok?'])))
|
||||||
|
(.then (fn [[response ok?]]
|
||||||
|
(cond
|
||||||
|
(and on-success ok?)
|
||||||
|
(on-success response)
|
||||||
|
|
||||||
|
(and on-error (not ok?))
|
||||||
|
(on-error response)
|
||||||
|
|
||||||
|
:else false)))
|
||||||
|
(.catch (or on-error
|
||||||
|
(fn [error]
|
||||||
|
(utils/show-popup "Error" (str error))))))))
|
|
@ -0,0 +1,48 @@
|
||||||
|
(ns status-im.utils.mixpanel
|
||||||
|
(:require-macros [status-im.utils.slurp :as slurp])
|
||||||
|
(:require [cljs.reader :as reader]
|
||||||
|
[goog.crypt.base64 :as b64]
|
||||||
|
[status-im.utils.build :as build]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
|
[status-im.utils.datetime :as datetime]
|
||||||
|
[status-im.utils.http :as http]
|
||||||
|
[status-im.utils.platform :as platform]
|
||||||
|
[status-im.utils.types :as types]))
|
||||||
|
|
||||||
|
(def base-url "http://api.mixpanel.com/")
|
||||||
|
(def base-track-url (str base-url "track/"))
|
||||||
|
|
||||||
|
(defn encode [m]
|
||||||
|
(b64/encodeString (types/clj->json m)))
|
||||||
|
|
||||||
|
(defn- build-url [id label props]
|
||||||
|
(str base-track-url
|
||||||
|
"?data="
|
||||||
|
(encode {:event label
|
||||||
|
:properties (merge
|
||||||
|
{:token config/mixpanel-token
|
||||||
|
:distinct_id id
|
||||||
|
:os platform/os
|
||||||
|
:os-version platform/version
|
||||||
|
:app-version build/version
|
||||||
|
:time (datetime/timestamp)}
|
||||||
|
props)})))
|
||||||
|
|
||||||
|
(defn track [id label props]
|
||||||
|
(http/get (build-url id label props)))
|
||||||
|
|
||||||
|
;; Mixpanel events definition
|
||||||
|
|
||||||
|
(def events (reader/read-string (slurp/slurp "./src/status_im/utils/mixpanel_events.edn")))
|
||||||
|
(def event-by-trigger (reduce-kv #(assoc %1 (:trigger %3) %3) {} events))
|
||||||
|
|
||||||
|
(defn matches? [event trigger]
|
||||||
|
(if (= 1 (count trigger))
|
||||||
|
(= (first event) (first trigger))
|
||||||
|
(and
|
||||||
|
(= (first event) (first trigger))
|
||||||
|
(= (second event) (second trigger)))))
|
||||||
|
|
||||||
|
(defn matching-events [event definitions]
|
||||||
|
(reduce-kv #(if (matches? event %2) (conj %1 %3) %1) [] definitions))
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
;; This file is supposed to be edited by Chad.
|
||||||
|
;; Chad loves mixpanel. When Chad was a child he dreamed of being a mixpanel tamer.
|
||||||
|
|
||||||
|
[;; Account creation
|
||||||
|
|
||||||
|
{:label "Account created"
|
||||||
|
:trigger [:account-finalized]}
|
||||||
|
{:label "Account restored"
|
||||||
|
:trigger [:account-recovered]}
|
||||||
|
|
||||||
|
;; Account lifecycle
|
||||||
|
|
||||||
|
{:label "Login"
|
||||||
|
:trigger [:initialize-account]}
|
||||||
|
|
||||||
|
{:label "Logout"
|
||||||
|
:trigger [:navigate-to :accounts]}
|
||||||
|
|
||||||
|
;; Tab navigation
|
||||||
|
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to-clean :home]
|
||||||
|
:properties {:target :home}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to-tab :home]
|
||||||
|
:properties {:target :home}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to-tab :my-profile]
|
||||||
|
:properties {:target :my-profile}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to-clean :wallet]
|
||||||
|
:properties {:target :wallet}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to-tab :wallet]
|
||||||
|
:properties {:target :wallet}}
|
||||||
|
|
||||||
|
;; New
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to-tab :new]
|
||||||
|
:properties {:target :new}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :new-chat]
|
||||||
|
:properties {:target :new-chat}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:scan-qr-code]
|
||||||
|
:properties {:target :new-chat-qr-code}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:show-profile]
|
||||||
|
:properties {:target :show-profile}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:open-contact-toggle-list :chat-group]
|
||||||
|
:properties {:target :new-group-chat}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :new-public-chat]
|
||||||
|
:properties {:target :new-public-chat}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :open-dapp]
|
||||||
|
:properties {:target :open-dapp}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :dapp-description]
|
||||||
|
:properties {:target :open-dapp-description}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:open-dapp-in-browser]
|
||||||
|
:properties {:target :open-selected-dapp}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :new-group]
|
||||||
|
:properties {:target :start-group-chat-next}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:create-new-public-chat]
|
||||||
|
:properties {:target :create-public-chat}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :new-public-chat]
|
||||||
|
:properties {:target :join-public-chat}}
|
||||||
|
|
||||||
|
;; Chat
|
||||||
|
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to-chat]
|
||||||
|
:properties {:target :open-existing-chat}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :browser]
|
||||||
|
:properties {:target :open-existing-dapp}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:start-chat]
|
||||||
|
:properties {:target :start-chat}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:send-current-message]
|
||||||
|
:properties {:target :send-current-message}}
|
||||||
|
|
||||||
|
;; Wallet
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :wallet-send-transaction]
|
||||||
|
:properties {:target :wallet-send-transaction}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :wallet-request-transaction]
|
||||||
|
:properties {:target :wallet-request-transaction}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :transactions-history]
|
||||||
|
:properties {:target :transactions-history}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :recent-recipients]
|
||||||
|
:properties {:target :select-recipient
|
||||||
|
:type :recent-recipients}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :recipient-qr-code]
|
||||||
|
:properties {:target :select-recipient
|
||||||
|
:type :recipient-qr-code}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :contact-code]
|
||||||
|
:properties {:target :select-recipient
|
||||||
|
:type :contact-code}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :wallet-send-assets]
|
||||||
|
:properties {:target :wallet-send-assets}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:wallet.send/toggle-advanced]
|
||||||
|
:properties {:target :wallet-advanced}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:wallet.send/set-signing?]
|
||||||
|
:properties {:target :wallet-open-sign-transaction}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:wallet/sign-transaction]
|
||||||
|
:properties {:target :wallet-sign-transaction}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to-clean :wallet]
|
||||||
|
:properties {:target :wallet-got-it}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :wallet-transaction-sent]
|
||||||
|
:properties {:target :wallet-transaction-sent}}
|
||||||
|
|
||||||
|
|
||||||
|
;;Profile
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:my-profile/start-editing-profile]
|
||||||
|
:properties {:target :edit-profile}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:my-profile/update-picture]
|
||||||
|
:properties {:target :edit-image
|
||||||
|
:type :gallery}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :profile-photo-capture]
|
||||||
|
:properties {:target :edit-image
|
||||||
|
:type :capture}}
|
||||||
|
{:label "Tap"
|
||||||
|
:trigger [:navigate-to :profile-qr-viewer]
|
||||||
|
:properties {:target :share-contact-code}}]
|
|
@ -4,11 +4,18 @@
|
||||||
[status-im.react-native.js-dependencies :as rn-dependencies]))
|
[status-im.react-native.js-dependencies :as rn-dependencies]))
|
||||||
|
|
||||||
(def platform
|
(def platform
|
||||||
(when-let [pl (.-Platform rn-dependencies/react-native)]
|
(.-Platform rn-dependencies/react-native))
|
||||||
(.-OS pl)))
|
|
||||||
|
|
||||||
(def android? (= platform "android"))
|
(def os
|
||||||
(def ios? (= platform "ios"))
|
(when platform
|
||||||
|
(.-OS platform)))
|
||||||
|
|
||||||
|
(def version
|
||||||
|
(when platform
|
||||||
|
(.-Version platform)))
|
||||||
|
|
||||||
|
(def android? (= os "android"))
|
||||||
|
(def ios? (= os "ios"))
|
||||||
(def iphone-x? (and ios? (ios/iphone-x-dimensions?)))
|
(def iphone-x? (and ios? (ios/iphone-x-dimensions?)))
|
||||||
|
|
||||||
(def platform-specific
|
(def platform-specific
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(ns status-im.utils.prices
|
(ns status-im.utils.prices
|
||||||
(:require [status-im.utils.utils :as utils]
|
(:require [status-im.utils.http :as http]
|
||||||
[status-im.utils.types :as types]))
|
[status-im.utils.types :as types]))
|
||||||
|
|
||||||
;; Responsible for interacting with Cryptocompare API to get current prices for
|
;; Responsible for interacting with Cryptocompare API to get current prices for
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
:last-day (:OPEN24HOUR entry)}))
|
:last-day (:OPEN24HOUR entry)}))
|
||||||
|
|
||||||
(defn get-prices [from to on-success on-error]
|
(defn get-prices [from to on-success on-error]
|
||||||
(utils/http-get
|
(http/get
|
||||||
(gen-price-url from to)
|
(gen-price-url from to)
|
||||||
(fn [resp] (on-success (format-price-resp from to resp)))
|
(fn [resp] (on-success (format-price-resp from to resp)))
|
||||||
on-error))
|
on-error))
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
(defn wrap-first-time
|
(defn wrap-first-time
|
||||||
"Allows to avoid
|
"Allows to avoid
|
||||||
\"Use of undeclared Var status-im.utils.platform/platform\"
|
\"Use of undeclared Var status-im.utils.platform/os\"
|
||||||
warning. When defstyle or defnstyle is called first time status-im.utils.platform
|
warning. When defstyle or defnstyle is called first time status-im.utils.platform
|
||||||
namespace will be explicitly required so that clojurescript compiler will compile
|
namespace will be explicitly required so that clojurescript compiler will compile
|
||||||
it before using status-im.utils.platform/platform in macro"
|
it before using status-im.utils.platform/os in macro"
|
||||||
[body]
|
[body]
|
||||||
`(do
|
`(do
|
||||||
~@[(when @first-time
|
~@[(when @first-time
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
(defn body [style]
|
(defn body [style]
|
||||||
`(let [style# ~style
|
`(let [style# ~style
|
||||||
common# (dissoc style# :android :ios)
|
common# (dissoc style# :android :ios)
|
||||||
platform# (keyword status-im.utils.platform/platform)
|
platform# (keyword status-im.utils.platform/os)
|
||||||
platform-specific# (get style# platform#)]
|
platform-specific# (get style# platform#)]
|
||||||
(if platform-specific#
|
(if platform-specific#
|
||||||
(merge common# platform-specific#)
|
(merge common# platform-specific#)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(ns status-im.utils.transactions
|
(ns status-im.utils.transactions
|
||||||
(:require [status-im.utils.utils :as utils]
|
(:require [status-im.utils.http :as http]
|
||||||
[status-im.utils.types :as types]))
|
[status-im.utils.types :as types]))
|
||||||
|
|
||||||
(defn- get-network-subdomain [network]
|
(defn- get-network-subdomain [network]
|
||||||
|
@ -52,6 +52,6 @@
|
||||||
{})))
|
{})))
|
||||||
|
|
||||||
(defn get-transactions [network account on-success on-error]
|
(defn get-transactions [network account on-success on-error]
|
||||||
(utils/http-get (get-transaction-url network account)
|
(http/get (get-transaction-url network account)
|
||||||
#(on-success (format-transactions-response % account))
|
#(on-success (format-transactions-response % account))
|
||||||
on-error))
|
on-error))
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
(name s)
|
(name s)
|
||||||
s))
|
s))
|
||||||
|
|
||||||
(defn to-edn-string [value]
|
|
||||||
(with-out-str (pr value)))
|
|
||||||
|
|
||||||
(defn clj->json [data]
|
(defn clj->json [data]
|
||||||
(.stringify js/JSON (clj->js data)))
|
(.stringify js/JSON (clj->js data)))
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
(ns status-im.utils.utils
|
(ns status-im.utils.utils
|
||||||
(:require [status-im.constants :as const]
|
(:require [status-im.i18n :as i18n]
|
||||||
[status-im.i18n :as i18n]
|
|
||||||
[clojure.string :as str]
|
|
||||||
[status-im.react-native.js-dependencies :as rn-dependencies]))
|
[status-im.react-native.js-dependencies :as rn-dependencies]))
|
||||||
|
|
||||||
;; Default HTTP request timeout ms
|
|
||||||
(def http-request-default-timeout-ms 3000)
|
|
||||||
|
|
||||||
(defn show-popup [title content]
|
(defn show-popup [title content]
|
||||||
(.alert (.-Alert rn-dependencies/react-native)
|
(.alert (.-Alert rn-dependencies/react-native)
|
||||||
title
|
title
|
||||||
|
@ -47,56 +42,6 @@
|
||||||
:onPress on-accept
|
:onPress on-accept
|
||||||
:accessibility-label :yes-button})))))
|
:accessibility-label :yes-button})))))
|
||||||
|
|
||||||
(defn http-post
|
|
||||||
"Performs an HTTP POST request"
|
|
||||||
([action data on-success]
|
|
||||||
(http-post action data on-success nil))
|
|
||||||
([action data on-success on-error]
|
|
||||||
(http-post action data on-success on-error nil))
|
|
||||||
([action data on-success on-error {:keys [timeout-ms] :as opts}]
|
|
||||||
(-> (rn-dependencies/fetch (str const/server-address action)
|
|
||||||
(clj->js {:method "POST"
|
|
||||||
:headers {:accept "application/json"
|
|
||||||
:content-type "application/json"}
|
|
||||||
:body (.stringify js/JSON (clj->js data))
|
|
||||||
:timeout (or timeout-ms http-request-default-timeout-ms)}))
|
|
||||||
(.then (fn [response]
|
|
||||||
(.text response)))
|
|
||||||
(.then (fn [text]
|
|
||||||
(let [json (.parse js/JSON text)
|
|
||||||
obj (js->clj json :keywordize-keys true)]
|
|
||||||
(on-success obj))))
|
|
||||||
(.catch (or on-error
|
|
||||||
(fn [error]
|
|
||||||
(show-popup "Error" (str error))))))))
|
|
||||||
|
|
||||||
(defn http-get
|
|
||||||
"Performs an HTTP GET request"
|
|
||||||
([url on-success on-error]
|
|
||||||
(http-get url on-success on-error nil))
|
|
||||||
([url on-success on-error {:keys [valid-response? timeout-ms] :as opts}]
|
|
||||||
(-> (rn-dependencies/fetch url
|
|
||||||
(clj->js {:method "GET"
|
|
||||||
:headers {"Cache-Control" "no-cache"}
|
|
||||||
:timeout (or timeout-ms http-request-default-timeout-ms)}))
|
|
||||||
(.then (fn [response]
|
|
||||||
(let [ok? (.-ok response)
|
|
||||||
ok?' (if valid-response?
|
|
||||||
(and ok? (valid-response? response))
|
|
||||||
ok?)]
|
|
||||||
[(.-_bodyText response) ok?'])))
|
|
||||||
(.then (fn [[response ok?]]
|
|
||||||
(cond
|
|
||||||
ok? (on-success response)
|
|
||||||
|
|
||||||
(and on-error (not ok?))
|
|
||||||
(on-error response)
|
|
||||||
|
|
||||||
:else false)))
|
|
||||||
(.catch (or on-error
|
|
||||||
(fn [error]
|
|
||||||
(show-popup "Error" (str error))))))))
|
|
||||||
|
|
||||||
;; background-timer
|
;; background-timer
|
||||||
|
|
||||||
(defn set-timeout [cb ms]
|
(defn set-timeout [cb ms]
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
(def snoopy-bars #js {:default #js {}})
|
(def snoopy-bars #js {:default #js {}})
|
||||||
(def snoopy-buffer #js {:default #js {}})
|
(def snoopy-buffer #js {:default #js {}})
|
||||||
(def EventEmmiter #js {})
|
(def EventEmmiter #js {})
|
||||||
|
(def fetch #js {})
|
||||||
|
|
||||||
(def background-timer #js {:setTimeout js/setTimeout
|
(def background-timer #js {:setTimeout js/setTimeout
|
||||||
:setInterval js/setInterval
|
:setInterval js/setInterval
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
[status-im.test.utils.signing-phrase.core]
|
[status-im.test.utils.signing-phrase.core]
|
||||||
[status-im.test.utils.transducers]
|
[status-im.test.utils.transducers]
|
||||||
[status-im.test.utils.async]
|
[status-im.test.utils.async]
|
||||||
[status-im.test.utils.datetime]))
|
[status-im.test.utils.datetime]
|
||||||
|
[status-im.test.utils.mixpanel]))
|
||||||
|
|
||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
|
|
||||||
|
@ -57,4 +58,5 @@
|
||||||
'status-im.test.utils.gfycat.core
|
'status-im.test.utils.gfycat.core
|
||||||
'status-im.test.utils.signing-phrase.core
|
'status-im.test.utils.signing-phrase.core
|
||||||
'status-im.test.utils.transducers
|
'status-im.test.utils.transducers
|
||||||
'status-im.test.utils.datetime)
|
'status-im.test.utils.datetime
|
||||||
|
'status-im.test.utils.mixpanel)
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
(ns status-im.test.utils.mixpanel
|
||||||
|
(:require [cljs.test :refer-macros [deftest is testing async]]
|
||||||
|
[status-im.utils.mixpanel :as mixpanel]))
|
||||||
|
|
||||||
|
(deftest events
|
||||||
|
(is (not (nil? mixpanel/events))))
|
||||||
|
|
||||||
|
(deftest matches?
|
||||||
|
(is (true? (mixpanel/matches? [:key] [:key])))
|
||||||
|
(is (false? (mixpanel/matches? [:key1] [:key2])))
|
||||||
|
(is (true? (mixpanel/matches? [:key :subkey] [:key])))
|
||||||
|
(is (false? (mixpanel/matches? [:key] [:key :subkey]))))
|
||||||
|
|
||||||
|
(def definitions {[:key] {:trigger [:key]} [:key :subkey] {:trigger [:key :subkey]}})
|
||||||
|
|
||||||
|
(deftest matching-event
|
||||||
|
(is (empty? (mixpanel/matching-events [:non-existing] definitions)))
|
||||||
|
(is (= 1 (count (mixpanel/matching-events [:key] definitions))))
|
||||||
|
(is (= 2 (count (mixpanel/matching-events [:key :subkey] definitions))))
|
||||||
|
(is (empty? (mixpanel/matching-events [:key1 :another-subkey] definitions))))
|
Loading…
Reference in New Issue