Add undo buttons to toasts
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import {memo, useCallback} from 'react'
|
import {memo} from 'react'
|
||||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import type React from '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 {useBookmarkMutation} from '#/state/queries/bookmarks/useBookmarkMutation'
|
||||||
import {useTheme} from '#/alf'
|
import {useTheme} from '#/alf'
|
||||||
import {Bookmark, BookmarkFilled} from '#/components/icons/Bookmark'
|
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 * as toast from '#/components/Toast'
|
||||||
import {PostControlButton, PostControlButtonIcon} from './PostControlButton'
|
import {PostControlButton, PostControlButtonIcon} from './PostControlButton'
|
||||||
|
|
||||||
@@ -27,31 +28,84 @@ export const BookmarkButton = memo(function BookmarkButton({
|
|||||||
const {uri, cid, viewer} = post
|
const {uri, cid, viewer} = post
|
||||||
const isBookmarked = !!viewer?.bookmarked
|
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 {
|
try {
|
||||||
if (isBookmarked) {
|
await bookmark({
|
||||||
await bookmark({
|
action: 'create',
|
||||||
action: 'delete',
|
uri,
|
||||||
uri,
|
cid,
|
||||||
})
|
})
|
||||||
toast.show(_(msg`Removed from saved posts`))
|
|
||||||
} else {
|
toast.show(
|
||||||
await bookmark({
|
<toast.Outer>
|
||||||
action: 'create',
|
<toast.Icon />
|
||||||
uri,
|
<toast.Text>
|
||||||
cid,
|
<Trans>Post saved</Trans>
|
||||||
})
|
</toast.Text>
|
||||||
toast.show(_(msg`Post saved`), {
|
{!disableUndo && (
|
||||||
|
<toast.Action
|
||||||
|
label={undoLabel}
|
||||||
|
onPress={() => remove({disableUndo: true})}>
|
||||||
|
{undoLabel}
|
||||||
|
</toast.Action>
|
||||||
|
)}
|
||||||
|
</toast.Outer>,
|
||||||
|
{
|
||||||
type: 'success',
|
type: 'success',
|
||||||
})
|
},
|
||||||
}
|
)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
const {raw, clean} = cleanError(e)
|
const {raw, clean} = cleanError(e)
|
||||||
toast.show(clean || raw || e, {
|
toast.show(clean || raw || e, {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [_, uri, cid, isBookmarked, bookmark, cleanError])
|
}
|
||||||
|
|
||||||
|
const remove = async ({disableUndo}: {disableUndo?: boolean} = {}) => {
|
||||||
|
try {
|
||||||
|
await bookmark({
|
||||||
|
action: 'delete',
|
||||||
|
uri,
|
||||||
|
})
|
||||||
|
|
||||||
|
toast.show(
|
||||||
|
<toast.Outer>
|
||||||
|
<toast.Icon icon={TrashIcon} />
|
||||||
|
<toast.Text>
|
||||||
|
<Trans>Removed from saved posts</Trans>
|
||||||
|
</toast.Text>
|
||||||
|
{!disableUndo && (
|
||||||
|
<toast.Action
|
||||||
|
label={undoLabel}
|
||||||
|
onPress={() => save({disableUndo: true})}>
|
||||||
|
{undoLabel}
|
||||||
|
</toast.Action>
|
||||||
|
)}
|
||||||
|
</toast.Outer>,
|
||||||
|
)
|
||||||
|
} 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 (
|
return (
|
||||||
<PostControlButton
|
<PostControlButton
|
||||||
|
|||||||
@@ -216,17 +216,20 @@ function BookmarkNotFound({
|
|||||||
const cleanError = useCleanError()
|
const cleanError = useCleanError()
|
||||||
const [removed, setRemoved] = useState(false)
|
const [removed, setRemoved] = useState(false)
|
||||||
|
|
||||||
const remove = useCallback(async () => {
|
const remove = async () => {
|
||||||
try {
|
try {
|
||||||
setRemoved(true)
|
setRemoved(true)
|
||||||
await bookmark({action: 'delete', uri: post.uri})
|
await bookmark({action: 'delete', uri: post.uri})
|
||||||
|
toast.show(_(msg`Removed from saved posts`), {
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
const {raw, clean} = cleanError(e)
|
const {raw, clean} = cleanError(e)
|
||||||
toast.show(clean || raw || e, {
|
toast.show(clean || raw || e, {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [post.uri, bookmark, cleanError])
|
}
|
||||||
|
|
||||||
if (removed) return null
|
if (removed) return null
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user