diff options
-rw-r--r-- | src/view/com/auth/onboarding/RecommendedFeeds.tsx | 101 | ||||
-rw-r--r-- | src/view/com/auth/onboarding/RecommendedFeedsDesktop.tsx (renamed from src/view/com/auth/onboarding/RecommendedFeeds.web.tsx) | 2 | ||||
-rw-r--r-- | src/view/com/auth/onboarding/RecommendedFeedsMobile.tsx | 95 | ||||
-rw-r--r-- | src/view/com/auth/onboarding/Welcome.tsx | 133 | ||||
-rw-r--r-- | src/view/com/auth/onboarding/WelcomeDesktop.tsx (renamed from src/view/com/auth/onboarding/Welcome.web.tsx) | 2 | ||||
-rw-r--r-- | src/view/com/auth/onboarding/WelcomeMobile.tsx | 123 | ||||
-rw-r--r-- | src/view/com/util/layouts/withBreakpoints.tsx | 22 |
7 files changed, 262 insertions, 216 deletions
diff --git a/src/view/com/auth/onboarding/RecommendedFeeds.tsx b/src/view/com/auth/onboarding/RecommendedFeeds.tsx index 4a3200168..76204ce31 100644 --- a/src/view/com/auth/onboarding/RecommendedFeeds.tsx +++ b/src/view/com/auth/onboarding/RecommendedFeeds.tsx @@ -1,91 +1,10 @@ -import React from 'react' -import {FlatList, StyleSheet, View} from 'react-native' -import {Text} from 'view/com/util/text/Text' -import {usePalette} from 'lib/hooks/usePalette' -import {Button} from 'view/com/util/forms/Button' -import {observer} from 'mobx-react-lite' -import {CustomFeed} from 'view/com/feeds/CustomFeed' -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' -import {RECOMMENDED_FEEDS} from 'lib/constants' - -type Props = { - next: () => void -} -export const RecommendedFeeds = observer(({next}: Props) => { - const pal = usePalette('default') - - return ( - <View style={[styles.container]} testID="recommendedFeedsScreen"> - <ViewHeader title="Recommended Feeds" showBackButton={false} /> - <Text type="lg-medium" style={[pal.text, styles.header]}> - Check out some recommended feeds. Tap + to add them to your list of - pinned feeds. - </Text> - - <FlatList - data={RECOMMENDED_FEEDS} - renderItem={({item}) => <Item item={item} />} - keyExtractor={item => item.did + item.rkey} - style={{flex: 1}} - /> - - <Button - onPress={next} - label="Continue" - testID="continueBtn" - style={styles.button} - labelStyle={styles.buttonText} - /> - </View> - ) -}) - -type ItemProps = { - did: string - rkey: string -} - -const Item = ({item}: {item: ItemProps}) => { - const uri = makeRecordUri(item.did, 'app.bsky.feed.generator', item.rkey) - const data = useCustomFeed(uri) - if (!data) return null - return ( - <CustomFeed - item={data} - key={uri} - showDescription - showLikes - showSaveBtn - style={[ - { - // @ts-ignore - cursor: isDesktopWeb ? 'pointer' : 'auto', - }, - ]} - /> - ) -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'space-between', - }, - header: { - marginBottom: 16, - marginHorizontal: 16, - }, - button: { - marginBottom: 24, - marginHorizontal: 16, - marginTop: 16, - }, - buttonText: { - textAlign: 'center', - fontSize: 18, - paddingVertical: 4, - }, -}) +import 'react' +import {withBreakpoints} from 'view/com/util/layouts/withBreakpoints' +import {RecommendedFeedsDesktop} from './RecommendedFeedsDesktop' +import {RecommendedFeedsMobile} from './RecommendedFeedsMobile' + +export const RecommendedFeeds = withBreakpoints( + RecommendedFeedsMobile, + RecommendedFeedsMobile, + RecommendedFeedsDesktop, +) diff --git a/src/view/com/auth/onboarding/RecommendedFeeds.web.tsx b/src/view/com/auth/onboarding/RecommendedFeedsDesktop.tsx index 9038c7a5a..d305f4a82 100644 --- a/src/view/com/auth/onboarding/RecommendedFeeds.web.tsx +++ b/src/view/com/auth/onboarding/RecommendedFeedsDesktop.tsx @@ -17,7 +17,7 @@ import {RECOMMENDED_FEEDS} from 'lib/constants' type Props = { next: () => void } -export const RecommendedFeeds = observer(({next}: Props) => { +export const RecommendedFeedsDesktop = observer(({next}: Props) => { const pal = usePalette('default') const title = ( diff --git a/src/view/com/auth/onboarding/RecommendedFeedsMobile.tsx b/src/view/com/auth/onboarding/RecommendedFeedsMobile.tsx new file mode 100644 index 000000000..b84b75df7 --- /dev/null +++ b/src/view/com/auth/onboarding/RecommendedFeedsMobile.tsx @@ -0,0 +1,95 @@ +import React from 'react' +import {FlatList, StyleSheet, View} from 'react-native' +import {Text} from 'view/com/util/text/Text' +import {usePalette} from 'lib/hooks/usePalette' +import {Button} from 'view/com/util/forms/Button' +import {observer} from 'mobx-react-lite' +import {CustomFeed} from 'view/com/feeds/CustomFeed' +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' +import {RECOMMENDED_FEEDS} from 'lib/constants' + +type Props = { + next: () => void +} +export const RecommendedFeedsMobile = observer(({next}: Props) => { + const pal = usePalette('default') + + return ( + <View style={[styles.container]} testID="recommendedFeedsScreen"> + <ViewHeader + title="Recommended Feeds" + showBackButton={false} + showOnDesktop + /> + <Text type="lg-medium" style={[pal.text, styles.header]}> + Check out some recommended feeds. Tap + to add them to your list of + pinned feeds. + </Text> + + <FlatList + data={RECOMMENDED_FEEDS} + renderItem={({item}) => <Item item={item} />} + keyExtractor={item => item.did + item.rkey} + style={{flex: 1}} + /> + + <Button + onPress={next} + label="Continue" + testID="continueBtn" + style={styles.button} + labelStyle={styles.buttonText} + /> + </View> + ) +}) + +type ItemProps = { + did: string + rkey: string +} + +const Item = ({item}: {item: ItemProps}) => { + const uri = makeRecordUri(item.did, 'app.bsky.feed.generator', item.rkey) + const data = useCustomFeed(uri) + if (!data) return null + return ( + <CustomFeed + item={data} + key={uri} + showDescription + showLikes + showSaveBtn + style={[ + { + // @ts-ignore + cursor: isDesktopWeb ? 'pointer' : 'auto', + }, + ]} + /> + ) +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'space-between', + }, + header: { + marginBottom: 16, + marginHorizontal: 16, + }, + button: { + marginBottom: 24, + marginHorizontal: 16, + marginTop: 16, + }, + buttonText: { + textAlign: 'center', + fontSize: 18, + paddingVertical: 4, + }, +}) diff --git a/src/view/com/auth/onboarding/Welcome.tsx b/src/view/com/auth/onboarding/Welcome.tsx index 6f95c0853..b44b58f84 100644 --- a/src/view/com/auth/onboarding/Welcome.tsx +++ b/src/view/com/auth/onboarding/Welcome.tsx @@ -1,123 +1,10 @@ -import React from 'react' -import {Pressable, StyleSheet, View} from 'react-native' -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 {Button} from 'view/com/util/forms/Button' -import {observer} from 'mobx-react-lite' -import {ViewHeader} from 'view/com/util/ViewHeader' -import {isDesktopWeb} from 'platform/detection' - -type Props = { - next: () => void - skip: () => void -} - -export const Welcome = observer(({next, skip}: Props) => { - const pal = usePalette('default') - - return ( - <View style={[styles.container]} testID="welcomeOnboarding"> - <ViewHeader - showOnDesktop - showBorder={false} - showBackButton={false} - title="" - renderButton={() => { - return ( - <Pressable - accessibilityRole="button" - style={[s.flexRow, s.alignCenter]} - onPress={skip}> - <Text style={[pal.link]}>Skip</Text> - <FontAwesomeIcon - icon={'chevron-right'} - size={14} - color={pal.colors.link} - /> - </Pressable> - ) - }} - /> - <View> - <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} /> - <View style={[styles.rowText]}> - <Text type="lg-bold" style={[pal.text]}> - Bluesky is public. - </Text> - <Text type="lg-thin" 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="lg-bold" style={[pal.text]}> - Bluesky is open. - </Text> - <Text type="lg-thin" 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="lg-bold" style={[pal.text]}> - Bluesky is flexible. - </Text> - <Text type="lg-thin" style={[pal.text, s.pt2]}> - Choose the algorithms that power your experience with custom - feeds. - </Text> - </View> - </View> - </View> - - <Button - onPress={next} - label="Continue" - testID="continueBtn" - labelStyle={styles.buttonText} - /> - </View> - ) -}) - -const styles = StyleSheet.create({ - container: { - flex: 1, - marginBottom: isDesktopWeb ? 30 : 60, - marginHorizontal: 16, - justifyContent: 'space-between', - }, - title: { - fontSize: 42, - fontWeight: '800', - }, - row: { - flexDirection: 'row', - columnGap: 20, - alignItems: 'center', - marginVertical: 20, - }, - rowText: { - flex: 1, - }, - spacer: { - height: 20, - }, - buttonText: { - textAlign: 'center', - fontSize: 18, - marginVertical: 4, - }, -}) +import 'react' +import {withBreakpoints} from 'view/com/util/layouts/withBreakpoints' +import {WelcomeDesktop} from './WelcomeDesktop' +import {WelcomeMobile} from './WelcomeMobile' + +export const Welcome = withBreakpoints( + WelcomeMobile, + WelcomeDesktop, + WelcomeDesktop, +) diff --git a/src/view/com/auth/onboarding/Welcome.web.tsx b/src/view/com/auth/onboarding/WelcomeDesktop.tsx index af3ca7074..e63693443 100644 --- a/src/view/com/auth/onboarding/Welcome.web.tsx +++ b/src/view/com/auth/onboarding/WelcomeDesktop.tsx @@ -14,7 +14,7 @@ type Props = { skip: () => void } -export const Welcome = observer(({next}: Props) => { +export const WelcomeDesktop = observer(({next}: Props) => { const pal = usePalette('default') const horizontal = useMediaQuery({ query: '(min-width: 1230px)', diff --git a/src/view/com/auth/onboarding/WelcomeMobile.tsx b/src/view/com/auth/onboarding/WelcomeMobile.tsx new file mode 100644 index 000000000..eb72de836 --- /dev/null +++ b/src/view/com/auth/onboarding/WelcomeMobile.tsx @@ -0,0 +1,123 @@ +import React from 'react' +import {Pressable, StyleSheet, View} from 'react-native' +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 {Button} from 'view/com/util/forms/Button' +import {observer} from 'mobx-react-lite' +import {ViewHeader} from 'view/com/util/ViewHeader' +import {isDesktopWeb} from 'platform/detection' + +type Props = { + next: () => void + skip: () => void +} + +export const WelcomeMobile = observer(({next, skip}: Props) => { + const pal = usePalette('default') + + return ( + <View style={[styles.container]} testID="welcomeOnboarding"> + <ViewHeader + showOnDesktop + showBorder={false} + showBackButton={false} + title="" + renderButton={() => { + return ( + <Pressable + accessibilityRole="button" + style={[s.flexRow, s.alignCenter]} + onPress={skip}> + <Text style={[pal.link]}>Skip</Text> + <FontAwesomeIcon + icon={'chevron-right'} + size={14} + color={pal.colors.link} + /> + </Pressable> + ) + }} + /> + <View> + <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} /> + <View style={[styles.rowText]}> + <Text type="lg-bold" style={[pal.text]}> + Bluesky is public. + </Text> + <Text type="lg-thin" 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="lg-bold" style={[pal.text]}> + Bluesky is open. + </Text> + <Text type="lg-thin" 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="lg-bold" style={[pal.text]}> + Bluesky is flexible. + </Text> + <Text type="lg-thin" style={[pal.text, s.pt2]}> + Choose the algorithms that power your experience with custom + feeds. + </Text> + </View> + </View> + </View> + + <Button + onPress={next} + label="Continue" + testID="continueBtn" + labelStyle={styles.buttonText} + /> + </View> + ) +}) + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginBottom: isDesktopWeb ? 30 : 60, + marginHorizontal: 16, + justifyContent: 'space-between', + }, + title: { + fontSize: 42, + fontWeight: '800', + }, + row: { + flexDirection: 'row', + columnGap: 20, + alignItems: 'center', + marginVertical: 20, + }, + rowText: { + flex: 1, + }, + spacer: { + height: 20, + }, + buttonText: { + textAlign: 'center', + fontSize: 18, + marginVertical: 4, + }, +}) diff --git a/src/view/com/util/layouts/withBreakpoints.tsx b/src/view/com/util/layouts/withBreakpoints.tsx new file mode 100644 index 000000000..4214c1040 --- /dev/null +++ b/src/view/com/util/layouts/withBreakpoints.tsx @@ -0,0 +1,22 @@ +import React from 'react' +import {useMediaQuery} from 'react-responsive' +import {isNative} from 'platform/detection' + +export const withBreakpoints = + <P extends object>( + Mobile: React.ComponentType<P>, + Tablet: React.ComponentType<P>, + Desktop: React.ComponentType<P>, + ): React.FC<P> => + (props: P) => { + const isTabletOrMobile = useMediaQuery({query: '(max-width: 1224px)'}) + const isMobile = useMediaQuery({query: '(max-width: 800px)'}) + + if (isMobile || isNative) { + return <Mobile {...props} /> + } + if (isTabletOrMobile) { + return <Tablet {...props} /> + } + return <Desktop {...props} /> + } |