feat: 🎸 Feature toggle context
This commit is contained in:
parent
aa98a400d9
commit
ce056821a1
|
@ -1,8 +1,12 @@
|
|||
import * as eva from '@eva-design/eva'
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
import CookieManager from '@react-native-cookies/cookies'
|
||||
import initSkolplattformen from '@skolplattformen/api-skolplattformen'
|
||||
import initHjarntorget from '@skolplattformen/api-hjarntorget'
|
||||
import initSkolplattformen, {
|
||||
features as featuresSkolplattformen,
|
||||
} from '@skolplattformen/api-skolplattformen'
|
||||
import initHjarntorget, {
|
||||
features as featuresHjarntorget,
|
||||
} from '@skolplattformen/api-hjarntorget'
|
||||
|
||||
import { ApiProvider } from '@skolplattformen/hooks'
|
||||
import { ApplicationProvider, IconRegistry } from '@ui-kitten/components'
|
||||
|
@ -19,6 +23,7 @@ import useSettingsStorage from './hooks/useSettingsStorage'
|
|||
import { translations } from './utils/translation'
|
||||
import { Reporter } from '@skolplattformen/hooks'
|
||||
import { Api } from '@skolplattformen/api'
|
||||
import { FeatureProvider } from './context/feature/featureContext'
|
||||
|
||||
const ApiList = new Map<string, Api>([
|
||||
// @ts-expect-error Why is fetch failing here?
|
||||
|
@ -77,27 +82,31 @@ export default () => {
|
|||
const api = ApiList.get('goteborg-hjarntorget')!
|
||||
|
||||
return (
|
||||
<SchoolPlatformProvider>
|
||||
<ApiProvider api={api} storage={AsyncStorage} reporter={reporter}>
|
||||
<SafeAreaProvider>
|
||||
<StatusBar
|
||||
backgroundColor={colorScheme === 'dark' ? '#2E3137' : '#FFF'}
|
||||
barStyle={colorScheme === 'dark' ? 'light-content' : 'dark-content'}
|
||||
translucent
|
||||
/>
|
||||
<IconRegistry icons={EvaIconsPack} />
|
||||
<ApplicationProvider
|
||||
{...eva}
|
||||
// @ts-expect-error Unknown error
|
||||
customMapping={customMapping}
|
||||
theme={colorScheme === 'dark' ? darkTheme : lightTheme}
|
||||
>
|
||||
<LanguageProvider cache={true} data={translations}>
|
||||
<AppNavigator />
|
||||
</LanguageProvider>
|
||||
</ApplicationProvider>
|
||||
</SafeAreaProvider>
|
||||
</ApiProvider>
|
||||
</SchoolPlatformProvider>
|
||||
<FeatureProvider features={featuresHjarntorget}>
|
||||
<SchoolPlatformProvider>
|
||||
<ApiProvider api={api} storage={AsyncStorage} reporter={reporter}>
|
||||
<SafeAreaProvider>
|
||||
<StatusBar
|
||||
backgroundColor={colorScheme === 'dark' ? '#2E3137' : '#FFF'}
|
||||
barStyle={
|
||||
colorScheme === 'dark' ? 'light-content' : 'dark-content'
|
||||
}
|
||||
translucent
|
||||
/>
|
||||
<IconRegistry icons={EvaIconsPack} />
|
||||
<ApplicationProvider
|
||||
{...eva}
|
||||
// @ts-expect-error Unknown error
|
||||
customMapping={customMapping}
|
||||
theme={colorScheme === 'dark' ? darkTheme : lightTheme}
|
||||
>
|
||||
<LanguageProvider cache={true} data={translations}>
|
||||
<AppNavigator />
|
||||
</LanguageProvider>
|
||||
</ApplicationProvider>
|
||||
</SafeAreaProvider>
|
||||
</ApiProvider>
|
||||
</SchoolPlatformProvider>
|
||||
</FeatureProvider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
} from 'react-native'
|
||||
import { schema } from '../app.json'
|
||||
import { SchoolPlatformContext } from '../context/schoolPlatform/schoolPlatformContext'
|
||||
import { useFeature } from '../hooks/useFeature'
|
||||
import useSettingsStorage from '../hooks/useSettingsStorage'
|
||||
import { useTranslation } from '../hooks/useTranslation'
|
||||
import { Layout as LayoutStyle, Sizing, Typography } from '../styles'
|
||||
|
@ -57,6 +58,7 @@ export const Login = () => {
|
|||
const [loginMethodIndex, setLoginMethodIndex] =
|
||||
useSettingsStorage('loginMethodIndex')
|
||||
|
||||
const loginBankIdSameDevice = useFeature('LOGIN_BANK_ID_SAME_DEVICE')
|
||||
const { currentSchoolPlatform, changeSchoolPlatform } = useContext(
|
||||
SchoolPlatformContext
|
||||
)
|
||||
|
@ -66,11 +68,14 @@ export const Login = () => {
|
|||
const valid = Personnummer.valid(personalIdNumber)
|
||||
|
||||
const loginMethods = [
|
||||
t('auth.bankid.OpenOnThisDevice'),
|
||||
t('auth.bankid.OpenOnAnotherDevice'),
|
||||
t('auth.loginAsTestUser'),
|
||||
]
|
||||
|
||||
if (loginBankIdSameDevice) {
|
||||
loginMethods.unshift(t('auth.bankid.OpenOnThisDevice'))
|
||||
}
|
||||
|
||||
const schoolPlatforms = [
|
||||
{
|
||||
id: 'stockholm-skolplattformen',
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { Features, FeatureType } from '@skolplattformen/api'
|
||||
import React from 'react'
|
||||
|
||||
export const FeatureFlagsContext = React.createContext<Features>({
|
||||
LOGIN_BANK_ID_SAME_DEVICE: false,
|
||||
})
|
||||
|
||||
interface Props {
|
||||
features: Features
|
||||
}
|
||||
|
||||
export const FeatureProvider: React.FC<Props> = (props) => {
|
||||
return (
|
||||
<FeatureFlagsContext.Provider value={props.features} {...props}>
|
||||
{props.children}
|
||||
</FeatureFlagsContext.Provider>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react'
|
||||
import { FeatureType, Features } from '@skolplattformen/api'
|
||||
import { FeatureFlagsContext } from '../context/feature/featureContext'
|
||||
|
||||
export const useFeature = (name: FeatureType) => {
|
||||
const features = React.useContext<Features>(FeatureFlagsContext)
|
||||
if (features === null) {
|
||||
throw new Error('You must wrap your components in a FeatureProvider.')
|
||||
}
|
||||
|
||||
return features[name]
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { Feature } from '@skolplattformen/api'
|
||||
import { Features } from '@skolplattformen/api'
|
||||
|
||||
export const features: Feature[] = [
|
||||
{ name: 'login', enabled: true },
|
||||
]
|
||||
export const features: Features = {
|
||||
LOGIN_BANK_ID_SAME_DEVICE: false
|
||||
}
|
|
@ -3,6 +3,7 @@ import { Api, FetcherOptions, Fetch, RNCookieManager,
|
|||
ToughCookieJar,
|
||||
wrapReactNativeCookieManager,
|
||||
wrapToughCookie } from '@skolplattformen/api'
|
||||
export { features } from './features'
|
||||
|
||||
const init = (
|
||||
fetchImpl: Fetch,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import { Features } from '@skolplattformen/api'
|
||||
|
||||
export const features: Features = {
|
||||
LOGIN_BANK_ID_SAME_DEVICE: true
|
||||
}
|
|
@ -3,6 +3,7 @@ import { Api, FetcherOptions, Fetch, RNCookieManager,
|
|||
ToughCookieJar,
|
||||
wrapReactNativeCookieManager,
|
||||
wrapToughCookie } from '@skolplattformen/api'
|
||||
export { features } from './features'
|
||||
|
||||
const init = (
|
||||
fetchImpl: Fetch,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export interface Feature {
|
||||
name: string;
|
||||
enabled: boolean;
|
||||
}
|
||||
export interface Features {
|
||||
LOGIN_BANK_ID_SAME_DEVICE: boolean;
|
||||
}
|
||||
|
||||
export type FeatureType = keyof Features;
|
||||
|
|
|
@ -9,9 +9,9 @@ export {
|
|||
RNCookieManager,
|
||||
ToughCookieJar,
|
||||
wrapReactNativeCookieManager,
|
||||
wrapToughCookie,
|
||||
wrapToughCookie,
|
||||
} from './cookies'
|
||||
export { URLSearchParams } from './URLSearchParams'
|
||||
|
||||
export { wrap };
|
||||
export { Feature } from './features'
|
||||
export { FeatureType, Features } from './features'
|
|
@ -1,27 +0,0 @@
|
|||
import { Feature } from '@skolplattformen/api'
|
||||
import React from 'react'
|
||||
|
||||
const FeatureFlagsContext = React.createContext<Feature[]>([])
|
||||
|
||||
interface Props {
|
||||
features: Feature[]
|
||||
}
|
||||
|
||||
export const FeatureProvider: React.FC<Props> = (props) => {
|
||||
return (
|
||||
<FeatureFlagsContext.Provider value={props.features} {...props}>
|
||||
{props.children}
|
||||
</FeatureFlagsContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useFeature = (name: string) => {
|
||||
const features = React.useContext<Feature[]>(FeatureFlagsContext)
|
||||
if (features === null) {
|
||||
throw new Error('You must wrap your components in a FeatureProvider.')
|
||||
}
|
||||
|
||||
const feature = features.find((f) => f.name === name)
|
||||
|
||||
return feature && feature.enabled
|
||||
}
|
Loading…
Reference in New Issue