diff --git a/assets/icons/bookmarkDeleteLarge.svg b/assets/icons/bookmarkDeleteLarge.svg
new file mode 100644
index 0000000000..e2ded1e8d8
--- /dev/null
+++ b/assets/icons/bookmarkDeleteLarge.svg
@@ -0,0 +1 @@
+
diff --git a/src/components/icons/Bookmark.tsx b/src/components/icons/Bookmark.tsx
index 966f423dff..c8fb8242f4 100644
--- a/src/components/icons/Bookmark.tsx
+++ b/src/components/icons/Bookmark.tsx
@@ -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',
+})
diff --git a/src/screens/Bookmarks/components/EmptyState.tsx b/src/screens/Bookmarks/components/EmptyState.tsx
new file mode 100644
index 0000000000..bfd80903d1
--- /dev/null
+++ b/src/screens/Bookmarks/components/EmptyState.tsx
@@ -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 (
+
+
+
+
+ Nothing saved yet
+
+
+
+
+
+
+ Go home
+
+
+
+
+
+ )
+}
diff --git a/src/screens/Bookmarks.tsx b/src/screens/Bookmarks/index.tsx
similarity index 85%
rename from src/screens/Bookmarks.tsx
rename to src/screens/Bookmarks/index.tsx
index 74edb83049..1c30f32e97 100644
--- a/src/screens/Bookmarks.tsx
+++ b/src/screens/Bookmarks/index.tsx
@@ -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,
- },
- })
- }
- if (AppBskyFeedDefs.isPostView(bookmark.item)) {
- i.push({
- type: 'bookmark',
- key: bookmark.item.uri,
- bookmark: {
- ...bookmark,
- item: bookmark.item as $Typed,
- },
- })
+ 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,
+ },
+ })
+ }
+ if (AppBskyFeedDefs.isPostView(bookmark.item)) {
+ i.push({
+ type: 'bookmark',
+ key: bookmark.item.uri,
+ bookmark: {
+ ...bookmark,
+ item: bookmark.item as $Typed,
+ },
+ })
+ }
}
+ } else {
+ i.push({type: 'empty', key: 'empty'})
}
}
return i
}, [isLoading, error, data])
+ const isEmpty = items.length === 1 && items[0]?.type === 'empty'
+
return (
}
initialNumToRender={initialNumToRender}
@@ -265,6 +278,9 @@ function renderItem({item, index}: {item: ListItem; index: number}) {
case 'loading': {
return
}
+ case 'empty': {
+ return
+ }
case 'bookmark': {
return (