修复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 });
|
||||
const activeBlockIndexRef = useRef<number | null>(null);
|
||||
const suppressNextUpdateRef = useRef(false);
|
||||
const allowOnUpdateRef = useRef(true);
|
||||
const allowOnUpdateRef = useRef(false);
|
||||
const { fontFamily, fontSize, lineHeight, tableLineHeight } = useSettingsStore();
|
||||
|
||||
const editor = useEditor({
|
||||
@@ -906,15 +906,12 @@ export function Editor({ content, onChange, onEditorReady, onToggleAI, onExport,
|
||||
|
||||
useEffect(() => {
|
||||
if (editor && content !== editor.getHTML()) {
|
||||
const normalizedContent = cleanupAccidentalStandaloneInlineCode(content);
|
||||
// 不再调用 cleanupAccidentalStandaloneInlineCode,直接使用原始内容
|
||||
suppressNextUpdateRef.current = true;
|
||||
allowOnUpdateRef.current = false;
|
||||
queueMicrotask(() => {
|
||||
editor.commands.setContent(normalizedContent);
|
||||
editor.commands.setContent(content);
|
||||
});
|
||||
if (normalizedContent !== content) {
|
||||
onChange(normalizedContent);
|
||||
}
|
||||
}
|
||||
if (editor && onEditorReady) {
|
||||
onEditorReady(editor);
|
||||
|
||||
@@ -26,7 +26,7 @@ export function ImportProvider({ children }: { children: React.ReactNode }) {
|
||||
const [isImporting, setIsImporting] = useState(false);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const targetParentIdRef = useRef<string | null>(null);
|
||||
const { pages, fetchPages } = useEditorStore();
|
||||
const { pages, fetchPages, setActivePageId } = useEditorStore();
|
||||
|
||||
const postPage = useCallback(
|
||||
async (
|
||||
@@ -110,11 +110,12 @@ export function ImportProvider({ children }: { children: React.ReactNode }) {
|
||||
if (!file) return;
|
||||
|
||||
setIsImporting(true);
|
||||
let importedPageId: string | null = null;
|
||||
try {
|
||||
if (file.name.toLowerCase().endsWith(".zip")) {
|
||||
await handleZipImport(file);
|
||||
} else {
|
||||
await handleSingleFileImport(file);
|
||||
importedPageId = await handleSingleFileImport(file);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Import failed", error);
|
||||
@@ -122,39 +123,45 @@ export function ImportProvider({ children }: { children: React.ReactNode }) {
|
||||
alert(message);
|
||||
} finally {
|
||||
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 title = file.name.replace(/\.md$/i, "");
|
||||
// 直接存储原始 Markdown,tiptap-markdown 扩展会在编辑器加载时自动解析
|
||||
// 使用 importMarkdown 字段,让服务器转换为 HTML
|
||||
const parentId = targetParentIdRef.current;
|
||||
const existing = pages.find((p) => p.type === "file" && p.parentId === parentId && (p.title || "").trim() === title.trim());
|
||||
|
||||
if (existing) {
|
||||
await putPage(
|
||||
existing.id,
|
||||
{
|
||||
title,
|
||||
content: text,
|
||||
importMarkdown: text,
|
||||
parentId,
|
||||
type: "file",
|
||||
},
|
||||
"更新导入文件"
|
||||
);
|
||||
return;
|
||||
return existing.id;
|
||||
}
|
||||
|
||||
await postPage(
|
||||
const result = await postPage(
|
||||
{
|
||||
title,
|
||||
content: text,
|
||||
importMarkdown: text,
|
||||
parentId,
|
||||
type: "file",
|
||||
},
|
||||
"创建导入文件"
|
||||
);
|
||||
return result.id;
|
||||
};
|
||||
|
||||
const handleZipImport = async (file: File) => {
|
||||
@@ -255,7 +262,7 @@ export function ImportProvider({ children }: { children: React.ReactNode }) {
|
||||
existing.id,
|
||||
{
|
||||
title,
|
||||
content: markdown,
|
||||
importMarkdown: markdown,
|
||||
parentId,
|
||||
type: "file",
|
||||
},
|
||||
@@ -265,7 +272,7 @@ export function ImportProvider({ children }: { children: React.ReactNode }) {
|
||||
await postPage(
|
||||
{
|
||||
title,
|
||||
content: markdown,
|
||||
importMarkdown: markdown,
|
||||
parentId,
|
||||
type: "file",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user