feat: add local OneNote and ONEPKG reader
This commit is contained in:
107
src/components/PageReader.tsx
Normal file
107
src/components/PageReader.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
import type { OneNotePageDto } from '../onenote/model/dto.js';
|
||||
|
||||
interface PageReaderProps {
|
||||
page?: OneNotePageDto;
|
||||
loading: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
function formatDate(value: string | undefined): string | null {
|
||||
if (!value) return null;
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) return value;
|
||||
return new Intl.DateTimeFormat(undefined, {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: 'short',
|
||||
}).format(date);
|
||||
}
|
||||
|
||||
export function PageReader({ page, loading, error }: PageReaderProps) {
|
||||
if (loading) {
|
||||
return (
|
||||
<section className="page-reader page-reader--empty" aria-live="polite">
|
||||
<p>Loading extracted page text…</p>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<section className="page-reader page-reader--error" role="alert">
|
||||
<p className="eyebrow">Page unavailable</p>
|
||||
<h2>Could not read this page</h2>
|
||||
<p>{error}</p>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
if (!page) {
|
||||
return (
|
||||
<section className="page-reader page-reader--empty">
|
||||
<p>Select a readable page to inspect its extracted text.</p>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const createdAt = formatDate(page.createdAt);
|
||||
const updatedAt = formatDate(page.updatedAt);
|
||||
|
||||
return (
|
||||
<article className="page-reader" aria-labelledby="selected-page-title">
|
||||
<header className="page-reader__header">
|
||||
<p className="eyebrow">Selected page</p>
|
||||
<h2 id="selected-page-title">{page.title || 'Untitled page'}</h2>
|
||||
{createdAt || updatedAt ? (
|
||||
<dl className="page-metadata">
|
||||
{createdAt ? (
|
||||
<>
|
||||
<dt>Created</dt>
|
||||
<dd>{createdAt}</dd>
|
||||
</>
|
||||
) : null}
|
||||
{updatedAt ? (
|
||||
<>
|
||||
<dt>Modified</dt>
|
||||
<dd>{updatedAt}</dd>
|
||||
</>
|
||||
) : null}
|
||||
</dl>
|
||||
) : null}
|
||||
</header>
|
||||
|
||||
<div className="page-content">
|
||||
{page.blocks.length === 0 && page.text.length === 0 ? (
|
||||
<p className="empty-message">No readable plain text was extracted.</p>
|
||||
) : page.blocks.length === 0 ? (
|
||||
<p className="extracted-text">{page.text}</p>
|
||||
) : (
|
||||
page.blocks.map((block, index) => {
|
||||
switch (block.kind) {
|
||||
case 'text':
|
||||
return (
|
||||
<p className="extracted-text" key={index}>
|
||||
{block.text}
|
||||
</p>
|
||||
);
|
||||
case 'line-break':
|
||||
return <br key={index} />;
|
||||
case 'link':
|
||||
return (
|
||||
<p className="extracted-text" key={index}>
|
||||
{block.text}
|
||||
</p>
|
||||
);
|
||||
case 'unsupported':
|
||||
return (
|
||||
<aside className="unsupported-block" key={index}>
|
||||
<strong>{block.sourceKind}</strong>
|
||||
<span>{block.description}</span>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user