Persist in-app feature flags (dev-only feature) (#19619)
This commit improves in-app feature flags to persist what is currently only stored in a Reagent atom by using RN Async Storage https://reactnative.dev/docs/asyncstorage. This should make them more convenient to use, which is a good thing overall for developers. Additionally, there's now a top-right button in screen Settings > Feature Flags that will reset the flags to the initial values obtained from environment variables. These in-app feature flags are exclusively available in debug builds in Settings > Feature Flags, and only visible when flag ENABLE_QUO_PREVIEW is enabled. There's no impact whatsoever in prod builds. A reminder that they are not meant to be used by users (yet). It's worth noting that RN has deprecated Async Storage and now recommends other community solutions, but for a dev-only feature, I think it's fine.
This commit is contained in:
parent
ab191407ed
commit
8ad58bb364
|
@ -15,7 +15,9 @@
|
|||
:text-align :left
|
||||
:title "Features Flags"
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:right-side [{:icon-name :i/rotate
|
||||
:on-press #(ff/reset-flags)}]}]
|
||||
(doall
|
||||
(for [context-name ff/feature-flags-categories
|
||||
:let [context-flags (filter (fn [[k]]
|
||||
|
@ -36,4 +38,3 @@
|
|||
:container-style {:margin-right 8}
|
||||
:on-change #(ff/toggle flag)}]
|
||||
[quo/text (second (string/split (name flag) "."))]]))]))])
|
||||
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
[status-im.contexts.profile.push-notifications.events :as notifications]
|
||||
[status-im.contexts.shell.jump-to.state :as shell.state]
|
||||
[status-im.contexts.shell.jump-to.utils :as shell.utils]
|
||||
[status-im.feature-flags :as ff]
|
||||
[status-im.navigation.core :as navigation]
|
||||
status-im.contexts.wallet.signals
|
||||
status-im.events
|
||||
status-im.navigation.core
|
||||
[status-im.setup.dev :as dev]
|
||||
[status-im.setup.global-error :as global-error]
|
||||
[status-im.setup.interceptors :as interceptors]
|
||||
|
@ -63,6 +63,9 @@
|
|||
(async-storage/get-item :selected-stack-id #(shell.utils/change-selected-stack-id % nil nil))
|
||||
(async-storage/get-item :screen-height #(reset! shell.state/screen-height %))
|
||||
|
||||
(when config/quo-preview-enabled?
|
||||
(ff/load-flags))
|
||||
|
||||
(dev/setup)
|
||||
(log/info "hermesEnabled ->" (is-hermes))
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.feature-flags
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[react-native.async-storage :as async-storage]
|
||||
[react-native.config :as config]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
|
@ -8,20 +9,22 @@
|
|||
[k]
|
||||
(= "1" (config/get-config k)))
|
||||
|
||||
(def ^:private initial-flags
|
||||
{::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)
|
||||
::wallet.activities (enabled-in-env? :FLAG_WALLET_ACTIVITY_ENABLED)
|
||||
::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE)
|
||||
::wallet.assets-modal-manage-tokens (enabled-in-env? :FLAG_ASSETS_MODAL_MANAGE_TOKENS)
|
||||
::wallet.bridge-token (enabled-in-env? :FLAG_BRIDGE_TOKEN_ENABLED)
|
||||
::wallet.contacts (enabled-in-env? :FLAG_CONTACTS_ENABLED)
|
||||
::wallet.edit-derivation-path (enabled-in-env? :FLAG_EDIT_DERIVATION_PATH)
|
||||
::wallet.graph (enabled-in-env? :FLAG_GRAPH_ENABLED)
|
||||
::wallet.import-private-key (enabled-in-env? :FLAG_IMPORT_PRIVATE_KEY_ENABLED)
|
||||
::wallet.long-press-watch-only-asset (enabled-in-env? :FLAG_LONG_PRESS_WATCH_ONLY_ASSET_ENABLED)
|
||||
::wallet.swap (enabled-in-env? :FLAG_SWAP_ENABLED)
|
||||
::wallet.wallet-connect (enabled-in-env? :FLAG_WALLET_CONNECT_ENABLED)})
|
||||
|
||||
(defonce ^:private feature-flags-config
|
||||
(reagent/atom
|
||||
{::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)
|
||||
::wallet.activities (enabled-in-env? :FLAG_WALLET_ACTIVITY_ENABLED)
|
||||
::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE)
|
||||
::wallet.assets-modal-manage-tokens (enabled-in-env? :FLAG_ASSETS_MODAL_MANAGE_TOKENS)
|
||||
::wallet.bridge-token (enabled-in-env? :FLAG_BRIDGE_TOKEN_ENABLED)
|
||||
::wallet.contacts (enabled-in-env? :FLAG_CONTACTS_ENABLED)
|
||||
::wallet.edit-derivation-path (enabled-in-env? :FLAG_EDIT_DERIVATION_PATH)
|
||||
::wallet.graph (enabled-in-env? :FLAG_GRAPH_ENABLED)
|
||||
::wallet.import-private-key (enabled-in-env? :FLAG_IMPORT_PRIVATE_KEY_ENABLED)
|
||||
::wallet.long-press-watch-only-asset (enabled-in-env? :FLAG_LONG_PRESS_WATCH_ONLY_ASSET_ENABLED)
|
||||
::wallet.swap (enabled-in-env? :FLAG_SWAP_ENABLED)
|
||||
::wallet.wallet-connect (enabled-in-env? :FLAG_WALLET_CONNECT_ENABLED)}))
|
||||
(reagent/atom initial-flags))
|
||||
|
||||
(defn feature-flags [] @feature-flags-config)
|
||||
|
||||
|
@ -37,7 +40,28 @@
|
|||
|
||||
(defn toggle
|
||||
[flag]
|
||||
(swap! feature-flags-config update flag not))
|
||||
(let [new-flags (update @feature-flags-config flag not)]
|
||||
(async-storage/set-item!
|
||||
:feature-flags
|
||||
new-flags
|
||||
(fn []
|
||||
(reset! feature-flags-config new-flags)))))
|
||||
|
||||
(defn load-flags
|
||||
[]
|
||||
(async-storage/get-item
|
||||
:feature-flags
|
||||
(fn [flags]
|
||||
(when flags
|
||||
(reset! feature-flags-config flags)))))
|
||||
|
||||
(defn reset-flags
|
||||
[]
|
||||
(async-storage/set-item!
|
||||
:feature-flags
|
||||
initial-flags
|
||||
(fn []
|
||||
(reset! feature-flags-config initial-flags))))
|
||||
|
||||
(defn alert
|
||||
[flag action]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const WebSocket = require('ws');
|
||||
const { NativeModules } = require('react-native');
|
||||
|
||||
require('@react-native-async-storage/async-storage/jest/async-storage-mock');
|
||||
mockAsyncStorage = require('@react-native-async-storage/async-storage/jest/async-storage-mock');
|
||||
require('react-native-gesture-handler/jestSetup');
|
||||
require('react-native-reanimated/src/reanimated2/jestUtils').setUpTests();
|
||||
|
||||
|
|
Loading…
Reference in New Issue