add toggle for experimental oauth
This commit is contained in:
@@ -4,6 +4,7 @@ import {useLingui} from '@lingui/react'
|
|||||||
|
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
|
import {useExperimentalOauthEnabled} from '#/state/preferences/experimental-oauth'
|
||||||
import {type SessionAccount, useSessionApi} from '#/state/session'
|
import {type SessionAccount, useSessionApi} from '#/state/session'
|
||||||
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
@@ -17,6 +18,8 @@ export function useAccountSwitcher() {
|
|||||||
const {resumeSession} = useSessionApi()
|
const {resumeSession} = useSessionApi()
|
||||||
const {requestSwitchToAccount} = useLoggedOutViewControls()
|
const {requestSwitchToAccount} = useLoggedOutViewControls()
|
||||||
|
|
||||||
|
const shouldUseOauth = useExperimentalOauthEnabled() || USE_OAUTH
|
||||||
|
|
||||||
const onPressSwitchAccount = useCallback(
|
const onPressSwitchAccount = useCallback(
|
||||||
async (
|
async (
|
||||||
account: SessionAccount,
|
account: SessionAccount,
|
||||||
@@ -29,7 +32,7 @@ export function useAccountSwitcher() {
|
|||||||
try {
|
try {
|
||||||
setPendingDid(account.did)
|
setPendingDid(account.did)
|
||||||
// TODO: this should be checking if it is an oauth session
|
// TODO: this should be checking if it is an oauth session
|
||||||
if (USE_OAUTH || account.accessJwt) {
|
if (shouldUseOauth || account.accessJwt) {
|
||||||
if (isWeb) {
|
if (isWeb) {
|
||||||
// We're switching accounts, which remounts the entire app.
|
// We're switching accounts, which remounts the entire app.
|
||||||
// On mobile, this gets us Home, but on the web we also need reset the URL.
|
// On mobile, this gets us Home, but on the web we also need reset the URL.
|
||||||
@@ -61,7 +64,7 @@ export function useAccountSwitcher() {
|
|||||||
setPendingDid(null)
|
setPendingDid(null)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[_, resumeSession, requestSwitchToAccount, pendingDid],
|
[_, resumeSession, requestSwitchToAccount, pendingDid, shouldUseOauth],
|
||||||
)
|
)
|
||||||
|
|
||||||
return {onPressSwitchAccount, pendingDid}
|
return {onPressSwitchAccount, pendingDid}
|
||||||
|
|||||||
+209
-197
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@ import {useLingui} from '@lingui/react'
|
|||||||
import {USE_OAUTH} from '#/lib/app-info'
|
import {USE_OAUTH} from '#/lib/app-info'
|
||||||
import {logEvent} from '#/lib/statsig/statsig'
|
import {logEvent} from '#/lib/statsig/statsig'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
|
import {useExperimentalOauthEnabled} from '#/state/preferences/experimental-oauth'
|
||||||
import {type SessionAccount, useSession, useSessionApi} from '#/state/session'
|
import {type SessionAccount, useSession, useSessionApi} from '#/state/session'
|
||||||
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
@@ -28,6 +29,8 @@ export const ChooseAccountForm = ({
|
|||||||
const {resumeSession} = useSessionApi()
|
const {resumeSession} = useSessionApi()
|
||||||
const {setShowLoggedOut} = useLoggedOutViewControls()
|
const {setShowLoggedOut} = useLoggedOutViewControls()
|
||||||
|
|
||||||
|
const shouldUseOauth = useExperimentalOauthEnabled() || USE_OAUTH
|
||||||
|
|
||||||
const onSelect = React.useCallback(
|
const onSelect = React.useCallback(
|
||||||
async (account: SessionAccount) => {
|
async (account: SessionAccount) => {
|
||||||
if (pendingDid) {
|
if (pendingDid) {
|
||||||
@@ -35,7 +38,7 @@ export const ChooseAccountForm = ({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// TODO: this should be checking if it is an oauth session
|
// TODO: this should be checking if it is an oauth session
|
||||||
if (!USE_OAUTH && !account.accessJwt) {
|
if (!shouldUseOauth && !account.accessJwt) {
|
||||||
// Move to login form.
|
// Move to login form.
|
||||||
onSelectAccount(account)
|
onSelectAccount(account)
|
||||||
return
|
return
|
||||||
@@ -69,6 +72,7 @@ export const ChooseAccountForm = ({
|
|||||||
pendingDid,
|
pendingDid,
|
||||||
onSelectAccount,
|
onSelectAccount,
|
||||||
setShowLoggedOut,
|
setShowLoggedOut,
|
||||||
|
shouldUseOauth,
|
||||||
_,
|
_,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {cleanError} from '#/lib/strings/errors'
|
|||||||
import {createFullHandle} from '#/lib/strings/handles'
|
import {createFullHandle} from '#/lib/strings/handles'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
|
import {useExperimentalOauthEnabled} from '#/state/preferences/experimental-oauth'
|
||||||
import {useSetHasCheckedForStarterPack} from '#/state/preferences/used-starter-packs'
|
import {useSetHasCheckedForStarterPack} from '#/state/preferences/used-starter-packs'
|
||||||
import {useSessionApi} from '#/state/session'
|
import {useSessionApi} from '#/state/session'
|
||||||
import {getNativeOAuthClient} from '#/state/session/oauth-native-client'
|
import {getNativeOAuthClient} from '#/state/session/oauth-native-client'
|
||||||
@@ -54,7 +55,9 @@ interface LoginFormProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function LoginForm(props: LoginFormProps) {
|
export function LoginForm(props: LoginFormProps) {
|
||||||
if (USE_OAUTH) {
|
const shouldUseOauth = useExperimentalOauthEnabled() || USE_OAUTH
|
||||||
|
|
||||||
|
if (shouldUseOauth) {
|
||||||
return <OAuthLoginFormInner {...props} />
|
return <OAuthLoginFormInner {...props} />
|
||||||
} else {
|
} else {
|
||||||
return <LoginFormInner {...props} />
|
return <LoginFormInner {...props} />
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ const schema = z.object({
|
|||||||
kawaii: z.boolean().optional(),
|
kawaii: z.boolean().optional(),
|
||||||
hasCheckedForStarterPack: z.boolean().optional(),
|
hasCheckedForStarterPack: z.boolean().optional(),
|
||||||
subtitlesEnabled: z.boolean().optional(),
|
subtitlesEnabled: z.boolean().optional(),
|
||||||
|
experimentalOauthEnabled: z.boolean().optional(),
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
mutedThreads: z.array(z.string()),
|
mutedThreads: z.array(z.string()),
|
||||||
trendingDisabled: z.boolean().optional(),
|
trendingDisabled: z.boolean().optional(),
|
||||||
@@ -172,6 +173,7 @@ export const defaults: Schema = {
|
|||||||
kawaii: false,
|
kawaii: false,
|
||||||
hasCheckedForStarterPack: false,
|
hasCheckedForStarterPack: false,
|
||||||
subtitlesEnabled: true,
|
subtitlesEnabled: true,
|
||||||
|
experimentalOauthEnabled: false,
|
||||||
trendingDisabled: false,
|
trendingDisabled: false,
|
||||||
trendingVideoDisabled: false,
|
trendingVideoDisabled: false,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import * as persisted from '#/state/persisted'
|
||||||
|
|
||||||
|
type StateContext = boolean
|
||||||
|
type SetContext = (v: boolean) => void
|
||||||
|
|
||||||
|
const stateContext = React.createContext<StateContext>(
|
||||||
|
Boolean(persisted.defaults.experimentalOauthEnabled),
|
||||||
|
)
|
||||||
|
const setContext = React.createContext<SetContext>((_: boolean) => {})
|
||||||
|
|
||||||
|
export function Provider({children}: {children: React.ReactNode}) {
|
||||||
|
const [state, setState] = React.useState(
|
||||||
|
Boolean(persisted.get('experimentalOauthEnabled')),
|
||||||
|
)
|
||||||
|
|
||||||
|
const setStateWrapped = React.useCallback(
|
||||||
|
(
|
||||||
|
experimentalOauthEnabled: persisted.Schema['experimentalOauthEnabled'],
|
||||||
|
) => {
|
||||||
|
setState(Boolean(experimentalOauthEnabled))
|
||||||
|
persisted.write('experimentalOauthEnabled', experimentalOauthEnabled)
|
||||||
|
},
|
||||||
|
[setState],
|
||||||
|
)
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
return persisted.onUpdate(
|
||||||
|
'experimentalOauthEnabled',
|
||||||
|
experimentalOauthEnabled => {
|
||||||
|
setState(Boolean(experimentalOauthEnabled))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}, [setStateWrapped])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<stateContext.Provider value={state}>
|
||||||
|
<setContext.Provider value={setStateWrapped}>
|
||||||
|
{children}
|
||||||
|
</setContext.Provider>
|
||||||
|
</stateContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useExperimentalOauthEnabled = () => React.useContext(stateContext)
|
||||||
|
export const useSetExperimentalOauthEnabled = () => React.useContext(setContext)
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import React from 'react'
|
import type React from 'react'
|
||||||
|
|
||||||
import {Provider as AltTextRequiredProvider} from './alt-text-required'
|
import {Provider as AltTextRequiredProvider} from './alt-text-required'
|
||||||
import {Provider as AutoplayProvider} from './autoplay'
|
import {Provider as AutoplayProvider} from './autoplay'
|
||||||
import {Provider as DisableHapticsProvider} from './disable-haptics'
|
import {Provider as DisableHapticsProvider} from './disable-haptics'
|
||||||
|
import {Provider as ExperimentalOauthProvider} from './experimental-oauth'
|
||||||
import {Provider as ExternalEmbedsProvider} from './external-embeds-prefs'
|
import {Provider as ExternalEmbedsProvider} from './external-embeds-prefs'
|
||||||
import {Provider as HiddenPostsProvider} from './hidden-posts'
|
import {Provider as HiddenPostsProvider} from './hidden-posts'
|
||||||
import {Provider as InAppBrowserProvider} from './in-app-browser'
|
import {Provider as InAppBrowserProvider} from './in-app-browser'
|
||||||
@@ -41,7 +42,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
<UsedStarterPacksProvider>
|
<UsedStarterPacksProvider>
|
||||||
<SubtitlesProvider>
|
<SubtitlesProvider>
|
||||||
<TrendingSettingsProvider>
|
<TrendingSettingsProvider>
|
||||||
|
<ExperimentalOauthProvider>
|
||||||
<KawaiiProvider>{children}</KawaiiProvider>
|
<KawaiiProvider>{children}</KawaiiProvider>
|
||||||
|
</ExperimentalOauthProvider>
|
||||||
</TrendingSettingsProvider>
|
</TrendingSettingsProvider>
|
||||||
</SubtitlesProvider>
|
</SubtitlesProvider>
|
||||||
</UsedStarterPacksProvider>
|
</UsedStarterPacksProvider>
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
type SessionApiContext,
|
type SessionApiContext,
|
||||||
type SessionStateContext,
|
type SessionStateContext,
|
||||||
} from '#/state/session/types'
|
} from '#/state/session/types'
|
||||||
|
import {useExperimentalOauthEnabled} from '../preferences/experimental-oauth'
|
||||||
import {
|
import {
|
||||||
type OauthBskyAppAgent,
|
type OauthBskyAppAgent,
|
||||||
oauthCreateAgent,
|
oauthCreateAgent,
|
||||||
@@ -57,6 +58,8 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
return initialState
|
return initialState
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const shouldUseOauth = useExperimentalOauthEnabled() || USE_OAUTH
|
||||||
|
|
||||||
const onAgentSessionChange = React.useCallback(
|
const onAgentSessionChange = React.useCallback(
|
||||||
(agent: BskyAgent, accountDid: string, sessionEvent: AtpSessionEvent) => {
|
(agent: BskyAgent, accountDid: string, sessionEvent: AtpSessionEvent) => {
|
||||||
const refreshedAccount = agentToSessionAccount(agent) // Mutable, so snapshot it right away.
|
const refreshedAccount = agentToSessionAccount(agent) // Mutable, so snapshot it right away.
|
||||||
@@ -187,7 +190,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
account: SessionAccount
|
account: SessionAccount
|
||||||
}
|
}
|
||||||
|
|
||||||
if (USE_OAUTH) {
|
if (shouldUseOauth) {
|
||||||
agentAccount = await oauthResumeSession(storedAccount)
|
agentAccount = await oauthResumeSession(storedAccount)
|
||||||
} else {
|
} else {
|
||||||
agentAccount = await createAgentAndResume(
|
agentAccount = await createAgentAndResume(
|
||||||
@@ -209,7 +212,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
})
|
})
|
||||||
addSessionDebugLog({type: 'method:end', method: 'resumeSession', account})
|
addSessionDebugLog({type: 'method:end', method: 'resumeSession', account})
|
||||||
},
|
},
|
||||||
[onAgentSessionChange, cancelPendingTask],
|
[onAgentSessionChange, cancelPendingTask, shouldUseOauth],
|
||||||
)
|
)
|
||||||
|
|
||||||
const removeAccount = React.useCallback<SessionApiContext['removeAccount']>(
|
const removeAccount = React.useCallback<SessionApiContext['removeAccount']>(
|
||||||
@@ -256,7 +259,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
a => a.did === synced.currentAccount?.did,
|
a => a.did === synced.currentAccount?.did,
|
||||||
)
|
)
|
||||||
// TODO: this should be checking if it is an oauth session
|
// TODO: this should be checking if it is an oauth session
|
||||||
if (syncedAccount && (USE_OAUTH || syncedAccount?.refreshJwt)) {
|
if (syncedAccount && (shouldUseOauth || syncedAccount?.refreshJwt)) {
|
||||||
if (syncedAccount.did !== state.currentAgentState.did) {
|
if (syncedAccount.did !== state.currentAgentState.did) {
|
||||||
resumeSession(syncedAccount)
|
resumeSession(syncedAccount)
|
||||||
} else {
|
} else {
|
||||||
@@ -272,7 +275,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, [state, resumeSession])
|
}, [state, resumeSession, shouldUseOauth])
|
||||||
|
|
||||||
const stateContext = React.useMemo(
|
const stateContext = React.useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {StyleSheet, TouchableOpacity, View} from 'react-native'
|
import {Pressable, StyleSheet, TouchableOpacity, View} from 'react-native'
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
@@ -7,12 +7,20 @@ import {useFocusEffect} from '@react-navigation/native'
|
|||||||
|
|
||||||
import {usePalette} from '#/lib/hooks/usePalette'
|
import {usePalette} from '#/lib/hooks/usePalette'
|
||||||
import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
||||||
import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
|
import {
|
||||||
|
type CommonNavigatorParams,
|
||||||
|
type NativeStackScreenProps,
|
||||||
|
} from '#/lib/routes/types'
|
||||||
import {s} from '#/lib/styles'
|
import {s} from '#/lib/styles'
|
||||||
import {getEntries} from '#/logger/logDump'
|
import {getEntries} from '#/logger/logDump'
|
||||||
|
import {
|
||||||
|
useExperimentalOauthEnabled,
|
||||||
|
useSetExperimentalOauthEnabled,
|
||||||
|
} from '#/state/preferences/experimental-oauth'
|
||||||
import {useTickEveryMinute} from '#/state/shell'
|
import {useTickEveryMinute} from '#/state/shell'
|
||||||
import {useSetMinimalShellMode} from '#/state/shell'
|
import {useSetMinimalShellMode} from '#/state/shell'
|
||||||
import {Text} from '#/view/com/util/text/Text'
|
import {Text} from '#/view/com/util/text/Text'
|
||||||
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {ViewHeader} from '#/view/com/util/ViewHeader'
|
import {ViewHeader} from '#/view/com/util/ViewHeader'
|
||||||
import {ScrollView} from '#/view/com/util/Views'
|
import {ScrollView} from '#/view/com/util/Views'
|
||||||
import * as Layout from '#/components/Layout'
|
import * as Layout from '#/components/Layout'
|
||||||
@@ -28,6 +36,11 @@ export function LogScreen({}: NativeStackScreenProps<
|
|||||||
const timeAgo = useGetTimeAgo()
|
const timeAgo = useGetTimeAgo()
|
||||||
const tick = useTickEveryMinute()
|
const tick = useTickEveryMinute()
|
||||||
|
|
||||||
|
const experimentalOauthEnabled = useExperimentalOauthEnabled()
|
||||||
|
const setExperimentalOauthEnabled = useSetExperimentalOauthEnabled()
|
||||||
|
|
||||||
|
const titlePressCount = React.useRef(0)
|
||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
React.useCallback(() => {
|
React.useCallback(() => {
|
||||||
setMinimalShellMode(false)
|
setMinimalShellMode(false)
|
||||||
@@ -44,7 +57,22 @@ export function LogScreen({}: NativeStackScreenProps<
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout.Screen>
|
<Layout.Screen>
|
||||||
|
<Pressable
|
||||||
|
accessibilityRole="button"
|
||||||
|
onPress={() => {
|
||||||
|
titlePressCount.current += 1
|
||||||
|
if (titlePressCount.current === 7) {
|
||||||
|
Toast.show(
|
||||||
|
experimentalOauthEnabled
|
||||||
|
? _(msg`Experimental OAuth Disabled`)
|
||||||
|
: _(msg`Experimental OAuth Enabled`),
|
||||||
|
)
|
||||||
|
setExperimentalOauthEnabled(!experimentalOauthEnabled)
|
||||||
|
titlePressCount.current = 0
|
||||||
|
}
|
||||||
|
}}>
|
||||||
<ViewHeader title="Log" />
|
<ViewHeader title="Log" />
|
||||||
|
</Pressable>
|
||||||
<ScrollView style={s.flex1}>
|
<ScrollView style={s.flex1}>
|
||||||
{getEntries()
|
{getEntries()
|
||||||
.slice(0)
|
.slice(0)
|
||||||
|
|||||||
Reference in New Issue
Block a user