diff --git a/lib/facts/feature-flags.js b/lib/facts/feature-flags.js new file mode 100644 index 000000000..7b5fe8680 --- /dev/null +++ b/lib/facts/feature-flags.js @@ -0,0 +1,7 @@ +// @flow + +const config = { + url: 'https://feature-flags.commtechnologies.org', +}; + +export default config; diff --git a/lib/utils/feature-flags-utils.js b/lib/utils/feature-flags-utils.js new file mode 100644 index 000000000..cd719bcf7 --- /dev/null +++ b/lib/utils/feature-flags-utils.js @@ -0,0 +1,28 @@ +// @flow + +import featureFlags from '../facts/feature-flags.js'; + +type FeatureFlagsConfiguration = { + +enabledFeatures: $ReadOnlyArray, +}; + +async function fetchFeatureFlags( + platform: string, + isStaff: boolean, + codeVersion: number, +): Promise { + const url = `${ + featureFlags.url + }/features?platform=${platform}&is_staff=${isStaff.toString()}&code_version=${codeVersion}`; + const response = await fetch(url, { + headers: { + Accept: 'application/json', + }, + }); + const json = await response.json(); + return { + enabledFeatures: json.enabled_features, + }; +} + +export { fetchFeatureFlags }; diff --git a/native/components/feature-flags-provider.react.js b/native/components/feature-flags-provider.react.js index 7c7e24522..9b7394cb3 100644 --- a/native/components/feature-flags-provider.react.js +++ b/native/components/feature-flags-provider.react.js @@ -1,34 +1,65 @@ // @flow import * as React from 'react'; +import { Platform } from 'react-native'; + +import { fetchFeatureFlags } from 'lib/utils/feature-flags-utils.js'; +import { useIsCurrentUserStaff } from 'native/utils/staff-utils.js'; + +import { codeVersion } from '../redux/persist.js'; type FeatureFlagsConfiguration = { +[feature: string]: boolean, }; type FeatureFlagsContextType = { +configuration: FeatureFlagsConfiguration, +loaded: boolean, }; const defaultContext = { configuration: {}, loaded: false, }; const FeatureFlagsContext: React.Context = React.createContext(defaultContext); type Props = { +children: React.Node, }; function FeatureFlagsProvider(props: Props): React.Node { const { children } = props; + const isStaff = useIsCurrentUserStaff(); + + const [featuresConfig, setFeaturesConfig] = React.useState(defaultContext); + React.useEffect(() => { + (async () => { + try { + const config = await fetchFeatureFlags( + Platform.OS, + isStaff, + codeVersion, + ); + const configuration = {}; + for (const feature of config.enabledFeatures) { + configuration[feature] = true; + } + setFeaturesConfig({ + configuration, + loaded: true, + }); + } catch (e) { + console.error('Feature flag retrieval failed:', e); + } + })(); + }, [isStaff]); + return ( - + {children} ); } export { FeatureFlagsContext, FeatureFlagsProvider };