Rework web onboarding
parent
5d9534ca72
commit
5e765bf1cb
|
@ -148,3 +148,110 @@ export const HITSLOP_10 = createHitslop(10)
|
|||
export const HITSLOP_20 = createHitslop(20)
|
||||
export const HITSLOP_30 = createHitslop(30)
|
||||
export const BACK_HITSLOP = HITSLOP_30
|
||||
|
||||
export const RECOMMENDED_FEEDS = [
|
||||
{
|
||||
did: 'did:plc:hsqwcidfez66lwm3gxhfv5in',
|
||||
rkey: 'aaaf2pqeodmpy',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:gekdk2nd47gkk3utfz2xf7cn',
|
||||
rkey: 'aaap4tbjcfe5y',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:5rw2on4i56btlcajojaxwcat',
|
||||
rkey: 'aaao6g552b33o',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:jfhpnnst6flqway4eaeqzj2a',
|
||||
rkey: 'for-science',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:7q4nnnxawajbfaq7to5dpbsy',
|
||||
rkey: 'bsky-news',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:jcoy7v3a2t4rcfdh6i4kza25',
|
||||
rkey: 'astro',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:tenurhgjptubkk5zf5qhi3og',
|
||||
rkey: 'h-nba',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:vpkhqolt662uhesyj6nxm7ys',
|
||||
rkey: 'devfeed',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:cndfx4udwgvpjaakvxvh7wm5',
|
||||
rkey: 'flipboard-tech',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:w4xbfzo7kqfes5zb7r6qv3rw',
|
||||
rkey: 'blacksky',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:lptjvw6ut224kwrj7ub3sqbe',
|
||||
rkey: 'aaaotfjzjplna',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:gkvpokm7ec5j5yxls6xk4e3z',
|
||||
rkey: 'formula-one',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:q6gjnaw2blty4crticxkmujt',
|
||||
rkey: 'positivifeed',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:l72uci4styb4jucsgcrrj5ap',
|
||||
rkey: 'aaao5dzfm36u4',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:k3jkadxv5kkjgs6boyon7m6n',
|
||||
rkey: 'aaaavlyvqzst2',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:nkahctfdi6bxk72umytfwghw',
|
||||
rkey: 'aaado2uvfsc6w',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:epihigio3d7un7u3gpqiy5gv',
|
||||
rkey: 'aaaekwsc7zsvs',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:qiknc4t5rq7yngvz7g4aezq7',
|
||||
rkey: 'aaaejxlobe474',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:mlq4aycufcuolr7ax6sezpc4',
|
||||
rkey: 'aaaoudweck6uy',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:rcez5hcvq3vzlu5x7xrjyccg',
|
||||
rkey: 'aaadzjxbcddzi',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:lnxbuzaenlwjrncx6sc4cfdr',
|
||||
rkey: 'aaab2vesjtszc',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:x3cya3wkt4n6u4ihmvpsc5if',
|
||||
rkey: 'aaacynbxwimok',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:abv47bjgzjgoh3yrygwoi36x',
|
||||
rkey: 'aaagt6amuur5e',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:ffkgesg3jsv2j7aagkzrtcvt',
|
||||
rkey: 'aaacjerk7gwek',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:geoqe3qls5mwezckxxsewys2',
|
||||
rkey: 'aaai43yetqshu',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:2wqomm3tjqbgktbrfwgvrw34',
|
||||
rkey: 'authors',
|
||||
},
|
||||
]
|
||||
|
|
|
@ -67,6 +67,19 @@ export class CustomFeedModel {
|
|||
}
|
||||
}
|
||||
|
||||
async pin() {
|
||||
try {
|
||||
await this.rootStore.preferences.addPinnedFeed(this.uri)
|
||||
} catch (error) {
|
||||
this.rootStore.log.error('Failed to pin feed', error)
|
||||
} finally {
|
||||
track('CustomFeed:Pin', {
|
||||
name: this.data.displayName,
|
||||
uri: this.uri,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async unsave() {
|
||||
try {
|
||||
await this.rootStore.preferences.removeSavedFeed(this.uri)
|
||||
|
|
|
@ -6,7 +6,6 @@ import {s} from 'lib/styles'
|
|||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useStores} from 'state/index'
|
||||
import {useAnalytics} from 'lib/analytics/analytics'
|
||||
import {CenteredView} from '../util/Views'
|
||||
import {Welcome} from './onboarding/Welcome'
|
||||
import {RecommendedFeeds} from './onboarding/RecommendedFeeds'
|
||||
|
||||
|
@ -24,17 +23,15 @@ export const Onboarding = observer(() => {
|
|||
const skip = () => store.onboarding.skip()
|
||||
|
||||
return (
|
||||
<CenteredView style={[s.hContentRegion, pal.view]}>
|
||||
<SafeAreaView testID="noSessionView" style={s.hContentRegion}>
|
||||
<ErrorBoundary>
|
||||
{store.onboarding.step === 'Welcome' && (
|
||||
<Welcome skip={skip} next={next} />
|
||||
)}
|
||||
{store.onboarding.step === 'RecommendedFeeds' && (
|
||||
<RecommendedFeeds next={next} />
|
||||
)}
|
||||
</ErrorBoundary>
|
||||
</SafeAreaView>
|
||||
</CenteredView>
|
||||
<SafeAreaView testID="onboardingView" style={[s.hContentRegion, pal.view]}>
|
||||
<ErrorBoundary>
|
||||
{store.onboarding.step === 'Welcome' && (
|
||||
<Welcome skip={skip} next={next} />
|
||||
)}
|
||||
{store.onboarding.step === 'RecommendedFeeds' && (
|
||||
<RecommendedFeeds next={next} />
|
||||
)}
|
||||
</ErrorBoundary>
|
||||
</SafeAreaView>
|
||||
)
|
||||
})
|
||||
|
|
|
@ -9,113 +9,7 @@ import {useCustomFeed} from 'lib/hooks/useCustomFeed'
|
|||
import {makeRecordUri} from 'lib/strings/url-helpers'
|
||||
import {ViewHeader} from 'view/com/util/ViewHeader'
|
||||
import {isDesktopWeb} from 'platform/detection'
|
||||
|
||||
const TEMPORARY_RECOMMENDED_FEEDS = [
|
||||
{
|
||||
did: 'did:plc:hsqwcidfez66lwm3gxhfv5in',
|
||||
rkey: 'aaaf2pqeodmpy',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:gekdk2nd47gkk3utfz2xf7cn',
|
||||
rkey: 'aaap4tbjcfe5y',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:5rw2on4i56btlcajojaxwcat',
|
||||
rkey: 'aaao6g552b33o',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:jfhpnnst6flqway4eaeqzj2a',
|
||||
rkey: 'for-science',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:7q4nnnxawajbfaq7to5dpbsy',
|
||||
rkey: 'bsky-news',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:jcoy7v3a2t4rcfdh6i4kza25',
|
||||
rkey: 'astro',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:tenurhgjptubkk5zf5qhi3og',
|
||||
rkey: 'h-nba',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:vpkhqolt662uhesyj6nxm7ys',
|
||||
rkey: 'devfeed',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:cndfx4udwgvpjaakvxvh7wm5',
|
||||
rkey: 'flipboard-tech',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:w4xbfzo7kqfes5zb7r6qv3rw',
|
||||
rkey: 'blacksky',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:lptjvw6ut224kwrj7ub3sqbe',
|
||||
rkey: 'aaaotfjzjplna',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:gkvpokm7ec5j5yxls6xk4e3z',
|
||||
rkey: 'formula-one',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:q6gjnaw2blty4crticxkmujt',
|
||||
rkey: 'positivifeed',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:l72uci4styb4jucsgcrrj5ap',
|
||||
rkey: 'aaao5dzfm36u4',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:k3jkadxv5kkjgs6boyon7m6n',
|
||||
rkey: 'aaaavlyvqzst2',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:nkahctfdi6bxk72umytfwghw',
|
||||
rkey: 'aaado2uvfsc6w',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:epihigio3d7un7u3gpqiy5gv',
|
||||
rkey: 'aaaekwsc7zsvs',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:qiknc4t5rq7yngvz7g4aezq7',
|
||||
rkey: 'aaaejxlobe474',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:mlq4aycufcuolr7ax6sezpc4',
|
||||
rkey: 'aaaoudweck6uy',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:rcez5hcvq3vzlu5x7xrjyccg',
|
||||
rkey: 'aaadzjxbcddzi',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:lnxbuzaenlwjrncx6sc4cfdr',
|
||||
rkey: 'aaab2vesjtszc',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:x3cya3wkt4n6u4ihmvpsc5if',
|
||||
rkey: 'aaacynbxwimok',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:abv47bjgzjgoh3yrygwoi36x',
|
||||
rkey: 'aaagt6amuur5e',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:ffkgesg3jsv2j7aagkzrtcvt',
|
||||
rkey: 'aaacjerk7gwek',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:geoqe3qls5mwezckxxsewys2',
|
||||
rkey: 'aaai43yetqshu',
|
||||
},
|
||||
{
|
||||
did: 'did:plc:2wqomm3tjqbgktbrfwgvrw34',
|
||||
rkey: 'authors',
|
||||
},
|
||||
]
|
||||
import {RECOMMENDED_FEEDS} from 'lib/constants'
|
||||
|
||||
type Props = {
|
||||
next: () => void
|
||||
|
@ -132,7 +26,7 @@ export const RecommendedFeeds = observer(({next}: Props) => {
|
|||
</Text>
|
||||
|
||||
<FlatList
|
||||
data={TEMPORARY_RECOMMENDED_FEEDS}
|
||||
data={RECOMMENDED_FEEDS}
|
||||
renderItem={({item}) => <Item item={item} />}
|
||||
keyExtractor={item => item.did + item.rkey}
|
||||
style={{flex: 1}}
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
import React from 'react'
|
||||
import {FlatList, StyleSheet, View} from 'react-native'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {Text} from 'view/com/util/text/Text'
|
||||
import {TitleColumnLayout} from 'view/com/util/layouts/TitleColumnLayout'
|
||||
import {UserAvatar} from 'view/com/util/UserAvatar'
|
||||
import {Button} from 'view/com/util/forms/Button'
|
||||
import * as Toast from 'view/com/util/Toast'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useCustomFeed} from 'lib/hooks/useCustomFeed'
|
||||
import {makeRecordUri} from 'lib/strings/url-helpers'
|
||||
import {sanitizeHandle} from 'lib/strings/handles'
|
||||
import {HeartIcon} from 'lib/icons'
|
||||
import {RECOMMENDED_FEEDS} from 'lib/constants'
|
||||
|
||||
type Props = {
|
||||
next: () => void
|
||||
}
|
||||
export const RecommendedFeeds = observer(({next}: Props) => {
|
||||
const pal = usePalette('default')
|
||||
|
||||
const title = (
|
||||
<>
|
||||
<Text style={[pal.textLight, styles.title1]}>Choose your</Text>
|
||||
<Text style={[pal.link, styles.title2]}>Recomended</Text>
|
||||
<Text style={[pal.link, styles.title2]}>Feeds</Text>
|
||||
<Text type="2xl-medium" style={[pal.textLight, styles.description]}>
|
||||
Feeds are created by users to curate content. Choose some feeds that you
|
||||
find interesting.
|
||||
</Text>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
marginTop: 20,
|
||||
}}>
|
||||
<Button onPress={next} testID="continueBtn">
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingLeft: 2,
|
||||
gap: 6,
|
||||
}}>
|
||||
<Text
|
||||
type="2xl-medium"
|
||||
style={{color: '#fff', position: 'relative', top: -1}}>
|
||||
Done
|
||||
</Text>
|
||||
<FontAwesomeIcon icon="angle-right" color="#fff" size={14} />
|
||||
</View>
|
||||
</Button>
|
||||
</View>
|
||||
</>
|
||||
)
|
||||
|
||||
return (
|
||||
<TitleColumnLayout
|
||||
testID="recommendedFeedsScreen"
|
||||
title={title}
|
||||
horizontal
|
||||
titleStyle={{minWidth: 470}}
|
||||
contentStyle={{paddingHorizontal: 0}}>
|
||||
<FlatList
|
||||
data={RECOMMENDED_FEEDS}
|
||||
renderItem={({item}) => <Item {...item} />}
|
||||
keyExtractor={item => item.did + item.rkey}
|
||||
style={{flex: 1}}
|
||||
/>
|
||||
</TitleColumnLayout>
|
||||
)
|
||||
})
|
||||
|
||||
const Item = observer(({did, rkey}: {did: string; rkey: string}) => {
|
||||
const pal = usePalette('default')
|
||||
const uri = makeRecordUri(did, 'app.bsky.feed.generator', rkey)
|
||||
const item = useCustomFeed(uri)
|
||||
if (!item) return null
|
||||
const onToggle = async () => {
|
||||
if (item.isSaved) {
|
||||
try {
|
||||
await item.unsave()
|
||||
} catch (e) {
|
||||
Toast.show('There was an issue contacting your server')
|
||||
console.error('Failed to unsave feed', {e})
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
await item.save()
|
||||
await item.pin()
|
||||
} catch (e) {
|
||||
Toast.show('There was an issue contacting your server')
|
||||
console.error('Failed to pin feed', {e})
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<View testID={`feed-${item.displayName}`}>
|
||||
<View
|
||||
style={[
|
||||
pal.border,
|
||||
{
|
||||
flexDirection: 'row',
|
||||
gap: 18,
|
||||
maxWidth: 670,
|
||||
borderRightWidth: 1,
|
||||
paddingHorizontal: 24,
|
||||
paddingVertical: 24,
|
||||
borderTopWidth: 1,
|
||||
},
|
||||
]}>
|
||||
<View style={{marginTop: 2}}>
|
||||
<UserAvatar type="algo" size={42} avatar={item.data.avatar} />
|
||||
</View>
|
||||
<View>
|
||||
<Text
|
||||
type="2xl-bold"
|
||||
numberOfLines={1}
|
||||
style={[pal.text, {fontSize: 19}]}>
|
||||
{item.displayName}
|
||||
</Text>
|
||||
|
||||
<Text style={[pal.textLight, {marginBottom: 8}]} numberOfLines={1}>
|
||||
by {sanitizeHandle(item.data.creator.handle, '@')}
|
||||
</Text>
|
||||
|
||||
{item.data.description ? (
|
||||
<Text
|
||||
type="xl"
|
||||
style={[pal.text, {maxWidth: 550, marginBottom: 18}]}
|
||||
numberOfLines={6}>
|
||||
{item.data.description}
|
||||
</Text>
|
||||
) : null}
|
||||
|
||||
<View style={{flexDirection: 'row', alignItems: 'center', gap: 12}}>
|
||||
<Button
|
||||
type="inverted"
|
||||
style={{paddingVertical: 6}}
|
||||
onPress={onToggle}>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingRight: 2,
|
||||
gap: 6,
|
||||
}}>
|
||||
{item.isSaved ? (
|
||||
<>
|
||||
<FontAwesomeIcon
|
||||
icon="check"
|
||||
size={16}
|
||||
color={pal.colors.textInverted}
|
||||
/>
|
||||
<Text type="lg-medium" style={pal.textInverted}>
|
||||
Added
|
||||
</Text>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<FontAwesomeIcon
|
||||
icon="plus"
|
||||
size={16}
|
||||
color={pal.colors.textInverted}
|
||||
/>
|
||||
<Text type="lg-medium" style={pal.textInverted}>
|
||||
Add
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</Button>
|
||||
|
||||
<View style={{flexDirection: 'row', gap: 4}}>
|
||||
<HeartIcon
|
||||
size={16}
|
||||
strokeWidth={2.5}
|
||||
style={[pal.textLight, {position: 'relative', top: 2}]}
|
||||
/>
|
||||
<Text type="lg-medium" style={[pal.text, pal.textLight]}>
|
||||
{item.data.likeCount || 0}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
marginHorizontal: 16,
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
title1: {
|
||||
fontSize: 36,
|
||||
fontWeight: '800',
|
||||
textAlign: 'right',
|
||||
},
|
||||
title2: {
|
||||
fontSize: 58,
|
||||
fontWeight: '800',
|
||||
textAlign: 'right',
|
||||
},
|
||||
description: {
|
||||
maxWidth: 400,
|
||||
marginTop: 10,
|
||||
marginLeft: 'auto',
|
||||
textAlign: 'right',
|
||||
},
|
||||
})
|
|
@ -41,8 +41,10 @@ export const Welcome = observer(({next, skip}: Props) => {
|
|||
}}
|
||||
/>
|
||||
<View>
|
||||
<Text style={[pal.text, styles.title]}>Welcome to </Text>
|
||||
<Text style={[pal.text, pal.link, styles.title]}>Bluesky</Text>
|
||||
<Text style={[pal.text, styles.title]}>
|
||||
Welcome to{' '}
|
||||
<Text style={[pal.text, pal.link, styles.title]}>Bluesky</Text>
|
||||
</Text>
|
||||
<View style={styles.spacer} />
|
||||
<View style={[styles.row]}>
|
||||
<FontAwesomeIcon icon={'globe'} size={36} color={pal.colors.link} />
|
||||
|
@ -98,7 +100,7 @@ const styles = StyleSheet.create({
|
|||
justifyContent: 'space-between',
|
||||
},
|
||||
title: {
|
||||
fontSize: 48,
|
||||
fontSize: 42,
|
||||
fontWeight: '800',
|
||||
},
|
||||
row: {
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
import React from 'react'
|
||||
import {StyleSheet, View} from 'react-native'
|
||||
import {useMediaQuery} from 'react-responsive'
|
||||
import {Text} from 'view/com/util/text/Text'
|
||||
import {s} from 'lib/styles'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {TitleColumnLayout} from 'view/com/util/layouts/TitleColumnLayout'
|
||||
import {Button} from 'view/com/util/forms/Button'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
|
||||
type Props = {
|
||||
next: () => void
|
||||
skip: () => void
|
||||
}
|
||||
|
||||
export const Welcome = observer(({next}: Props) => {
|
||||
const pal = usePalette('default')
|
||||
const horizontal = useMediaQuery({
|
||||
query: '(min-width: 1230px)',
|
||||
})
|
||||
const title = (
|
||||
<>
|
||||
<Text
|
||||
style={[
|
||||
pal.textLight,
|
||||
{
|
||||
fontSize: 36,
|
||||
fontWeight: '800',
|
||||
textAlign: horizontal ? 'right' : 'left',
|
||||
},
|
||||
]}>
|
||||
Welcome to
|
||||
</Text>
|
||||
<Text
|
||||
style={[
|
||||
pal.link,
|
||||
{
|
||||
fontSize: 72,
|
||||
fontWeight: '800',
|
||||
textAlign: horizontal ? 'right' : 'left',
|
||||
},
|
||||
]}>
|
||||
Bluesky
|
||||
</Text>
|
||||
</>
|
||||
)
|
||||
return (
|
||||
<TitleColumnLayout
|
||||
testID="welcomeOnboarding"
|
||||
title={title}
|
||||
horizontal={horizontal}
|
||||
titleStyle={horizontal ? {paddingBottom: 160} : undefined}>
|
||||
<View style={[styles.row]}>
|
||||
<FontAwesomeIcon icon={'globe'} size={36} color={pal.colors.link} />
|
||||
<View style={[styles.rowText]}>
|
||||
<Text type="xl-bold" style={[pal.text]}>
|
||||
Bluesky is public.
|
||||
</Text>
|
||||
<Text type="xl" style={[pal.text, s.pt2]}>
|
||||
Your posts, likes, and blocks are public. Mutes are private.
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={[styles.row]}>
|
||||
<FontAwesomeIcon icon={'at'} size={36} color={pal.colors.link} />
|
||||
<View style={[styles.rowText]}>
|
||||
<Text type="xl-bold" style={[pal.text]}>
|
||||
Bluesky is open.
|
||||
</Text>
|
||||
<Text type="xl" style={[pal.text, s.pt2]}>
|
||||
Never lose access to your followers and data.
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={[styles.row]}>
|
||||
<FontAwesomeIcon icon={'gear'} size={36} color={pal.colors.link} />
|
||||
<View style={[styles.rowText]}>
|
||||
<Text type="xl-bold" style={[pal.text]}>
|
||||
Bluesky is flexible.
|
||||
</Text>
|
||||
<Text type="xl" style={[pal.text, s.pt2]}>
|
||||
Choose the algorithms that power your experience with custom feeds.
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.spacer} />
|
||||
<View style={{flexDirection: 'row'}}>
|
||||
<Button onPress={next} testID="continueBtn">
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingLeft: 2,
|
||||
gap: 6,
|
||||
}}>
|
||||
<Text
|
||||
type="2xl-medium"
|
||||
style={{color: '#fff', position: 'relative', top: -1}}>
|
||||
Next
|
||||
</Text>
|
||||
<FontAwesomeIcon icon="angle-right" color="#fff" size={14} />
|
||||
</View>
|
||||
</Button>
|
||||
</View>
|
||||
</TitleColumnLayout>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
columnGap: 20,
|
||||
alignItems: 'center',
|
||||
marginVertical: 20,
|
||||
},
|
||||
rowText: {
|
||||
flex: 1,
|
||||
},
|
||||
spacer: {
|
||||
height: 20,
|
||||
},
|
||||
})
|
|
@ -0,0 +1,62 @@
|
|||
import React from 'react'
|
||||
import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
|
||||
interface Props {
|
||||
testID?: string
|
||||
title: React.Component
|
||||
horizontal: boolean
|
||||
titleStyle?: StyleProp<ViewStyle>
|
||||
contentStyle?: StyleProp<ViewStyle>
|
||||
}
|
||||
|
||||
export function TitleColumnLayout({
|
||||
testID,
|
||||
title,
|
||||
horizontal,
|
||||
children,
|
||||
titleStyle,
|
||||
contentStyle,
|
||||
}: React.PropsWithChildren<Props>) {
|
||||
const pal = usePalette('default')
|
||||
|
||||
const layoutStyles = horizontal ? styles2Column : styles1Column
|
||||
return (
|
||||
<View testID={testID} style={layoutStyles.container}>
|
||||
<View style={[layoutStyles.title, pal.viewLight, titleStyle]}>
|
||||
{title}
|
||||
</View>
|
||||
<View style={[layoutStyles.content, contentStyle]}>{children}</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles2Column = StyleSheet.create({
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
height: '100%',
|
||||
},
|
||||
title: {
|
||||
flex: 1,
|
||||
paddingHorizontal: 40,
|
||||
paddingBottom: 80,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
content: {
|
||||
flex: 2,
|
||||
paddingHorizontal: 40,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
})
|
||||
|
||||
const styles1Column = StyleSheet.create({
|
||||
container: {},
|
||||
title: {
|
||||
paddingHorizontal: 40,
|
||||
paddingVertical: 40,
|
||||
},
|
||||
content: {
|
||||
paddingHorizontal: 40,
|
||||
paddingVertical: 40,
|
||||
},
|
||||
})
|
|
@ -20,7 +20,6 @@ import {NavigationProp} from 'lib/routes/types'
|
|||
const ShellInner = observer(() => {
|
||||
const store = useStores()
|
||||
const {isDesktop} = useWebMediaQueries()
|
||||
|
||||
const navigator = useNavigation<NavigationProp>()
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -29,6 +28,8 @@ const ShellInner = observer(() => {
|
|||
})
|
||||
}, [navigator, store.shell])
|
||||
|
||||
const showSideNavs =
|
||||
isDesktop && store.session.hasSession && !store.onboarding.isActive
|
||||
return (
|
||||
<>
|
||||
<View style={s.hContentRegion}>
|
||||
|
@ -36,7 +37,7 @@ const ShellInner = observer(() => {
|
|||
<FlatNavigator />
|
||||
</ErrorBoundary>
|
||||
</View>
|
||||
{isDesktop && store.session.hasSession && (
|
||||
{showSideNavs && (
|
||||
<>
|
||||
<DesktopLeftNav />
|
||||
<DesktopRightNav />
|
||||
|
|
Loading…
Reference in New Issue