Archived
84 lines
2.9 KiB
TypeScript
84 lines
2.9 KiB
TypeScript
import { useEffect } from "react";
|
||
import { useTranslation } from "react-i18n-lite";
|
||
import { useAnnotations } from "@/context/AnnotationsContext";
|
||
import type { MarkerEntry } from "@/types";
|
||
import {
|
||
CollapsibleMarkerPassage,
|
||
CollapsibleMarkerThought,
|
||
} from "@/components/annotations/CollapsibleMarkerText";
|
||
import { MarkerPassageActions } from "@/components/annotations/MarkerPassageActions";
|
||
|
||
interface BookMarkersPanelProps {
|
||
ebookId: number;
|
||
isOpen: boolean;
|
||
onClose: () => void;
|
||
onGoToPassage: (marker: MarkerEntry) => void;
|
||
emptyHintKey?: string;
|
||
}
|
||
|
||
export function BookMarkersPanel({
|
||
ebookId,
|
||
isOpen,
|
||
onClose,
|
||
onGoToPassage,
|
||
emptyHintKey = "annotations.selectTextHint",
|
||
}: BookMarkersPanelProps) {
|
||
const { t } = useTranslation();
|
||
const { markers, loadBookmarks, removeBookmark, state } = useAnnotations();
|
||
|
||
useEffect(() => {
|
||
if (isOpen) void loadBookmarks(ebookId);
|
||
}, [isOpen, ebookId, loadBookmarks]);
|
||
|
||
if (!isOpen) return null;
|
||
|
||
return (
|
||
<>
|
||
<div className="reader-panel-backdrop" onClick={onClose} aria-hidden />
|
||
<aside className="reader-side-panel reader-markers-panel" role="dialog" aria-label={t("annotations.inBookPanel")}>
|
||
<header className="reader-panel-header">
|
||
<h2>{t("annotations.inBookPanel")}</h2>
|
||
<button type="button" className="reader-panel-close" onClick={onClose} aria-label={t("annotations.close")}>
|
||
×
|
||
</button>
|
||
</header>
|
||
<div className="reader-panel-body">
|
||
{state.bookmarksLoading ? (
|
||
<p className="annotations-loading">{t("annotations.loading")}</p>
|
||
) : markers.length === 0 ? (
|
||
<p className="annotations-empty">{t(emptyHintKey)}</p>
|
||
) : (
|
||
<ul className="marker-thread-list">
|
||
{markers.map((m) => (
|
||
<li key={m.id} className="marker-thread">
|
||
{m.chapter_title && (
|
||
<span className="marker-thread-chapter">{m.chapter_title}</span>
|
||
)}
|
||
{m.location_text ? (
|
||
<CollapsibleMarkerPassage
|
||
text={m.location_text}
|
||
highlightColor={m.highlight_color}
|
||
className="annotation-quote"
|
||
/>
|
||
) : m.chapter_title ? (
|
||
<span className="annotation-quote marker-page-label">{m.chapter_title}</span>
|
||
) : null}
|
||
{m.content ? (
|
||
<CollapsibleMarkerThought text={m.content} />
|
||
) : (
|
||
<span className="annotation-kind-badge bookmark-badge">{t("annotations.bookmarkOnly")}</span>
|
||
)}
|
||
<MarkerPassageActions
|
||
onGoToPassage={() => onGoToPassage(m)}
|
||
onDelete={() => removeBookmark(m.id)}
|
||
/>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
)}
|
||
</div>
|
||
</aside>
|
||
</>
|
||
);
|
||
}
|