Add empty state

This commit is contained in:
Eric Bailey
2025-08-25 18:04:17 -05:00
parent a639758f5f
commit 969557d118
4 changed files with 102 additions and 21 deletions
+5
View File
@@ -9,3 +9,8 @@ export const Bookmark = createSinglePathSVG({
export const BookmarkFilled = createSinglePathSVG({
path: 'M16 2.5a4 4 0 0 1 4 4v12.995c0 1.62-1.825 2.567-3.15 1.636l-3.7-2.6a2.001 2.001 0 0 0-2.3 0l-3.7 2.6C5.825 22.062 4 21.115 4 19.495V6.5a4 4 0 0 1 4-4h8Z',
})
// custom, not part of icon library, for LARGE (64px) size
export const BookmarkDeleteLarge = createSinglePathSVG({
path: 'M14.2 2.625c.834 0 1.482 0 2.001.042.523.043.949.131 1.331.326.635.324 1.151.84 1.475 1.475.195.382.283.807.326 1.33.042.52.042 1.168.042 2.002v11.09c0 .495 0 .893-.027 1.199-.028.301-.087.585-.26.809-.249.323-.63.518-1.037.533-.282.01-.547-.107-.808-.26-.265-.154-.588-.385-.991-.673l-3.54-2.528c-.36-.258-.461-.322-.559-.347a.626.626 0 0 0-.306 0c-.098.025-.199.09-.559.347l-3.54 2.528c-.403.288-.726.519-.991.674-.261.152-.526.269-.808.259a1.376 1.376 0 0 1-1.038-.534c-.172-.223-.231-.507-.259-.808a7.31 7.31 0 0 1-.024-.528l-.003-.67V7.8c0-.834 0-1.482.042-2.001.043-.523.13-.949.325-1.331a3.376 3.376 0 0 1 1.476-1.475c.382-.195.808-.283 1.33-.326.52-.042 1.168-.042 2.002-.042h4.4Zm-4.4.75c-.846 0-1.458 0-1.94.04-.477.039-.792.114-1.051.246A2.626 2.626 0 0 0 5.66 4.81c-.132.259-.208.574-.247 1.051-.04.482-.039 1.094-.039 1.94v11.09l.003.658c.003.186.01.34.021.473.025.267.07.37.106.418a.626.626 0 0 0 .472.243c.059.002.168-.022.4-.158.23-.133.52-.34.935-.636l3.54-2.529c.308-.22.543-.396.81-.464.222-.056.454-.056.676 0 .267.068.5.244.81.464l3.54 2.529c.414.296.704.503.933.636.233.137.343.16.402.158a.626.626 0 0 0 .472-.243c.036-.048.081-.15.106-.419.024-.263.024-.62.024-1.13V7.8c0-.846 0-1.458-.04-1.94-.039-.477-.114-.792-.246-1.051A2.627 2.627 0 0 0 17.19 3.66c-.259-.132-.575-.207-1.051-.246-.482-.04-1.094-.04-1.94-.04H9.8Zm4.056 4.238a.375.375 0 0 1 .53.53L12.53 10l1.857 1.856a.375.375 0 0 1-.53.53L12 10.53l-1.856 1.857a.375.375 0 0 1-.53-.53L11.47 10 9.613 8.144a.375.375 0 0 1 .53-.53L12 9.47l1.856-1.857Z',
})
@@ -0,0 +1,59 @@
import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {atoms as a, useTheme} from '#/alf'
import {ButtonText} from '#/components/Button'
import {BookmarkDeleteLarge} from '#/components/icons/Bookmark'
import {Link} from '#/components/Link'
import {Text} from '#/components/Typography'
export function EmptyState() {
const t = useTheme()
const {_} = useLingui()
return (
<View
style={[
a.align_center,
{
paddingVertical: 64,
},
]}>
<BookmarkDeleteLarge
width={64}
fill={t.atoms.text_contrast_medium.color}
/>
<View style={[a.pt_sm]}>
<Text
style={[
a.text_lg,
a.font_medium,
a.text_center,
t.atoms.text_contrast_medium,
]}>
<Trans>Nothing saved yet</Trans>
</Text>
</View>
<View style={[a.pt_2xl]}>
<Link
to="/"
action="navigate"
label={_(
msg({
message: `Go home`,
context: `Button to go back to the home timeline`,
}),
)}
size="small"
color="secondary">
<ButtonText>
<Trans context="Button to go back to the home timeline">
Go home
</Trans>
</ButtonText>
</Link>
</View>
</View>
)
}
@@ -23,6 +23,7 @@ import {useSetMinimalShellMode} from '#/state/shell'
import {Post} from '#/view/com/post/Post'
import {List} from '#/view/com/util/List'
import {PostFeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
import {EmptyState} from '#/screens/Bookmarks/components/EmptyState'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {BookmarkFilled} from '#/components/icons/Bookmark'
@@ -64,6 +65,10 @@ type ListItem =
type: 'loading'
key: 'loading'
}
| {
type: 'empty'
key: 'empty'
}
| {
type: 'bookmark'
key: string
@@ -124,34 +129,41 @@ function BookmarksInner() {
} else {
const bookmarks = data.pages.flatMap(p => p.bookmarks)
for (const bookmark of bookmarks) {
if (AppBskyFeedDefs.isBlockedPost(bookmark.item)) return null
if (AppBskyFeedDefs.isNotFoundPost(bookmark.item)) {
i.push({
type: 'bookmarkNotFound',
key: bookmark.item.uri,
bookmark: {
...bookmark,
item: bookmark.item as $Typed<AppBskyFeedDefs.NotFoundPost>,
},
})
}
if (AppBskyFeedDefs.isPostView(bookmark.item)) {
i.push({
type: 'bookmark',
key: bookmark.item.uri,
bookmark: {
...bookmark,
item: bookmark.item as $Typed<AppBskyFeedDefs.PostView>,
},
})
if (bookmarks.length > 0) {
for (const bookmark of bookmarks) {
if (AppBskyFeedDefs.isBlockedPost(bookmark.item)) {
}
if (AppBskyFeedDefs.isNotFoundPost(bookmark.item)) {
i.push({
type: 'bookmarkNotFound',
key: bookmark.item.uri,
bookmark: {
...bookmark,
item: bookmark.item as $Typed<AppBskyFeedDefs.NotFoundPost>,
},
})
}
if (AppBskyFeedDefs.isPostView(bookmark.item)) {
i.push({
type: 'bookmark',
key: bookmark.item.uri,
bookmark: {
...bookmark,
item: bookmark.item as $Typed<AppBskyFeedDefs.PostView>,
},
})
}
}
} else {
i.push({type: 'empty', key: 'empty'})
}
}
return i
}, [isLoading, error, data])
const isEmpty = items.length === 1 && items[0]?.type === 'empty'
return (
<List
data={items}
@@ -166,6 +178,7 @@ function BookmarksInner() {
isFetchingNextPage={isFetchingNextPage}
error={cleanedError}
onRetry={fetchNextPage}
style={[isEmpty && a.border_t_0]}
/>
}
initialNumToRender={initialNumToRender}
@@ -265,6 +278,9 @@ function renderItem({item, index}: {item: ListItem; index: number}) {
case 'loading': {
return <PostFeedLoadingPlaceholder />
}
case 'empty': {
return <EmptyState />
}
case 'bookmark': {
return (
<BookmarkPost post={item.bookmark.item} hideTopBorder={index === 0} />