mirror of
https://github.com/priyanshujain/margin.git
synced 2026-10-02 19:17:03 +00:00
feat(ui): back-to-library, export-only download button, save in book setup
This commit is contained in:
1 parent
686c7768c7
commit
e9669290ec
3 files changed
+30
-13
No files matched your search
@@ -25,6 +25,7 @@ function PdfDock() {
|
|||||||
const timer = useRef<ReturnType<typeof setTimeout>>(undefined);
|
const timer = useRef<ReturnType<typeof setTimeout>>(undefined);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!book) return;
|
||||||
clearTimeout(timer.current);
|
clearTimeout(timer.current);
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
timer.current = setTimeout(() => {
|
timer.current = setTimeout(() => {
|
||||||
@@ -44,7 +45,7 @@ function PdfDock() {
|
|||||||
<section className="dock">
|
<section className="dock">
|
||||||
<div className="dock-head">
|
<div className="dock-head">
|
||||||
<span className="label">Preview</span>
|
<span className="label">Preview</span>
|
||||||
<span className="meta">{busy ? "updating…" : TRIM_LABEL[book.settings.trim]}</span>
|
<span className="meta">{busy ? "updating…" : TRIM_LABEL[book?.settings.trim ?? "6x9"]}</span>
|
||||||
</div>
|
</div>
|
||||||
{error ? (
|
{error ? (
|
||||||
<pre className="dock-error">{error}</pre>
|
<pre className="dock-error">{error}</pre>
|
||||||
@@ -58,19 +59,21 @@ function PdfDock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function HtmlDock() {
|
function HtmlDock() {
|
||||||
const chapters = useBook((s) => s.book.chapters);
|
const book = useBook((s) => s.book);
|
||||||
const trim = useBook((s) => s.book.settings.trim);
|
|
||||||
const activeChapterId = useBook((s) => s.activeChapterId);
|
const activeChapterId = useBook((s) => s.activeChapterId);
|
||||||
|
const chapters = book?.chapters ?? [];
|
||||||
const idx = chapters.findIndex((c) => c.id === activeChapterId);
|
const idx = chapters.findIndex((c) => c.id === activeChapterId);
|
||||||
const chapter = chapters[idx];
|
const chapter = chapters[idx] ?? chapters[0];
|
||||||
const html = useMemo(() => generateHTML(chapter.content, editorExtensions), [chapter.content]);
|
const html = useMemo(() => (chapter ? generateHTML(chapter.content, editorExtensions) : ""), [chapter]);
|
||||||
|
|
||||||
|
if (!book || !chapter) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="dock">
|
<section className="dock">
|
||||||
<div className="dock-head">
|
<div className="dock-head">
|
||||||
<span className="label">Preview</span>
|
<span className="label">Preview</span>
|
||||||
<span className="meta">
|
<span className="meta">
|
||||||
{TRIM_LABEL[trim]} · {idx + 1} of {chapters.length}
|
{TRIM_LABEL[book.settings.trim]} · {idx + 1} of {chapters.length}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="page">
|
<div className="page">
|
||||||
|
|||||||
@@ -28,12 +28,14 @@ function Field({ label, children }: { label: string; children: ReactNode }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Settings({ onClose }: { onClose: () => void }) {
|
export function Settings({ onClose, onSave }: { onClose: () => void; onSave: () => void }) {
|
||||||
const metadata = useBook((s) => s.book.metadata);
|
const book = useBook((s) => s.book);
|
||||||
const settings = useBook((s) => s.book.settings);
|
|
||||||
const setMetadata = useBook((s) => s.setMetadata);
|
const setMetadata = useBook((s) => s.setMetadata);
|
||||||
const setSettings = useBook((s) => s.setSettings);
|
const setSettings = useBook((s) => s.setSettings);
|
||||||
|
|
||||||
|
if (!book) return null;
|
||||||
|
const { metadata, settings } = book;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="overlay" onClick={onClose}>
|
<div className="overlay" onClick={onClose}>
|
||||||
<div className="panel" onClick={(e) => e.stopPropagation()}>
|
<div className="panel" onClick={(e) => e.stopPropagation()}>
|
||||||
@@ -81,6 +83,17 @@ export function Settings({ onClose }: { onClose: () => void }) {
|
|||||||
Add bleed for full-page images (print)
|
Add bleed for full-page images (print)
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="panel-foot">
|
||||||
|
<button
|
||||||
|
className="btn-primary"
|
||||||
|
onClick={() => {
|
||||||
|
onSave();
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,17 +2,18 @@ import { useBook } from "../store/useBook";
|
|||||||
import { Icon } from "./Icon";
|
import { Icon } from "./Icon";
|
||||||
|
|
||||||
export function Sidebar() {
|
export function Sidebar() {
|
||||||
const chapters = useBook((s) => s.book.chapters);
|
const chapters = useBook((s) => s.book?.chapters ?? []);
|
||||||
const activeChapterId = useBook((s) => s.activeChapterId);
|
const activeChapterId = useBook((s) => s.activeChapterId);
|
||||||
const setActiveChapter = useBook((s) => s.setActiveChapter);
|
const setActiveChapter = useBook((s) => s.setActiveChapter);
|
||||||
const addChapter = useBook((s) => s.addChapter);
|
const addChapter = useBook((s) => s.addChapter);
|
||||||
|
const closeBook = useBook((s) => s.closeBook);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className="sidebar">
|
<aside className="sidebar">
|
||||||
<div className="brand">
|
<button className="brand" onClick={closeBook} title="Back to library">
|
||||||
|
<Icon d="M14 7l-5 5 5 5" size={15} />
|
||||||
<span className="mark">margin</span>
|
<span className="mark">margin</span>
|
||||||
<span className="dot" />
|
</button>
|
||||||
</div>
|
|
||||||
<div className="nav-label">Chapters</div>
|
<div className="nav-label">Chapters</div>
|
||||||
<ul className="chapters">
|
<ul className="chapters">
|
||||||
{chapters.map((chapter, i) => (
|
{chapters.map((chapter, i) => (
|
||||||
|
|||||||
Reference in new issue
Block a user