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/useBookmarkMutation.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/useBookmarkMutation.ts')
-rw-r--r-- | src/state/queries/bookmarks/useBookmarkMutation.ts | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/state/queries/bookmarks/useBookmarkMutation.ts b/src/state/queries/bookmarks/useBookmarkMutation.ts new file mode 100644 index 000000000..c6e745aa0 --- /dev/null +++ b/src/state/queries/bookmarks/useBookmarkMutation.ts @@ -0,0 +1,65 @@ +import {type AppBskyFeedDefs} from '@atproto/api' +import {useMutation, useQueryClient} from '@tanstack/react-query' + +import {isNetworkError} from '#/lib/strings/errors' +import {logger} from '#/logger' +import {updatePostShadow} from '#/state/cache/post-shadow' +import { + optimisticallyDeleteBookmark, + optimisticallySaveBookmark, +} from '#/state/queries/bookmarks/useBookmarksQuery' +import {useAgent} from '#/state/session' + +type MutationArgs = + | {action: 'create'; post: AppBskyFeedDefs.PostView} + | { + action: 'delete' + /** + * For deletions, we only need to URI. Plus, in some cases we only know the + * URI, such as when a post was deleted by the author. + */ + uri: string + } + +export function useBookmarkMutation() { + const qc = useQueryClient() + const agent = useAgent() + + return useMutation({ + async mutationFn(args: MutationArgs) { + if (args.action === 'create') { + updatePostShadow(qc, args.post.uri, {bookmarked: true}) + await agent.app.bsky.bookmark.createBookmark({ + uri: args.post.uri, + cid: args.post.cid, + }) + } else if (args.action === 'delete') { + updatePostShadow(qc, args.uri, {bookmarked: false}) + await agent.app.bsky.bookmark.deleteBookmark({ + uri: args.uri, + }) + } + }, + onSuccess(_, args) { + if (args.action === 'create') { + optimisticallySaveBookmark(qc, args.post) + } else if (args.action === 'delete') { + optimisticallyDeleteBookmark(qc, {uri: args.uri}) + } + }, + onError(e, args) { + if (args.action === 'create') { + updatePostShadow(qc, args.post.uri, {bookmarked: false}) + } else if (args.action === 'delete') { + updatePostShadow(qc, args.uri, {bookmarked: true}) + } + + if (!isNetworkError(e)) { + logger.error('bookmark mutation failed', { + bookmarkAction: args.action, + safeMessage: e, + }) + } + }, + }) +} |