From c92ead60e3837fa787314587a210fda456942d3f Mon Sep 17 00:00:00 2001 From: iven Date: Tue, 2 Jun 2026 23:16:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(app):=20EditorPage=20=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E5=B7=B2=E6=9C=89=E6=97=A5=E8=AE=B0=20=E2=80=94=20=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=E4=B8=BA=20LoadJournal=20=E5=8E=9F=E5=AD=90=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - _loadExistingJournal 改用单一 LoadJournal event 替代多个细粒度事件 - 添加 _titleController 同步,确保 LoadJournal 后标题输入框正确显示 - 不触发 auto-save (isDirty=false),因为这是加载而非用户编辑 --- .../features/editor/views/editor_page.dart | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/app/lib/features/editor/views/editor_page.dart b/app/lib/features/editor/views/editor_page.dart index 565094b..4c426de 100644 --- a/app/lib/features/editor/views/editor_page.dart +++ b/app/lib/features/editor/views/editor_page.dart @@ -283,48 +283,44 @@ class _EditorViewState extends State<_EditorView> { } } - /// 从 Isar 加载已有日记的笔画、元素、标签、心情、标题 + /// 从 Isar 加载已有日记 — 使用 LoadJournal 原子事件一次性还原 Future _loadExistingJournal(String id) async { try { - // 加载日记元数据 final entry = await widget.repo.getJournal(id); if (entry == null || !mounted) return; - final bloc = context.read(); - - // 加载标题和心情 - bloc.add(TitleChanged(entry.title)); - bloc.add(MoodChanged(entry.mood)); - - // 加载标签 - if (entry.tags.isNotEmpty) { - bloc.add(TagsLoaded(entry.tags)); - } - // 加载元素(含笔画) final elements = await widget.repo.getElements(id); if (!mounted) return; - for (final element in elements) { - if (element.elementType == ElementType.handwritingRef) { - // 从 handwriting_ref 元素中恢复笔画 - final strokesData = element.content['strokes']; - if (strokesData is List) { - final strokes = strokesData - .map((s) => Stroke.fromJson(s as Map)) - .toList(); - bloc.add(StrokesLoaded(strokes)); - } + // 从 handwriting_ref 元素中反序列化笔画 + List strokes = []; + final strokesElement = elements + .where((e) => e.elementType == ElementType.handwritingRef) + .firstOrNull; + if (strokesElement != null) { + final strokesData = strokesElement.content['strokes']; + if (strokesData is List) { + strokes = strokesData + .map((s) => Stroke.fromJson(s as Map)) + .toList(); } } - // 加载非笔画元素(贴纸/文字/图片) - final nonStrokeElements = elements + // 过滤掉 handwriting_ref 元素(笔画单独管理) + final otherElements = elements .where((e) => e.elementType != ElementType.handwritingRef) .toList(); - if (nonStrokeElements.isNotEmpty) { - bloc.add(ElementsLoaded(nonStrokeElements)); - } + + // 原子加载 — 一次 dispatch 还原所有状态 + context.read().add(LoadJournal( + title: entry.title, + mood: entry.mood, + tags: entry.tags, + strokes: strokes, + elements: otherElements, + lastSavedAt: entry.updatedAt, + )); } catch (e) { debugPrint('加载日记数据失败: $e'); } @@ -621,6 +617,13 @@ class _EditorStackState extends State<_EditorStack> { @override void didUpdateWidget(covariant _EditorStack oldWidget) { super.didUpdateWidget(oldWidget); + + // 同步标题输入框(LoadJournal 更新 state.title 时 controller 需要跟随) + if (widget.state.title != oldWidget.state.title && + widget.state.title != _titleController.text) { + _titleController.text = widget.state.title; + } + final currentTool = widget.state.activeTool; // 防止重复弹窗:只在工具切换时触发