From cf8b03801fd8e98bcd2da4d099a9dfbf5876de7d Mon Sep 17 00:00:00 2001 From: Hailey Date: Thu, 29 Feb 2024 17:56:29 -0800 Subject: Dedicated screen for hashtags, POC ALF list (#3047) * create dedicated hashtag "search" screen clarify loading component name more adjustments rework `ViewHeader` to keep chevron centered w/ first line adjustments adjustments use `author` instead of `handle` in route add web route for url add web route for url Add desktop list header support web keep header lowercase add optional subtitle to view header correct isFetching logic oops use `isFetching` for clarity in footer combine logic update bskyweb finish screen style, add footer, add spinner, etc add list add header, params create a screen * add variable to server path * localize `By` * add empty state * more adjustments * sanitize author * fix web * add custom message for hashtag not found error * ellipsis in middle * fix * fix trans * account for multiple # * encode # * replaceall * Use sanitized tag * don't call function in lingui * add share button --------- Co-authored-by: Eric Bailey --- src/components/Lists.tsx | 228 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 src/components/Lists.tsx (limited to 'src/components/Lists.tsx') diff --git a/src/components/Lists.tsx b/src/components/Lists.tsx new file mode 100644 index 000000000..cf00734f0 --- /dev/null +++ b/src/components/Lists.tsx @@ -0,0 +1,228 @@ +import React from 'react' +import {atoms as a, useBreakpoints, useTheme} from '#/alf' +import {View} from 'react-native' +import {Loader} from '#/components/Loader' +import {Trans} from '@lingui/macro' +import {cleanError} from 'lib/strings/errors' +import {Button} from '#/components/Button' +import {Text} from '#/components/Typography' +import {StackActions} from '@react-navigation/native' +import {useNavigation} from '@react-navigation/core' +import {NavigationProp} from 'lib/routes/types' + +export function ListFooter({ + isFetching, + isError, + error, + onRetry, +}: { + isFetching: boolean + isError: boolean + error?: string + onRetry?: () => Promise +}) { + const t = useTheme() + + return ( + + {isFetching ? ( + + ) : ( + + )} + + ) +} + +function ListFooterMaybeError({ + isError, + error, + onRetry, +}: { + isError: boolean + error?: string + onRetry?: () => Promise +}) { + const t = useTheme() + + if (!isError) return null + + return ( + + + + {error ? ( + cleanError(error) + ) : ( + Oops, something went wrong! + )} + + + + + ) +} + +export function ListHeaderDesktop({ + title, + subtitle, +}: { + title: string + subtitle?: string +}) { + const {gtTablet} = useBreakpoints() + const t = useTheme() + + if (!gtTablet) return null + + return ( + + {title} + {subtitle ? ( + + {subtitle} + + ) : undefined} + + ) +} + +export function ListMaybePlaceholder({ + isLoading, + isEmpty, + isError, + empty, + error, + onRetry, +}: { + isLoading: boolean + isEmpty: boolean + isError: boolean + empty?: string + error?: string + onRetry?: () => Promise +}) { + const navigation = useNavigation() + const t = useTheme() + + const canGoBack = navigation.canGoBack() + const onGoBack = React.useCallback(() => { + if (canGoBack) { + navigation.goBack() + } else { + navigation.navigate('HomeTab') + navigation.dispatch(StackActions.popToTop()) + } + }, [navigation, canGoBack]) + + if (!isEmpty) return null + + return ( + + {isLoading ? ( + + + + ) : ( + <> + + + {isError ? ( + Oops! + ) : isEmpty ? ( + Page not found + ) : undefined} + + + {isError ? ( + + {error ? error : Something went wrong!} + + ) : isEmpty ? ( + + {empty ? ( + empty + ) : ( + + We're sorry! We can't find the page you were looking for. + + )} + + ) : undefined} + + + {isError && onRetry && ( + + )} + + + + )} + + ) +} -- cgit 1.4.1 From 82655f2ee3c208c2a0ab148dba1bccf884213375 Mon Sep 17 00:00:00 2001 From: Hailey Date: Fri, 1 Mar 2024 15:47:59 -0800 Subject: Few list tweaks on web (#3062) * share button only on native * update gttablet to be 1300px * improve web layout * change re-layout to mobile breakpoint * adjustable not found reason * don't show the borders on mobile web * slight padding for the spinner --- src/alf/index.tsx | 2 +- src/components/Lists.tsx | 28 +++++++++++++++++++++++----- src/screens/Hashtag.tsx | 35 +++++++++++++++++++++-------------- 3 files changed, 45 insertions(+), 20 deletions(-) (limited to 'src/components/Lists.tsx') diff --git a/src/alf/index.tsx b/src/alf/index.tsx index 06d6ebf01..27738e91d 100644 --- a/src/alf/index.tsx +++ b/src/alf/index.tsx @@ -17,7 +17,7 @@ const breakpoints: { [key: string]: number } = { gtMobile: 800, - gtTablet: 1200, + gtTablet: 1300, } function getActiveBreakpoints({width}: {width: number}) { const active: (keyof typeof breakpoints)[] = Object.keys(breakpoints).filter( diff --git a/src/components/Lists.tsx b/src/components/Lists.tsx index cf00734f0..12a935807 100644 --- a/src/components/Lists.tsx +++ b/src/components/Lists.tsx @@ -9,6 +9,7 @@ import {Text} from '#/components/Typography' import {StackActions} from '@react-navigation/native' import {useNavigation} from '@react-navigation/core' import {NavigationProp} from 'lib/routes/types' +import {router} from '#/routes' export function ListFooter({ isFetching, @@ -30,6 +31,7 @@ export function ListFooter({ a.align_center, a.justify_center, a.border_t, + a.pb_lg, t.atoms.border_contrast_low, {height: 100}, ]}> @@ -128,6 +130,7 @@ export function ListMaybePlaceholder({ isError, empty, error, + notFoundType = 'page', onRetry, }: { isLoading: boolean @@ -135,10 +138,12 @@ export function ListMaybePlaceholder({ isError: boolean empty?: string error?: string + notFoundType?: 'page' | 'results' onRetry?: () => Promise }) { const navigation = useNavigation() const t = useTheme() + const {gtMobile} = useBreakpoints() const canGoBack = navigation.canGoBack() const onGoBack = React.useCallback(() => { @@ -146,7 +151,14 @@ export function ListMaybePlaceholder({ navigation.goBack() } else { navigation.navigate('HomeTab') - navigation.dispatch(StackActions.popToTop()) + + // Checking the state for routes ensures that web doesn't encounter errors while going back + if (navigation.getState()?.routes) { + navigation.dispatch(StackActions.push(...router.matchPath('/'))) + } else { + navigation.navigate('HomeTab') + navigation.dispatch(StackActions.popToTop()) + } } }, [navigation, canGoBack]) @@ -157,8 +169,7 @@ export function ListMaybePlaceholder({ style={[ a.flex_1, a.align_center, - a.border_t, - a.justify_between, + !gtMobile ? [a.justify_between, a.border_t] : a.gap_5xl, t.atoms.border_contrast_low, {paddingTop: 175, paddingBottom: 110}, ]}> @@ -173,7 +184,13 @@ export function ListMaybePlaceholder({ {isError ? ( Oops! ) : isEmpty ? ( - Page not found + <> + {notFoundType === 'results' ? ( + No results found + ) : ( + Page not found + )} + ) : undefined} @@ -195,7 +212,8 @@ export function ListMaybePlaceholder({ ) : undefined} - + {isError && onRetry && (