"use client";
import { useContext, useState } from "react";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useToast } from "@/components/ui/use-toast";
import { useClientConfig } from "@/lib/clientConfig";
import { BookmarkListContext } from "@/lib/hooks/list-context";
import { api } from "@/lib/trpc";
import {
Archive,
Link,
List,
ListX,
MoreHorizontal,
Pencil,
RotateCw,
Star,
Tags,
Trash2,
} from "lucide-react";
import type { ZBookmark, ZBookmarkedLink } from "@hoarder/trpc/types/bookmarks";
import { useAddToListModal } from "./AddToListModal";
import { BookmarkedTextEditor } from "./BookmarkedTextEditor";
import { useTagModel } from "./TagModal";
export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) {
const { toast } = useToast();
const linkId = bookmark.id;
const demoMode = !!useClientConfig().demoMode;
const { setOpen: setTagModalIsOpen, content: tagModal } =
useTagModel(bookmark);
const { setOpen: setAddToListModalOpen, content: addToListModal } =
useAddToListModal(bookmark.id);
const [isTextEditorOpen, setTextEditorOpen] = useState(false);
const { listId } = useContext(BookmarkListContext);
const invalidateAllBookmarksCache =
api.useUtils().bookmarks.getBookmarks.invalidate;
const invalidateBookmarkCache =
api.useUtils().bookmarks.getBookmark.invalidate;
const invalidateSearchCache =
api.useUtils().bookmarks.searchBookmarks.invalidate;
const onError = () => {
toast({
variant: "destructive",
title: "Something went wrong",
description: "There was a problem with your request.",
});
};
const deleteBookmarkMutator = api.bookmarks.deleteBookmark.useMutation({
onSuccess: () => {
toast({
description: "The bookmark has been deleted!",
});
},
onError,
onSettled: () => {
invalidateAllBookmarksCache();
invalidateSearchCache();
},
});
const updateBookmarkMutator = api.bookmarks.updateBookmark.useMutation({
onSuccess: () => {
toast({
description: "The bookmark has been updated!",
});
},
onError,
onSettled: () => {
invalidateBookmarkCache({ bookmarkId: bookmark.id });
invalidateAllBookmarksCache();
invalidateSearchCache();
},
});
const crawlBookmarkMutator = api.bookmarks.recrawlBookmark.useMutation({
onSuccess: () => {
toast({
description: "Re-fetch has been enqueued!",
});
},
onError,
onSettled: () => {
invalidateBookmarkCache({ bookmarkId: bookmark.id });
},
});
const removeFromListMutator = api.lists.removeFromList.useMutation({
onSuccess: (_resp, req) => {
invalidateAllBookmarksCache({ listId: req.listId });
toast({
description: "The bookmark has been deleted from the list",
});
},
onError,
});
return (
<>
{tagModal}
{addToListModal}
{bookmark.content.type === "text" && (
setTextEditorOpen(true)}>
Edit
)}
updateBookmarkMutator.mutate({
bookmarkId: linkId,
favourited: !bookmark.favourited,
})
}
>
{bookmark.favourited ? "Un-favourite" : "Favourite"}
updateBookmarkMutator.mutate({
bookmarkId: linkId,
archived: !bookmark.archived,
})
}
>
{bookmark.archived ? "Un-archive" : "Archive"}
{bookmark.content.type === "link" && (
{
navigator.clipboard.writeText(
(bookmark.content as ZBookmarkedLink).url,
);
toast({
description: "Link was added to your clipboard!",
});
}}
>
Copy Link
)}
setTagModalIsOpen(true)}>
Edit Tags
setAddToListModalOpen(true)}>
Add to List
{listId && (
removeFromListMutator.mutate({
listId,
bookmarkId: bookmark.id,
})
}
>
Remove from List
)}
{bookmark.content.type === "link" && (
crawlBookmarkMutator.mutate({ bookmarkId: bookmark.id })
}
>
Refresh
)}
deleteBookmarkMutator.mutate({ bookmarkId: bookmark.id })
}
>
Delete
>
);
}