diff options
Diffstat (limited to 'apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx')
| -rw-r--r-- | apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx | 267 |
1 files changed, 149 insertions, 118 deletions
diff --git a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx index 4725c77f..66de6156 100644 --- a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx +++ b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx @@ -22,6 +22,7 @@ import { SquarePen, Trash2, } from "lucide-react"; +import { useSession } from "next-auth/react"; import type { ZBookmark, @@ -46,9 +47,13 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) { const { t } = useTranslation(); const { toast } = useToast(); const linkId = bookmark.id; + const { data: session } = useSession(); const demoMode = !!useClientConfig().demoMode; + // Check if the current user owns this bookmark + const isOwner = session?.user?.id === bookmark.userId; + const [isClipboardAvailable, setIsClipboardAvailable] = useState(false); useEffect(() => { @@ -114,6 +119,142 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) { onError, }); + // Define action items array + const actionItems = [ + { + id: "edit", + title: t("actions.edit"), + icon: <Pencil className="mr-2 size-4" />, + visible: isOwner, + disabled: false, + onClick: () => setEditBookmarkDialogOpen(true), + }, + { + id: "open-editor", + title: t("actions.open_editor"), + icon: <SquarePen className="mr-2 size-4" />, + visible: isOwner && bookmark.content.type === BookmarkTypes.TEXT, + disabled: false, + onClick: () => setTextEditorOpen(true), + }, + { + id: "favorite", + title: bookmark.favourited + ? t("actions.unfavorite") + : t("actions.favorite"), + icon: ( + <FavouritedActionIcon + className="mr-2 size-4" + favourited={bookmark.favourited} + /> + ), + visible: isOwner, + disabled: demoMode, + onClick: () => + updateBookmarkMutator.mutate({ + bookmarkId: linkId, + favourited: !bookmark.favourited, + }), + }, + { + id: "archive", + title: bookmark.archived ? t("actions.unarchive") : t("actions.archive"), + icon: ( + <ArchivedActionIcon + className="mr-2 size-4" + archived={bookmark.archived} + /> + ), + visible: isOwner, + disabled: demoMode, + onClick: () => + updateBookmarkMutator.mutate({ + bookmarkId: linkId, + archived: !bookmark.archived, + }), + }, + { + id: "download-full-page", + title: t("actions.download_full_page_archive"), + icon: <FileDown className="mr-2 size-4" />, + visible: isOwner && bookmark.content.type === BookmarkTypes.LINK, + disabled: false, + onClick: () => { + fullPageArchiveBookmarkMutator.mutate({ + bookmarkId: bookmark.id, + archiveFullPage: true, + }); + }, + }, + { + id: "copy-link", + title: t("actions.copy_link"), + icon: <Link className="mr-2 size-4" />, + visible: bookmark.content.type === BookmarkTypes.LINK, + disabled: !isClipboardAvailable, + onClick: () => { + navigator.clipboard.writeText( + (bookmark.content as ZBookmarkedLink).url, + ); + toast({ + description: t("toasts.bookmarks.clipboard_copied"), + }); + }, + }, + { + id: "manage-lists", + title: t("actions.manage_lists"), + icon: <List className="mr-2 size-4" />, + visible: isOwner, + disabled: false, + onClick: () => setManageListsModalOpen(true), + }, + { + id: "remove-from-list", + title: t("actions.remove_from_list"), + icon: <ListX className="mr-2 size-4" />, + visible: + (isOwner || + (withinListContext && + (withinListContext.userRole === "editor" || + withinListContext.userRole === "owner"))) && + !!listId && + !!withinListContext && + withinListContext.type === "manual", + disabled: demoMode, + onClick: () => + removeFromListMutator.mutate({ + listId: listId!, + bookmarkId: bookmark.id, + }), + }, + { + id: "refresh", + title: t("actions.refresh"), + icon: <RotateCw className="mr-2 size-4" />, + visible: isOwner && bookmark.content.type === BookmarkTypes.LINK, + disabled: demoMode, + onClick: () => crawlBookmarkMutator.mutate({ bookmarkId: bookmark.id }), + }, + { + id: "delete", + title: t("actions.delete"), + icon: <Trash2 className="mr-2 size-4" />, + visible: isOwner, + disabled: demoMode, + className: "text-destructive", + onClick: () => setDeleteBookmarkDialogOpen(true), + }, + ]; + + // Filter visible items + const visibleItems = actionItems.filter((item) => item.visible); + + // If no items are visible, don't render the dropdown + if (visibleItems.length === 0) { + return null; + } + return ( <> {manageListsModal} @@ -142,127 +283,17 @@ export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) { </Button> </DropdownMenuTrigger> <DropdownMenuContent className="w-fit"> - <DropdownMenuItem onClick={() => setEditBookmarkDialogOpen(true)}> - <Pencil className="mr-2 size-4" /> - <span>{t("actions.edit")}</span> - </DropdownMenuItem> - {bookmark.content.type === BookmarkTypes.TEXT && ( - <DropdownMenuItem onClick={() => setTextEditorOpen(true)}> - <SquarePen className="mr-2 size-4" /> - <span>{t("actions.open_editor")}</span> - </DropdownMenuItem> - )} - <DropdownMenuItem - disabled={demoMode} - onClick={() => - updateBookmarkMutator.mutate({ - bookmarkId: linkId, - favourited: !bookmark.favourited, - }) - } - > - <FavouritedActionIcon - className="mr-2 size-4" - favourited={bookmark.favourited} - /> - <span> - {bookmark.favourited - ? t("actions.unfavorite") - : t("actions.favorite")} - </span> - </DropdownMenuItem> - <DropdownMenuItem - disabled={demoMode} - onClick={() => - updateBookmarkMutator.mutate({ - bookmarkId: linkId, - archived: !bookmark.archived, - }) - } - > - <ArchivedActionIcon - className="mr-2 size-4" - archived={bookmark.archived} - /> - <span> - {bookmark.archived - ? t("actions.unarchive") - : t("actions.archive")} - </span> - </DropdownMenuItem> - - {bookmark.content.type === BookmarkTypes.LINK && ( - <DropdownMenuItem - onClick={() => { - fullPageArchiveBookmarkMutator.mutate({ - bookmarkId: bookmark.id, - archiveFullPage: true, - }); - }} - > - <FileDown className="mr-2 size-4" /> - <span>{t("actions.download_full_page_archive")}</span> - </DropdownMenuItem> - )} - - {bookmark.content.type === BookmarkTypes.LINK && ( + {visibleItems.map((item) => ( <DropdownMenuItem - disabled={!isClipboardAvailable} - onClick={() => { - navigator.clipboard.writeText( - (bookmark.content as ZBookmarkedLink).url, - ); - toast({ - description: t("toasts.bookmarks.clipboard_copied"), - }); - }} + key={item.id} + disabled={item.disabled} + className={item.className} + onClick={item.onClick} > - <Link className="mr-2 size-4" /> - <span>{t("actions.copy_link")}</span> + {item.icon} + <span>{item.title}</span> </DropdownMenuItem> - )} - - <DropdownMenuItem onClick={() => setManageListsModalOpen(true)}> - <List className="mr-2 size-4" /> - <span>{t("actions.manage_lists")}</span> - </DropdownMenuItem> - - {listId && - withinListContext && - withinListContext.type === "manual" && ( - <DropdownMenuItem - disabled={demoMode} - onClick={() => - removeFromListMutator.mutate({ - listId, - bookmarkId: bookmark.id, - }) - } - > - <ListX className="mr-2 size-4" /> - <span>{t("actions.remove_from_list")}</span> - </DropdownMenuItem> - )} - - {bookmark.content.type === BookmarkTypes.LINK && ( - <DropdownMenuItem - disabled={demoMode} - onClick={() => - crawlBookmarkMutator.mutate({ bookmarkId: bookmark.id }) - } - > - <RotateCw className="mr-2 size-4" /> - <span>{t("actions.refresh")}</span> - </DropdownMenuItem> - )} - <DropdownMenuItem - disabled={demoMode} - className="text-destructive" - onClick={() => setDeleteBookmarkDialogOpen(true)} - > - <Trash2 className="mr-2 size-4" /> - <span>{t("actions.delete")}</span> - </DropdownMenuItem> + ))} </DropdownMenuContent> </DropdownMenu> </> |
