mirror of
https://github.com/priyanshujain/margin.git
synced 2026-10-02 19:17:03 +00:00
refactor(store): nullable open book with open/close for library nav
This commit is contained in:
1 parent
4896e10aba
commit
a6404847d1
1 file changed
+26
-37
+26
-37
@@ -1,61 +1,50 @@
|
||||
import { create } from "zustand";
|
||||
import type { JSONContent } from "@tiptap/core";
|
||||
import { type Book, type BookMetadata, type BookSettings, createChapter, starterBook } from "../model/book";
|
||||
import { type Book, type BookMetadata, type BookSettings, createChapter } from "../model/book";
|
||||
|
||||
interface BookState {
|
||||
book: Book;
|
||||
book: Book | null;
|
||||
activeChapterId: string;
|
||||
path: string | null;
|
||||
dirty: boolean;
|
||||
openBook: (book: Book) => void;
|
||||
closeBook: () => void;
|
||||
setActiveChapter: (id: string) => void;
|
||||
setChapterContent: (id: string, content: JSONContent) => void;
|
||||
setChapterTitle: (id: string, title: string) => void;
|
||||
addChapter: () => void;
|
||||
setMetadata: (patch: Partial<BookMetadata>) => void;
|
||||
setSettings: (patch: Partial<BookSettings>) => void;
|
||||
replaceBook: (book: Book, path: string) => void;
|
||||
markSaved: (path: string) => void;
|
||||
markSaved: () => void;
|
||||
}
|
||||
|
||||
export const useBook = create<BookState>((set) => {
|
||||
const book = starterBook();
|
||||
return {
|
||||
book,
|
||||
activeChapterId: book.chapters[0].id,
|
||||
path: null,
|
||||
export const useBook = create<BookState>((set) => ({
|
||||
book: null,
|
||||
activeChapterId: "",
|
||||
dirty: false,
|
||||
openBook: (book) => set({ book, activeChapterId: book.chapters[0]?.id ?? "", dirty: false }),
|
||||
closeBook: () => set({ book: null, activeChapterId: "", dirty: false }),
|
||||
setActiveChapter: (id) => set({ activeChapterId: id }),
|
||||
setChapterContent: (id, content) =>
|
||||
set((s) => ({
|
||||
dirty: true,
|
||||
book: {
|
||||
...s.book,
|
||||
chapters: s.book.chapters.map((c) => (c.id === id ? { ...c, content } : c)),
|
||||
},
|
||||
})),
|
||||
set((s) =>
|
||||
s.book
|
||||
? { dirty: true, book: { ...s.book, chapters: s.book.chapters.map((c) => (c.id === id ? { ...c, content } : c)) } }
|
||||
: {}
|
||||
),
|
||||
setChapterTitle: (id, title) =>
|
||||
set((s) => ({
|
||||
dirty: true,
|
||||
book: {
|
||||
...s.book,
|
||||
chapters: s.book.chapters.map((c) => (c.id === id ? { ...c, title } : c)),
|
||||
},
|
||||
})),
|
||||
set((s) =>
|
||||
s.book
|
||||
? { dirty: true, book: { ...s.book, chapters: s.book.chapters.map((c) => (c.id === id ? { ...c, title } : c)) } }
|
||||
: {}
|
||||
),
|
||||
addChapter: () =>
|
||||
set((s) => {
|
||||
if (!s.book) return {};
|
||||
const chapter = createChapter();
|
||||
return {
|
||||
activeChapterId: chapter.id,
|
||||
dirty: true,
|
||||
book: { ...s.book, chapters: [...s.book.chapters, chapter] },
|
||||
};
|
||||
return { activeChapterId: chapter.id, dirty: true, book: { ...s.book, chapters: [...s.book.chapters, chapter] } };
|
||||
}),
|
||||
setMetadata: (patch) =>
|
||||
set((s) => ({ dirty: true, book: { ...s.book, metadata: { ...s.book.metadata, ...patch } } })),
|
||||
set((s) => (s.book ? { dirty: true, book: { ...s.book, metadata: { ...s.book.metadata, ...patch } } } : {})),
|
||||
setSettings: (patch) =>
|
||||
set((s) => ({ dirty: true, book: { ...s.book, settings: { ...s.book.settings, ...patch } } })),
|
||||
replaceBook: (book, path) =>
|
||||
set({ book, activeChapterId: book.chapters[0]?.id ?? "", path, dirty: false }),
|
||||
markSaved: (path) => set({ path, dirty: false }),
|
||||
};
|
||||
});
|
||||
set((s) => (s.book ? { dirty: true, book: { ...s.book, settings: { ...s.book.settings, ...patch } } } : {})),
|
||||
markSaved: () => set({ dirty: false }),
|
||||
}));
|
||||
Reference in new issue
Block a user