MCPcopy
hub / github.com/Narcooo/inkos / ChapterReader

Function ChapterReader

packages/studio/src/pages/ChapterReader.tsx:34–266  ·  view source on GitHub ↗
({ bookId, chapterNumber, nav, theme, t }: {
  bookId: string;
  chapterNumber: number;
  nav: Nav;
  theme: Theme;
  t: TFunction;
})

Source from the content-addressed store, hash-verified

32}
33
34export function ChapterReader({ bookId, chapterNumber, nav, theme, t }: {
35 bookId: string;
36 chapterNumber: number;
37 nav: Nav;
38 theme: Theme;
39 t: TFunction;
40}) {
41 const c = useColors(theme);
42 const { data, loading, error, refetch } = useApi<ChapterData>(
43 `/books/${bookId}/chapters/${chapterNumber}`,
44 );
45 const [editing, setEditing] = useState(false);
46 const [editContent, setEditContent] = useState("");
47 const [saving, setSaving] = useState(false);
48
49 const handleStartEdit = () => {
50 if (!data) return;
51 setEditContent(data.content);
52 setEditing(true);
53 };
54
55 const handleCancelEdit = () => {
56 setEditing(false);
57 setEditContent("");
58 };
59
60 const handleSave = async () => {
61 setSaving(true);
62 try {
63 await fetchJson(`/books/${bookId}/chapters/${chapterNumber}`, {
64 method: "PUT",
65 headers: { "Content-Type": "application/json" },
66 body: JSON.stringify({ content: editContent }),
67 });
68 setEditing(false);
69 refetch();
70 } catch (e) {
71 alert(e instanceof Error ? e.message : "Save failed");
72 } finally {
73 setSaving(false);
74 }
75 };
76
77 if (loading) return (
78 <div className="flex flex-col items-center justify-center py-32 space-y-4">
79 <div className="w-8 h-8 border-2 border-primary/20 border-t-primary rounded-full animate-spin" />
80 <span className="text-sm text-muted-foreground">{t("reader.openingManuscript")}</span>
81 </div>
82 );
83
84 if (error) return <div className="text-destructive p-8 bg-destructive/5 rounded-xl border border-destructive/20">Error: {error}</div>;
85 if (!data) return null;
86
87 // Split markdown content into title and body
88 const lines = data.content.split("\n");
89 const titleLine = lines.find((l) => l.startsWith("# "));
90 const title = titleLine?.replace(/^#\s*/, "") ?? `Chapter ${chapterNumber}`;
91 const body = lines

Callers

nothing calls this directly

Calls 4

useColorsFunction · 0.90
useApiFunction · 0.90
tFunction · 0.85
replaceMethod · 0.80

Tested by

no test coverage detected