[#5169] Remove Mixpanel
This commit is contained in:
parent
59edf46be3
commit
bb7d31a357
1
.env
1
.env
|
@ -9,7 +9,6 @@ QUEUE_MESSAGE_ENABLED=1
|
|||
RN_BRIDGE_THRESHOLD_WARNINGS=0
|
||||
POW_TARGET=0.002
|
||||
POW_TIME=1
|
||||
MIXPANEL_TOKEN=e1c71ae86923310ffb75de525d54cabf
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
TESTFAIRY_TOKEN=969f6c921cb435cea1d41d1ea3f5b247d6026d55
|
||||
INSTABUG_TOKEN=758630ed52864cbad9c5eeeac596c60c
|
||||
|
|
1
.env.e2e
1
.env.e2e
|
@ -8,7 +8,6 @@ JSC_ENABLED=1
|
|||
QUEUE_MESSAGE_ENABLED=1
|
||||
RN_BRIDGE_THRESHOLD_WARNINGS=0
|
||||
COMPILE_VIEWS_ENABLED=0
|
||||
MIXPANEL_TOKEN=e1c71ae86923310ffb75de525d54cabf
|
||||
POW_TARGET=0.002
|
||||
POW_TIME=1
|
||||
DEFAULT_NETWORK=testnet_rpc
|
||||
|
|
|
@ -7,7 +7,6 @@ LOG_LEVEL_STATUS_GO=info
|
|||
JSC_ENABLED=1
|
||||
QUEUE_MESSAGE_ENABLED=1
|
||||
RN_BRIDGE_THRESHOLD_WARNINGS=0
|
||||
MIXPANEL_TOKEN=e1c71ae86923310ffb75de525d54cabf
|
||||
TESTFAIRY_TOKEN=969f6c921cb435cea1d41d1ea3f5b247d6026d55
|
||||
POW_TARGET=0.002
|
||||
POW_TIME=1
|
||||
|
|
|
@ -7,7 +7,6 @@ LOG_LEVEL_STATUS_GO=info
|
|||
JSC_ENABLED=1
|
||||
QUEUE_MESSAGE_ENABLED=1
|
||||
RN_BRIDGE_THRESHOLD_WARNINGS=0
|
||||
MIXPANEL_TOKEN=3f2e1a8970f159aa2a3d5dc5d65eab38
|
||||
TESTFAIRY_TOKEN=969f6c921cb435cea1d41d1ea3f5b247d6026d55
|
||||
POW_TARGET=0.002
|
||||
POW_TIME=1
|
||||
|
|
|
@ -10,7 +10,6 @@ QUEUE_MESSAGE_ENABLED=0
|
|||
RN_BRIDGE_THRESHOLD_WARNINGS=0
|
||||
POW_TARGET=0.002
|
||||
POW_TIME=1
|
||||
MIXPANEL_TOKEN=2584e00100d319d12e538cc4d0fa9fc1
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
TESTFAIRY_TOKEN=969f6c921cb435cea1d41d1ea3f5b247d6026d55
|
||||
INSTABUG_TOKEN=758630ed52864cbad9c5eeeac596c60c
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
[status-im.data-store.realm.schemas.base.v3.core :as v3]
|
||||
[status-im.data-store.realm.schemas.base.v4.core :as v4]
|
||||
[status-im.data-store.realm.schemas.base.v5.core :as v5]
|
||||
[status-im.data-store.realm.schemas.base.v6.core :as v6]))
|
||||
[status-im.data-store.realm.schemas.base.v6.core :as v6]
|
||||
[status-im.data-store.realm.schemas.base.v7.core :as v7]))
|
||||
|
||||
;; put schemas ordered by version
|
||||
(def schemas [{:schema v1/schema
|
||||
|
@ -24,4 +25,7 @@
|
|||
:migration v5/migration}
|
||||
{:schema v6/schema
|
||||
:schemaVersion 6
|
||||
:migration v6/migration}])
|
||||
:migration v6/migration}
|
||||
{:schema v7/schema
|
||||
:schemaVersion 7
|
||||
:migration v7/migration}])
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v7.account)
|
||||
|
||||
(def schema {:name :account
|
||||
:primaryKey :address
|
||||
:properties {:address :string
|
||||
:public-key :string
|
||||
:name {:type :string :optional true}
|
||||
:email {:type :string :optional true}
|
||||
:status {:type :string :optional true}
|
||||
:debug? {:type :bool :default false}
|
||||
:photo-path :string
|
||||
:signing-phrase {:type :string}
|
||||
:mnemonic {:type :string :optional true}
|
||||
:last-updated {:type :int :default 0}
|
||||
:last-sign-in {:type :int :default 0}
|
||||
:signed-up? {:type :bool
|
||||
:default false}
|
||||
:network :string
|
||||
:networks {:type :list
|
||||
:objectType :network}
|
||||
:bootnodes {:type :list
|
||||
:objectType :bootnode}
|
||||
:last-request {:type :int :optional true}
|
||||
:settings {:type :string}
|
||||
:dev-mode? {:type :bool :default false}
|
||||
:seed-backed-up? {:type :bool :default false}
|
||||
:wallet-set-up-passed? {:type :bool
|
||||
:default false}
|
||||
:mainnet-warning-shown? {:type :bool
|
||||
:default false}}})
|
|
@ -0,0 +1,12 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v7.core
|
||||
(:require [status-im.data-store.realm.schemas.base.v1.network :as network]
|
||||
[status-im.data-store.realm.schemas.base.v4.bootnode :as bootnode]
|
||||
[status-im.data-store.realm.schemas.base.v7.account :as account]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def schema [network/schema
|
||||
bootnode/schema
|
||||
account/schema])
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating base database v7: " old-realm new-realm))
|
|
@ -28,12 +28,11 @@
|
|||
(handlers/register-handler-fx
|
||||
::update-connection-status
|
||||
[re-frame/trim-v]
|
||||
(fn [{{:keys [network-status mailserver-status] :as db} :db :as cofx} [is-connected?]]
|
||||
(cond-> (handlers-macro/merge-fx cofx
|
||||
(fn [{db :db :as cofx} [is-connected?]]
|
||||
(handlers-macro/merge-fx
|
||||
cofx
|
||||
{:db (assoc db :network-status (if is-connected? :online :offline))}
|
||||
(inbox/request-messages))
|
||||
is-connected?
|
||||
(assoc :drain-mixpanel-events nil))))
|
||||
(inbox/request-messages))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
::update-network-status
|
||||
|
|
|
@ -51,16 +51,6 @@
|
|||
:other-accounts "Other accounts"
|
||||
:sign-you-in "Signing you in…"
|
||||
|
||||
:help-improve "Help improve Status\nby sharing usage patterns"
|
||||
:help-improve? "Help improve Status?"
|
||||
:help-improve-description "We collect anonymous data to understand how Status is used and inform future development. Whilst we appreciate your help to make Status better, this is an optional choice and can be changed at any time."
|
||||
:learn-what-we-collect-link "Learn more about what we collect"
|
||||
:share-usage-data "Share data"
|
||||
:dont-want-to-share "Do not share"
|
||||
:confirmation-title "Share data with Status?"
|
||||
:confirmation-text "Are you sure you want to share anonymous data with Status?"
|
||||
:confirmation-action "Share"
|
||||
|
||||
;;drawer
|
||||
:switch-users "Switch users"
|
||||
:logout-title "Log out?"
|
||||
|
|
|
@ -119,7 +119,7 @@
|
|||
(fn [{{:accounts/keys [create] :as db} :db :as cofx} _]
|
||||
(handlers-macro/merge-fx cofx
|
||||
{:db db
|
||||
:dispatch [:navigate-to-clean :usage-data [:account-finalized true]]}
|
||||
:dispatch [:navigate-to-clean :home]}
|
||||
(accounts.utils/account-update {:name (:name create)}))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
:account-recovered-navigate
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db [:accounts/recover :processing] false)
|
||||
:dispatch [:navigate-to :usage-data [:account-finalized false]]}))
|
||||
:dispatch [:navigate-to-clean :home]}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:recover-account
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
[status-im.ui.components.styles :as styles]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.components.toolbar.view :as toolbar]
|
||||
[status-im.utils.config :as config]
|
||||
[status-im.utils.mixpanel :as mixpanel]))
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(defn- options-list [{:keys [anon-id]}]
|
||||
[react/view action-button.styles/actions-list
|
||||
|
@ -51,8 +50,7 @@
|
|||
:accessibility-label :invite-friends-button
|
||||
:icon :icons/share
|
||||
:icon-opts {:color colors/blue}
|
||||
:on-press #(do (mixpanel/track anon-id "Tap" {:target :invite-friends} false)
|
||||
(list-selection/open-share {:message (i18n/label :t/get-status-at)}))}]])
|
||||
:on-press #(list-selection/open-share {:message (i18n/label :t/get-status-at)})}]])
|
||||
|
||||
(views/defview add-new []
|
||||
(views/letsubs [account [:get-current-account]
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.screens.intro.views :as intro.views]
|
||||
[status-im.ui.screens.accounts.create.views :as create.views]
|
||||
[status-im.ui.screens.usage-data.views :as usage-data.views]
|
||||
[status-im.ui.screens.accounts.login.views :as login.views]
|
||||
[status-im.ui.screens.accounts.recover.views :as recover.views]
|
||||
[status-im.ui.screens.accounts.views :as accounts.views]))
|
||||
|
@ -13,7 +12,6 @@
|
|||
(views/letsubs [view-id [:get :view-id]]
|
||||
(let [component (case view-id
|
||||
:intro intro.views/intro
|
||||
:usage-data usage-data.views/usage-data
|
||||
:accounts accounts.views/accounts
|
||||
:recover recover.views/recover
|
||||
:create-account create.views/create-account
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
status-im.ui.screens.offline-messaging-settings.events
|
||||
status-im.ui.screens.bootnodes-settings.events
|
||||
status-im.ui.screens.currency-settings.events
|
||||
status-im.ui.screens.usage-data.events
|
||||
status-im.utils.keychain.events
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.native-module.core :as status]
|
||||
|
@ -58,7 +57,6 @@
|
|||
[status-im.utils.handlers-macro :as handlers-macro]
|
||||
[status-im.utils.http :as http]
|
||||
[status-im.utils.instabug :as instabug]
|
||||
[status-im.utils.mixpanel :as mixpanel]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.types :as types]
|
||||
[status-im.utils.utils :as utils]
|
||||
|
|
|
@ -157,12 +157,6 @@
|
|||
:action-fn #(re-frame/dispatch [:navigate-to :bootnodes-settings])
|
||||
:accessibility-label :bootnodes-settings-button}])
|
||||
[profile.components/settings-item-separator]
|
||||
[profile.components/settings-item
|
||||
{:label-kw :t/help-improve?
|
||||
:value (i18n/label (if sharing-usage-data? :on :off))
|
||||
:action-fn #(re-frame/dispatch [:navigate-to :usage-data [:navigate-back]])
|
||||
:accessibility-label :help-improve}]
|
||||
[profile.components/settings-item-separator]
|
||||
[profile.components/settings-switch-item
|
||||
{:label-kw :t/dev-mode
|
||||
:value dev-mode?
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
(ns status-im.ui.screens.usage-data.events
|
||||
(:require [status-im.utils.handlers :as handlers]
|
||||
[status-im.ui.screens.accounts.utils :as accounts.utils]))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:help-improve-handler
|
||||
(fn [{db :db} [_ yes? next]]
|
||||
(merge (accounts.utils/account-update {:sharing-usage-data? yes?} {:db db})
|
||||
{:dispatch (or next [:navigate-to-clean :home])})))
|
|
@ -1,72 +0,0 @@
|
|||
(ns status-im.ui.screens.usage-data.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defnstyle defstyle]])
|
||||
(:require [status-im.ui.components.colors :as colors]
|
||||
[status-im.utils.platform :as platform]))
|
||||
|
||||
(defn scaled-x [window-width n] (* (/ window-width 375) n))
|
||||
(defn scaled-y [window-height n] (* (/ window-height 667) n))
|
||||
|
||||
(def usage-data-view
|
||||
{:flex 1
|
||||
:background-color colors/white
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(defn image-container [window-height]
|
||||
{;; on screens less tall than iPhone 5, let's not show the image at all
|
||||
:display (if (>= window-height 568) "flex" "none")
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:margin-bottom (scaled-y window-height 30)})
|
||||
|
||||
(defn usage-data-image [window-height]
|
||||
{:width (* (/ 390 432) (scaled-y window-height 138))
|
||||
:height (scaled-y window-height 138)})
|
||||
|
||||
(defnstyle help-improve-text [window-height]
|
||||
{:text-align :center
|
||||
:color colors/black
|
||||
:margin-bottom (scaled-y window-height 8)
|
||||
:margin-left 46
|
||||
:margin-right 46
|
||||
:ios {:line-height 28
|
||||
:font-size 22
|
||||
:font-weight :bold
|
||||
:letter-spacing -0.3}
|
||||
:android {:font-size 24
|
||||
:line-height 30}})
|
||||
|
||||
(defn help-improve-text-description [window-height]
|
||||
{:line-height 21
|
||||
:margin-bottom (scaled-y window-height 26)
|
||||
:margin-left 34
|
||||
:margin-right 34
|
||||
:text-align :center
|
||||
:color colors/gray})
|
||||
|
||||
(def learn-what-we-collect-link
|
||||
{:text-align :center
|
||||
:color colors/blue
|
||||
:margin-left 61
|
||||
:margin-right 63})
|
||||
|
||||
(defn bottom-button-container [window-height]
|
||||
{:flex-direction :row
|
||||
;; we need to make a margin smaller on iPhone 5(s)
|
||||
:margin-top (scaled-y window-height
|
||||
(if (and platform/ios?
|
||||
(> window-height 568))
|
||||
96 48))
|
||||
:margin-left 41
|
||||
:margin-right 42})
|
||||
|
||||
(defn share-button [window-width]
|
||||
{:padding-horizontal 18
|
||||
:width (scaled-x window-width 138)
|
||||
:margin-right 16})
|
||||
|
||||
(defn dont-share-button [window-width]
|
||||
{:padding-horizontal 18
|
||||
;; don't do text wrap on super small devices
|
||||
:min-width 130
|
||||
:width (scaled-x window-width 138)})
|
|
@ -1,43 +0,0 @@
|
|||
(ns status-im.ui.screens.usage-data.views
|
||||
(:require-macros [status-im.utils.views :as views])
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[status-im.ui.components.common.common :as components.common]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.ui.components.status-bar.view :as status-bar]
|
||||
[status-im.ui.screens.usage-data.styles :as styles]
|
||||
[status-im.utils.utils :as utils]))
|
||||
|
||||
(views/defview usage-data []
|
||||
(views/letsubs [next [:get-screen-params]
|
||||
{:keys [width height]} [:dimensions/window]]
|
||||
[react/view {:style styles/usage-data-view}
|
||||
[status-bar/status-bar {:flat? true}]
|
||||
[react/view
|
||||
[react/view {:style (styles/image-container height)}
|
||||
[react/image {:source (:analytics-image resources/ui)
|
||||
:style (styles/usage-data-image height)}]]
|
||||
[react/i18n-text {:style (styles/help-improve-text height)
|
||||
:key :help-improve}]
|
||||
[react/view
|
||||
[react/i18n-text {:style (styles/help-improve-text-description height)
|
||||
:key :help-improve-description}]]
|
||||
[react/text {:style styles/learn-what-we-collect-link
|
||||
:on-press #(.openURL react/linking "https://wiki.status.im/Help_Improve_Status#Help_Improve_Status")}
|
||||
(i18n/label :t/learn-what-we-collect-link)]]
|
||||
[react/view (styles/bottom-button-container height)
|
||||
[components.common/button {:button-style (styles/share-button width)
|
||||
:uppercase? false
|
||||
:on-press #(utils/show-confirmation {:ios-confirm-style "default"}
|
||||
(i18n/label :t/confirmation-title)
|
||||
(i18n/label :t/confirmation-text)
|
||||
(i18n/label :t/confirmation-action)
|
||||
(fn [] (re-frame/dispatch [:help-improve-handler true next]))
|
||||
nil)
|
||||
:label (i18n/label :t/share-usage-data)}]
|
||||
[components.common/button {:button-style (styles/dont-share-button width)
|
||||
:uppercase? false
|
||||
:on-press #(re-frame/dispatch [:help-improve-handler false next])
|
||||
:label (i18n/label :t/dont-want-to-share)}]]]))
|
||||
|
|
@ -49,7 +49,6 @@
|
|||
[status-im.ui.screens.add-new.open-dapp.views :refer [open-dapp dapp-description]]
|
||||
[status-im.ui.screens.intro.views :refer [intro]]
|
||||
[status-im.ui.screens.accounts.create.views :refer [create-account]]
|
||||
[status-im.ui.screens.usage-data.views :refer [usage-data]]
|
||||
[status-im.ui.screens.profile.seed.views :refer [backup-seed]]))
|
||||
|
||||
(defn get-main-component [view-id]
|
||||
|
@ -57,7 +56,6 @@
|
|||
:collectibles-list collectibles-list
|
||||
:intro intro
|
||||
:create-account create-account
|
||||
:usage-data usage-data
|
||||
(:home :wallet :my-profile) main-tabs
|
||||
:browser browser
|
||||
:open-dapp open-dapp
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
(def add-custom-mailservers-enabled? (enabled? (get-config :ADD_CUSTOM_MAILSERVERS_ENABLED "1")))
|
||||
(def rn-bridge-threshold-warnings-enabled? (enabled? (get-config :RN_BRIDGE_THRESHOLD_WARNINGS 0)))
|
||||
(def mixpanel-token (get-config :MIXPANEL_TOKEN))
|
||||
(def default-network (get-config :DEFAULT_NETWORK))
|
||||
;; the default value should be a string for `enabled?` to work correctly.
|
||||
(def rpc-networks-only? (enabled? (get-config :RPC_NETWORKS_ONLY "1")))
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
[re-frame.core :refer [reg-event-db reg-event-fx] :as re-frame]
|
||||
[re-frame.interceptor :refer [->interceptor get-coeffect get-effect]]
|
||||
[status-im.utils.instabug :as instabug]
|
||||
[status-im.utils.mixpanel :as mixpanel]
|
||||
[status-im.models.account :as models.account]
|
||||
[cljs.core.async :as async]
|
||||
[taoensso.timbre :as log]))
|
||||
|
@ -93,26 +92,6 @@
|
|||
(throw (ex-info (check-spec-msg event-id new-db) {})))
|
||||
context))))
|
||||
|
||||
(def track-mixpanel
|
||||
"send an event to mixpanel for tracking"
|
||||
(->interceptor
|
||||
:id track-mixpanel
|
||||
:after
|
||||
(fn track-handler
|
||||
[context]
|
||||
(let [new-db (get-coeffect context :db)
|
||||
[event-name] (get-coeffect context :event)]
|
||||
(when (get-in new-db [:account/account :sharing-usage-data?])
|
||||
(let [event (get-coeffect context :event)
|
||||
offline? (or (= :offline (:network-status new-db))
|
||||
(= :offline (:sync-state new-db)))
|
||||
anon-id (:device-UUID new-db)]
|
||||
(doseq [{:keys [label properties]}
|
||||
(mixpanel/matching-events new-db event mixpanel/event-by-trigger)]
|
||||
(mixpanel/track anon-id label properties offline?)
|
||||
(instabug/track label properties)))))
|
||||
context)))
|
||||
|
||||
(defn register-handler
|
||||
([name handler] (register-handler name nil handler))
|
||||
([name middleware handler]
|
||||
|
@ -121,8 +100,7 @@
|
|||
(def default-interceptors
|
||||
[debug-handlers-names
|
||||
(when js/goog.DEBUG check-spec)
|
||||
(re-frame/inject-cofx :now)
|
||||
track-mixpanel])
|
||||
(re-frame/inject-cofx :now)])
|
||||
|
||||
(defn register-handler-db
|
||||
([name handler] (register-handler-db name nil handler))
|
||||
|
@ -146,8 +124,3 @@
|
|||
(remove (fn [{:keys [dapp? pending?]}]
|
||||
(or pending? dapp?)))
|
||||
(map :whisper-identity)))
|
||||
|
||||
(re-frame.core/reg-fx
|
||||
:drain-mixpanel-events
|
||||
(fn []
|
||||
(async/go (async/<! (mixpanel/drain-events-queue!)))))
|
||||
|
|
|
@ -19,16 +19,6 @@
|
|||
(defn- prepare-event-name [event {:keys [target]}]
|
||||
(str event " " target))
|
||||
|
||||
;; `event` is an event name, e.g. "Tap"
|
||||
;; `properties` is a map of event details or nil, e.g. {:target :send-current-message}
|
||||
;; (see status-im.utils.mixpanel-events for list of trackable events)
|
||||
(defn track [event properties]
|
||||
(when (= event "Tap")
|
||||
(let [event-name (prepare-event-name event properties)]
|
||||
(try
|
||||
(.logUserEventWithName instabug event-name)
|
||||
(catch :default _ nil)))))
|
||||
|
||||
(defn log [str]
|
||||
(if js/goog.DEBUG
|
||||
(log/debug str)
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
(ns status-im.utils.mixpanel
|
||||
(:require-macros [status-im.utils.slurp :as slurp])
|
||||
(:require [cljs.core.async :as async]
|
||||
[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]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.mixpanel-events :as mixpanel-events]
|
||||
[status-im.utils.config :as config]))
|
||||
|
||||
(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- make-event [id label props]
|
||||
{: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)})
|
||||
|
||||
;; holds events that are accumulated while offline. will start throwing away old
|
||||
;; events if we accumulate more than 2000
|
||||
(def ^:private pending-events-queue (async/chan (async/sliding-buffer 2000)))
|
||||
|
||||
(defn- submit-batch
|
||||
"Submit a batch of events to mixpanel via POST"
|
||||
[events]
|
||||
(let [done-chan (async/chan)]
|
||||
(log/debug "submitting" (count events) "events")
|
||||
(http/post base-track-url
|
||||
(str "data=" (encode (into [] events)))
|
||||
(fn [_]
|
||||
(log/debug "successfully submitted events")
|
||||
(async/go (async/close! done-chan)))
|
||||
(fn [error]
|
||||
(log/error "error while submitting events" error)
|
||||
(async/go (async/close! done-chan))))
|
||||
done-chan))
|
||||
|
||||
;; maximum number of events that should be submitted to mixpanel's batch
|
||||
;; endpoint at once (see https://mixpanel.com/help/reference/http)
|
||||
(def max-batch-size 50)
|
||||
|
||||
(defn drain-events-queue!
|
||||
"Drains accumulated events and submits them in batches of <max-batch-size>"
|
||||
([]
|
||||
(drain-events-queue! pending-events-queue submit-batch))
|
||||
([queue callback]
|
||||
(let [events (loop [accumulator []]
|
||||
(if-let [event (async/poll! queue)]
|
||||
(recur (conj accumulator event))
|
||||
accumulator))]
|
||||
(async/go
|
||||
(doseq [batch (partition-all max-batch-size events)]
|
||||
(async/<! (callback batch)))))))
|
||||
|
||||
(defn track
|
||||
"Track or accumulate an event"
|
||||
[id label props offline?]
|
||||
(log/debug "tracking" id label props offline?)
|
||||
(let [event (make-event id label props)]
|
||||
;; enqueue event
|
||||
(async/go (async/>! pending-events-queue event))
|
||||
;; drain queue if we are online
|
||||
(when-not offline?
|
||||
(async/go (async/<! (drain-events-queue!))))))
|
||||
|
||||
(def event-tag "events")
|
||||
|
||||
;; Mixpanel events definition
|
||||
(defn event->triggers
|
||||
"Transform definitions vector into map which will be used for matching later
|
||||
|
||||
[{:trigger [:en1]}
|
||||
{:trigger [:en1 :p1]}
|
||||
{:trigger [:en2 :p1]}
|
||||
{:trigger [:en3 :p1 :p2 :p3]}]
|
||||
|
||||
will be transformed into
|
||||
|
||||
{:en1 {events ({:trigger [:en1]})
|
||||
:p1 {events ({:trigger [:en1 :p1]})}}
|
||||
:en2 {:p1 {events ({:trigger [:en2 :p1]})}}
|
||||
:en3 {:p1 {:p2 {:p3 {events ({:trigger [:en3 :p1 :p2 :p3]})}}}}}"
|
||||
[events]
|
||||
(reduce (fn [m {:keys [trigger] :as event}]
|
||||
(update-in m (conj trigger event-tag) conj event))
|
||||
{}
|
||||
events))
|
||||
|
||||
(def event-by-trigger
|
||||
(event->triggers mixpanel-events/events))
|
||||
|
||||
(defn matching-events [db [event-name first-arg :as event] triggers]
|
||||
(let [cnt (count event)
|
||||
triggers (cond->
|
||||
;; first we get all events which are triggered by event name
|
||||
;; (the case when :trigger contains only one element)
|
||||
;; {:trigger [:only-event-name-here]}
|
||||
(get-in triggers [event-name event-tag])
|
||||
|
||||
;; when event contains two or more elements we are trying
|
||||
;; to match by first two elements of :trigger
|
||||
;; {:trigger [:event-name :one-parameter]}
|
||||
(>= cnt 2)
|
||||
(concat (get-in triggers [event-name first-arg event-tag]))
|
||||
|
||||
;; also if event contains more than one parameter (more than
|
||||
;; two elements) we are trying to match it with equal :trigger
|
||||
;; {:trigger [:e-name :p1 :p2 :p3]}
|
||||
;; will match only with [:e-name :p1 :p2 :p3] event
|
||||
(> cnt 2)
|
||||
(concat (get-in triggers (conj event event-tag))))]
|
||||
(->> triggers
|
||||
|
||||
(filter (fn [{:keys [filter-fn]}]
|
||||
(or (not filter-fn) (filter-fn db event))))
|
||||
|
||||
(mapcat (fn [{:keys [data-fn] :as trigger}]
|
||||
(if data-fn
|
||||
(let [data (data-fn db event)]
|
||||
(if (map? data)
|
||||
[(update trigger :properties merge data)]
|
||||
(map (partial update trigger :properties merge) data)))
|
||||
[trigger]))))))
|
|
@ -1,205 +0,0 @@
|
|||
(ns status-im.utils.mixpanel-events)
|
||||
;; This file is supposed to be edited by Chad.
|
||||
;; Chad loves mixpanel. When Chad was a child he dreamed of being a mixpanel tamer.
|
||||
|
||||
;; To add a new event definition, add a new map to this vector
|
||||
;; :label is a free string that is displayed in mixpanel
|
||||
;; :trigger is the re-frame style event that when matched will generate the emission of a mixpanel event
|
||||
;; :properties is a map of key / value pair that will be added to the mixpanel event to provide more context
|
||||
(def events
|
||||
[;; 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]}
|
||||
|
||||
; Push notification settings
|
||||
|
||||
{:label "Tap"
|
||||
:trigger [:request-notifications-granted]
|
||||
:properties {:target :granted-push-notifications}}
|
||||
|
||||
{:label "Tap"
|
||||
:trigger [:request-notifications-denied]
|
||||
:properties {:target :denied-push-notifications}}
|
||||
|
||||
;; 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 :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]
|
||||
: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 [:wallet/sign-transaction-modal]
|
||||
:properties {:target :dapp-sign-transaction}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-clean :wallet]
|
||||
:properties {:target :wallet-got-it}}
|
||||
{:label "Tap"
|
||||
:trigger [:send-transaction-message]
|
||||
:properties {:target :wallet-transaction-sent}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :collectibles-list]
|
||||
:properties {:target :collectibles-list}}
|
||||
{:label "Tap"
|
||||
:trigger [:open-collectible-in-browser]
|
||||
:properties {:target :open-collectible-in-browser}}
|
||||
|
||||
;;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}}
|
||||
{:label "Tap"
|
||||
:trigger [:set :my-profile/advanced? true]
|
||||
:properties {:target :profile-advanced
|
||||
:type :open}}
|
||||
{:label "Tap"
|
||||
:trigger [:set :my-profile/advanced? false]
|
||||
:properties {:target :profile-advanced
|
||||
:type :closed}}
|
||||
{:label "Tap"
|
||||
:trigger [:switch-dev-mode true]
|
||||
:properties {:target :profile-dev-mode
|
||||
:type :on}}
|
||||
{:label "Tap"
|
||||
:trigger [:switch-dev-mode false]
|
||||
:properties {:target :profile-dev-mode
|
||||
:type :off}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :backup-seed]
|
||||
:properties {:target :backup-your-seed-phrase}}
|
||||
{:label "Tap"
|
||||
:trigger [:set-in [:my-profile/seed :step] :12-words]
|
||||
:properties {:target :seed-phrase
|
||||
:type :welcome-ok}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/enter-two-random-words]
|
||||
:properties {:target :seed-phrase
|
||||
:type :step1-next}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/set-step :second-word]
|
||||
:properties {:target :seed-phrase
|
||||
:type :step2-next}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/finish]
|
||||
:properties {:target :seed-phrase
|
||||
:type :step3-done}}])
|
|
@ -42,7 +42,6 @@
|
|||
[status-im.test.utils.transducers]
|
||||
[status-im.test.utils.async]
|
||||
[status-im.test.utils.datetime]
|
||||
[status-im.test.utils.mixpanel]
|
||||
[status-im.test.utils.prices]
|
||||
[status-im.test.utils.keychain.core]
|
||||
[status-im.test.utils.universal-links.core]
|
||||
|
@ -100,7 +99,6 @@
|
|||
'status-im.test.utils.signing-phrase.core
|
||||
'status-im.test.utils.transducers
|
||||
'status-im.test.utils.datetime
|
||||
'status-im.test.utils.mixpanel
|
||||
'status-im.test.utils.prices
|
||||
'status-im.test.utils.keychain.core
|
||||
'status-im.test.utils.universal-links.core
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
(ns status-im.test.utils.mixpanel
|
||||
(:require [cljs.test :refer [async deftest is]]
|
||||
[status-im.utils.mixpanel :as mixpanel]
|
||||
[cljs.core.async :as async]))
|
||||
|
||||
(def definitions
|
||||
(mixpanel/event->triggers
|
||||
[{:trigger [:key]}
|
||||
{:trigger [:key :subkey]}
|
||||
{:trigger [:key2]
|
||||
:filter-fn (fn [_ [_ first-parameter]]
|
||||
(true? first-parameter))}
|
||||
{:trigger [:key3 :p1 :p2 :p3]}]))
|
||||
|
||||
(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 (= 1 (count (mixpanel/matching-events {} [:key2 true] definitions))))
|
||||
(is (= 1 (count (mixpanel/matching-events {} [:key3 :p1 :p2 :p3] definitions))))
|
||||
(is (empty? (mixpanel/matching-events {} [:key3 :p1 :p2 :p4] definitions)))
|
||||
(is (empty? (mixpanel/matching-events {} [:key2 false] definitions)))
|
||||
(is (empty? (mixpanel/matching-events {} [:key1 :another-subkey] definitions))))
|
||||
|
||||
(deftest drain-events-queue!-test
|
||||
(async
|
||||
done
|
||||
(let [queue (async/chan (async/sliding-buffer 2000))
|
||||
results (atom [])]
|
||||
(async/go
|
||||
(async/<! (async/onto-chan queue (range 123) false))
|
||||
(async/<!
|
||||
(mixpanel/drain-events-queue!
|
||||
queue
|
||||
(fn [events]
|
||||
(let [result-chan (async/chan)]
|
||||
(swap! results conj events)
|
||||
(async/go (async/close! result-chan))
|
||||
result-chan))))
|
||||
(is (= @results [(range 50)
|
||||
(range 50 100)
|
||||
(range 100 123)]))
|
||||
(done)))))
|
Loading…
Reference in New Issue