import Link from "next/link"; import { ActionButton } from "@/components/ui/action-button"; import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog"; import { Button } from "@/components/ui/button"; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@/components/ui/collapsible"; import FilePickerButton from "@/components/ui/file-picker-button"; import { toast } from "@/components/ui/use-toast"; import { ASSET_TYPE_TO_ICON } from "@/lib/attachments"; import useUpload from "@/lib/hooks/upload-file"; import { useTranslation } from "@/lib/i18n/client"; import { ChevronsDownUp, Download, Pencil, Plus, Trash2 } from "lucide-react"; import { useAttachBookmarkAsset, useDetachBookmarkAsset, useReplaceBookmarkAsset, } from "@karakeep/shared-react/hooks/assets"; import { BookmarkTypes, ZBookmark } from "@karakeep/shared/types/bookmarks"; import { getAssetUrl } from "@karakeep/shared/utils/assetUtils"; import { humanFriendlyNameForAssertType, isAllowedToAttachAsset, isAllowedToDetachAsset, } from "@karakeep/trpc/lib/attachments"; export default function AttachmentBox({ bookmark, readOnly = false, }: { bookmark: ZBookmark; readOnly?: boolean; }) { const { t } = useTranslation(); const { mutate: attachAsset, isPending: isAttaching } = useAttachBookmarkAsset({ onSuccess: () => { toast({ description: "Attachment has been attached!", }); }, onError: (e) => { toast({ description: e.message, variant: "destructive", }); }, }); const { mutate: replaceAsset, isPending: isReplacing } = useReplaceBookmarkAsset({ onSuccess: () => { toast({ description: "Attachment has been replaced!", }); }, onError: (e) => { toast({ description: e.message, variant: "destructive", }); }, }); const { mutate: detachAsset, isPending: isDetaching } = useDetachBookmarkAsset({ onSuccess: () => { toast({ description: "Attachment has been detached!", }); }, onError: (e) => { toast({ description: e.message, variant: "destructive", }); }, }); const { mutate: uploadAsset } = useUpload({ onError: (e) => { toast({ description: e.error, variant: "destructive", }); }, }); bookmark.assets.sort((a, b) => a.assetType.localeCompare(b.assetType)); return ( {t("common.attachments")} {bookmark.assets.map((asset) => (
{ASSET_TYPE_TO_ICON[asset.assetType]}

{asset.assetType === "userUploaded" && asset.fileName ? asset.fileName : humanFriendlyNameForAssertType(asset.assetType)}

{!readOnly && isAllowedToAttachAsset(asset.assetType) && asset.assetType !== "userUploaded" && ( uploadAsset(file, { onSuccess: (resp) => { replaceAsset({ bookmarkId: bookmark.id, oldAssetId: asset.id, newAssetId: resp.assetId, }); }, }) } > )} {!readOnly && isAllowedToDetachAsset(asset.assetType) && ( ( detachAsset( { bookmarkId: bookmark.id, assetId: asset.id }, { onSettled: () => setDialogOpen(false) }, ) } > Delete )} > )}
))} {!readOnly && !bookmark.assets.some((asset) => asset.assetType == "bannerImage") && bookmark.content.type != BookmarkTypes.ASSET && ( uploadAsset(file, { onSuccess: (resp) => { attachAsset({ bookmarkId: bookmark.id, asset: { id: resp.assetId, assetType: "bannerImage", }, }); }, }) } > Attach a Banner )} {!readOnly && ( uploadAsset(file, { onSuccess: (resp) => { attachAsset({ bookmarkId: bookmark.id, asset: { id: resp.assetId, assetType: "userUploaded", }, }); }, }) } > Upload File )}
); }