diff options
author | Eric Bailey <git@esb.lol> | 2025-09-04 17:30:15 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-04 17:30:15 -0500 |
commit | 535d4d6cf74cfb49a70804bccb4de1613d2ac09c (patch) | |
tree | 78198de5712398e5a9a4b43ec69b254f81081442 /src/state/queries/bookmarks/useBookmarksQuery.ts | |
parent | 04b869714e512ed29653892d45dab806396824e1 (diff) | |
download | voidsky-535d4d6cf74cfb49a70804bccb4de1613d2ac09c.tar.zst |
📓 Bookmarks (#8976)
* Add button to controls, respace * Hook up shadow and mutation * Add Bookmarks screen * Build out Bookmarks screen * Handle removals via shadow * Use truncateAndInvalidate strategy * Add empty state * Add toasts * Add undo buttons to toasts * Stage NUX, needs image * Finesse post controls * New reply icon * Use curvier variant of repost icon * Prevent layout shift with align_start * Update api pkg * Swap in new image * Limit spacing on desktop * Rm decimals over 10k * Better optimistic adding/removing * Add metrics * Comment * Remove unused code block * Remove debug limit * Fork shadow for web/native * Tweak alt * add preventExpansion: true * Refine hitslop * Add count to anchor * Reduce space in compact mode --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Diffstat (limited to 'src/state/queries/bookmarks/useBookmarksQuery.ts')
-rw-r--r-- | src/state/queries/bookmarks/useBookmarksQuery.ts | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/state/queries/bookmarks/useBookmarksQuery.ts b/src/state/queries/bookmarks/useBookmarksQuery.ts new file mode 100644 index 000000000..46838facb --- /dev/null +++ b/src/state/queries/bookmarks/useBookmarksQuery.ts @@ -0,0 +1,114 @@ +import { + type $Typed, + type AppBskyBookmarkGetBookmarks, + type AppBskyFeedDefs, +} from '@atproto/api' +import { + type InfiniteData, + type QueryClient, + type QueryKey, + useInfiniteQuery, +} from '@tanstack/react-query' + +import {useAgent} from '#/state/session' + +export const bookmarksQueryKeyRoot = 'bookmarks' +export const createBookmarksQueryKey = () => [bookmarksQueryKeyRoot] + +export function useBookmarksQuery() { + const agent = useAgent() + + return useInfiniteQuery< + AppBskyBookmarkGetBookmarks.OutputSchema, + Error, + InfiniteData<AppBskyBookmarkGetBookmarks.OutputSchema>, + QueryKey, + string | undefined + >({ + queryKey: createBookmarksQueryKey(), + async queryFn({pageParam}) { + const res = await agent.app.bsky.bookmark.getBookmarks({ + cursor: pageParam, + }) + return res.data + }, + initialPageParam: undefined, + getNextPageParam: lastPage => lastPage.cursor, + }) +} + +export async function truncateAndInvalidate(qc: QueryClient) { + qc.setQueriesData<InfiniteData<AppBskyBookmarkGetBookmarks.OutputSchema>>( + {queryKey: [bookmarksQueryKeyRoot]}, + data => { + if (data) { + return { + pageParams: data.pageParams.slice(0, 1), + pages: data.pages.slice(0, 1), + } + } + return data + }, + ) + return qc.invalidateQueries({queryKey: [bookmarksQueryKeyRoot]}) +} + +export async function optimisticallySaveBookmark( + qc: QueryClient, + post: AppBskyFeedDefs.PostView, +) { + qc.setQueriesData<InfiniteData<AppBskyBookmarkGetBookmarks.OutputSchema>>( + { + queryKey: [bookmarksQueryKeyRoot], + }, + data => { + if (!data) return data + return { + ...data, + pages: data.pages.map((page, index) => { + if (index === 0) { + post.$type = 'app.bsky.feed.defs#postView' + return { + ...page, + bookmarks: [ + { + createdAt: new Date().toISOString(), + subject: { + uri: post.uri, + cid: post.cid, + }, + item: post as $Typed<AppBskyFeedDefs.PostView>, + }, + ...page.bookmarks, + ], + } + } + return page + }), + } + }, + ) +} + +export async function optimisticallyDeleteBookmark( + qc: QueryClient, + {uri}: {uri: string}, +) { + qc.setQueriesData<InfiniteData<AppBskyBookmarkGetBookmarks.OutputSchema>>( + { + queryKey: [bookmarksQueryKeyRoot], + }, + data => { + if (!data) return data + return { + ...data, + pages: data.pages.map(page => { + return { + ...page, + bookmarks: page.bookmarks.filter(b => b.subject.uri !== uri), + } + }), + } + }, + ) +} |