Rework logged out state to preserve routing and work for web
parent
b5c64a03b6
commit
774fb83719
|
@ -122,7 +122,9 @@ export class SessionModel {
|
||||||
try {
|
try {
|
||||||
return await this.resumeSession(sess)
|
return await this.resumeSession(sess)
|
||||||
} finally {
|
} finally {
|
||||||
|
runInAction(() => {
|
||||||
this.isResumingSession = false
|
this.isResumingSession = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.rootStore.log.debug(
|
this.rootStore.log.debug(
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {SafeAreaView} from 'react-native'
|
||||||
|
import {observer} from 'mobx-react-lite'
|
||||||
|
import {Signin} from 'view/com/auth/Signin'
|
||||||
|
import {CreateAccount} from 'view/com/auth/CreateAccount'
|
||||||
|
import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
|
||||||
|
import {s} from 'lib/styles'
|
||||||
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {useStores} from 'state/index'
|
||||||
|
import {useAnalytics} from 'lib/analytics'
|
||||||
|
import {SplashScreen} from './SplashScreen'
|
||||||
|
import {CenteredView} from '../util/Views'
|
||||||
|
|
||||||
|
enum ScreenState {
|
||||||
|
S_SigninOrCreateAccount,
|
||||||
|
S_Signin,
|
||||||
|
S_CreateAccount,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LoggedOut = observer(() => {
|
||||||
|
const pal = usePalette('default')
|
||||||
|
const store = useStores()
|
||||||
|
const {screen} = useAnalytics()
|
||||||
|
const [screenState, setScreenState] = React.useState<ScreenState>(
|
||||||
|
ScreenState.S_SigninOrCreateAccount,
|
||||||
|
)
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
screen('Login')
|
||||||
|
store.shell.setMinimalShellMode(true)
|
||||||
|
}, [store, screen])
|
||||||
|
|
||||||
|
if (
|
||||||
|
store.session.isResumingSession ||
|
||||||
|
screenState === ScreenState.S_SigninOrCreateAccount
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<SplashScreen
|
||||||
|
onPressSignin={() => setScreenState(ScreenState.S_Signin)}
|
||||||
|
onPressCreateAccount={() => setScreenState(ScreenState.S_CreateAccount)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CenteredView style={[s.hContentRegion, pal.view]}>
|
||||||
|
<SafeAreaView testID="noSessionView" style={s.hContentRegion}>
|
||||||
|
<ErrorBoundary>
|
||||||
|
{screenState === ScreenState.S_Signin ? (
|
||||||
|
<Signin
|
||||||
|
onPressBack={() =>
|
||||||
|
setScreenState(ScreenState.S_SigninOrCreateAccount)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
) : undefined}
|
||||||
|
{screenState === ScreenState.S_CreateAccount ? (
|
||||||
|
<CreateAccount
|
||||||
|
onPressBack={() =>
|
||||||
|
setScreenState(ScreenState.S_SigninOrCreateAccount)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
) : undefined}
|
||||||
|
</ErrorBoundary>
|
||||||
|
</SafeAreaView>
|
||||||
|
</CenteredView>
|
||||||
|
)
|
||||||
|
})
|
|
@ -1,28 +1,19 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {StyleSheet} from 'react-native'
|
import {StyleSheet, View} from 'react-native'
|
||||||
import LinearGradient from 'react-native-linear-gradient'
|
import {s, colors} from 'lib/styles'
|
||||||
import {s, gradients} from 'lib/styles'
|
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
|
|
||||||
export const LogoTextHero = () => {
|
export const LogoTextHero = () => {
|
||||||
return (
|
return (
|
||||||
<LinearGradient
|
<View style={[styles.textHero]}>
|
||||||
colors={[gradients.blue.start, gradients.blue.end]}
|
|
||||||
start={{x: 0, y: 0}}
|
|
||||||
end={{x: 1, y: 1}}
|
|
||||||
style={[styles.textHero]}>
|
|
||||||
<Text type="title-lg" style={[s.white, s.bold]}>
|
<Text type="title-lg" style={[s.white, s.bold]}>
|
||||||
Bluesky
|
Bluesky
|
||||||
</Text>
|
</Text>
|
||||||
</LinearGradient>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
logo: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
textHero: {
|
textHero: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
@ -30,5 +21,6 @@ const styles = StyleSheet.create({
|
||||||
paddingRight: 20,
|
paddingRight: 20,
|
||||||
paddingVertical: 15,
|
paddingVertical: 15,
|
||||||
marginBottom: 20,
|
marginBottom: 20,
|
||||||
|
backgroundColor: colors.blue3,
|
||||||
},
|
},
|
||||||
})
|
})
|
|
@ -0,0 +1,92 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {SafeAreaView, StyleSheet, TouchableOpacity, View} from 'react-native'
|
||||||
|
import Image, {Source as ImageSource} from 'view/com/util/images/Image'
|
||||||
|
import {Text} from 'view/com/util/text/Text'
|
||||||
|
import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
|
||||||
|
import {colors} from 'lib/styles'
|
||||||
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {CLOUD_SPLASH} from 'lib/assets'
|
||||||
|
import {CenteredView} from '../util/Views'
|
||||||
|
|
||||||
|
export const SplashScreen = ({
|
||||||
|
onPressSignin,
|
||||||
|
onPressCreateAccount,
|
||||||
|
}: {
|
||||||
|
onPressSignin: () => void
|
||||||
|
onPressCreateAccount: () => void
|
||||||
|
}) => {
|
||||||
|
const pal = usePalette('default')
|
||||||
|
return (
|
||||||
|
<CenteredView style={styles.container}>
|
||||||
|
<Image source={CLOUD_SPLASH as ImageSource} style={styles.bgImg} />
|
||||||
|
<SafeAreaView testID="noSessionView" style={styles.container}>
|
||||||
|
<ErrorBoundary>
|
||||||
|
<View style={styles.hero}>
|
||||||
|
<View style={styles.heroText}>
|
||||||
|
<Text style={styles.title}>Bluesky</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View testID="signinOrCreateAccount" style={styles.btns}>
|
||||||
|
<TouchableOpacity
|
||||||
|
testID="createAccountButton"
|
||||||
|
style={[pal.view, styles.btn]}
|
||||||
|
onPress={onPressCreateAccount}>
|
||||||
|
<Text style={[pal.link, styles.btnLabel]}>
|
||||||
|
Create a new account
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
testID="signInButton"
|
||||||
|
style={[pal.view, styles.btn]}
|
||||||
|
onPress={onPressSignin}>
|
||||||
|
<Text style={[pal.link, styles.btnLabel]}>Sign in</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</ErrorBoundary>
|
||||||
|
</SafeAreaView>
|
||||||
|
</CenteredView>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
|
hero: {
|
||||||
|
flex: 2,
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
bgImg: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
|
heroText: {
|
||||||
|
backgroundColor: colors.white,
|
||||||
|
paddingTop: 10,
|
||||||
|
paddingBottom: 20,
|
||||||
|
},
|
||||||
|
btns: {
|
||||||
|
paddingBottom: 40,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
textAlign: 'center',
|
||||||
|
color: colors.blue3,
|
||||||
|
fontSize: 68,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
btn: {
|
||||||
|
borderRadius: 4,
|
||||||
|
paddingVertical: 16,
|
||||||
|
marginBottom: 20,
|
||||||
|
marginHorizontal: 20,
|
||||||
|
backgroundColor: colors.blue3,
|
||||||
|
},
|
||||||
|
btnLabel: {
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: 21,
|
||||||
|
color: colors.white,
|
||||||
|
},
|
||||||
|
})
|
|
@ -0,0 +1,102 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {StyleSheet, TouchableOpacity, View} from 'react-native'
|
||||||
|
import {Text} from 'view/com/util/text/Text'
|
||||||
|
import {TextLink} from '../util/Link'
|
||||||
|
import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
|
||||||
|
import {s, colors} from 'lib/styles'
|
||||||
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {CenteredView} from '../util/Views'
|
||||||
|
|
||||||
|
export const SplashScreen = ({
|
||||||
|
onPressSignin,
|
||||||
|
onPressCreateAccount,
|
||||||
|
}: {
|
||||||
|
onPressSignin: () => void
|
||||||
|
onPressCreateAccount: () => void
|
||||||
|
}) => {
|
||||||
|
const pal = usePalette('default')
|
||||||
|
return (
|
||||||
|
<CenteredView style={styles.container}>
|
||||||
|
<View testID="noSessionView" style={styles.containerInner}>
|
||||||
|
<ErrorBoundary>
|
||||||
|
<Text style={styles.title}>Bluesky</Text>
|
||||||
|
<Text style={styles.subtitle}>See what's next</Text>
|
||||||
|
<View testID="signinOrCreateAccount" style={styles.btns}>
|
||||||
|
<TouchableOpacity
|
||||||
|
testID="createAccountButton"
|
||||||
|
style={[styles.btn, {backgroundColor: colors.blue3}]}
|
||||||
|
onPress={onPressCreateAccount}>
|
||||||
|
<Text style={[s.white, styles.btnLabel]}>
|
||||||
|
Create a new account
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity
|
||||||
|
testID="signInButton"
|
||||||
|
style={[styles.btn, pal.btn]}
|
||||||
|
onPress={onPressSignin}>
|
||||||
|
<Text style={[pal.link, styles.btnLabel]}>Sign in</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
<Text
|
||||||
|
type="xl"
|
||||||
|
style={[styles.notice, pal.textLight]}
|
||||||
|
lineHeight={1.3}>
|
||||||
|
Bluesky will launch soon.{' '}
|
||||||
|
<TextLink
|
||||||
|
type="xl"
|
||||||
|
text="Join the waitlist"
|
||||||
|
href="#"
|
||||||
|
style={pal.link}
|
||||||
|
/>{' '}
|
||||||
|
to try the beta before it's publicly available.
|
||||||
|
</Text>
|
||||||
|
</ErrorBoundary>
|
||||||
|
</View>
|
||||||
|
</CenteredView>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
height: '100%',
|
||||||
|
backgroundColor: colors.gray1,
|
||||||
|
},
|
||||||
|
containerInner: {
|
||||||
|
backgroundColor: colors.white,
|
||||||
|
paddingVertical: 40,
|
||||||
|
paddingBottom: 50,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
textAlign: 'center',
|
||||||
|
color: colors.blue3,
|
||||||
|
fontSize: 68,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
paddingBottom: 10,
|
||||||
|
},
|
||||||
|
subtitle: {
|
||||||
|
textAlign: 'center',
|
||||||
|
color: colors.gray5,
|
||||||
|
fontSize: 52,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
paddingBottom: 30,
|
||||||
|
},
|
||||||
|
btns: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
paddingBottom: 40,
|
||||||
|
},
|
||||||
|
btn: {
|
||||||
|
flex: 1,
|
||||||
|
borderRadius: 30,
|
||||||
|
paddingVertical: 12,
|
||||||
|
marginHorizontal: 10,
|
||||||
|
},
|
||||||
|
btnLabel: {
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: 18,
|
||||||
|
},
|
||||||
|
notice: {
|
||||||
|
paddingHorizontal: 40,
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
})
|
|
@ -0,0 +1,47 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {ActivityIndicator, StyleSheet, View} from 'react-native'
|
||||||
|
import {observer} from 'mobx-react-lite'
|
||||||
|
import {useStores} from 'state/index'
|
||||||
|
import {LoggedOut} from './LoggedOut'
|
||||||
|
import {Text} from '../util/text/Text'
|
||||||
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
|
||||||
|
export const withAuthRequired = <P extends object>(
|
||||||
|
Component: React.ComponentType<P>,
|
||||||
|
): React.FC<P> =>
|
||||||
|
observer((props: P) => {
|
||||||
|
const store = useStores()
|
||||||
|
if (store.session.isResumingSession) {
|
||||||
|
return <Loading />
|
||||||
|
}
|
||||||
|
if (!store.session.hasSession) {
|
||||||
|
return <LoggedOut />
|
||||||
|
}
|
||||||
|
return <Component {...props} />
|
||||||
|
})
|
||||||
|
|
||||||
|
function Loading() {
|
||||||
|
const pal = usePalette('default')
|
||||||
|
return (
|
||||||
|
<View style={[styles.loading, pal.view]}>
|
||||||
|
<ActivityIndicator size="large" />
|
||||||
|
<Text type="2xl" style={[styles.loadingText, pal.textLight]}>
|
||||||
|
Firing up the grill...
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
loading: {
|
||||||
|
height: '100%',
|
||||||
|
alignContent: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
paddingBottom: 100,
|
||||||
|
},
|
||||||
|
loadingText: {
|
||||||
|
paddingVertical: 20,
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
})
|
|
@ -4,6 +4,7 @@ import {useFocusEffect, useIsFocused} from '@react-navigation/native'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import useAppState from 'react-native-appstate-hook'
|
import useAppState from 'react-native-appstate-hook'
|
||||||
import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types'
|
import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {ViewHeader} from '../com/util/ViewHeader'
|
import {ViewHeader} from '../com/util/ViewHeader'
|
||||||
import {Feed} from '../com/posts/Feed'
|
import {Feed} from '../com/posts/Feed'
|
||||||
import {LoadLatestBtn} from '../com/util/LoadLatestBtn'
|
import {LoadLatestBtn} from '../com/util/LoadLatestBtn'
|
||||||
|
@ -18,7 +19,8 @@ import {ComposeIcon2} from 'lib/icons'
|
||||||
const HEADER_HEIGHT = 42
|
const HEADER_HEIGHT = 42
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
|
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home'>
|
||||||
export const HomeScreen = observer(function Home(_opts: Props) {
|
export const HomeScreen = withAuthRequired(
|
||||||
|
observer(function Home(_opts: Props) {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const onMainScroll = useOnMainScroll(store)
|
const onMainScroll = useOnMainScroll(store)
|
||||||
const {screen, track} = useAnalytics()
|
const {screen, track} = useAnalytics()
|
||||||
|
@ -109,4 +111,5 @@ export const HomeScreen = observer(function Home(_opts: Props) {
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
|
)
|
||||||
|
|
|
@ -1,164 +0,0 @@
|
||||||
import React, {useEffect, useState} from 'react'
|
|
||||||
import {SafeAreaView, StyleSheet, TouchableOpacity, View} from 'react-native'
|
|
||||||
import Image, {Source as ImageSource} from 'view/com/util/images/Image'
|
|
||||||
import {observer} from 'mobx-react-lite'
|
|
||||||
import {Signin} from '../com/login/Signin'
|
|
||||||
import {CreateAccount} from '../com/login/CreateAccount'
|
|
||||||
import {Text} from '../com/util/text/Text'
|
|
||||||
import {ErrorBoundary} from '../com/util/ErrorBoundary'
|
|
||||||
import {colors} from 'lib/styles'
|
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {useStores} from 'state/index'
|
|
||||||
import {CLOUD_SPLASH} from 'lib/assets'
|
|
||||||
import {useAnalytics} from 'lib/analytics'
|
|
||||||
|
|
||||||
enum ScreenState {
|
|
||||||
S_SigninOrCreateAccount,
|
|
||||||
S_Signin,
|
|
||||||
S_CreateAccount,
|
|
||||||
}
|
|
||||||
|
|
||||||
const SigninOrCreateAccount = ({
|
|
||||||
onPressSignin,
|
|
||||||
onPressCreateAccount,
|
|
||||||
}: {
|
|
||||||
onPressSignin: () => void
|
|
||||||
onPressCreateAccount: () => void
|
|
||||||
}) => {
|
|
||||||
const {screen} = useAnalytics()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
screen('Login')
|
|
||||||
}, [screen])
|
|
||||||
|
|
||||||
const pal = usePalette('default')
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<View style={styles.hero}>
|
|
||||||
<View style={styles.heroText}>
|
|
||||||
<Text style={styles.title}>Bluesky</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View testID="signinOrCreateAccount" style={styles.btns}>
|
|
||||||
<TouchableOpacity
|
|
||||||
testID="createAccountButton"
|
|
||||||
style={[pal.view, styles.btn]}
|
|
||||||
onPress={onPressCreateAccount}>
|
|
||||||
<Text style={[pal.link, styles.btnLabel]}>Create a new account</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<TouchableOpacity
|
|
||||||
testID="signInButton"
|
|
||||||
style={[pal.view, styles.btn]}
|
|
||||||
onPress={onPressSignin}>
|
|
||||||
<Text style={[pal.link, styles.btnLabel]}>Sign in</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Login = observer(() => {
|
|
||||||
const pal = usePalette('default')
|
|
||||||
const store = useStores()
|
|
||||||
const [screenState, setScreenState] = useState<ScreenState>(
|
|
||||||
ScreenState.S_SigninOrCreateAccount,
|
|
||||||
)
|
|
||||||
|
|
||||||
if (
|
|
||||||
store.session.isResumingSession ||
|
|
||||||
screenState === ScreenState.S_SigninOrCreateAccount
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<View style={styles.container}>
|
|
||||||
<Image source={CLOUD_SPLASH as ImageSource} style={styles.bgImg} />
|
|
||||||
<SafeAreaView testID="noSessionView" style={styles.container}>
|
|
||||||
<ErrorBoundary>
|
|
||||||
{!store.session.isResumingSession && (
|
|
||||||
<SigninOrCreateAccount
|
|
||||||
onPressSignin={() => setScreenState(ScreenState.S_Signin)}
|
|
||||||
onPressCreateAccount={() =>
|
|
||||||
setScreenState(ScreenState.S_CreateAccount)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</ErrorBoundary>
|
|
||||||
</SafeAreaView>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={[styles.container, pal.view]}>
|
|
||||||
<SafeAreaView testID="noSessionView" style={styles.container}>
|
|
||||||
<ErrorBoundary>
|
|
||||||
{screenState === ScreenState.S_Signin ? (
|
|
||||||
<Signin
|
|
||||||
onPressBack={() =>
|
|
||||||
setScreenState(ScreenState.S_SigninOrCreateAccount)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
) : undefined}
|
|
||||||
{screenState === ScreenState.S_CreateAccount ? (
|
|
||||||
<CreateAccount
|
|
||||||
onPressBack={() =>
|
|
||||||
setScreenState(ScreenState.S_SigninOrCreateAccount)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
) : undefined}
|
|
||||||
</ErrorBoundary>
|
|
||||||
</SafeAreaView>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
height: '100%',
|
|
||||||
},
|
|
||||||
outer: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
hero: {
|
|
||||||
flex: 2,
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
bgImg: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
},
|
|
||||||
heroText: {
|
|
||||||
backgroundColor: colors.white,
|
|
||||||
paddingTop: 10,
|
|
||||||
paddingBottom: 20,
|
|
||||||
},
|
|
||||||
btns: {
|
|
||||||
paddingBottom: 40,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
textAlign: 'center',
|
|
||||||
color: colors.blue3,
|
|
||||||
fontSize: 68,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
subtitle: {
|
|
||||||
textAlign: 'center',
|
|
||||||
color: colors.blue3,
|
|
||||||
fontSize: 18,
|
|
||||||
},
|
|
||||||
btn: {
|
|
||||||
borderRadius: 4,
|
|
||||||
paddingVertical: 16,
|
|
||||||
marginBottom: 20,
|
|
||||||
marginHorizontal: 20,
|
|
||||||
backgroundColor: colors.blue3,
|
|
||||||
},
|
|
||||||
btnLabel: {
|
|
||||||
textAlign: 'center',
|
|
||||||
fontSize: 21,
|
|
||||||
// fontWeight: '500',
|
|
||||||
color: colors.white,
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -1,156 +0,0 @@
|
||||||
import React, {useState} from 'react'
|
|
||||||
import {SafeAreaView, StyleSheet, TouchableOpacity, View} from 'react-native'
|
|
||||||
import {observer} from 'mobx-react-lite'
|
|
||||||
import {CenteredView} from '../com/util/Views'
|
|
||||||
import {Signin} from '../com/login/Signin'
|
|
||||||
import {CreateAccount} from '../com/login/CreateAccount'
|
|
||||||
import {Text} from '../com/util/text/Text'
|
|
||||||
import {ErrorBoundary} from '../com/util/ErrorBoundary'
|
|
||||||
import {colors} from 'lib/styles'
|
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
|
|
||||||
enum ScreenState {
|
|
||||||
S_SigninOrCreateAccount,
|
|
||||||
S_Signin,
|
|
||||||
S_CreateAccount,
|
|
||||||
}
|
|
||||||
|
|
||||||
const SigninOrCreateAccount = ({
|
|
||||||
onPressSignin,
|
|
||||||
onPressCreateAccount,
|
|
||||||
}: {
|
|
||||||
onPressSignin: () => void
|
|
||||||
onPressCreateAccount: () => void
|
|
||||||
}) => {
|
|
||||||
const pal = usePalette('default')
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<View style={styles.hero}>
|
|
||||||
<View style={styles.heroText}>
|
|
||||||
<Text style={styles.title}>Bluesky</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View testID="signinOrCreateAccount" style={styles.btns}>
|
|
||||||
<TouchableOpacity
|
|
||||||
testID="createAccountButton"
|
|
||||||
style={[pal.view, styles.btn]}
|
|
||||||
onPress={onPressCreateAccount}>
|
|
||||||
<Text style={[pal.link, styles.btnLabel]}>New account</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<TouchableOpacity
|
|
||||||
testID="signInButton"
|
|
||||||
style={[pal.view, styles.btn]}
|
|
||||||
onPress={onPressSignin}>
|
|
||||||
<Text style={[pal.link, styles.btnLabel]}>Sign in</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Login = observer(() => {
|
|
||||||
const pal = usePalette('default')
|
|
||||||
const [screenState, setScreenState] = useState<ScreenState>(
|
|
||||||
ScreenState.S_SigninOrCreateAccount,
|
|
||||||
)
|
|
||||||
|
|
||||||
if (screenState === ScreenState.S_SigninOrCreateAccount) {
|
|
||||||
return (
|
|
||||||
<CenteredView style={[styles.container, styles.vertCenter]}>
|
|
||||||
<ErrorBoundary>
|
|
||||||
<SigninOrCreateAccount
|
|
||||||
onPressSignin={() => setScreenState(ScreenState.S_Signin)}
|
|
||||||
onPressCreateAccount={() =>
|
|
||||||
setScreenState(ScreenState.S_CreateAccount)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</ErrorBoundary>
|
|
||||||
</CenteredView>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CenteredView
|
|
||||||
style={[
|
|
||||||
styles.container,
|
|
||||||
styles.containerBorder,
|
|
||||||
pal.view,
|
|
||||||
pal.borderDark,
|
|
||||||
]}>
|
|
||||||
<SafeAreaView testID="noSessionView" style={styles.container}>
|
|
||||||
<ErrorBoundary>
|
|
||||||
{screenState === ScreenState.S_Signin ? (
|
|
||||||
<Signin
|
|
||||||
onPressBack={() =>
|
|
||||||
setScreenState(ScreenState.S_SigninOrCreateAccount)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
) : undefined}
|
|
||||||
{screenState === ScreenState.S_CreateAccount ? (
|
|
||||||
<CreateAccount
|
|
||||||
onPressBack={() =>
|
|
||||||
setScreenState(ScreenState.S_SigninOrCreateAccount)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
) : undefined}
|
|
||||||
</ErrorBoundary>
|
|
||||||
</SafeAreaView>
|
|
||||||
</CenteredView>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
height: '100%',
|
|
||||||
},
|
|
||||||
containerBorder: {
|
|
||||||
borderLeftWidth: 1,
|
|
||||||
borderRightWidth: 1,
|
|
||||||
},
|
|
||||||
vertCenter: {
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
bgImg: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
},
|
|
||||||
hero: {},
|
|
||||||
heroText: {
|
|
||||||
backgroundColor: colors.white,
|
|
||||||
paddingTop: 10,
|
|
||||||
paddingBottom: 20,
|
|
||||||
},
|
|
||||||
btns: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
paddingTop: 40,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
textAlign: 'center',
|
|
||||||
color: colors.blue3,
|
|
||||||
fontSize: 68,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
subtitle: {
|
|
||||||
textAlign: 'center',
|
|
||||||
color: colors.blue3,
|
|
||||||
fontSize: 18,
|
|
||||||
},
|
|
||||||
btn: {
|
|
||||||
flex: 1,
|
|
||||||
borderRadius: 4,
|
|
||||||
paddingVertical: 16,
|
|
||||||
marginBottom: 20,
|
|
||||||
marginHorizontal: 20,
|
|
||||||
borderWidth: 1,
|
|
||||||
borderColor: colors.blue3,
|
|
||||||
},
|
|
||||||
btnLabel: {
|
|
||||||
textAlign: 'center',
|
|
||||||
fontSize: 21,
|
|
||||||
fontWeight: '500',
|
|
||||||
color: colors.blue3,
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -1,11 +1,13 @@
|
||||||
import React, {useEffect} from 'react'
|
import React, {useEffect} from 'react'
|
||||||
import {FlatList, View} from 'react-native'
|
import {FlatList, View} from 'react-native'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
|
import {observer} from 'mobx-react-lite'
|
||||||
import useAppState from 'react-native-appstate-hook'
|
import useAppState from 'react-native-appstate-hook'
|
||||||
import {
|
import {
|
||||||
NativeStackScreenProps,
|
NativeStackScreenProps,
|
||||||
NotificationsTabNavigatorParams,
|
NotificationsTabNavigatorParams,
|
||||||
} from 'lib/routes/types'
|
} from 'lib/routes/types'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {ViewHeader} from '../com/util/ViewHeader'
|
import {ViewHeader} from '../com/util/ViewHeader'
|
||||||
import {Feed} from '../com/notifications/Feed'
|
import {Feed} from '../com/notifications/Feed'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
|
@ -19,7 +21,8 @@ type Props = NativeStackScreenProps<
|
||||||
NotificationsTabNavigatorParams,
|
NotificationsTabNavigatorParams,
|
||||||
'Notifications'
|
'Notifications'
|
||||||
>
|
>
|
||||||
export const NotificationsScreen = ({}: Props) => {
|
export const NotificationsScreen = withAuthRequired(
|
||||||
|
observer(({}: Props) => {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const onMainScroll = useOnMainScroll(store)
|
const onMainScroll = useOnMainScroll(store)
|
||||||
const scrollElRef = React.useRef<FlatList>(null)
|
const scrollElRef = React.useRef<FlatList>(null)
|
||||||
|
@ -92,4 +95,5 @@ export const NotificationsScreen = ({}: Props) => {
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}),
|
||||||
|
)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
||||||
import {ViewHeader} from '../com/util/ViewHeader'
|
import {ViewHeader} from '../com/util/ViewHeader'
|
||||||
import {PostRepostedBy as PostRepostedByComponent} from '../com/post-thread/PostRepostedBy'
|
import {PostRepostedBy as PostRepostedByComponent} from '../com/post-thread/PostRepostedBy'
|
||||||
|
@ -8,7 +9,7 @@ import {useStores} from 'state/index'
|
||||||
import {makeRecordUri} from 'lib/strings/url-helpers'
|
import {makeRecordUri} from 'lib/strings/url-helpers'
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostRepostedBy'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostRepostedBy'>
|
||||||
export const PostRepostedByScreen = ({route}: Props) => {
|
export const PostRepostedByScreen = withAuthRequired(({route}: Props) => {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const {name, rkey} = route.params
|
const {name, rkey} = route.params
|
||||||
const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
|
const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
|
||||||
|
@ -25,4 +26,4 @@ export const PostRepostedByScreen = ({route}: Props) => {
|
||||||
<PostRepostedByComponent uri={uri} />
|
<PostRepostedByComponent uri={uri} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {StyleSheet, View} from 'react-native'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
||||||
import {makeRecordUri} from 'lib/strings/url-helpers'
|
import {makeRecordUri} from 'lib/strings/url-helpers'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {ViewHeader} from '../com/util/ViewHeader'
|
import {ViewHeader} from '../com/util/ViewHeader'
|
||||||
import {PostThread as PostThreadComponent} from '../com/post-thread/PostThread'
|
import {PostThread as PostThreadComponent} from '../com/post-thread/PostThread'
|
||||||
import {ComposePrompt} from 'view/com/composer/Prompt'
|
import {ComposePrompt} from 'view/com/composer/Prompt'
|
||||||
|
@ -16,7 +17,7 @@ import {isDesktopWeb} from 'platform/detection'
|
||||||
const SHELL_FOOTER_HEIGHT = 44
|
const SHELL_FOOTER_HEIGHT = 44
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostThread'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostThread'>
|
||||||
export const PostThreadScreen = ({route}: Props) => {
|
export const PostThreadScreen = withAuthRequired(({route}: Props) => {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const safeAreaInsets = useSafeAreaInsets()
|
const safeAreaInsets = useSafeAreaInsets()
|
||||||
const {name, rkey} = route.params
|
const {name, rkey} = route.params
|
||||||
|
@ -84,7 +85,7 @@ export const PostThreadScreen = ({route}: Props) => {
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
prompt: {
|
prompt: {
|
||||||
|
|
|
@ -2,13 +2,14 @@ import React from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {ViewHeader} from '../com/util/ViewHeader'
|
import {ViewHeader} from '../com/util/ViewHeader'
|
||||||
import {PostVotedBy as PostLikedByComponent} from '../com/post-thread/PostVotedBy'
|
import {PostVotedBy as PostLikedByComponent} from '../com/post-thread/PostVotedBy'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {makeRecordUri} from 'lib/strings/url-helpers'
|
import {makeRecordUri} from 'lib/strings/url-helpers'
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostUpvotedBy'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostUpvotedBy'>
|
||||||
export const PostUpvotedByScreen = ({route}: Props) => {
|
export const PostUpvotedByScreen = withAuthRequired(({route}: Props) => {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const {name, rkey} = route.params
|
const {name, rkey} = route.params
|
||||||
const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
|
const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
|
||||||
|
@ -25,4 +26,4 @@ export const PostUpvotedByScreen = ({route}: Props) => {
|
||||||
<PostLikedByComponent uri={uri} direction="up" />
|
<PostLikedByComponent uri={uri} direction="up" />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
|
@ -26,7 +26,7 @@ export const PrivacyPolicyScreen = (_props: Props) => {
|
||||||
<ViewHeader title="Privacy Policy" />
|
<ViewHeader title="Privacy Policy" />
|
||||||
<ScrollView style={[s.hContentRegion, pal.view]}>
|
<ScrollView style={[s.hContentRegion, pal.view]}>
|
||||||
<View style={[s.p20]}>
|
<View style={[s.p20]}>
|
||||||
<Text type="title-xl" style={[pal.text, s.pb20]}>
|
<Text type="title-xl" style={[pal.text, s.bold, s.pb20]}>
|
||||||
Privacy Policy
|
Privacy Policy
|
||||||
</Text>
|
</Text>
|
||||||
<PrivacyPolicyHtml />
|
<PrivacyPolicyHtml />
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {ActivityIndicator, StyleSheet, View} from 'react-native'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {ViewSelector} from '../com/util/ViewSelector'
|
import {ViewSelector} from '../com/util/ViewSelector'
|
||||||
import {CenteredView} from '../com/util/Views'
|
import {CenteredView} from '../com/util/Views'
|
||||||
import {ProfileUiModel, Sections} from 'state/models/profile-ui'
|
import {ProfileUiModel, Sections} from 'state/models/profile-ui'
|
||||||
|
@ -25,7 +26,8 @@ const END_ITEM = {_reactKey: '__end__'}
|
||||||
const EMPTY_ITEM = {_reactKey: '__empty__'}
|
const EMPTY_ITEM = {_reactKey: '__empty__'}
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Profile'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Profile'>
|
||||||
export const ProfileScreen = observer(({route}: Props) => {
|
export const ProfileScreen = withAuthRequired(
|
||||||
|
observer(({route}: Props) => {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const {screen, track} = useAnalytics()
|
const {screen, track} = useAnalytics()
|
||||||
|
|
||||||
|
@ -140,7 +142,9 @@ export const ProfileScreen = observer(({route}: Props) => {
|
||||||
if (item === END_ITEM) {
|
if (item === END_ITEM) {
|
||||||
return <Text style={styles.endItem}>- end of feed -</Text>
|
return <Text style={styles.endItem}>- end of feed -</Text>
|
||||||
}
|
}
|
||||||
return <FeedItem item={item} ignoreMuteFor={uiState.profile.did} />
|
return (
|
||||||
|
<FeedItem item={item} ignoreMuteFor={uiState.profile.did} />
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else if (uiState.feed.isEmpty) {
|
} else if (uiState.feed.isEmpty) {
|
||||||
items = items.concat([EMPTY_ITEM])
|
items = items.concat([EMPTY_ITEM])
|
||||||
|
@ -196,7 +200,8 @@ export const ProfileScreen = observer(({route}: Props) => {
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
function LoadingMoreFooter() {
|
function LoadingMoreFooter() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -2,12 +2,13 @@ import React from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {ViewHeader} from '../com/util/ViewHeader'
|
import {ViewHeader} from '../com/util/ViewHeader'
|
||||||
import {ProfileFollowers as ProfileFollowersComponent} from '../com/profile/ProfileFollowers'
|
import {ProfileFollowers as ProfileFollowersComponent} from '../com/profile/ProfileFollowers'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFollowers'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFollowers'>
|
||||||
export const ProfileFollowersScreen = ({route}: Props) => {
|
export const ProfileFollowersScreen = withAuthRequired(({route}: Props) => {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const {name} = route.params
|
const {name} = route.params
|
||||||
|
|
||||||
|
@ -23,4 +24,4 @@ export const ProfileFollowersScreen = ({route}: Props) => {
|
||||||
<ProfileFollowersComponent name={name} />
|
<ProfileFollowersComponent name={name} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
|
@ -2,12 +2,13 @@ import React from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {ViewHeader} from '../com/util/ViewHeader'
|
import {ViewHeader} from '../com/util/ViewHeader'
|
||||||
import {ProfileFollows as ProfileFollowsComponent} from '../com/profile/ProfileFollows'
|
import {ProfileFollows as ProfileFollowsComponent} from '../com/profile/ProfileFollows'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFollows'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'ProfileFollows'>
|
||||||
export const ProfileFollowsScreen = ({route}: Props) => {
|
export const ProfileFollowsScreen = withAuthRequired(({route}: Props) => {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const {name} = route.params
|
const {name} = route.params
|
||||||
|
|
||||||
|
@ -23,4 +24,4 @@ export const ProfileFollowsScreen = ({route}: Props) => {
|
||||||
<ProfileFollowsComponent name={name} />
|
<ProfileFollowsComponent name={name} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {
|
||||||
FontAwesomeIcon,
|
FontAwesomeIcon,
|
||||||
FontAwesomeIconStyle,
|
FontAwesomeIconStyle,
|
||||||
} from '@fortawesome/react-native-fontawesome'
|
} from '@fortawesome/react-native-fontawesome'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {ScrollView} from '../com/util/Views'
|
import {ScrollView} from '../com/util/Views'
|
||||||
import {
|
import {
|
||||||
NativeStackScreenProps,
|
NativeStackScreenProps,
|
||||||
|
@ -36,7 +37,8 @@ const MENU_HITSLOP = {left: 10, top: 10, right: 30, bottom: 10}
|
||||||
const FIVE_MIN = 5 * 60 * 1e3
|
const FIVE_MIN = 5 * 60 * 1e3
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<SearchTabNavigatorParams, 'Search'>
|
type Props = NativeStackScreenProps<SearchTabNavigatorParams, 'Search'>
|
||||||
export const SearchScreen = observer<Props>(({}: Props) => {
|
export const SearchScreen = withAuthRequired(
|
||||||
|
observer<Props>(({}: Props) => {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
|
@ -188,7 +190,8 @@ export const SearchScreen = observer<Props>(({}: Props) => {
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {StyleSheet, View} from 'react-native'
|
import {StyleSheet, View} from 'react-native'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {ScrollView} from '../com/util/Views'
|
import {ScrollView} from '../com/util/Views'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {
|
import {
|
||||||
|
@ -17,7 +18,8 @@ import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
|
||||||
const FIVE_MIN = 5 * 60 * 1e3
|
const FIVE_MIN = 5 * 60 * 1e3
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<SearchTabNavigatorParams, 'Search'>
|
type Props = NativeStackScreenProps<SearchTabNavigatorParams, 'Search'>
|
||||||
export const SearchScreen = observer(({}: Props) => {
|
export const SearchScreen = withAuthRequired(
|
||||||
|
observer(({}: Props) => {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const scrollElRef = React.useRef<ScrollView>(null)
|
const scrollElRef = React.useRef<ScrollView>(null)
|
||||||
|
@ -56,7 +58,8 @@ export const SearchScreen = observer(({}: Props) => {
|
||||||
<View style={s.footerSpacer} />
|
<View style={s.footerSpacer} />
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
} from '@fortawesome/react-native-fontawesome'
|
} from '@fortawesome/react-native-fontawesome'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
|
||||||
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import * as AppInfo from 'lib/app-info'
|
import * as AppInfo from 'lib/app-info'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {s, colors} from 'lib/styles'
|
import {s, colors} from 'lib/styles'
|
||||||
|
@ -33,7 +34,8 @@ import {useAnalytics} from 'lib/analytics'
|
||||||
import {NavigationProp} from 'lib/routes/types'
|
import {NavigationProp} from 'lib/routes/types'
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Settings'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Settings'>
|
||||||
export const SettingsScreen = observer(function Settings({}: Props) {
|
export const SettingsScreen = withAuthRequired(
|
||||||
|
observer(function Settings({}: Props) {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
|
@ -261,7 +263,8 @@ export const SettingsScreen = observer(function Settings({}: Props) {
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
function AccountDropdownBtn({handle}: {handle: string}) {
|
function AccountDropdownBtn({handle}: {handle: string}) {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
|
|
|
@ -131,7 +131,7 @@ export const DesktopLeftNav = observer(function DesktopLeftNav() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.leftNav}>
|
<View style={styles.leftNav}>
|
||||||
<ProfileCard />
|
{store.session.hasSession && <ProfileCard />}
|
||||||
<BackBtn />
|
<BackBtn />
|
||||||
<NavItem
|
<NavItem
|
||||||
href="/"
|
href="/"
|
||||||
|
@ -164,6 +164,7 @@ export const DesktopLeftNav = observer(function DesktopLeftNav() {
|
||||||
}
|
}
|
||||||
label="Notifications"
|
label="Notifications"
|
||||||
/>
|
/>
|
||||||
|
{store.session.hasSession && (
|
||||||
<NavItem
|
<NavItem
|
||||||
href={`/profile/${store.me.handle}`}
|
href={`/profile/${store.me.handle}`}
|
||||||
icon={<UserIcon strokeWidth={1.75} size={28} style={pal.text} />}
|
icon={<UserIcon strokeWidth={1.75} size={28} style={pal.text} />}
|
||||||
|
@ -172,6 +173,7 @@ export const DesktopLeftNav = observer(function DesktopLeftNav() {
|
||||||
}
|
}
|
||||||
label="Profile"
|
label="Profile"
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
<NavItem
|
<NavItem
|
||||||
href="/settings"
|
href="/settings"
|
||||||
icon={<CogIcon strokeWidth={1.75} size={28} style={pal.text} />}
|
icon={<CogIcon strokeWidth={1.75} size={28} style={pal.text} />}
|
||||||
|
@ -180,7 +182,7 @@ export const DesktopLeftNav = observer(function DesktopLeftNav() {
|
||||||
}
|
}
|
||||||
label="Settings"
|
label="Settings"
|
||||||
/>
|
/>
|
||||||
<ComposeBtn />
|
{store.session.hasSession && <ComposeBtn />}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,12 +7,14 @@ import {Text} from 'view/com/util/text/Text'
|
||||||
import {TextLink} from 'view/com/util/Link'
|
import {TextLink} from 'view/com/util/Link'
|
||||||
import {FEEDBACK_FORM_URL} from 'lib/constants'
|
import {FEEDBACK_FORM_URL} from 'lib/constants'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
|
import {useStores} from 'state/index'
|
||||||
|
|
||||||
export const DesktopRightNav = observer(function DesktopRightNav() {
|
export const DesktopRightNav = observer(function DesktopRightNav() {
|
||||||
|
const store = useStores()
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
return (
|
return (
|
||||||
<View style={[styles.rightNav, pal.view]}>
|
<View style={[styles.rightNav, pal.view]}>
|
||||||
<DesktopSearch />
|
{store.session.hasSession && <DesktopSearch />}
|
||||||
<View style={styles.message}>
|
<View style={styles.message}>
|
||||||
<Text type="md" style={[pal.textLight, styles.messageLine]}>
|
<Text type="md" style={[pal.textLight, styles.messageLine]}>
|
||||||
Welcome to Bluesky! This is a beta application that's still in
|
Welcome to Bluesky! This is a beta application that's still in
|
||||||
|
|
|
@ -5,7 +5,6 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||||
import {Drawer} from 'react-native-drawer-layout'
|
import {Drawer} from 'react-native-drawer-layout'
|
||||||
import {useNavigationState} from '@react-navigation/native'
|
import {useNavigationState} from '@react-navigation/native'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {Login} from 'view/screens/Login'
|
|
||||||
import {ModalsContainer} from 'view/com/modals/Modal'
|
import {ModalsContainer} from 'view/com/modals/Modal'
|
||||||
import {Lightbox} from 'view/com/lightbox/Lightbox'
|
import {Lightbox} from 'view/com/lightbox/Lightbox'
|
||||||
import {Text} from 'view/com/util/text/Text'
|
import {Text} from 'view/com/util/text/Text'
|
||||||
|
@ -104,20 +103,6 @@ export const Shell: React.FC = observer(() => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!store.session.hasSession) {
|
|
||||||
return (
|
|
||||||
<View style={styles.outerContainer}>
|
|
||||||
<StatusBar
|
|
||||||
barStyle={
|
|
||||||
theme.colorScheme === 'dark' ? 'light-content' : 'dark-content'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Login />
|
|
||||||
<ModalsContainer />
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View testID="mobileShellView" style={[styles.outerContainer, pal.view]}>
|
<View testID="mobileShellView" style={[styles.outerContainer, pal.view]}>
|
||||||
<StatusBar
|
<StatusBar
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {View, StyleSheet} from 'react-native'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {DesktopLeftNav} from './desktop/LeftNav'
|
import {DesktopLeftNav} from './desktop/LeftNav'
|
||||||
import {DesktopRightNav} from './desktop/RightNav'
|
import {DesktopRightNav} from './desktop/RightNav'
|
||||||
import {Login} from '../screens/Login'
|
|
||||||
import {ErrorBoundary} from '../com/util/ErrorBoundary'
|
import {ErrorBoundary} from '../com/util/ErrorBoundary'
|
||||||
import {Lightbox} from '../com/lightbox/Lightbox'
|
import {Lightbox} from '../com/lightbox/Lightbox'
|
||||||
import {ModalsContainer} from '../com/modals/Modal'
|
import {ModalsContainer} from '../com/modals/Modal'
|
||||||
|
@ -45,21 +44,10 @@ const ShellInner = observer(() => {
|
||||||
|
|
||||||
export const Shell: React.FC = observer(() => {
|
export const Shell: React.FC = observer(() => {
|
||||||
const pageBg = useColorSchemeStyle(styles.bgLight, styles.bgDark)
|
const pageBg = useColorSchemeStyle(styles.bgLight, styles.bgDark)
|
||||||
const store = useStores()
|
|
||||||
|
|
||||||
if (isMobileWeb) {
|
if (isMobileWeb) {
|
||||||
return <NoMobileWeb />
|
return <NoMobileWeb />
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!store.session.hasSession) {
|
|
||||||
return (
|
|
||||||
<View style={[s.hContentRegion, pageBg]}>
|
|
||||||
<Login />
|
|
||||||
<ModalsContainer />
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[s.hContentRegion, pageBg]}>
|
<View style={[s.hContentRegion, pageBg]}>
|
||||||
<RoutesContainer>
|
<RoutesContainer>
|
||||||
|
|
Loading…
Reference in New Issue