import React from "react";
import { ActionButton } from "@/components/ui/action-button";
import { MarkdownReadonly } from "@/components/ui/markdown/markdown-readonly";
import LoadingSpinner from "@/components/ui/spinner";
import { toast } from "@/components/ui/use-toast";
import { useClientConfig } from "@/lib/clientConfig";
import { useTranslation } from "@/lib/i18n/client";
import { cn } from "@/lib/utils";
import { ChevronUp, RefreshCw, Sparkles, Trash2 } from "lucide-react";
import {
useSummarizeBookmark,
useUpdateBookmark,
} from "@karakeep/shared-react/hooks/bookmarks";
import { BookmarkTypes, ZBookmark } from "@karakeep/shared/types/bookmarks";
function AISummary({
bookmarkId,
summary,
readOnly = false,
}: {
bookmarkId: string;
summary: string;
readOnly?: boolean;
}) {
const [isExpanded, setIsExpanded] = React.useState(false);
const { mutate: resummarize, isPending: isResummarizing } =
useSummarizeBookmark({
onError: () => {
toast({
description: "Something went wrong",
variant: "destructive",
});
},
});
const { mutate: updateBookmark, isPending: isUpdatingBookmark } =
useUpdateBookmark({
onError: () => {
toast({
description: "Something went wrong",
variant: "destructive",
});
},
});
return (
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
!isExpanded && setIsExpanded(true)}
>
{summary}
{isExpanded && (
{!readOnly && (
<>
}
className="rounded-full bg-gray-200 p-1 text-gray-600 dark:bg-gray-700 dark:text-gray-400"
aria-label={isExpanded ? "Collapse" : "Expand"}
loading={isResummarizing}
onClick={() => resummarize({ bookmarkId })}
>
}
className="rounded-full bg-gray-200 p-1 text-gray-600 dark:bg-gray-700 dark:text-gray-400"
aria-label={isExpanded ? "Collapse" : "Expand"}
loading={isUpdatingBookmark}
onClick={() =>
updateBookmark({ bookmarkId, summary: null })
}
>
>
)}
)}
);
}
export default function SummarizeBookmarkArea({
bookmark,
readOnly = false,
}: {
bookmark: ZBookmark;
readOnly?: boolean;
}) {
const { t } = useTranslation();
const { mutate, isPending } = useSummarizeBookmark({
onError: () => {
toast({
description: "Something went wrong",
variant: "destructive",
});
},
});
const clientConfig = useClientConfig();
if (bookmark.content.type !== BookmarkTypes.LINK) {
return null;
}
if (bookmark.summary) {
return (
);
} else if (!clientConfig.inference.isConfigured || readOnly) {
return null;
} else {
return (
mutate({ bookmarkId: bookmark.id })}
className={cn(
`relative w-full overflow-hidden bg-opacity-30 bg-gradient-to-r from-blue-400 via-purple-500 to-pink-500 text-gray-50 transition-all duration-300`,
)}
loading={isPending}
>
{isPending && (
)}
{t("actions.summarize_with_ai")}
);
}
}