From eb298d2e60a0ddf26ebaf8f27373418bbf7769e3 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 6 Mar 2024 05:55:34 +0000 Subject: Initial feature gating and A/B testing integration (#3122) * Add statsig dependency * Add SDK provider * Move to separate file, add tier and hashing * Disable local storage for now * Add initial gate testing fixture * Fork for web just in case * More WIP * wip * Rm test gate * Add shim on native * Clarify --- src/App.native.tsx | 33 ++++++++++++++------------ src/App.web.tsx | 33 ++++++++++++++------------ src/lib/statsig/statsig.tsx | 11 +++++++++ src/lib/statsig/statsig.web.tsx | 51 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 30 deletions(-) create mode 100644 src/lib/statsig/statsig.tsx create mode 100644 src/lib/statsig/statsig.web.tsx (limited to 'src') diff --git a/src/App.native.tsx b/src/App.native.tsx index 4da3f85f0..eff8ab099 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -43,6 +43,7 @@ import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unre import * as persisted from '#/state/persisted' import {Splash} from '#/Splash' import {Provider as PortalProvider} from '#/components/Portal' +import {Provider as StatsigProvider} from '#/lib/statsig/statsig' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useIntentHandler} from 'lib/hooks/useIntentHandler' @@ -77,21 +78,23 @@ function InnerApp() { - - - - - {/* All components should be within this provider */} - - - - - - - - - - + + + + + + {/* All components should be within this provider */} + + + + + + + + + + + diff --git a/src/App.web.tsx b/src/App.web.tsx index 6ac32a011..eb2e42593 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -32,6 +32,7 @@ import { import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread' import * as persisted from '#/state/persisted' import {Provider as PortalProvider} from '#/components/Portal' +import {Provider as StatsigProvider} from '#/lib/statsig/statsig' import {useIntentHandler} from 'lib/hooks/useIntentHandler' function InnerApp() { @@ -54,21 +55,23 @@ function InnerApp() { - - - - - {/* All components should be within this provider */} - - - - - - - - - - + + + + + + {/* All components should be within this provider */} + + + + + + + + + + + ) diff --git a/src/lib/statsig/statsig.tsx b/src/lib/statsig/statsig.tsx new file mode 100644 index 000000000..88a57c3fc --- /dev/null +++ b/src/lib/statsig/statsig.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +export function useGate(_gateName: string) { + // Not enabled for native yet. + return false +} + +export function Provider({children}: {children: React.ReactNode}) { + // Not enabled for native yet. + return children +} diff --git a/src/lib/statsig/statsig.web.tsx b/src/lib/statsig/statsig.web.tsx new file mode 100644 index 000000000..6508131c4 --- /dev/null +++ b/src/lib/statsig/statsig.web.tsx @@ -0,0 +1,51 @@ +import React from 'react' +import {StatsigProvider, useGate as useStatsigGate} from 'statsig-react' +import {useSession} from '../../state/session' +import {sha256} from 'js-sha256' + +const statsigOptions = { + environment: { + tier: process.env.NODE_ENV === 'development' ? 'development' : 'production', + }, + // Don't block on waiting for network. The fetched config will kick in on next load. + // This ensures the UI is always consistent and doesn't update mid-session. + // Note this makes cold load (no local storage) and private mode return `false` for all gates. + initTimeoutMs: 1, +} + +export function useGate(gateName: string) { + const {isLoading, value} = useStatsigGate(gateName) + if (isLoading) { + // This should not happen because of waitForInitialization={true}. + console.error('Did not expected isLoading to ever be true.') + } + return value +} + +function toStatsigUser(did: string | undefined) { + let userID: string | undefined + if (did) { + userID = sha256(did) + } + return {userID} +} + +export function Provider({children}: {children: React.ReactNode}) { + const {currentAccount} = useSession() + const currentStatsigUser = React.useMemo( + () => toStatsigUser(currentAccount?.did), + [currentAccount?.did], + ) + return ( + + {children} + + ) +} -- cgit 1.4.1