added chapter view, fixes, added ratings, added chapter updates/deletions

This commit is contained in:
lnn0q 2025-06-01 00:37:26 +03:00
parent 029b7e9353
commit 4801cf3a13
34 changed files with 1345 additions and 191 deletions

View file

@ -20,21 +20,25 @@ import {
} from '../types';
import { Prose } from './ui/prose';
export function EditorSlate() {
export function EditorSlate({
initialValue,
onChange,
readOnly
}: {
readonly initialValue?: Descendant[];
readonly onChange?: (values: Descendant[]) => void;
readonly readOnly?: boolean;
}) {
return (
<>
<Card.Root
variant={'subtle'}
width="100%"
maxWidth="840px"
minHeight="100%"
flex={1}
justifyContent="center"
alignItems="center"
background={readOnly ? 'none' : undefined}
>
{/* <Card.Header>
<Heading textAlign="center">Editor</Heading>
</Card.Header> */}
<Card.Body
width="100%"
css={{
@ -44,7 +48,20 @@ export function EditorSlate() {
}
}}
>
<EditorViewport />
<EditorViewport
initialValue={
initialValue ?? [
{
type: 'paragraph',
children: [{ text: '' }]
}
]
}
onChange={values => {
if (onChange != null) onChange(values);
}}
readOnly={readOnly}
/>
</Card.Body>
</Card.Root>
</>
@ -65,91 +82,63 @@ type AlignType = (typeof TEXT_ALIGN_TYPES)[number];
type ListType = (typeof LIST_TYPES)[number];
type CustomElementFormat = CustomElementType | AlignType | ListType;
function EditorViewport() {
function EditorViewport({
initialValue,
onChange,
readOnly
}: {
readonly initialValue: Descendant[];
readonly onChange: (values: Descendant[]) => void;
readonly readOnly?: boolean;
}) {
const renderElement = useCallback((props: RenderElementProps) => <Element {...props} />, []);
const renderLeaf = useCallback((props: RenderLeafProps) => <Leaf {...props} />, []);
const editor = useMemo(() => withHistory(withReact(createEditor())), []);
const initialValue: Descendant[] = [
{
type: 'paragraph',
children: [
{ text: 'This is editable ' },
{ text: 'rich', bold: true },
{ text: ' text, ' },
{ text: 'much', italic: true },
{ text: ' better than a ' },
{ text: '<textarea>', code: true },
{ text: '!' }
]
},
{
type: 'paragraph',
children: [
{
text: "Since it's rich text, you can do things like turn a selection of text "
},
{ text: 'bold', bold: true },
{
text: ', or add a semantically rendered block quote in the middle of the page, like this:'
}
]
},
{
type: 'block-quote',
children: [{ text: 'A wise quote.' }]
},
{
type: 'paragraph',
align: 'center',
children: [{ text: 'Try it out for yourself!' }]
}
];
return (
<Slate editor={editor} initialValue={initialValue}>
<Wrap justifyContent="center" alignItems="center" gap={1}>
<MarkButton format="bold" icon="nf nf-oct-bold" />
<MarkButton format="italic" icon="nf nf-oct-italic" />
<MarkButton format="underline" icon="nf nf-md-format_underline" />
<MarkButton format="code" icon="nf nf-oct-code" />
<BlockButton format="heading-one" icon="nf nf-fa-heading" text="1" />
<BlockButton format="heading-two" icon="nf nf-fa-heading" text="2" />
<BlockButton format="block-quote" icon="nf nf-oct-quote" />
<BlockButton format="numbered-list" icon="nf nf-fa-list_ol" />
<BlockButton format="bulleted-list" icon="nf nf-fa-list_ul" />
<BlockButton format="left" icon="nf nf-fa-align_left" />
<BlockButton format="center" icon="nf nf-fa-align_center" />
<BlockButton format="right" icon="nf nf-fa-align_right" />
<BlockButton format="justify" icon="nf nf-fa-align_justify" />
</Wrap>
<Slate editor={editor} initialValue={initialValue} onChange={onChange}>
{!readOnly && (
<Wrap justifyContent="center" alignItems="center" gap={1}>
<MarkButton format="bold" icon="nf nf-oct-bold" />
<MarkButton format="italic" icon="nf nf-oct-italic" />
<MarkButton format="underline" icon="nf nf-md-format_underline" />
<MarkButton format="code" icon="nf nf-oct-code" />
<BlockButton format="heading-one" icon="nf nf-fa-heading" text="1" />
<BlockButton format="heading-two" icon="nf nf-fa-heading" text="2" />
<BlockButton format="block-quote" icon="nf nf-oct-quote" />
<BlockButton format="numbered-list" icon="nf nf-fa-list_ol" />
<BlockButton format="bulleted-list" icon="nf nf-fa-list_ul" />
<BlockButton format="left" icon="nf nf-fa-align_left" />
<BlockButton format="center" icon="nf nf-fa-align_center" />
<BlockButton format="right" icon="nf nf-fa-align_right" />
<BlockButton format="justify" icon="nf nf-fa-align_justify" />
</Wrap>
)}
<Stack
width="100%"
maxWidth="100%"
height="100%"
paddingX={3}
display="flex"
justifyContent="center"
alignItems="center"
flex={1}
>
<Prose
width="100%"
minWidth="100%"
display="flex"
justifyContent="center"
alignItems="center"
>
<Prose width="100%" minWidth="100%" height="100%" display="flex" flex={1}>
<Editable
className="slate-editor"
style={{
outline: 'none',
minWidth: '100%',
maxWidth: 'unset',
maxHeight: '75vh',
maxHeight: readOnly ? undefined : '60vh',
height: '100%',
padding: 0,
overflowY: 'auto'
}}
renderElement={renderElement}
renderLeaf={renderLeaf}
readOnly={readOnly}
placeholder=""
spellCheck
autoFocus