diff --git a/src/manage/qd/BookChapter.tsx b/src/manage/qd/BookChapter.tsx index 28d07cf..4306278 100644 --- a/src/manage/qd/BookChapter.tsx +++ b/src/manage/qd/BookChapter.tsx @@ -4,12 +4,12 @@ import { loadChapterListsIfNeeded, useBookContext, useBookStatus } from "./BookS import { useEffect, useRef, useState } from "react"; import { useDb } from "../dbProvider"; import type { QdChapterInfo } from "../../types"; -import MonacoEditor, { MonacoEditorHandle } from 'react-monaco-editor'; import type { Volume } from "../../qdtypes"; import { useBookInfo } from "./BookInfoProvider"; import { get_new_volumes } from "../../utils/qd"; import VolumesList from "./VolumesList"; import styles from './BookChapter.module.css'; +import ChapterEditor from "./ChapterEditor"; export default function BookChapter() { const setItems = useBookContext(); @@ -20,23 +20,34 @@ export default function BookChapter() { const [err, setErr] = useState(null); const [listErr, setListErr] = useState(null); const [chapter, setChapter] = useState(null); - const [chapterContent, setChapterContent] = useState(''); const bookInfo = useBookInfo(); - const editorRef = useRef(null); - async function load() { + const editorRef = useRef(null); + async function load(controller?: AbortController) { const primaryKey = bookStatus.chapterLists?.find(chapter => chapter.id === id)?.primaryKey; const data = await (primaryKey ? db.getQdChapter(primaryKey) : db.getLatestQdChapter(id)); + if (controller?.signal.aborted) { + return; + } if (data) { + if (data.id !== id) return; setChapter(data); - setChapterContent(data.contents ? data.contents.join('\n') : data.chapterInfo.content); + setErr(null); } else { setErr("章节不存在"); + setChapter(null); } } function handle_load() { - load().catch(e => { + const controller = new AbortController(); + load(controller).catch(e => { + if (controller.signal.aborted) { + return; + } setErr(e instanceof Error ? e.message : String(e)); }); + return () => { + controller.abort(); + } } function handle_list_load() { if (listErr) { @@ -52,10 +63,10 @@ export default function BookChapter() { return; } if (chapter) setChapter(null); - if (chapterContent) setChapterContent(''); if (err) setErr(null); - handle_load(); + const abort = handle_load(); handle_list_load(); + return abort; }, [id]); setItems([{ title: chapter ? `章节详情:${chapter.chapterInfo.chapterName}` : '章节详情' @@ -75,7 +86,7 @@ export default function BookChapter() { return (<> { setTimeout(() => { - editorRef.current?.editor.layout(); + editorRef.current?.layout(); }, 1); }}> @@ -89,15 +100,7 @@ export default function BookChapter() { title="数据加载失败" subTitle={err} extra={} />} - {chapter && } + {chapter && } {!chapter && !err && } diff --git a/src/manage/qd/ChapterEditor.tsx b/src/manage/qd/ChapterEditor.tsx new file mode 100644 index 0000000..6c5a061 --- /dev/null +++ b/src/manage/qd/ChapterEditor.tsx @@ -0,0 +1,45 @@ +import { Component, createRef } from "react"; +import { QdChapterInfo } from "../../types"; +import MonacoEditor, { MonacoEditorHandle } from 'react-monaco-editor'; + +export interface ChapterEditorProps { + chapter: QdChapterInfo; +} + +export interface ChapterEditorState { + content: string; +} + +export default class ChapterEditor extends Component { + ref; + constructor(props: ChapterEditorProps) { + super(props); + this.ref = createRef(); + this.state = { + content: props.chapter.contents ? props.chapter.contents.join('\n') : props.chapter.chapterInfo.content, + }; + } + componentDidUpdate(prevProps: Readonly, _prevState: Readonly, _snapshot?: unknown): void { + if (prevProps.chapter.id !== this.props.chapter.id) { + this.setState({ + content: this.props.chapter.contents ? this.props.chapter.contents.join('\n') : this.props.chapter.chapterInfo.content, + }); + } + } + layout() { + this.ref.current?.editor.layout(); + } + render() { + return (<> + this.setState({ content: newValue })} + options={{ + wordWrap: 'on', + }} + /> + ); + } +}