diff --git a/src/components/PostControls/BookmarkButton.tsx b/src/components/PostControls/BookmarkButton.tsx
index c32b660804..6b9623837f 100644
--- a/src/components/PostControls/BookmarkButton.tsx
+++ b/src/components/PostControls/BookmarkButton.tsx
@@ -1,6 +1,6 @@
-import {memo, useCallback} from 'react'
+import {memo} from 'react'
import {type AppBskyFeedDefs} from '@atproto/api'
-import {msg} from '@lingui/macro'
+import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import type React from 'react'
@@ -9,6 +9,7 @@ import {type Shadow} from '#/state/cache/post-shadow'
import {useBookmarkMutation} from '#/state/queries/bookmarks/useBookmarkMutation'
import {useTheme} from '#/alf'
import {Bookmark, BookmarkFilled} from '#/components/icons/Bookmark'
+import {Trash_Stroke2_Corner0_Rounded as TrashIcon} from '#/components/icons/Trash'
import * as toast from '#/components/Toast'
import {PostControlButton, PostControlButtonIcon} from './PostControlButton'
@@ -27,31 +28,84 @@ export const BookmarkButton = memo(function BookmarkButton({
const {uri, cid, viewer} = post
const isBookmarked = !!viewer?.bookmarked
- const onHandlePress = useCallback(async () => {
+ const undoLabel = _(
+ msg({
+ message: `Undo`,
+ context: `Button label to undo saving/removing a post from saved posts.`,
+ }),
+ )
+
+ const save = async ({disableUndo}: {disableUndo?: boolean} = {}) => {
try {
- if (isBookmarked) {
- await bookmark({
- action: 'delete',
- uri,
- })
- toast.show(_(msg`Removed from saved posts`))
- } else {
- await bookmark({
- action: 'create',
- uri,
- cid,
- })
- toast.show(_(msg`Post saved`), {
+ await bookmark({
+ action: 'create',
+ uri,
+ cid,
+ })
+
+ toast.show(
+
+
+
+ Post saved
+
+ {!disableUndo && (
+ remove({disableUndo: true})}>
+ {undoLabel}
+
+ )}
+ ,
+ {
type: 'success',
- })
- }
+ },
+ )
} catch (e: any) {
const {raw, clean} = cleanError(e)
toast.show(clean || raw || e, {
type: 'error',
})
}
- }, [_, uri, cid, isBookmarked, bookmark, cleanError])
+ }
+
+ const remove = async ({disableUndo}: {disableUndo?: boolean} = {}) => {
+ try {
+ await bookmark({
+ action: 'delete',
+ uri,
+ })
+
+ toast.show(
+
+
+
+ Removed from saved posts
+
+ {!disableUndo && (
+ save({disableUndo: true})}>
+ {undoLabel}
+
+ )}
+ ,
+ )
+ } catch (e: any) {
+ const {raw, clean} = cleanError(e)
+ toast.show(clean || raw || e, {
+ type: 'error',
+ })
+ }
+ }
+
+ const onHandlePress = async () => {
+ if (isBookmarked) {
+ await remove()
+ } else {
+ await save()
+ }
+ }
return (
{
+ const remove = async () => {
try {
setRemoved(true)
await bookmark({action: 'delete', uri: post.uri})
+ toast.show(_(msg`Removed from saved posts`), {
+ type: 'error',
+ })
} catch (e: any) {
const {raw, clean} = cleanError(e)
toast.show(clean || raw || e, {
type: 'error',
})
}
- }, [post.uri, bookmark, cleanError])
+ }
if (removed) return null