about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-08-30 14:57:03 -0700
committerPaul Frazee <pfrazee@gmail.com>2023-08-30 14:57:03 -0700
commit05d1d8d8a4565e7d042f8c09760186b4037dcd2f (patch)
treee103178d643356dbe06fbaa9867e8a0dbff272a3
parentcd8ae1298e6ef67e5c40cdde24449b49ae2d914b (diff)
downloadvoidsky-05d1d8d8a4565e7d042f8c09760186b4037dcd2f.tar.zst
Fix onboarding on mobile web
-rw-r--r--src/view/com/auth/onboarding/RecommendedFeeds.tsx101
-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.tsx95
-rw-r--r--src/view/com/auth/onboarding/Welcome.tsx133
-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.tsx123
-rw-r--r--src/view/com/util/layouts/withBreakpoints.tsx22
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} />
+  }