refactor: create useBookmark() hook, used for bookmark and undo a bookmark

This commit is contained in:
P. Reis 2024-12-13 11:20:57 -03:00
parent 4031de3f52
commit 9e49099003
2 changed files with 81 additions and 0 deletions

View File

@ -45,6 +45,7 @@ export { useUpdateGroupTag } from './groups/useUpdateGroupTag.ts';
// Statuses
export { useBookmarks } from './statuses/useBookmarks.ts';
export { useBookmark } from './statuses/useBookmark.ts';
// Streaming
export { useUserStream } from './streaming/useUserStream.ts';

View File

@ -0,0 +1,80 @@
import { importEntities } from 'soapbox/entity-store/actions.ts';
import { Entities } from 'soapbox/entity-store/entities.ts';
import { useTransaction } from 'soapbox/entity-store/hooks/index.ts';
import { useApi } from 'soapbox/hooks/useApi.ts';
import { useAppDispatch } from 'soapbox/hooks/useAppDispatch.ts';
import { useLoggedIn } from 'soapbox/hooks/useLoggedIn.ts';
import { statusSchema } from 'soapbox/schemas/index.ts';
/**
* Bookmark and undo a bookmark, with optimistic update.
*
* https://docs.joinmastodon.org/methods/statuses/#bookmark
* POST /api/v1/statuses/:id/bookmark
*
* https://docs.joinmastodon.org/methods/statuses/#unbookmark
* POST /api/v1/statuses/:id/unbookmark
*/
function useBookmark() {
const api = useApi();
const dispatch = useAppDispatch();
const { isLoggedIn } = useLoggedIn();
const { transaction } = useTransaction();
function bookmarkEffect(statusId: string) {
transaction({
Statuses: {
[statusId]: (status) => ({
...status,
bookmarked: true,
}),
},
});
}
function unbookmarkEffect(statusId: string) {
transaction({
Statuses: {
[statusId]: (status) => ({
...status,
bookmarked: false,
}),
},
});
}
async function bookmark(statusId: string) {
if (!isLoggedIn) return;
bookmarkEffect(statusId);
try {
const response = await api.post(`/api/v1/statuses/${statusId}/bookmark`);
const result = statusSchema.safeParse(await response.json());
if (result.success) {
dispatch(importEntities([result.data], Entities.STATUSES, 'bookmarks'));
}
} catch (e) {
unbookmarkEffect(statusId);
}
}
async function unbookmark(statusId: string) {
if (!isLoggedIn) return;
unbookmarkEffect(statusId);
try {
await api.post(`/api/v1/statuses/${statusId}/unbookmark`);
} catch (e) {
bookmarkEffect(statusId);
}
}
return {
bookmark,
unbookmark,
bookmarkEffect,
unbookmarkEffect,
};
}
export { useBookmark };