aboutsummaryrefslogtreecommitdiffstats
path: root/packages/shared-react
diff options
context:
space:
mode:
Diffstat (limited to 'packages/shared-react')
-rw-r--r--packages/shared-react/hooks/bookmark-grid-context.tsx27
-rw-r--r--packages/shared-react/hooks/bookmarks.ts91
-rw-r--r--packages/shared-react/hooks/lists.ts15
3 files changed, 129 insertions, 4 deletions
diff --git a/packages/shared-react/hooks/bookmark-grid-context.tsx b/packages/shared-react/hooks/bookmark-grid-context.tsx
new file mode 100644
index 00000000..5814da12
--- /dev/null
+++ b/packages/shared-react/hooks/bookmark-grid-context.tsx
@@ -0,0 +1,27 @@
+"use client";
+
+import { createContext, useContext } from "react";
+
+import type { ZGetBookmarksRequest } from "@hoarder/trpc/types/bookmarks";
+
+export const BookmarkGridContext = createContext<
+ ZGetBookmarksRequest | undefined
+>(undefined);
+
+export function BookmarkGridContextProvider({
+ query,
+ children,
+}: {
+ query: ZGetBookmarksRequest;
+ children: React.ReactNode;
+}) {
+ return (
+ <BookmarkGridContext.Provider value={query}>
+ {children}
+ </BookmarkGridContext.Provider>
+ );
+}
+
+export function useBookmarkGridContext() {
+ return useContext(BookmarkGridContext);
+}
diff --git a/packages/shared-react/hooks/bookmarks.ts b/packages/shared-react/hooks/bookmarks.ts
index 7349e680..5f246b38 100644
--- a/packages/shared-react/hooks/bookmarks.ts
+++ b/packages/shared-react/hooks/bookmarks.ts
@@ -1,4 +1,22 @@
import { api } from "../trpc";
+import { useBookmarkGridContext } from "./bookmark-grid-context";
+import { useAddBookmarkToList } from "./lists";
+
+export function useCreateBookmarkWithPostHook(
+ ...opts: Parameters<typeof api.bookmarks.createBookmark.useMutation>
+) {
+ const apiUtils = api.useUtils();
+ const postCreationCB = useBookmarkPostCreationHook();
+ return api.bookmarks.createBookmark.useMutation({
+ ...opts,
+ onSuccess: async (res, req, meta) => {
+ apiUtils.bookmarks.getBookmarks.invalidate();
+ apiUtils.bookmarks.searchBookmarks.invalidate();
+ await postCreationCB(res.id);
+ return opts[0]?.onSuccess?.(res, req, meta);
+ },
+ });
+}
export function useDeleteBookmark(
...opts: Parameters<typeof api.bookmarks.deleteBookmark.useMutation>
@@ -9,7 +27,7 @@ export function useDeleteBookmark(
onSuccess: (res, req, meta) => {
apiUtils.bookmarks.getBookmarks.invalidate();
apiUtils.bookmarks.searchBookmarks.invalidate();
- opts[0]?.onSuccess?.(res, req, meta);
+ return opts[0]?.onSuccess?.(res, req, meta);
},
});
}
@@ -24,7 +42,7 @@ export function useUpdateBookmark(
apiUtils.bookmarks.getBookmarks.invalidate();
apiUtils.bookmarks.searchBookmarks.invalidate();
apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: req.bookmarkId });
- opts[0]?.onSuccess?.(res, req, meta);
+ return opts[0]?.onSuccess?.(res, req, meta);
},
});
}
@@ -37,7 +55,74 @@ export function useRecrawlBookmark(
...opts,
onSuccess: (res, req, meta) => {
apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: req.bookmarkId });
- opts[0]?.onSuccess?.(res, req, meta);
+ return opts[0]?.onSuccess?.(res, req, meta);
+ },
+ });
+}
+
+export function useUpdateBookmarkTags(
+ ...opts: Parameters<typeof api.bookmarks.updateTags.useMutation>
+) {
+ const apiUtils = api.useUtils();
+ return api.bookmarks.updateTags.useMutation({
+ ...opts,
+ onSuccess: (res, req, meta) => {
+ apiUtils.bookmarks.getBookmark.invalidate({ bookmarkId: req.bookmarkId });
+
+ [...res.attached, ...res.detached].forEach((id) => {
+ apiUtils.tags.get.invalidate({ tagId: id });
+ apiUtils.bookmarks.getBookmarks.invalidate({ tagId: id });
+ });
+ apiUtils.tags.list.invalidate();
+ return opts[0]?.onSuccess?.(res, req, meta);
},
});
}
+
+/**
+ * Checks the grid query context to know if we need to augment the bookmark post creation to fit the grid context
+ */
+export function useBookmarkPostCreationHook() {
+ const gridQueryCtx = useBookmarkGridContext();
+ const { mutateAsync: updateBookmark } = useUpdateBookmark();
+ const { mutateAsync: addToList } = useAddBookmarkToList();
+ const { mutateAsync: updateTags } = useUpdateBookmarkTags();
+
+ return async (bookmarkId: string) => {
+ if (!gridQueryCtx) {
+ return;
+ }
+
+ const promises = [];
+ if (gridQueryCtx.favourited ?? gridQueryCtx.archived) {
+ promises.push(
+ updateBookmark({
+ bookmarkId,
+ favourited: gridQueryCtx.favourited,
+ archived: gridQueryCtx.archived,
+ }),
+ );
+ }
+
+ if (gridQueryCtx.listId) {
+ promises.push(
+ addToList({
+ bookmarkId,
+ listId: gridQueryCtx.listId,
+ }),
+ );
+ }
+
+ if (gridQueryCtx.tagId) {
+ promises.push(
+ updateTags({
+ bookmarkId,
+ attach: [{ tagId: gridQueryCtx.tagId }],
+ detach: [],
+ }),
+ );
+ }
+
+ return Promise.all(promises);
+ };
+}
diff --git a/packages/shared-react/hooks/lists.ts b/packages/shared-react/hooks/lists.ts
index 5cfcd194..f4b19c3c 100644
--- a/packages/shared-react/hooks/lists.ts
+++ b/packages/shared-react/hooks/lists.ts
@@ -1,5 +1,18 @@
import { api } from "../trpc";
+export function useAddBookmarkToList(
+ ...opts: Parameters<typeof api.lists.removeFromList.useMutation>
+) {
+ const apiUtils = api.useUtils();
+ return api.lists.addToList.useMutation({
+ ...opts,
+ onSuccess: (res, req, meta) => {
+ apiUtils.bookmarks.getBookmarks.invalidate({ listId: req.listId });
+ return opts[0]?.onSuccess?.(res, req, meta);
+ },
+ });
+}
+
export function useRemoveBookmarkFromList(
...opts: Parameters<typeof api.lists.removeFromList.useMutation>
) {
@@ -8,7 +21,7 @@ export function useRemoveBookmarkFromList(
...opts,
onSuccess: (res, req, meta) => {
apiUtils.bookmarks.getBookmarks.invalidate({ listId: req.listId });
- opts[0]?.onSuccess?.(res, req, meta);
+ return opts[0]?.onSuccess?.(res, req, meta);
},
});
}