Add empty states to the lists screen

This commit is contained in:
Paul Frazee
2023-05-05 11:40:56 -05:00
parent 5e723b0821
commit 806e52705d
5 changed files with 236 additions and 226 deletions
+1 -1
View File
@@ -62,7 +62,7 @@ export class ListsListModel {
this._xLoading(replace)
try {
let res
if (this.source === 'mine') {
if (this.source === 'blocklists') {
res = await this.rootStore.agent.app.bsky.graph.getListBlocks({
limit: PAGE_SIZE,
cursor: replace ? undefined : this.loadMoreCursor,
+6 -3
View File
@@ -7,6 +7,7 @@ import {
View,
ViewStyle,
} from 'react-native'
import {observer} from 'mobx-react-lite'
import {FlatList} from '../util/Views'
import {ListCard} from './ListCard'
import {ProfileCardFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
@@ -22,7 +23,8 @@ const EMPTY_ITEM = {_reactKey: '__empty__'}
const ERROR_ITEM = {_reactKey: '__error__'}
const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'}
export function ListsList({
export const ListsList = observer(
({
listsList,
style,
showPostFollowBtn,
@@ -40,7 +42,7 @@ export function ListsList({
renderEmptyState?: () => JSX.Element
testID?: string
headerOffset?: number
}) {
}) => {
const pal = usePalette('default')
const {track} = useAnalytics()
const [isRefreshing, setIsRefreshing] = React.useState(false)
@@ -174,7 +176,8 @@ export function ListsList({
)}
</View>
)
}
},
)
const styles = StyleSheet.create({
feedFooter: {paddingTop: 20},
+41 -34
View File
@@ -1,80 +1,87 @@
import React from 'react'
import {StyleSheet, View} from 'react-native'
import {useNavigation} from '@react-navigation/native'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {Text} from '../util/text/Text'
import {Button} from '../util/forms/Button'
import {MagnifyingGlassIcon} from 'lib/icons'
import {NavigationProp} from 'lib/routes/types'
import {usePalette} from 'lib/hooks/usePalette'
import {s} from 'lib/styles'
export function MyListsEmptyState() {
const pal = usePalette('default')
const palInverted = usePalette('inverted')
const navigation = useNavigation<NavigationProp>()
const onPressFindAccounts = React.useCallback(() => {
navigation.navigate('SearchTab')
navigation.popToTop()
}, [navigation])
const onPressCreateList = React.useCallback(() => {
// TODO
}, [])
return (
<View style={styles.emptyContainer}>
<View style={styles.emptyIconContainer}>
<MagnifyingGlassIcon style={[styles.emptyIcon, pal.text]} size={62} />
<View style={styles.container}>
<View style={styles.iconContainer}>
<FontAwesomeIcon
icon="list-ul"
style={[styles.icon, pal.text]}
size={62}
/>
</View>
<Text type="xl-medium" style={[s.textCenter, pal.text]}>
Your following feed is empty! Find some accounts to follow to fix this.
</Text>
<Button
type="inverted"
style={styles.emptyBtn}
onPress={onPressFindAccounts}>
<Text type="lg-medium" style={palInverted.text}>
Find accounts to follow
Lists are public collections of users. You can create a list or find
other users' lists on their profiles.
</Text>
<View style={styles.btns}>
<Button type="inverted" style={styles.btn} onPress={onPressCreateList}>
<FontAwesomeIcon
icon="angle-right"
icon="plus"
style={palInverted.text as FontAwesomeIconStyle}
size={14}
/>
<Text type="lg-medium" style={palInverted.text}>
New blocklist
</Text>
</Button>
</View>
<View style={[pal.viewLight, styles.notice]}>
<Text type="lg" style={[pal.textLight, s.textCenter]}>
Currently only "blocklists" are available, which is kind of weird but
we wanted to prioritize user safety. Feedlists will be implemented
soon!
</Text>
</View>
</View>
)
}
const styles = StyleSheet.create({
emptyContainer: {
container: {
height: '100%',
paddingVertical: 40,
paddingHorizontal: 30,
},
emptyIconContainer: {
iconContainer: {
marginBottom: 16,
},
emptyIcon: {
icon: {
marginLeft: 'auto',
marginRight: 'auto',
},
emptyBtn: {
btns: {
flexDirection: 'row',
justifyContent: 'center',
},
btn: {
gap: 10,
marginVertical: 20,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingVertical: 18,
paddingVertical: 14,
paddingHorizontal: 24,
borderRadius: 30,
},
feedsTip: {
position: 'absolute',
left: 22,
},
feedsTipArrow: {
marginLeft: 32,
marginTop: 8,
notice: {
borderRadius: 12,
paddingHorizontal: 12,
paddingVertical: 10,
marginHorizontal: 30,
},
})
@@ -1,80 +1,80 @@
import React from 'react'
import {StyleSheet, View} from 'react-native'
import {useNavigation} from '@react-navigation/native'
import {
FontAwesomeIcon,
FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome'
import {Text} from '../util/text/Text'
import {Button} from '../util/forms/Button'
import {MagnifyingGlassIcon} from 'lib/icons'
import {NavigationProp} from 'lib/routes/types'
import {usePalette} from 'lib/hooks/usePalette'
import {s} from 'lib/styles'
export function SubscribedBlocklistsEmptyState() {
const pal = usePalette('default')
const palInverted = usePalette('inverted')
const navigation = useNavigation<NavigationProp>()
const onPressFindAccounts = React.useCallback(() => {
navigation.navigate('SearchTab')
navigation.popToTop()
}, [navigation])
const onPressCreateList = React.useCallback(() => {
// TODO
}, [])
return (
<View style={styles.emptyContainer}>
<View style={styles.emptyIconContainer}>
<MagnifyingGlassIcon style={[styles.emptyIcon, pal.text]} size={62} />
<View style={styles.container}>
<View style={styles.iconContainer}>
<FontAwesomeIcon
icon="list-ul"
style={[styles.icon, pal.text]}
size={62}
/>
</View>
<Text type="xl-medium" style={[s.textCenter, pal.text]}>
Your following feed is empty! Find some accounts to follow to fix this.
</Text>
<Button
type="inverted"
style={styles.emptyBtn}
onPress={onPressFindAccounts}>
<Text type="lg-medium" style={palInverted.text}>
Find accounts to follow
You can subscribe to blocklists to automatically block all of the users
they include. Blocklists and your subscriptions are public.
</Text>
<View style={styles.btns}>
<Button type="inverted" style={styles.btn} onPress={onPressCreateList}>
<FontAwesomeIcon
icon="angle-right"
icon="plus"
style={palInverted.text as FontAwesomeIconStyle}
size={14}
/>
<Text type="lg-medium" style={palInverted.text}>
New blocklist
</Text>
</Button>
</View>
</View>
)
}
const styles = StyleSheet.create({
emptyContainer: {
container: {
height: '100%',
paddingVertical: 40,
paddingHorizontal: 30,
},
emptyIconContainer: {
iconContainer: {
marginBottom: 16,
},
emptyIcon: {
icon: {
marginLeft: 'auto',
marginRight: 'auto',
},
emptyBtn: {
btns: {
flexDirection: 'row',
justifyContent: 'center',
},
btn: {
gap: 10,
marginVertical: 20,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingVertical: 18,
paddingVertical: 14,
paddingHorizontal: 24,
borderRadius: 30,
},
feedsTip: {
position: 'absolute',
left: 22,
},
feedsTipArrow: {
marginLeft: 32,
marginTop: 8,
notice: {
borderRadius: 12,
paddingHorizontal: 12,
paddingVertical: 10,
marginHorizontal: 30,
},
})
+1 -1
View File
@@ -46,7 +46,7 @@ export const ListsScreen = withAuthRequired(({route}: Props) => {
return (
<TabBar
{...props}
items={['Mine', 'Subscribed Blocklists']}
items={['My Lists', 'Blocklists']}
indicatorColor={pal.colors.link}
indicatorPosition="bottom"
testID="tabs"