修复Markdown导入和编辑器初始化问题
- 修复编辑器初始化时自动保存导致内容被破坏的问题 - 将 allowOnUpdateRef 初始值从 true 改为 false - 避免编辑器加载内容时立即触发保存 - 移除编辑器内容更新时的 cleanupAccidentalStandaloneInlineCode 调用 - 直接使用原始内容,避免误删正常的代码块 - 改进Markdown导入逻辑 - 使用 importMarkdown 字段而非 content 字段 - 让服务器端正确转换Markdown为HTML - 支持ZIP文件中的Markdown导入 - 新增导入后自动打开文档功能 - 导入单个文件后自动打开该文档 - 左侧文档树自动定位到导入的文档 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -619,7 +619,7 @@ export function Editor({ content, onChange, onEditorReady, onToggleAI, onExport,
|
|||||||
}>({ sourceStartIndex: -1, sourceEndIndex: -1, targetInsertionIndex: -1 });
|
}>({ sourceStartIndex: -1, sourceEndIndex: -1, targetInsertionIndex: -1 });
|
||||||
const activeBlockIndexRef = useRef<number | null>(null);
|
const activeBlockIndexRef = useRef<number | null>(null);
|
||||||
const suppressNextUpdateRef = useRef(false);
|
const suppressNextUpdateRef = useRef(false);
|
||||||
const allowOnUpdateRef = useRef(true);
|
const allowOnUpdateRef = useRef(false);
|
||||||
const { fontFamily, fontSize, lineHeight, tableLineHeight } = useSettingsStore();
|
const { fontFamily, fontSize, lineHeight, tableLineHeight } = useSettingsStore();
|
||||||
|
|
||||||
const editor = useEditor({
|
const editor = useEditor({
|
||||||
@@ -906,15 +906,12 @@ export function Editor({ content, onChange, onEditorReady, onToggleAI, onExport,
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editor && content !== editor.getHTML()) {
|
if (editor && content !== editor.getHTML()) {
|
||||||
const normalizedContent = cleanupAccidentalStandaloneInlineCode(content);
|
// 不再调用 cleanupAccidentalStandaloneInlineCode,直接使用原始内容
|
||||||
suppressNextUpdateRef.current = true;
|
suppressNextUpdateRef.current = true;
|
||||||
allowOnUpdateRef.current = false;
|
allowOnUpdateRef.current = false;
|
||||||
queueMicrotask(() => {
|
queueMicrotask(() => {
|
||||||
editor.commands.setContent(normalizedContent);
|
editor.commands.setContent(content);
|
||||||
});
|
});
|
||||||
if (normalizedContent !== content) {
|
|
||||||
onChange(normalizedContent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (editor && onEditorReady) {
|
if (editor && onEditorReady) {
|
||||||
onEditorReady(editor);
|
onEditorReady(editor);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export function ImportProvider({ children }: { children: React.ReactNode }) {
|
|||||||
const [isImporting, setIsImporting] = useState(false);
|
const [isImporting, setIsImporting] = useState(false);
|
||||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
const targetParentIdRef = useRef<string | null>(null);
|
const targetParentIdRef = useRef<string | null>(null);
|
||||||
const { pages, fetchPages } = useEditorStore();
|
const { pages, fetchPages, setActivePageId } = useEditorStore();
|
||||||
|
|
||||||
const postPage = useCallback(
|
const postPage = useCallback(
|
||||||
async (
|
async (
|
||||||
@@ -110,11 +110,12 @@ export function ImportProvider({ children }: { children: React.ReactNode }) {
|
|||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
|
||||||
setIsImporting(true);
|
setIsImporting(true);
|
||||||
|
let importedPageId: string | null = null;
|
||||||
try {
|
try {
|
||||||
if (file.name.toLowerCase().endsWith(".zip")) {
|
if (file.name.toLowerCase().endsWith(".zip")) {
|
||||||
await handleZipImport(file);
|
await handleZipImport(file);
|
||||||
} else {
|
} else {
|
||||||
await handleSingleFileImport(file);
|
importedPageId = await handleSingleFileImport(file);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Import failed", error);
|
console.error("Import failed", error);
|
||||||
@@ -122,39 +123,45 @@ export function ImportProvider({ children }: { children: React.ReactNode }) {
|
|||||||
alert(message);
|
alert(message);
|
||||||
} finally {
|
} finally {
|
||||||
setIsImporting(false);
|
setIsImporting(false);
|
||||||
fetchPages();
|
await fetchPages();
|
||||||
|
// 导入单个文件后,自动打开该文档
|
||||||
|
if (importedPageId) {
|
||||||
|
setActivePageId(importedPageId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSingleFileImport = async (file: File) => {
|
const handleSingleFileImport = async (file: File): Promise<string> => {
|
||||||
const text = await file.text();
|
const text = await file.text();
|
||||||
const title = file.name.replace(/\.md$/i, "");
|
const title = file.name.replace(/\.md$/i, "");
|
||||||
// 直接存储原始 Markdown,tiptap-markdown 扩展会在编辑器加载时自动解析
|
// 使用 importMarkdown 字段,让服务器转换为 HTML
|
||||||
const parentId = targetParentIdRef.current;
|
const parentId = targetParentIdRef.current;
|
||||||
const existing = pages.find((p) => p.type === "file" && p.parentId === parentId && (p.title || "").trim() === title.trim());
|
const existing = pages.find((p) => p.type === "file" && p.parentId === parentId && (p.title || "").trim() === title.trim());
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
await putPage(
|
await putPage(
|
||||||
existing.id,
|
existing.id,
|
||||||
{
|
{
|
||||||
title,
|
title,
|
||||||
content: text,
|
importMarkdown: text,
|
||||||
parentId,
|
parentId,
|
||||||
type: "file",
|
type: "file",
|
||||||
},
|
},
|
||||||
"更新导入文件"
|
"更新导入文件"
|
||||||
);
|
);
|
||||||
return;
|
return existing.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
await postPage(
|
const result = await postPage(
|
||||||
{
|
{
|
||||||
title,
|
title,
|
||||||
content: text,
|
importMarkdown: text,
|
||||||
parentId,
|
parentId,
|
||||||
type: "file",
|
type: "file",
|
||||||
},
|
},
|
||||||
"创建导入文件"
|
"创建导入文件"
|
||||||
);
|
);
|
||||||
|
return result.id;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleZipImport = async (file: File) => {
|
const handleZipImport = async (file: File) => {
|
||||||
@@ -255,7 +262,7 @@ export function ImportProvider({ children }: { children: React.ReactNode }) {
|
|||||||
existing.id,
|
existing.id,
|
||||||
{
|
{
|
||||||
title,
|
title,
|
||||||
content: markdown,
|
importMarkdown: markdown,
|
||||||
parentId,
|
parentId,
|
||||||
type: "file",
|
type: "file",
|
||||||
},
|
},
|
||||||
@@ -265,7 +272,7 @@ export function ImportProvider({ children }: { children: React.ReactNode }) {
|
|||||||
await postPage(
|
await postPage(
|
||||||
{
|
{
|
||||||
title,
|
title,
|
||||||
content: markdown,
|
importMarkdown: markdown,
|
||||||
parentId,
|
parentId,
|
||||||
type: "file",
|
type: "file",
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user