diff --git a/.clj-kondo/config.edn b/.clj-kondo/config.edn index 4963334164..a0c50c61b2 100644 --- a/.clj-kondo/config.edn +++ b/.clj-kondo/config.edn @@ -16,18 +16,19 @@ :clj-kondo-config {:level :error} :cond-else {:level :error} :consistent-alias {:level :error - :aliases {clojure.set set - clojure.string string - clojure.walk walk - malli.core malli - malli.dev.pretty malli.pretty - malli.dev.virhe malli.virhe - malli.error malli.error - malli.generator malli.generator - malli.transform malli.transform - malli.util malli.util - schema.core schema - taoensso.timbre log}} + :aliases {clojure.set set + clojure.string string + clojure.walk walk + malli.core malli + malli.dev.pretty malli.pretty + malli.dev.virhe malli.virhe + malli.error malli.error + malli.generator malli.generator + malli.transform malli.transform + malli.util malli.util + schema.core schema + status-im.feature-flags ff + taoensso.timbre log}} :deprecated-namespace {:level :warning} :docstring-blank {:level :error} :equals-true {:level :error} diff --git a/src/status_im/config.cljs b/src/status_im/config.cljs index 2043934a52..7c3fc56b2b 100644 --- a/src/status_im/config.cljs +++ b/src/status_im/config.cljs @@ -169,8 +169,3 @@ (def community-accounts-selection-enabled? (enabled? (get-config :ACCOUNT_SELECTION_ENABLED "0"))) (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}) diff --git a/src/status_im/contexts/preview/feature_flags/style.cljs b/src/status_im/contexts/preview/feature_flags/style.cljs new file mode 100644 index 0000000000..63e9f98a7c --- /dev/null +++ b/src/status_im/contexts/preview/feature_flags/style.cljs @@ -0,0 +1,5 @@ +(ns status-im.contexts.preview.feature-flags.style) + +(def container + {:flex 1 + :margin-left 20}) diff --git a/src/status_im/contexts/preview/feature_flags/view.cljs b/src/status_im/contexts/preview/feature_flags/view.cljs new file mode 100644 index 0000000000..5de696d500 --- /dev/null +++ b/src/status_im/contexts/preview/feature_flags/view.cljs @@ -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) "."))]]))]))]) + diff --git a/src/status_im/contexts/profile/settings/list_items.cljs b/src/status_im/contexts/profile/settings/list_items.cljs index 8be148d89a..8a17d6c866 100644 --- a/src/status_im/contexts/profile/settings/list_items.cljs +++ b/src/status_im/contexts/profile/settings/list_items.cljs @@ -96,6 +96,13 @@ :action :arrow :image :icon :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})] [{:title (i18n/label :t/about) :on-press not-implemented/alert diff --git a/src/status_im/contexts/wallet/account/view.cljs b/src/status_im/contexts/wallet/account/view.cljs index fc17192b02..32adcd4172 100644 --- a/src/status_im/contexts/wallet/account/view.cljs +++ b/src/status_im/contexts/wallet/account/view.cljs @@ -3,11 +3,11 @@ [quo.core :as quo] [react-native.core :as rn] [reagent.core :as reagent] - [status-im.config :as config] [status-im.contexts.wallet.account.style :as style] [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.temp :as temp] + [status-im.feature-flags :as ff] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -53,9 +53,8 @@ :receive-action #(rf/dispatch [:open-modal :wallet-share-address {:status :receive}]) :buy-action #(rf/dispatch [:show-bottom-sheet {:content buy-drawer}]) - :bridge-action (if (:bridge-token config/wallet-feature-flags) - #(rf/dispatch [:open-modal :wallet-bridge]) - #(js/alert "feature disabled in config file"))}]) + :bridge-action #(ff/alert ::ff/wallet.bridge-token + (fn [] (rf/dispatch [:open-modal :wallet-bridge])))}]) [quo/tabs {:style style/tabs :size 32 diff --git a/src/status_im/contexts/wallet/common/sheets/account_options/view.cljs b/src/status_im/contexts/wallet/common/sheets/account_options/view.cljs index 9de634a3bc..d91b245c57 100644 --- a/src/status_im/contexts/wallet/common/sheets/account_options/view.cljs +++ b/src/status_im/contexts/wallet/common/sheets/account_options/view.cljs @@ -9,10 +9,10 @@ [react-native.gesture :as gesture] [react-native.platform :as platform] [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.remove-account.view :as remove-account] [status-im.contexts.wallet.common.utils :as utils] + [status-im.feature-flags :as ff] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -100,13 +100,12 @@ :accessibility-label :remove-account :label (i18n/label :t/remove-account) :danger? true - :on-press (fn [] - (if (:remove-account config/wallet-feature-flags) - (rf/dispatch [:show-bottom-sheet - {:content - (fn [] - [remove-account/view])}]) - (js/alert "Feature disabled in config file")))})]]] + :on-press #(ff/alert ::ff/wallet.remove-account + (fn [] + (rf/dispatch [:show-bottom-sheet + {:content + (fn [] + [remove-account/view])}])))})]]] (when show-account-selector? [:<> [quo/divider-line {:container-style style/divider-label}] diff --git a/src/status_im/contexts/wallet/create_account/view.cljs b/src/status_im/contexts/wallet/create_account/view.cljs index 3c4d3aba48..22cb0c3685 100644 --- a/src/status_im/contexts/wallet/create_account/view.cljs +++ b/src/status_im/contexts/wallet/create_account/view.cljs @@ -9,10 +9,10 @@ [reagent.core :as reagent] [status-im.common.emoji-picker.utils :as emoji-picker.utils] [status-im.common.standard-authentication.core :as standard-auth] - [status-im.config :as config] [status-im.constants :as constants] [status-im.contexts.wallet.common.utils :as utils] [status-im.contexts.wallet.create-account.style :as style] + [status-im.feature-flags :as ff] [utils.i18n :as i18n] [utils.re-frame :as rf] [utils.responsiveness :refer [iphone-11-Pro-20-pixel-from-width]] @@ -32,9 +32,9 @@ :size :xxs :customization-color account-color} :action :button - :action-props {:on-press (if (:edit-default-keypair config/wallet-feature-flags) - #(rf/dispatch [:navigate-to :wallet-select-keypair]) - #(js/alert "feature disabled in config file")) + :action-props {:on-press #(ff/alert ::ff/wallet.edit-default-keypair + (fn [] + (rf/dispatch [:navigate-to :wallet-select-keypair]))) :button-text (i18n/label :t/edit) :alignment :flex-start} :description :text diff --git a/src/status_im/contexts/wallet/edit_account/view.cljs b/src/status_im/contexts/wallet/edit_account/view.cljs index 48bc343fa0..4de50783fe 100644 --- a/src/status_im/contexts/wallet/edit_account/view.cljs +++ b/src/status_im/contexts/wallet/edit_account/view.cljs @@ -2,13 +2,13 @@ (:require [quo.core :as quo] [react-native.core :as rn] [reagent.core :as reagent] - [status-im.config :as config] [status-im.contexts.wallet.common.screen-base.create-or-edit-account.view :as create-or-edit-account] [status-im.contexts.wallet.common.sheets.network-preferences.view :as network-preferences] [status-im.contexts.wallet.common.sheets.remove-account.view :as remove-account] [status-im.contexts.wallet.edit-account.style :as style] + [status-im.feature-flags :as ff] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -66,13 +66,12 @@ {:page-nav-right-side [(when-not default-account? {:icon-name :i/delete :on-press - (fn [] - (if (:remove-account config/wallet-feature-flags) - (rf/dispatch [:show-bottom-sheet - {:content - (fn [] - [remove-account/view])}]) - (js/alert "Feature disabled in config file")))})] + #(ff/alert ::ff/wallet.remove-account + (fn [] + (rf/dispatch [:show-bottom-sheet + {:content + (fn [] + [remove-account/view])}])))})] :account-name account-name :account-emoji emoji :account-color color diff --git a/src/status_im/feature_flags.cljs b/src/status_im/feature_flags.cljs new file mode 100644 index 0000000000..1b28d26ae5 --- /dev/null +++ b/src/status_im/feature_flags.cljs @@ -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")))) diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 3c3deb756c..6e04f10e1f 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -31,6 +31,7 @@ [status-im.contexts.onboarding.syncing.progress.view :as syncing-devices] [status-im.contexts.onboarding.syncing.results.view :as syncing-results] [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.main :as quo.preview] [status-im.contexts.preview.status-im.main :as status-im-preview] @@ -406,4 +407,9 @@ status-im-preview/screens) (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}])))