feat(app): EditorPage 加载已有日记 — 替换为 LoadJournal 原子事件

- _loadExistingJournal 改用单一 LoadJournal event 替代多个细粒度事件
- 添加 _titleController 同步,确保 LoadJournal 后标题输入框正确显示
- 不触发 auto-save (isDirty=false),因为这是加载而非用户编辑
This commit is contained in:
iven
2026-06-02 23:16:58 +08:00
parent ab45f40cc8
commit c92ead60e3

View File

@@ -283,48 +283,44 @@ class _EditorViewState extends State<_EditorView> {
} }
} }
/// 从 Isar 加载已有日记的笔画、元素、标签、心情、标题 /// 从 Isar 加载已有日记 — 使用 LoadJournal 原子事件一次性还原
Future<void> _loadExistingJournal(String id) async { Future<void> _loadExistingJournal(String id) async {
try { try {
// 加载日记元数据
final entry = await widget.repo.getJournal(id); final entry = await widget.repo.getJournal(id);
if (entry == null || !mounted) return; if (entry == null || !mounted) return;
final bloc = context.read<EditorBloc>();
// 加载标题和心情
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); final elements = await widget.repo.getElements(id);
if (!mounted) return; if (!mounted) return;
for (final element in elements) { // 从 handwriting_ref 元素中反序列化笔画
if (element.elementType == ElementType.handwritingRef) { List<Stroke> strokes = [];
// 从 handwriting_ref 元素中恢复笔画 final strokesElement = elements
final strokesData = element.content['strokes']; .where((e) => e.elementType == ElementType.handwritingRef)
if (strokesData is List) { .firstOrNull;
final strokes = strokesData if (strokesElement != null) {
.map((s) => Stroke.fromJson(s as Map<String, dynamic>)) final strokesData = strokesElement.content['strokes'];
.toList(); if (strokesData is List) {
bloc.add(StrokesLoaded(strokes)); strokes = strokesData
} .map((s) => Stroke.fromJson(s as Map<String, dynamic>))
.toList();
} }
} }
// 加载非笔画元素(贴纸/文字/图片 // 过滤掉 handwriting_ref 元素(笔画单独管理
final nonStrokeElements = elements final otherElements = elements
.where((e) => e.elementType != ElementType.handwritingRef) .where((e) => e.elementType != ElementType.handwritingRef)
.toList(); .toList();
if (nonStrokeElements.isNotEmpty) {
bloc.add(ElementsLoaded(nonStrokeElements)); // 原子加载 — 一次 dispatch 还原所有状态
} context.read<EditorBloc>().add(LoadJournal(
title: entry.title,
mood: entry.mood,
tags: entry.tags,
strokes: strokes,
elements: otherElements,
lastSavedAt: entry.updatedAt,
));
} catch (e) { } catch (e) {
debugPrint('加载日记数据失败: $e'); debugPrint('加载日记数据失败: $e');
} }
@@ -621,6 +617,13 @@ class _EditorStackState extends State<_EditorStack> {
@override @override
void didUpdateWidget(covariant _EditorStack oldWidget) { void didUpdateWidget(covariant _EditorStack oldWidget) {
super.didUpdateWidget(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; final currentTool = widget.state.activeTool;
// 防止重复弹窗:只在工具切换时触发 // 防止重复弹窗:只在工具切换时触发