Add a UI for toggling developer feature flags (#18602)
This commit is contained in:
parent
07feff60ec
commit
ef6027575f
|
@ -16,18 +16,19 @@
|
||||||
:clj-kondo-config {:level :error}
|
:clj-kondo-config {:level :error}
|
||||||
:cond-else {:level :error}
|
:cond-else {:level :error}
|
||||||
:consistent-alias {:level :error
|
:consistent-alias {:level :error
|
||||||
:aliases {clojure.set set
|
:aliases {clojure.set set
|
||||||
clojure.string string
|
clojure.string string
|
||||||
clojure.walk walk
|
clojure.walk walk
|
||||||
malli.core malli
|
malli.core malli
|
||||||
malli.dev.pretty malli.pretty
|
malli.dev.pretty malli.pretty
|
||||||
malli.dev.virhe malli.virhe
|
malli.dev.virhe malli.virhe
|
||||||
malli.error malli.error
|
malli.error malli.error
|
||||||
malli.generator malli.generator
|
malli.generator malli.generator
|
||||||
malli.transform malli.transform
|
malli.transform malli.transform
|
||||||
malli.util malli.util
|
malli.util malli.util
|
||||||
schema.core schema
|
schema.core schema
|
||||||
taoensso.timbre log}}
|
status-im.feature-flags ff
|
||||||
|
taoensso.timbre log}}
|
||||||
:deprecated-namespace {:level :warning}
|
:deprecated-namespace {:level :warning}
|
||||||
:docstring-blank {:level :error}
|
:docstring-blank {:level :error}
|
||||||
:equals-true {:level :error}
|
:equals-true {:level :error}
|
||||||
|
|
|
@ -169,8 +169,3 @@
|
||||||
|
|
||||||
(def community-accounts-selection-enabled? (enabled? (get-config :ACCOUNT_SELECTION_ENABLED "0")))
|
(def community-accounts-selection-enabled? (enabled? (get-config :ACCOUNT_SELECTION_ENABLED "0")))
|
||||||
(def fetch-messages-enabled? (enabled? (get-config :FETCH_MESSAGES_ENABLED "1")))
|
(def fetch-messages-enabled? (enabled? (get-config :FETCH_MESSAGES_ENABLED "1")))
|
||||||
|
|
||||||
(def wallet-feature-flags
|
|
||||||
{:edit-default-keypair false
|
|
||||||
:bridge-token false
|
|
||||||
:remove-account false})
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
(ns status-im.contexts.preview.feature-flags.style)
|
||||||
|
|
||||||
|
(def container
|
||||||
|
{:flex 1
|
||||||
|
:margin-left 20})
|
|
@ -0,0 +1,39 @@
|
||||||
|
(ns status-im.contexts.preview.feature-flags.view
|
||||||
|
(:require
|
||||||
|
[clojure.string :as string]
|
||||||
|
[quo.core :as quo]
|
||||||
|
[re-frame.core :as rf]
|
||||||
|
[react-native.core :as rn]
|
||||||
|
[status-im.contexts.preview.feature-flags.style :as style]
|
||||||
|
[status-im.feature-flags :as ff]))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
[rn/view {:style {:flex 1}}
|
||||||
|
[quo/page-nav
|
||||||
|
{:type :title
|
||||||
|
:text-align :left
|
||||||
|
:title "Features Flags"
|
||||||
|
:icon-name :i/arrow-left
|
||||||
|
:on-press #(rf/dispatch [:navigate-back])}]
|
||||||
|
(doall
|
||||||
|
(for [context-name ff/feature-flags-categories
|
||||||
|
:let [context-flags (filter (fn [[k]]
|
||||||
|
(string/includes? (str k) context-name))
|
||||||
|
(ff/feature-flags))]]
|
||||||
|
^{:key (str context-name)}
|
||||||
|
[rn/view {:style style/container}
|
||||||
|
[quo/text
|
||||||
|
context-name]
|
||||||
|
(doall
|
||||||
|
(for [i (range (count context-flags))
|
||||||
|
:let [[flag] (nth context-flags i)]]
|
||||||
|
^{:key (str context-name flag i)}
|
||||||
|
[rn/view {:style {:flex-direction :row}}
|
||||||
|
[quo/selectors
|
||||||
|
{:type :toggle
|
||||||
|
:checked? (ff/enabled? flag)
|
||||||
|
:container-style {:margin-right 8}
|
||||||
|
:on-change #(ff/toggle flag)}]
|
||||||
|
[quo/text (second (string/split (name flag) "."))]]))]))])
|
||||||
|
|
|
@ -96,6 +96,13 @@
|
||||||
:action :arrow
|
:action :arrow
|
||||||
:image :icon
|
:image :icon
|
||||||
:blur? true
|
:blur? true
|
||||||
|
:image-props :i/light})
|
||||||
|
(when config/quo-preview-enabled?
|
||||||
|
{:title "Feature Flags"
|
||||||
|
:on-press #(rf/dispatch [:navigate-to :feature-flags])
|
||||||
|
:action :arrow
|
||||||
|
:image :icon
|
||||||
|
:blur? true
|
||||||
:image-props :i/light})]
|
:image-props :i/light})]
|
||||||
[{:title (i18n/label :t/about)
|
[{:title (i18n/label :t/about)
|
||||||
:on-press not-implemented/alert
|
:on-press not-implemented/alert
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.config :as config]
|
|
||||||
[status-im.contexts.wallet.account.style :as style]
|
[status-im.contexts.wallet.account.style :as style]
|
||||||
[status-im.contexts.wallet.account.tabs.view :as tabs]
|
[status-im.contexts.wallet.account.tabs.view :as tabs]
|
||||||
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
|
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
|
||||||
[status-im.contexts.wallet.common.temp :as temp]
|
[status-im.contexts.wallet.common.temp :as temp]
|
||||||
|
[status-im.feature-flags :as ff]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -53,9 +53,8 @@
|
||||||
:receive-action #(rf/dispatch [:open-modal :wallet-share-address {:status :receive}])
|
:receive-action #(rf/dispatch [:open-modal :wallet-share-address {:status :receive}])
|
||||||
:buy-action #(rf/dispatch [:show-bottom-sheet
|
:buy-action #(rf/dispatch [:show-bottom-sheet
|
||||||
{:content buy-drawer}])
|
{:content buy-drawer}])
|
||||||
:bridge-action (if (:bridge-token config/wallet-feature-flags)
|
:bridge-action #(ff/alert ::ff/wallet.bridge-token
|
||||||
#(rf/dispatch [:open-modal :wallet-bridge])
|
(fn [] (rf/dispatch [:open-modal :wallet-bridge])))}])
|
||||||
#(js/alert "feature disabled in config file"))}])
|
|
||||||
[quo/tabs
|
[quo/tabs
|
||||||
{:style style/tabs
|
{:style style/tabs
|
||||||
:size 32
|
:size 32
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
[react-native.gesture :as gesture]
|
[react-native.gesture :as gesture]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.config :as config]
|
|
||||||
[status-im.contexts.wallet.common.sheets.account-options.style :as style]
|
[status-im.contexts.wallet.common.sheets.account-options.style :as style]
|
||||||
[status-im.contexts.wallet.common.sheets.remove-account.view :as remove-account]
|
[status-im.contexts.wallet.common.sheets.remove-account.view :as remove-account]
|
||||||
[status-im.contexts.wallet.common.utils :as utils]
|
[status-im.contexts.wallet.common.utils :as utils]
|
||||||
|
[status-im.feature-flags :as ff]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -100,13 +100,12 @@
|
||||||
:accessibility-label :remove-account
|
:accessibility-label :remove-account
|
||||||
:label (i18n/label :t/remove-account)
|
:label (i18n/label :t/remove-account)
|
||||||
:danger? true
|
:danger? true
|
||||||
:on-press (fn []
|
:on-press #(ff/alert ::ff/wallet.remove-account
|
||||||
(if (:remove-account config/wallet-feature-flags)
|
(fn []
|
||||||
(rf/dispatch [:show-bottom-sheet
|
(rf/dispatch [:show-bottom-sheet
|
||||||
{:content
|
{:content
|
||||||
(fn []
|
(fn []
|
||||||
[remove-account/view])}])
|
[remove-account/view])}])))})]]]
|
||||||
(js/alert "Feature disabled in config file")))})]]]
|
|
||||||
(when show-account-selector?
|
(when show-account-selector?
|
||||||
[:<>
|
[:<>
|
||||||
[quo/divider-line {:container-style style/divider-label}]
|
[quo/divider-line {:container-style style/divider-label}]
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.common.emoji-picker.utils :as emoji-picker.utils]
|
[status-im.common.emoji-picker.utils :as emoji-picker.utils]
|
||||||
[status-im.common.standard-authentication.core :as standard-auth]
|
[status-im.common.standard-authentication.core :as standard-auth]
|
||||||
[status-im.config :as config]
|
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.wallet.common.utils :as utils]
|
[status-im.contexts.wallet.common.utils :as utils]
|
||||||
[status-im.contexts.wallet.create-account.style :as style]
|
[status-im.contexts.wallet.create-account.style :as style]
|
||||||
|
[status-im.feature-flags :as ff]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[utils.responsiveness :refer [iphone-11-Pro-20-pixel-from-width]]
|
[utils.responsiveness :refer [iphone-11-Pro-20-pixel-from-width]]
|
||||||
|
@ -32,9 +32,9 @@
|
||||||
:size :xxs
|
:size :xxs
|
||||||
:customization-color account-color}
|
:customization-color account-color}
|
||||||
:action :button
|
:action :button
|
||||||
:action-props {:on-press (if (:edit-default-keypair config/wallet-feature-flags)
|
:action-props {:on-press #(ff/alert ::ff/wallet.edit-default-keypair
|
||||||
#(rf/dispatch [:navigate-to :wallet-select-keypair])
|
(fn []
|
||||||
#(js/alert "feature disabled in config file"))
|
(rf/dispatch [:navigate-to :wallet-select-keypair])))
|
||||||
:button-text (i18n/label :t/edit)
|
:button-text (i18n/label :t/edit)
|
||||||
:alignment :flex-start}
|
:alignment :flex-start}
|
||||||
:description :text
|
:description :text
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
(:require [quo.core :as quo]
|
(:require [quo.core :as quo]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.config :as config]
|
|
||||||
[status-im.contexts.wallet.common.screen-base.create-or-edit-account.view
|
[status-im.contexts.wallet.common.screen-base.create-or-edit-account.view
|
||||||
:as create-or-edit-account]
|
:as create-or-edit-account]
|
||||||
[status-im.contexts.wallet.common.sheets.network-preferences.view
|
[status-im.contexts.wallet.common.sheets.network-preferences.view
|
||||||
:as network-preferences]
|
:as network-preferences]
|
||||||
[status-im.contexts.wallet.common.sheets.remove-account.view :as remove-account]
|
[status-im.contexts.wallet.common.sheets.remove-account.view :as remove-account]
|
||||||
[status-im.contexts.wallet.edit-account.style :as style]
|
[status-im.contexts.wallet.edit-account.style :as style]
|
||||||
|
[status-im.feature-flags :as ff]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -66,13 +66,12 @@
|
||||||
{:page-nav-right-side [(when-not default-account?
|
{:page-nav-right-side [(when-not default-account?
|
||||||
{:icon-name :i/delete
|
{:icon-name :i/delete
|
||||||
:on-press
|
:on-press
|
||||||
(fn []
|
#(ff/alert ::ff/wallet.remove-account
|
||||||
(if (:remove-account config/wallet-feature-flags)
|
(fn []
|
||||||
(rf/dispatch [:show-bottom-sheet
|
(rf/dispatch [:show-bottom-sheet
|
||||||
{:content
|
{:content
|
||||||
(fn []
|
(fn []
|
||||||
[remove-account/view])}])
|
[remove-account/view])}])))})]
|
||||||
(js/alert "Feature disabled in config file")))})]
|
|
||||||
:account-name account-name
|
:account-name account-name
|
||||||
:account-emoji emoji
|
:account-emoji emoji
|
||||||
:account-color color
|
:account-color color
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
(ns status-im.feature-flags
|
||||||
|
(:require
|
||||||
|
[clojure.string :as string]
|
||||||
|
[react-native.config :as config]
|
||||||
|
[reagent.core :as reagent]))
|
||||||
|
|
||||||
|
(defn- enabled-in-env?
|
||||||
|
[k]
|
||||||
|
(= "1" (config/get-config k)))
|
||||||
|
|
||||||
|
(defonce ^:private feature-flags-config
|
||||||
|
(reagent/atom
|
||||||
|
{::wallet.edit-default-keypair (enabled-in-env? :FLAG_EDIT_DEFAULT_KEYPAIR_ENABLED)
|
||||||
|
::wallet.bridge-token (enabled-in-env? :FLAG_BRIDGE_TOKEN_ENABLED)
|
||||||
|
::wallet.remove-account (enabled-in-env? :FLAG_REMOVE_ACCOUNT_ENABLED)}))
|
||||||
|
|
||||||
|
(defn feature-flags [] @feature-flags-config)
|
||||||
|
|
||||||
|
(def feature-flags-categories
|
||||||
|
(set (map
|
||||||
|
(fn [k]
|
||||||
|
(first (string/split (str (name k)) ".")))
|
||||||
|
(keys @feature-flags-config))))
|
||||||
|
|
||||||
|
(defn enabled?
|
||||||
|
[flag]
|
||||||
|
(get (feature-flags) flag))
|
||||||
|
|
||||||
|
(defn toggle
|
||||||
|
[flag]
|
||||||
|
(swap! feature-flags-config update flag not))
|
||||||
|
|
||||||
|
(defn alert
|
||||||
|
[flag action]
|
||||||
|
(if (enabled? flag)
|
||||||
|
(action)
|
||||||
|
(js/alert (str flag " is currently feature flagged off"))))
|
|
@ -31,6 +31,7 @@
|
||||||
[status-im.contexts.onboarding.syncing.progress.view :as syncing-devices]
|
[status-im.contexts.onboarding.syncing.progress.view :as syncing-devices]
|
||||||
[status-im.contexts.onboarding.syncing.results.view :as syncing-results]
|
[status-im.contexts.onboarding.syncing.results.view :as syncing-results]
|
||||||
[status-im.contexts.onboarding.welcome.view :as welcome]
|
[status-im.contexts.onboarding.welcome.view :as welcome]
|
||||||
|
[status-im.contexts.preview.feature-flags.view :as feature-flags]
|
||||||
[status-im.contexts.preview.quo.component-preview.view :as component-preview]
|
[status-im.contexts.preview.quo.component-preview.view :as component-preview]
|
||||||
[status-im.contexts.preview.quo.main :as quo.preview]
|
[status-im.contexts.preview.quo.main :as quo.preview]
|
||||||
[status-im.contexts.preview.status-im.main :as status-im-preview]
|
[status-im.contexts.preview.status-im.main :as status-im-preview]
|
||||||
|
@ -406,4 +407,9 @@
|
||||||
status-im-preview/screens)
|
status-im-preview/screens)
|
||||||
|
|
||||||
(when config/quo-preview-enabled?
|
(when config/quo-preview-enabled?
|
||||||
status-im-preview/main-screens)))
|
status-im-preview/main-screens)
|
||||||
|
|
||||||
|
(when config/quo-preview-enabled?
|
||||||
|
[{:name :feature-flags
|
||||||
|
:options {:insets {:top? true}}
|
||||||
|
:component feature-flags/view}])))
|
||||||
|
|
Loading…
Reference in New Issue