fix(app): 修复 4 个 Flutter 交互问题
Some checks failed
Main Merge / backend (push) Has been cancelled
Main Merge / frontend (push) Has been cancelled

1. 首页数据不刷新 — JournalRepository 添加 onJournalChanged
   Stream 变更通知,HomeBloc 订阅后自动刷新
2. 画笔再次点击不弹出面板 — 添加 ToolReactivated 事件,
   工具栏检测已激活工具时发出重新激活信号
3. 钢笔铅笔效果一样 — 调整 perfect_freehand 参数
   (pen: size 10/smooth 0.65, pencil: size 3/smooth 0.35)
4. 橡皮擦不生效 — ActiveStrokePainter 橡皮擦模式绘制
   半透明灰色反馈,笔画完成后 setState 触发 Layer 1 重绘
5. 贴纸文字无法缩放 — DraggableElement 用 Scale 手势
   替换 Pan 手势,支持双指缩放和旋转
This commit is contained in:
iven
2026-06-04 00:05:22 +08:00
parent 988ee7335a
commit 9fce34f4ef
14 changed files with 164 additions and 15 deletions

View File

@@ -7,6 +7,7 @@
// - JournalEntry ↔ JournalEntryCollection通过 toCollection/fromCollection
// - JournalElement ↔ JournalElementCollection通过 toCollection/fromCollection
import 'dart:async';
import 'dart:convert';
import 'package:isar/isar.dart';
@@ -22,6 +23,11 @@ import 'journal_repository.dart';
class IsarJournalRepository implements JournalRepository {
Isar get _isar => IsarDatabase.instance;
final StreamController<void> _changeController = StreamController<void>.broadcast();
@override
Stream<void> get onJournalChanged => _changeController.stream;
// ============================================================
// 日记 CRUD
// ============================================================
@@ -107,6 +113,7 @@ class IsarJournalRepository implements JournalRepository {
await _isar.writeTxn(() async {
await _isar.journalEntryCollections.put(col);
});
_changeController.add(null);
return entry;
}
@@ -143,6 +150,7 @@ class IsarJournalRepository implements JournalRepository {
await _isar.journalEntryCollections.put(col);
});
_changeController.add(null);
return updated;
}
@@ -176,6 +184,7 @@ class IsarJournalRepository implements JournalRepository {
await _isar.journalElementCollections.put(el);
}
});
_changeController.add(null);
}
// ============================================================

View File

@@ -7,6 +7,9 @@ import '../models/journal_entry.dart';
import '../models/journal_element.dart';
import 'journal_repository.dart';
/// 空的变更通知流 — Web 平台 stub
const _emptyStream = Stream<void>.empty();
/// Isar 本地日记仓库 — Web 空实现(抛出 UnsupportedError
class IsarJournalRepository implements JournalRepository {
@override
@@ -56,4 +59,7 @@ class IsarJournalRepository implements JournalRepository {
@override
Future<void> removeElement(String elementId) =>
throw UnsupportedError('IsarJournalRepository 不支持 Web 平台');
@override
Stream<void> get onJournalChanged => _emptyStream;
}

View File

@@ -6,6 +6,8 @@
// - SyncEngine 负责协调本地和远程仓库之间的数据同步
// - 内存实现 [InMemoryJournalRepository] 用于开发阶段快速迭代
import 'dart:async';
import '../models/journal_entry.dart';
import '../models/journal_element.dart';
@@ -52,6 +54,9 @@ abstract class JournalRepository {
/// 从日记中移除元素
Future<void> removeElement(String elementId);
/// 日记变更通知流 — create/update/delete 时发出信号
Stream<void> get onJournalChanged;
}
/// 内存实现 — 用于开发阶段快速迭代和单元测试
@@ -61,6 +66,10 @@ abstract class JournalRepository {
class InMemoryJournalRepository implements JournalRepository {
final Map<String, JournalEntry> _journals = {};
final Map<String, JournalElement> _elements = {};
final StreamController<void> _changeController = StreamController<void>.broadcast();
@override
Stream<void> get onJournalChanged => _changeController.stream;
@override
Future<List<JournalEntry>> getJournals({
@@ -122,6 +131,7 @@ class InMemoryJournalRepository implements JournalRepository {
@override
Future<JournalEntry> createJournal(JournalEntry entry) async {
_journals[entry.id] = entry;
_changeController.add(null);
return entry;
}
@@ -145,6 +155,7 @@ class InMemoryJournalRepository implements JournalRepository {
updatedAt: DateTime.now(),
);
_journals[entry.id] = updated;
_changeController.add(null);
return updated;
}
@@ -154,6 +165,7 @@ class InMemoryJournalRepository implements JournalRepository {
_journals.remove(id);
// 同时移除关联元素
_elements.removeWhere((_, e) => e.journalId == id);
_changeController.add(null);
}
@override

View File

@@ -131,6 +131,10 @@ class RemoteJournalRepository implements JournalRepository {
Future<void> removeElement(String elementId) async {
await _api.delete('/diary/elements/$elementId');
}
/// 远程仓库不提供本地变更通知,返回空流
@override
Stream<void> get onJournalChanged => const Stream<void>.empty();
}
/// API 异常封装 — 后端返回非 2xx 状态码时抛出