本次提交完成 macOS 端多项关键优化与修复: 1. 修复启动期竞态闪退问题,通过前移窗口属性初始化、串行化特效调用、跳过首次同步实现稳定启动 2. 实现系统菜单栏多语言本地化,支持中英日韩繁五种语言,软件内切换语言可同步更新菜单栏 3. 移除视图菜单中重复的全屏按钮,统一窗口标题栏逻辑 4. 新增 macOS App Store 打包配置与本地化资源
85 KiB
85 KiB
Changelog
所有重要变更均记录于此文件。格式基于 Keep a Changelog。
保留最近 14 个版本(v6.101.0 ~ v6.120.0)。更早版本(v6.87.0 ~ v6.100.0)的特性已合并进软件特性功能文档,详见文末归档概览。
[v6.121.0] - 2026-06-24
🐛 修复(macOS 启动期闪退)
闪退根因分析
- Issue: macOS 端启动后 3.5 秒闪退,崩溃栈与 v6.119.0 修复前完全一致
- 崩溃栈:
- Thread 0 (main):
macos_window_utils→[NSWindow setBackgroundColor:]→NSThemeFrame._updateBackdropView→-[NSView removeFromSuperview] - Thread 8 (io.flutter.raster):
impeller::Canvas::SetupRenderPass()—KERN_INVALID_ADDRESS at 0x0
- Thread 0 (main):
- 根因:
macos_window_utils插件的MainFlutterWindowManipulator.start()方法内部会调用showTitle()/makeTitlebarOpaque()/disableFullSizeContentView()/setWindowBackgroundColorToDefaultColor()四个方法setWindowBackgroundColorToDefaultColor()会触发[NSWindow setBackgroundColor:]→NSThemeFrame._updateBackdropView→removeFromSuperview- Dart 侧
WindowManipulator.initialize()→ 原生reset()→ 当mainFlutterWindow == nil时走start(nil)分支 → 触发上述竞态 - v6.119.0 的修复仅跳过了 Dart 侧
applyEffect中的冗余调用,但未跳过WindowManipulator.initialize()内部的reset()→start(nil)路径
- 修复:
- 在
MainFlutterWindow.awakeFromNib中提前调用MainFlutterWindowManipulator.start(mainFlutterWindow: self),让mainFlutterWindow静态属性先被设置 - 之后
WindowManipulator.initialize()的reset()会因mainFlutterWindow != nil走passthroughViewHandler.start()分支,不再触发setWindowBackgroundColorToDefaultColor() start()会覆盖awakeFromNib预设的透明属性,因此在start()之后重新设置(此时 Flutter 引擎未启动,Impeller raster 线程未运行,无竞态风险)
- 在
- 涉及文件:
macos/Runner/MainFlutterWindow.swift— 导入macos_window_utils,提前调用start,之后重新设置透明属性
🎨 优化(macOS 窗口标题栏 + 系统菜单栏)
1. macOS 系统菜单栏支持多语言
- Issue: macOS 系统菜单栏(应用菜单/编辑菜单/视图菜单/窗口菜单/帮助菜单)项目仅显示英文,未跟随系统语言
- 根因:
MainMenu.xib只有Base.lproj版本,无本地化.strings文件project.pbxproj的knownRegions仅包含en和Base
- 修复:
- 创建本地化文件:为 5 种主要语言创建
MainMenu.strings:en.lproj/MainMenu.strings— 英语zh-Hans.lproj/MainMenu.strings— 简体中文zh-Hant.lproj/MainMenu.strings— 繁体中文ja.lproj/MainMenu.strings— 日语ko.lproj/MainMenu.strings— 韩语
- 项目配置(
project.pbxproj):knownRegions添加zh-Hans/zh-Hant/ja/ko- 创建
MainMenu.strings的PBXVariantGroup和PBXFileReference - 将
MainMenu.strings添加到PBXResourcesBuildPhase
- 创建本地化文件:为 5 种主要语言创建
- 效果: 系统菜单栏跟随 macOS 系统语言显示对应文案
- 涉及文件:
macos/Runner/en.lproj/MainMenu.strings— 新增macos/Runner/zh-Hans.lproj/MainMenu.strings— 新增macos/Runner/zh-Hant.lproj/MainMenu.strings— 新增macos/Runner/ja.lproj/MainMenu.strings— 新增macos/Runner/ko.lproj/MainMenu.strings— 新增macos/Runner.xcodeproj/project.pbxproj— 添加本地化支持
2. 去掉视图菜单下的 "Enter Full Screen" 按钮
- Issue: macOS 系统菜单栏 → 视图菜单下有 "Enter Full Screen" 按钮,与 Flutter 侧自绘的绿灯按钮(弹 window size dialog)功能重复
- 修复: 删除
MainMenu.xib中 View 菜单下的 "Enter Full Screen" 菜单项 - 涉及文件:
macos/Runner/Base.lproj/MainMenu.xib— 删除 "Enter Full Screen" 菜单项
3. 软件内切换语言后 macOS 系统菜单栏同步更新
- Issue: 软件内切换语言后,macOS 系统菜单栏( 右边的按钮:应用菜单/编辑菜单/视图菜单/窗口菜单/帮助菜单)未跟随切换,仍显示原语言
- 根因:
- macOS 启动时根据系统语言偏好加载
MainMenu.strings,软件内切换语言仅更新 Flutter 侧 UI,未通知原生侧重新加载菜单标题 generalSettingsProvider.setLanguage方法只更新内存状态 + 持久化 KvStorage + 写日志,未调用任何 MethodChannel- XIB 加载后
NSMenuItem.identifier默认为 nil,无法通过 XIB objectId 直接定位菜单项
- macOS 启动时根据系统语言偏好加载
- 修复(三层联动):
- 原生侧 — 建立 objectId ↔ menuItem 映射(
MainFlutterWindow.swift):- 新增
menuItemIds静态数组,按深度优先顺序记录 XIB 中所有 menuItem 的 objectId(与MainMenu.xib声明顺序一致,跳过 separatorItem) - 新增
assignMenuItemIdentifiers()方法,在awakeFromNib中递归遍历NSApp.mainMenu,按顺序将 objectId 赋值给对应menuItem.identifier
- 新增
- 原生侧 — 切换菜单语言(
MainFlutterWindow.swift):- 新增
setMenuLanguage(languageId:)方法:- 根据 languageId 解析 lproj 目录名(
system→Bundle.preferredLocalizations(from:)跟随系统;zh-CN/zh-Hans→zh-Hans;zh-TW/zh-Hant→zh-Hant;en/ja/ko→ 对应 lproj) - 通过
Bundle.main.path(forResource:ofType:forLocalization:)加载对应语言的MainMenu.strings为[String: String] - 递归遍历
NSApp.mainMenu,根据menuItem.identifier(XIB objectId)查找.strings中的 key("id.title")并更新标题 - 替换
APP_NAME占位符为应用名(CFBundleName)
- 根据 languageId 解析 lproj 目录名(
- MethodChannel 新增
case "setMenuLanguage"处理,调用self.setMenuLanguage(languageId:)
- 新增
- Dart 侧 — 通知原生侧切换:
MacosPlatformService.setMenuLanguage(String languageId)— 新增静态方法,通过apps.xy.xianyan/macos通道调用原生侧generalSettingsProvider.setLanguage— 在更新状态后调用MacosPlatformService.setMenuLanguage(id)DesktopServicesManager._initMenuLanguage— 新增方法,应用启动时根据用户设置的语言同步菜单栏(macOS 启动时按系统语言加载.strings,需根据用户设置覆盖)
- 原生侧 — 建立 objectId ↔ menuItem 映射(
- 效果:
- 软件内切换语言后,系统菜单栏所有菜单项标题立即更新为目标语言
- 应用启动时菜单栏语言与用户设置一致(而非跟随系统语言)
- 涉及文件:
macos/Runner/MainFlutterWindow.swift— 新增menuItemIds/assignMenuItemIdentifiers/setMenuLanguage,awakeFromNib 调用assignMenuItemIdentifierslib/core/services/device/macos_platform_service.dart— 新增setMenuLanguage静态方法lib/features/settings/providers/general_settings_provider.dart—setLanguage调用MacosPlatformService.setMenuLanguagelib/app/services/desktop_services_manager.dart— 新增_initMenuLanguage,启动时同步菜单栏语言
📦 打包(macOS App Store 提交包重新打包)
1. 生成 App Store 提交用 pkg(x86_64 + arm64 通用二进制)
- 背景: v6.121.0 修复完成后需重新打包提交 App Store
- 流程:
flutter clean+flutter pub get+pod installflutter build macos --release— 构建 universal binary (x86_64 + arm64),201.0MBxcodebuild archive— 生成 xcarchive(Automatic 签名,Apple Development 证书)xcodebuild -exportArchive— 导出 App Store pkg,使用 Apple Distribution 证书重新签名
- 产物:
build/Runner.xcarchive— 归档文件build/Runner/闲言.pkg— 110MB,App Store 提交包
- 验证:
- 主可执行文件:universal (x86_64 + arm64)
- pkg 签名:3rd Party Mac Developer Installer: li zhenyang (5V9NVUU6K5)
- app 签名:Apple Distribution: li zhenyang (5V9NVUU6K5)
- Info.plist 包含
ITSAppUsesNonExemptEncryption=false加密合规声明
- 新增文件:
macos/ExportOptions.plist— App Store 导出配置(method=app-store, teamID=5V9NVUU6K5)
- 上传方式: 通过 Xcode Organizer 手动上传(
open -a Xcode-beta build/Runner.xcarchive→ Distribute App → App Store Connect → Upload) - 注意事项:
- Release 配置保持
CODE_SIGN_IDENTITY = "Apple Development"+CODE_SIGN_STYLE = Automatic,exportArchive 阶段会自动使用 Apple Distribution 证书重新签名 - 若直接将 CODE_SIGN_IDENTITY 改为 "Apple Distribution" 会与 Automatic 签名冲突,导致构建失败
- Release 配置保持
[v6.120.0] - 2026-06-24
📦 打包(macOS Universal Binary 提交 App Store)
1. macOS 包支持 x86_64 + arm64 双架构,用于 App Store 提交
- Issue: 原 macOS Release 配置强制
ARCHS = arm64,仅生成 arm64 单架构包,x86_64 Mac 无法原生运行;且 Flutter SDKxcode_backend.dart中存在强制 arm64 的"修复"代码,阻止 universal binary 构建 - 根因:
macos/Runner.xcodeproj/project.pbxprojRelease 配置中ARCHS = arm64限制只构建 arm64- Flutter SDK
packages/flutter_tools/bin/xcode_backend.dart第 646-648 行:当ARCHS包含空格(多架构)时强制改为arm64,导致flutter assemble只生成 arm64 的 FlutterMacOS.framework - Flutter SDK
flutter_tools.snapshot未包含darwin.dart中thinFramework的逐架构验证修复(snapshot 未随源码更新重新编译)
- 修复:
- 项目配置(
macos/Runner.xcodeproj/project.pbxproj):Release 配置ARCHS从arm64改为$(ARCHS_STANDARD),支持 universal binary - Flutter SDK 修复(
packages/flutter_tools/bin/xcode_backend.dart):移除if (platform == TargetPlatform.macos && archs.contains(' ')) archs = 'arm64'强制 arm64 逻辑,保留多架构传入flutter assemble - Snapshot 重建:修改
bin/cache/flutter_tools.stamp触发flutter_tools.snapshot重新编译,使darwin.dart的逐架构lipo -verify_arch验证修复生效
- 项目配置(
- 构建结果:
build/macos/Build/Products/Release/xianyan.app— universal (x86_64 + arm64),200.9MBbuild/xianyan.xcarchive— universal archive,用 Apple Distribution 证书签名build/pkg/闲言.pkg— 110MB,用 3rd Party Mac Developer Installer 证书签名
- 验证:
- 主可执行文件、FlutterMacOS.framework、App.framework 均为 universal (x86_64 + arm64)
- 签名正确:TeamIdentifier=5V9NVUU6K5,Format=app bundle with Mach-O universal
- Info.plist 包含
ITSAppUsesNonExemptEncryption=false加密合规声明
- 上传方式: 通过 Xcode Organizer 手动上传(open build/xianyan.xcarchive → Distribute App → App Store Connect → Upload)
- 涉及文件:
macos/Runner.xcodeproj/project.pbxproj— Release 配置 ARCHS 改为 universal- Flutter SDK
packages/flutter_tools/bin/xcode_backend.dart— 移除强制 arm64 逻辑(SDK 本地修改) - Flutter SDK
bin/cache/flutter_tools.stamp— 触发 snapshot 重建
- 注意事项:
- Flutter SDK 的
xcode_backend.dart修改是本地的,flutter upgrade或重新安装 Flutter SDK 后需重新应用 - 后续 macOS App Store 打包可直接执行
flutter build macos --release+xcodebuild archive+xcodebuild -exportArchive
- Flutter SDK 的
[v6.119.0] - 2026-06-24
🐛 修复(macOS Release 模式启动闪退)
1. macOS Release 模式启动 ~3.5 秒后 EXC_BAD_ACCESS 空指针崩溃
- Issue: macOS Release 模式启动后约 3.5 秒闪退,Debug 模式正常
- 崩溃栈:
- Thread 8 (io.flutter.raster):
impeller::Canvas::SetupRenderPass()(canvas.cc:1344) —KERN_INVALID_ADDRESS at 0x0 - Thread 0 (main):
macos_window_utils→[NSWindow setBackgroundColor:]→NSThemeFrame _updateBackdropView→-[NSView removeFromSuperview]
- Thread 8 (io.flutter.raster):
- 根因: 启动期
applyEffect()通过 PostFrame 回调调用setWindowBackgroundColorToClear(),触发[NSWindow setBackgroundColor:]修改视图层级(removeFromSuperview),与 Impeller raster 线程的SetupRenderPass产生竞态。Release 模式时序更紧凑,竞态更易触发;Debug 模式有 JIT 开销,时序较松散故未复现 - 修复(四层防御):
- 原生侧前移不变属性(
MainFlutterWindow.awakeFromNib):在 Flutter 引擎启动前预设isOpaque=false+backgroundColor=NSColor.clear+titlebarAppearsTransparent=true+titleVisibility=.hidden+fullSizeContentView,消除渲染期setBackgroundColor:调用 - Dart 侧跳过冗余调用(
MacosWindowEffectService.applyEffect):移除makeTitlebarTransparent()/enableFullSizeContentView()/hideTitle()/setWindowBackgroundColorToClear()四个已在 awakeFromNib 设置的调用,仅保留主题相关的overrideMacOSBrightness和NSVisualEffectView操作 - 互斥锁串行化(
MacosWindowEffectService):添加Completer<void>互斥锁,防止applyEffect()并发执行导致原生视图层级竞争 - 延迟首次应用(
DesktopServicesManager._initWindowEffect):首次applyEffect()延迟 500ms,等待 Impeller 完成初始渲染 - 跳过首次主题同步(
ThemeSyncService.syncThemeToDesktop):首次 build 的窗口特效同步由_initWindowEffect统一处理,避免 build() 与 PostFrame 回调并发触发applyEffect()
- 原生侧前移不变属性(
- 涉及文件:
macos/Runner/MainFlutterWindow.swift— awakeFromNib 中预设窗口透明属性lib/core/services/desktop/implementations/macos_window_effect_service.dart— 互斥锁 + 跳过冗余调用lib/app/services/desktop_services_manager.dart— 延迟首次 applyEffectlib/app/services/theme_sync_service.dart— 跳过首次窗口特效同步
[v6.118.0] - 2026-06-24
🐛 修复(macOS 全屏退出后窗口背景变黑)
1. macOS 原生全屏退出后窗口背景显示黑色而非桌面
- Issue: 通过「视图 → Enter Full Screen」进入原生全屏后,点击绿灯退出全屏(选择小窗),窗口缩小后背景变为黑色,无法透过窗口看到桌面
- 原因:
MacosWindowEffectService.applyEffect()调用WindowManipulator.setWindowBackgroundColorToClear()设置了isOpaque=false+backgroundColor=NSColor.clear- 但全屏模式下 macOS 强制窗口不透明(
isOpaque=true,backgroundColor=黑色) - 退出全屏后这些属性未自动恢复,导致窗口背景保持黑色
- 同时
titlebarAppearsTransparent也可能被系统重置
- 修复:
- 原生侧(
MainFlutterWindow.swift):监听NSWindow.didExitFullScreenNotification,全屏退出后立即重新设置isOpaque=false+backgroundColor=NSColor.clear+titlebarAppearsTransparent=true,并触发窗口重绘 - Dart 侧(
MacosPlatformService):新增initEventListeners()和onFullScreenExited回调,接收原生侧的全屏退出事件 - 服务层(
DesktopServicesManager):注册全屏退出回调,退出后重新调用applyEffect()恢复完整窗口特效(NSVisualEffectView 毛玻璃、标题栏融合等)
- 原生侧(
- 涉及文件:
macos/Runner/MainFlutterWindow.swift— 添加全屏退出通知监听 +handleFullScreenExit方法lib/core/services/device/macos_platform_service.dart— 新增原生事件监听机制lib/app/services/desktop_services_manager.dart— 注册全屏退出回调 + 重新应用特效
[v6.117.0] - 2026-06-24
🐛 修复(macOS 菜单栏打开页面绕过工作台模式)
1. macOS 顶部「闲言」菜单项打开页面不符合工作台模式且无法返回
- Issue: macOS 端通过系统顶部菜单栏 右侧的「闲言/文件/视图/帮助」菜单选项打开页面时,页面全屏覆盖整个窗口,不符合工作台模式布局,且无法返回上一页
- 原因:
MacosMenuBarWrapper._navigateTo直接调用appRouter.push(route),将页面 push 到根 GoRouter Navigator,绕过了工作台模式的右栏嵌套 Navigator,导致页面独占窗口 - 修复:
- 参考
DesktopTrayController._navigateTo的修复7.1方案,改为工作台模式感知导航 - 直接读取
splitViewProvider.workbenchEnabled判断工作台模式(不依赖 MediaQuery,避免窗口状态切换时尺寸未就绪导致判断失败) - 工作台模式开启且非全屏路由时,push 到右栏嵌套 Navigator(
rightPanelStackProvider),页面显示在右栏并支持栈式返回 - 非工作台模式或全屏路由仍走 GoRouter push
- 参考
- 涉及文件:
lib/features/desktop/macos_menu_bar_wrapper.dart
🔒 合规(App Store 加密出口合规声明)
1. macOS Info.plist 补充加密出口合规声明
- Issue: App Store Connect 上传构建版本时提示「你的 App 采用了哪种类型的加密算法?」合规问卷
- 原因: macOS 端
Info.plist缺少ITSAppUsesNonExemptEncryption声明(iOS 端已有) - 修复: 在
macos/Runner/Info.plist中添加ITSAppUsesNonExemptEncryption = false,声明 App 仅使用 Apple 操作系统提供的标准加密(HTTPS/TLS),不使用非豁免加密,跳过每次上传的出口合规问卷 - 涉及文件:
macos/Runner/Info.plist
[v6.116.0] - 2026-06-24
🐛 修复(情景诗词发送无回复 + 卡片堆积)
1. 情景诗词发送预选词后无诗词回复
- Issue: 输入预选词发送后,页面没有回复诗词
- 原因:
_buildMessages从poetrySessions历史列表构建消息,发送后新诗词未正确显示_send方法isExactTag检查过于严格,输入同义词(如"下雨")无法触发发送- 缺少用户消息反馈,发送后无视觉提示
- 修复:
- 重构
_buildMessages:直接从state.jinrishiciContent构建当前诗词消息,不再遍历历史 sessions - 新增
state.currentTag字段追踪当前预选词,发送后显示用户消息气泡 _send方法支持同义词自动映射(如"下雨"→"雨")和单匹配自动发送- 添加 API 错误提示(聊天中显示 ⚠️ 错误信息)
_selectSuggestion统一使用_doSend方法
- 重构
- 涉及文件:
weather_page.dart,weather_provider.dart
2. 情景诗词无限下滑显示多个相关诗词气泡卡片
- Issue: 发现页面 → 情景诗词一直下滑,出现无数个「相关诗词」气泡卡片
- 原因:
_buildMessages循环为每个历史 session 都添加诗词卡片,历史 session 越多卡片越多 - 修复: 仅显示最新 session 的诗词内容,发送一个预选词回应一首诗词,历史 session 不再展示
- 涉及文件:
lib/features/weather/presentation/weather_page.dart
3. 情景诗词收藏/分享按钮点击无反应
- Issue: 相关诗词卡片中的收藏和分享按钮点击无任何响应
- 原因:
_buildActionChip的GestureDetector缺少onTap回调,仅有 UI 渲染 - 修复:
_buildActionChip新增onTap可选回调参数,点击时触发触感反馈- 新增
_favoritePoetry方法:收藏诗词到本地数据库(AppDatabase),支持切换收藏状态 - 新增
_sharePoetry方法:调用ShareSheet弹出分享面板
- 涉及文件:
lib/features/weather/presentation/weather_page.dart
[v6.115.0] - 2026-06-24
🐛 修复(布局溢出)
1. 拾光栏设置面板工作台模式底部溢出 143px
- Issue: 工作台模式右栏打开「拾光栏设置」时,内容区超出可用高度导致底部溢出 143 像素
- 原因:
DateConfigSheet使用固定maxHeight约束 + 不可滚动的Column布局,右栏高度(扣除48px顶栏)不足时溢出 - 修复:
- 顶栏(拖拽指示器 + 关闭按钮 + 标题行)保持固定
- 内容区(角色卡片、日期行、显示项、轮播开关、Tips等)改为
Expanded+SingleChildScrollView可滚动布局 - 同时修复了
onTap回调的箭头函数语法问题(改为块体语法避免解析异常)
- 涉及文件:
lib/features/home/presentation/date_config_sheet.dart
[v6.114.0] - 2026-06-23
✨ 增强(热力图重绘 + 智能预加载 + 动画系统 + 导航增强)
1. 热力图年报水平滚动 + peakDay展示 + 月份标签 + 暗色模式
- Issue: 年报365天时单元格被压缩到8px下限,太小难以点击;peakDay已计算未展示;日期范围无月份分隔;暗色模式对比度过高
- 修复:
- 年报模式(cellWidth<12px):使用
SingleChildScrollView水平滚动,固定单元格14px - 新增 peakDay chip:显示最活跃日期(M月D日格式)
- 新增月份标签行:自动检测月份变化点,标签与热力图周列对齐
- 暗色模式
_levelColoralpha降低:1-4级分别 0.15/0.3/0.5/0.8
- 年报模式(cellWidth<12px):使用
- 涉及文件:
lib/features/reading_report/presentation/reading_report_widgets.dart
2. appPushWidget 支持 extra 参数
- Issue:
appPushWidget仅支持 builder 模式,不支持 extra 参数传递 - 修复: 新增
Object? extra可选参数,工作台模式下传入RightPanelEntry - 涉及文件:
lib/core/router/app_nav_extension.dart
3. 句子广场智能预加载
- Issue: 预加载阈值固定16,快速滚动时加载不及时
- 修复: 根据滚动速度(items/second)动态调整阈值:快速滚动(>3 items/s)时阈值翻倍(上限40),慢速滚动(<1 items/s)时恢复默认16
- 涉及文件:
lib/features/home/providers/home_provider.dart
4. Beta水印屏幕尺寸动态密度
- Issue: 水印组数密度系数固定1.5,不同屏幕宽高比密度不一致
- 修复: 根据屏幕宽高比动态调整密度系数:超宽屏(>1.8)用1.8,竖屏(<0.75)用1.2,标准屏1.5
- 涉及文件:
lib/shared/widgets/beta_testing_overlay.dart
5. 动画强度感知 — 仅首次入场动画开关
- Issue: 用户设置"无动画"后入场动画仍播放
- 修复: 入场动画读取
themeSettingsProvider.animationIntensity,durationMultiplier<=0时跳过动画,其他强度按倍率调整时长和曲线 - 涉及文件:
lib/features/home/presentation/widgets/home_sentence_list_section.dart
6. 句子卡片退出动画 + 列表项删除动画
- Issue: 屏蔽内容时卡片直接消失,无过渡动画
- 修复:
HomeState新增exitingIds字段标记退出中的卡片blockContent先标记退出中,延迟300ms后从列表移除- 退出动画:fadeOut + slideX(0→0.3) + scale(1.0→0.9)
- 涉及文件:
lib/features/home/providers/home_state.dart、lib/features/home/providers/home_interaction_mixin.dart、lib/features/home/presentation/widgets/home_sentence_list_section.dart
7. 创作卡片/编辑此句返回主页动画
- Issue: 从编辑器返回主页时无重新聚焦动画
- 修复: 新增
markReturnedFromEditor()方法,清空入场动画历史,编辑器返回后句子卡片重新播放入场动画 - 涉及文件:
lib/features/home/providers/home_provider.dart、lib/features/home/presentation/providers/sentence_detail_sheet.dart、lib/features/home/presentation/panels/sentence_detail_actions.dart
[v6.113.0] - 2026-06-23
🐛 修复(句子广场循环加载 + 热力图重绘 + 入场动画增强)
1. 句子广场骨架卡死修复(任务6)
- Issue: 主页句子广场滑到底部时显示骨架无法滑动,列表不增长
- 根因:
fetchNewSentences去重耗尽后使用 fallback 但hasMore=true,导致骨架持续显示但无新数据追加;_buildListBottom在hasMore=false时返回空SizedBox.shrink() - 修复:
home_feed_mixin.dart: 去重3轮后无新数据时,重置allSeenIds/allSeenTexts(保留最近20条避免立即重复),用本次返回数据继续填充列表,实现循环加载home_sentence_list_section.dart:_buildListBottom在hasMore=false且非离线时,显示"已经看完所有内容"提示 + 重新加载按钮(带入场动画)- 新增
resetAndReload()方法:清空已见集合,从第1页重新拉取
- 涉及文件:
lib/features/home/providers/home_feed_mixin.dart、lib/features/home/providers/home_provider.dart、lib/features/home/presentation/widgets/home_sentence_list_section.dart、lib/features/home/presentation/home_page.dart
2. 句子卡片入场动画增强(任务6.1)
- Issue: 句子载入时入场动画较单一(仅 fadeIn + slideY)
- 修复:
- 增强
_SentenceCardWithSkeleton入场动画:fadeIn + slideY(0.15) + scale(0.95→1.0, easeOutBack) + blur(4px→0, 聚焦效果) + shimmer(accent色微妙高光) - 错峰延迟从 50ms 提升到 60ms,最多 12 个卡片参与级联
- 骨架屏
_LoadingSkeletonCard增加 fadeIn + scale 入场动画
- 增强
- 涉及文件:
lib/features/home/presentation/widgets/home_sentence_list_section.dart
3. 使用报告活跃热力图重绘(任务7)
- Issue: 热力图卡片左边是热力图,右边空白,未铺满卡片
- 修复:
- 使用
LayoutBuilder响应式计算单元格尺寸,Expanded铺满卡片宽度 - 新增统计 chip 行:连续活跃天数、活跃天数/总天数、活跃率百分比
- 新增图例行:"活跃度分布" 标签 + 少→多 渐变图例
- 新增日期范围标注:底部显示起止日期(月.日格式)
- 单元格尺寸根据周数动态计算(clamp 8-18px),高度略大于宽度
- 使用
- 涉及文件:
lib/features/reading_report/presentation/reading_report_widgets.dart
[v6.112.0] - 2026-06-23
♻️ 重构(emoji完全迁移 + 窗口控制去重 + 鸿蒙端冗余简化)
1. _CloseActionTile 的 actionEmoji 迁移到 CupertinoIcons(任务10扩展)
- Issue: _CloseActionTile 的 actionEmoji 仍使用 emoji(🔴🟡❓),与任务8的 emoji→icon 迁移不一致
- 修复:
- actionEmoji 从字符串 emoji 改为 IconData(CupertinoIcons.xmark_circle_fill/minus_circle_fill/question_circle_fill)
- 图标颜色使用语义色:关闭=errorColor(红)、最小化=warningColor(黄)、询问=textHint(灰)
- 描述文本和分段控件子项改为 Row(Icon + Text) 布局
- optionText 函数移除 emoji,改为纯文本(Semantics value 应为描述性文本)
- 涉及文件:
lib/features/settings/presentation/workbench/workbench_settings_page.dart
2. AdaptiveNavBar 水平模式移除窗口控制按钮(任务10扩展)
- Issue: floatingNavBar 为 null 时回退到 AdaptiveNavBar 水平模式,会显示 - 口 X 按钮,与任务8"顶部去掉窗口按钮"要求矛盾
- 根因: DesktopWindowTitleBar 已在顶部提供完整窗口控制(macOS红黄绿灯/Windows方按钮),AdaptiveNavBar 水平模式的窗口控制按钮是重复显示
- 修复:
- 移除 _buildHorizontal 中的
if (isTop && pu.isDesktop) _buildDesktopWindowControls(context, ext)条件 - 删除 _buildDesktopWindowControls 方法、_showWindowSizeMenu 方法、_WindowControlBtn 类
- 删除不再需要的 imports(window_manager/WindowCloseHandler/WindowSizePopup/platform_utils)
- 删除未使用的 isRight、isTop、splitState 变量
- 移除 _buildHorizontal 中的
- 涉及文件:
lib/app/layout/adaptive_nav_bar.dart
3. 确认顶部窗口控制不缺失(任务10扩展)
- Issue: 任务8去掉顶部 - 口 X 按钮后,用户可能无法通过标准窗口控件关闭窗口
- 确认:
- macOS 端:DesktopWindowTitleBar 左侧提供红黄绿三圆点按钮(关闭/最小化/最大化),系统原生风格
- Windows 端:DesktopWindowTitleBar 右侧提供方形按钮(最小化/最大化/关闭),Windows 原生风格
- DesktopWindowTitleBar 在 app_shell.dart 中始终显示在桌面端顶部(第78-85行),窗口控制不缺失
- 涉及文件: 无修改(确认现有实现已满足需求)
4. GlassBottomBar 鸿蒙端防御性冗余简化(任务10扩展)
- Issue: floatingNavBar 构建时判断
AppShell._isOhos && !liquidGlassReady,但工作台模式已在 build() 中通过!pu.isOhos过滤鸿蒙端,此判断是防御性冗余 - 修复:
- floatingNavBar 直接构建 _buildGlassBottomBar,不再判断鸿蒙端
- 添加注释说明工作台模式已过滤鸿蒙端
- floatingNavBar 类型从
Widget?改为Widget(不再为 null)
- 涉及文件:
lib/app/layout/app_shell.dart
[v6.111.0] - 2026-06-23
✨ 新增与增强(情景诗词预选词 + 工作台导航栏图标化 + 滑动性能优化)
1. 情景诗词发送框改为输入预选框(任务5)
- Issue: 情景诗词页面发送框可输入任意文本,与"情景关联"语义不符
- 增强:
- 发送框改为预选词输入栏,只能发送预选的字词
- 输入时自动匹配预选词(支持同义词和拼音匹配),匹配不上时发送按钮禁用
- 发送预选词后根据预选字词调用 jinrishici API 获取对应标签的诗词
- 失焦时若仅1条建议自动填充,空输入+聚焦时显示常用标签
- 记录标签使用频率用于智能排序(getMostUsedTags/recordTagUsage)
- 涉及文件:
lib/features/weather/presentation/weather_page.dart、lib/features/weather/weather_provider.dart
2. 情景诗词设置城市联动 + 动态主题按钮字体不可见修复(任务5.1)
- Issue: 情景诗词设置页城市修改后页面不显示对应城市诗词;部分按钮字体色和按钮色一致导致选中时看不到字体
- 修复:
- WeatherSettingsNotifier 持久化到 KvStorage,城市修改后联动 weatherProvider.loadPoetryByTag(city)
- 新增"应用城市"按钮和 _onCityChanged 处理
- AppThemeExtension 新增 computeContrastColor 静态方法(WCAG 相对亮度公式)和 computedTextOnAccent getter
- _buildSegmentedRow 选中态文字颜色从 ext.textOnAccent 改为 _computeContrastColor(ext.accent)
- 任务9审计修复:原 _pow 方法对小数指数处理有 bug(0.4.toInt()=0 导致循环0次返回1.0),改用 dart:math 的 pow 确保计算精度
- 涉及文件:
lib/features/weather/presentation/weather_settings_page.dart、lib/core/theme/app_theme.dart
3. 诗词下方"第x首推荐"改为"相关诗词",只推荐一首(任务5.2)
- Issue: 诗词下方显示"第x首推荐",推荐多首诗词
- 修复: 改为"相关诗词"标题,matchedPoems 使用 .take(1) 只取1首
- 涉及文件:
lib/features/weather/presentation/weather_page.dart
4. macOS 托盘打开页面独占窗口修复(任务7.1)
- Issue: macOS 端工作台模式从托盘打开页面时独占一个窗口,导致工作台布局失效
- 根因: _navigateTo 方法使用 MediaQuery.sizeOf 判断工作台模式,窗口恢复时 MediaQuery 返回0导致判断失败
- 修复: 直接读取 splitViewProvider.workbenchEnabled 判断,工作台模式时 push 到 rightPanelStackProvider,完全绕过 MediaQuery
- 涉及文件:
lib/features/desktop/desktop_tray_controller.dart
5. 托盘切换工作台/导航栏位置概率不生效修复(任务7.2)
- Issue: macOS 端从托盘点击工作台模式开启/关闭或切换导航栏位置时概率不生效
- 根因: 未聚焦窗口 + 同步 updateMenu 与原生菜单回调冲突
- 修复: _onToggleWorkbench 和 _onSetNavBarPosition 添加 _focusMainWindow() 调用,_updateMenu 改为 Future.microtask 延迟执行
- 涉及文件:
lib/features/desktop/desktop_tray_controller.dart
6. 导航栏位置卡片 emoji 改 icon + 顶底用 GlassBottomBar 悬浮 tap 栏(任务8)
- Issue: 导航栏位置卡片使用 emoji 不统一;顶/底 tap 栏占位而非悬浮
- 增强:
- NavBarPosition 新增 icon 属性(CupertinoIcons.arrow_left/right/up/down)和 glassLabelIcon 属性(top/bottom 返回 rectangle_stack)
- 设置页分段控件和 Picker 弹窗从 emoji+label 改为 Row(Icon + Text)
- WorkbenchLayout 新增 floatingNavBar 参数,水平位置(顶/底)改用 Stack 布局实现悬浮不占位
- AppShell 提取 _buildGlassBottomBar 方法供窄屏布局和工作台顶/底布局复用
- 顶部去掉 - 口 X 窗口按钮,将 app 模式的 tap 栏调整到上方
- 涉及文件:
lib/core/providers/split_view_provider.dart、lib/features/settings/presentation/workbench/workbench_settings_page.dart、lib/features/settings/presentation/general/general_settings_pickers.dart、lib/core/layout/workbench/workbench_layout.dart、lib/app/layout/app_shell.dart
7. 工作台模式句子广场滑动卡顿优化(任务7)
- Issue: 工作台模式主页句子广场滑动时卡顿不丝滑
- 优化:
- 预加载检查(onCheckPreload/onLoadMore)从 Future(() => ...) 改为 WidgetsBinding.instance.addPostFrameCallback,避免在 build 中触发副作用
- SliverChildBuilderDelegate 设置 addRepaintBoundaries: false(已在子项手动添加 RepaintBoundary)和 addAutomaticKeepAlives: false(句子卡片无需保持存活状态)
- LongPressDraggable 的 feedback 改为轻量占位卡片(仅显示句子文本和作者),childWhenDragging 改为简单图标占位符,避免构建完整 SentenceCard
- CustomScrollView 添加 cacheExtent: 800,预渲染视口外的卡片,减少滚动时的重建
- 涉及文件:
lib/features/home/presentation/widgets/home_sentence_list_section.dart、lib/features/home/presentation/home_page.dart
8. 任务9审计修复:weather_provider 空指针风险
- Issue: loadPoetryByTag 方法中 state.weather! 和 state.mood! 使用非空断言,天气未加载完成时可能抛出空指针异常
- 修复: 直接从 jinrishiciData 提取数据,不再创建 WeatherPoetryResult 对象,避免 state.weather!/state.mood! 空指针风险
- 涉及文件:
lib/features/weather/weather_provider.dart
[v6.110.3] - 2026-06-23
🐛 修复(窗口尺寸选择菜单 clamp 崩溃 + 屏幕尺寸获取不可靠)
1. WindowSizePopup 选择尺寸时 clamp 抛出 Invalid argument(s): 360.0(严重)
- Issue: macOS 端点击窗口栏绿灯按钮,选择窗口尺寸预设时抛出
Invalid argument(s): 360.0,菜单无法应用尺寸 - 根因:
_applySize中targetH.clamp(minH, screen.height - 16)要求lowerLimit <= upperLimit- 当
_screenWorkArea异步初始化未完成时,回退到MediaQuery.sizeOf(context),而 MediaQuery 在桌面端返回的是窗口尺寸(可能很小,如 300×200) - 当
screen.height - 16 < 360(即窗口高度 < 376)时,clamp(360.0, <360)抛出Invalid argument(s): 360.0
- 修复:
- 使用
math.max(minW, screen.width - 16)确保 clamp 上限不小于下限 _applySize中若_screenWorkArea为 null,先await _refreshScreenWorkArea()同步刷新一次,避免回退到窗口尺寸- 添加安全默认值
Size(1280, 800)作为最终回退
- 使用
- 涉及文件:
lib/shared/widgets/window_size_popup.dart
2. _refreshScreenWorkArea 屏幕尺寸获取不可靠
- Issue:
PlatformDispatcher.views.first.physicalSize在窗口初始化阶段可能为Size.zero,导致计算出的屏幕尺寸为 0 - 根因: Flutter 视图未完成首帧布局时
physicalSize未初始化 - 修复:
- 检测
physical.isEmpty || dpr <= 0,回退到 MediaQuery - 添加防御性检查:若 workArea 为空或异常小(<100px),使用安全默认值
Size(1280, 800) - catch 块同样添加防御性检查
- 检测
- 涉及文件:
lib/shared/widgets/window_size_popup.dart
[v6.110.2] - 2026-06-23
🐛 修复(收藏页面瀑布流视图 RenderFlex 布局崩溃)
1. FavoriteGridCard 在瀑布流中 Expanded 无界高度约束崩溃(严重)
- Issue: macOS 运行时进入"我的收藏"页面,切换到瀑布流视图(MasonryGridView)后抛出
RenderFlex children have non-zero flex but incoming height constraints are unbounded,连锁触发RenderBox was not laid out: RenderFlex/RenderPadding/RenderDecoratedBox/RenderRepaintBoundary/RenderSemanticsGestureHandler,以及sliver_multi_box_adaptor.dart: child.hasSize断言失败和Null check operator used on a null value,导致整个收藏页面无法渲染 - 根因:
FavoriteGridCard同时用于网格视图(GridView.builder+childAspectRatio: 0.85,高度有界)和瀑布流视图(MasonryGridView.count,高度无界 0~Infinity)Column内使用Expanded包裹文本内容,Expanded要求父级提供有限高度约束- 瀑布流中父级高度约束为
0~Infinity(无界),Expanded与 shrink-wrap 互斥,触发断言 Column的mainAxisSize默认为MainAxisSize.max,在无界约束下尝试扩展到无限大小
- 修复:
- 将
Expanded改为Flexible(默认FlexFit.loose),在有界约束下可扩展填充剩余空间,在无界约束下可自然收缩到子组件固有大小 - 显式设置
Column的mainAxisSize: MainAxisSize.min,让 Column 收缩包裹子组件,避免在无界约束下尝试扩展 _buildHighlightedText已有maxLines: 5+overflow: TextOverflow.ellipsis限制,可保证文本不溢出
- 将
- 涉及文件:
lib/features/home/presentation/favorite/favorite_card.dart
[v6.110.1] - 2026-06-23
🐛 修复(Beta 水印蒙版布局崩溃 + 情景诗词标题溢出 + 框架错误弹窗骚扰)
1. BetaTestingOverlay 无限约束导致 RenderBox 布局失败(严重崩溃)
- Issue: macOS 运行时抛出
BoxConstraints forces an infinite width and infinite height+RenderBox was not laid out: RenderTransform,导致 4 个实验性页面(工具中心/编辑器/句子来源/桌面小部件)无法正常渲染 - 根因:
OverflowBox使用maxWidth/maxHeight: double.infinity传播无限约束Container设置width/height: double.infinity在无限约束下无法计算自身尺寸Transform.rotate包裹无限大小的子组件,导致 RenderBox 无法布局
- 修复:
- 移除
OverflowBox的double.infinity,改用屏幕对角线 × 1.5 作为有限容器尺寸(保证旋转后仍覆盖全屏) - 移除
Container的width/height: double.infinity,改用Padding避免无限尺寸传播
- 移除
- 涉及文件:
lib/shared/widgets/beta_testing_overlay.dart
2. BetaTestingOverlay ParentData 传递失败(Positioned 必须直接挂在 Stack 下)
- Issue: macOS 运行时抛出
Incorrect use of ParentDataWidget,Positioned无法找到Stack祖先 - 根因:
IgnorePointer包裹了Positioned.fill,阻断了StackParentData的传递(Positioned必须是Stack的直接子组件,中间不能有其他 RenderObjectWidget) - 修复: 将
Positioned.fill移到最外层作为根组件,IgnorePointer放在其内部 - 涉及文件:
lib/shared/widgets/beta_testing_overlay.dart
3. 情景诗词推荐列表标题 2 像素右侧溢出
- Issue: 情景诗词页面推荐 tab 中的诗词卡片元信息行(作者 + 标题 + 关键词)溢出 2 像素
- 根因:
- 作者
Text和标题Text未包裹Flexible,按固有宽度渲染不收缩 Spacer()强制占用剩余空间,与未收缩的文本冲突- 当作者名 + 《标题》+ 关键词 + 间距超过 Row 可用宽度时产生溢出
- 作者
- 修复:
- 作者和标题
Text用Flexible包裹,添加maxLines: 1+overflow: TextOverflow.ellipsis - 移除
Spacer(),改用固定SizedBox(width: AppSpacing.sm)间距,避免与Flexible冲突
- 作者和标题
- 涉及文件:
lib/features/weather/presentation/weather_page.dart
4. IOSScrollViewFlingVelocityTracker 时间戳乱序错误弹窗骚扰(Flutter 框架 bug 静默处理)
- Issue: macOS 上滚动时偶发
The position being added ... has a smaller timestamp ... than its predecessor错误,触发 Catcher2 弹窗打扰用户 - 根因: Flutter 框架
IOSScrollViewFlingVelocityTracker.addPosition断言时间戳单调递增,但 macOS/iOS 触摸事件时间戳偶尔乱序(框架已知 bug,非应用代码问题) - 修复:
Catcher2ConfigService: 新增_silentFrameworkErrorPatterns统一过滤框架内部已知非致命错误CopyableDialogReportMode: 匹配静默模式时自动确认不弹窗_ConsoleLogHandler: 静默错误降级为Log.w,不记录到CrashLogServiceGlobalErrorHandler: 同步增加smaller timestamp静默处理,保持双层防护一致性
- 涉及文件:
lib/core/services/catcher2_config_service.dart、lib/core/services/error/global_error_handler.dart
[v6.110.0] - 2026-06-23
✨ 新增(Beta 测试全局水印蒙版 + 诗词匹配增强 + 动画可交互)
1. Beta 测试全局透明水印蒙版(Issue 2 Flutter 实施)
- Issue: 工具中心/编辑器/句子来源/桌面小部件 4 个实验性页面需添加透明网格水印蒙版,标识 Beta 测试状态与设备溯源信息
- 修改:
- 新增
BetaTestingOverlay共享组件:透明网格水印,3 行内容(主标识/状态提示/溯源信息),字体统一 12px,斜向 -22° 排列,水印贯穿两侧(OverflowBox + Transform.rotate + Wrap 平铺) - 3 行内容:① 闲言APP beta testing(加粗)② 实验中的功能(斜体)③ IP · 机型 · 时间 · 版本 · 随机码(等宽字体)
- 异步并行加载设备信息(DeviceInfoService.getDeviceName)与 IP 地址(IpLocationService.queryMyIp),加载完成前不显示蒙版避免闪烁
- 浅色/深色主题自适应颜色,IgnorePointer 包裹不阻挡页面交互
- 偶数组额外显示
xianyan · beta标识行增加视觉层次 - 水印密度动态调整:LayoutBuilder 根据屏幕尺寸计算 itemCount(屏幕面积 / 单组面积 × 1.2 密度系数),clamp 到 [6, 30],小屏稀疏大屏饱满
- 本地 IP 回退:三级回退策略(queryMyIp 24h缓存 → KvStorage 永不过期上次IP → 未知IP),离线时仍可显示上次 IP
- 新增
- 涉及文件:
- 新增
lib/shared/widgets/beta_testing_overlay.dart - 修改
lib/features/home/presentation/home_tool_center.dart(Stack 顶层叠加) - 修改
lib/editor/pages/editor/editor_page.dart(ProEditorPage 与加载态均叠加) - 修改
lib/features/source/presentation/source_page.dart(CupertinoPageScaffold 外层 Stack 叠加) - 修改
lib/features/widget/presentation/widget_management_page.dart(CupertinoPageScaffold 外层 Stack 叠加)
- 新增
🐛 修复(诗词匹配精度 + API 标签限制 + 搜索历史 + 动画交互 + 功耗 tips + 去重池 + 加载动画)
2. 情景诗词匹配精度有限(拼音/同义词无法匹配)
- Issue:
findMatchingTags使用 contains 模糊匹配,输入"下雨"无法匹配"雨",拼音/同义词无法匹配 - 修改:
- 新增 60+ 条同义词/近义词映射表
kSynonymMap(如"下雨"→["雨"]、"南京"→["金陵"]、"梅"→["梅花"]) - 新增 3 层匹配策略:① 同义词映射 ② 中文包含匹配 ③ 拼音匹配(PinyinHelper.getShortPinyin/getPinyin)
- 新增拼音缓存
_pinyinCache避免重复计算 - 匹配结果按使用频率智能排序(
_sortByUsageFrequency)
- 新增 60+ 条同义词/近义词映射表
- 涉及文件:
lib/features/poetry/presentation/poetry_tags.dart
3. 无搜索历史记录与智能排序
- Issue: 用户频繁使用的标签未记录,无智能排序
- 修改:
- 新增
getTagUsageHistory/recordTagUsage/getMostUsedTags基于 KvStorage 持久化标签使用历史 - 存储格式
tag\u0000count,保留前 30 条高频标签 PoetryInputBar发送/选择建议时调用recordTagUsage记录- 输入框聚焦且为空时显示"常用"标签行(最多 6 个),点击直接发送
- 新增
- 涉及文件:
lib/features/poetry/presentation/poetry_tags.dartlib/features/poetry/presentation/poetry_widgets.dart
4. API 标签限制(fetchSentenceByTag 重试仍可能不匹配)
- Issue: jinrishici API 不支持客户端传 tag 参数,matchTags 重试最多 3 次仍可能不匹配
- 修改:
- 新增内存缓存
_tagCache(5 分钟 TTL),命中缓存直接返回避免重复请求 - 重试次数从 3 次增至 5 次,每次间隔 500ms
- 第 3 次仍不匹配时再次清除 Token 换推荐种子
- 5 次都不匹配时返回最后结果并缓存(仍可展示)
- 所有请求失败时回退到无标签的
fetchSentence()
- 新增内存缓存
- 涉及文件:
lib/core/services/data/jinrishici_sdk_service.dart
5. 动画为静态循环(无法响应用户交互)
- Issue: 工作台/分屏动画演示为纯演示性质,无法点击切换方向
- 修改:
- 新增
_paused1/_paused2状态与_togglePause1()/_togglePause2()方法 - 点击动画卡片切换暂停/继续,暂停时显示半透明遮罩 + play 图标
- AnimationController 通过
stop()/repeat(reverse: true)控制暂停/继续
- 新增
- 涉及文件:
lib/features/settings/presentation/workbench/workbench_animation_demos.dart
6. 动画尺寸固定(小屏拥挤)
- Issue:
_AnimationCard高度固定 60px,小屏下可能拥挤 - 修改:
- 改用 LayoutBuilder 自适应高度:
animHeight = (maxW * 0.5).clamp(50.0, 80.0) - 宽度与高度均根据父容器约束动态计算
- 改用 LayoutBuilder 自适应高度:
- 涉及文件:
lib/features/settings/presentation/workbench/workbench_animation_demos.dart
7. 功耗 tips 文案单一(未区分移动端/桌面端)
- Issue: 功耗提示未区分移动端/桌面端的功耗差异说明
- 修改:
PowerConsumptionTip根据pu.isMobile/pu.isDesktop显示不同文案- 移动端:"移动端同时打开多个页面会增加功耗与内存占用"
- 桌面端:"桌面端多页面并行渲染会占用更多显存与 CPU 资源"
- 其他平台:"同时打开多个页面会增加系统资源占用"
- 涉及文件:
lib/features/settings/presentation/workbench/workbench_animation_demos.dart
8. 日签去重池仅 20 条(高频换一句仍可能重复)
- Issue: 去重池容量仅 20 条,高频换一句后仍可能重复
- 修改:
_maxHistorySize从 20 扩容至 50,降低高频换一句时的重复概率 - 涉及文件:
lib/features/daily_card/daily_card_provider.dart
9. 换一句无加载动画(内容突然替换)
- Issue: 换一句过程中无过渡动画,内容突然替换
- 修改:
- AnimatedSwitcher 的 key 加入
content.text.hashCode,内容变化时触发过渡 - 新增
transitionBuilder:FadeTransition + ScaleTransition(0.95→1.0) - 新增
isRefreshing半透明遮罩 + CupertinoActivityIndicator 居中加载指示器 - IgnorePointer 包裹遮罩避免阻挡交互
- AnimatedSwitcher 的 key 加入
- 涉及文件:
lib/features/daily_card/presentation/daily_card_page.dart
[v6.109.0] - 2026-06-23
✨ 新增(情景诗词输入预选框 + 工作台动画演示)
1. 情景诗词发送框改为输入预选框
- Issue: 用户要求发送框只能发送预选词,输入时自动匹配预选词,根据预选词更换诗词
- 修改:
- 新增
PoetryInputBar组件:输入框+发送按钮,实时匹配预选词建议列表,仅允许发送精确匹配的预选词 - 新增
kAllPoetryTags扁平化标签列表、findMatchingTags模糊匹配、isExactTag精确匹配辅助函数 - 增强
fetchSentenceByTag:增加 matchTags 匹配重试(最多3次),提升标签与诗词相关性 - 增强城市显示:从纯文本改为带图标的卡片样式,显示当前城市+天气+温度
- 新增
- 涉及文件:
lib/features/poetry/presentation/poetry_tags.dartlib/features/poetry/presentation/poetry_widgets.dartlib/features/poetry/presentation/poetry_page.dartlib/core/services/data/jinrishici_sdk_service.dart
2. 工作台模式设置页增加动画演示图
- Issue: 工作台模式和分屏功能开关下方需增加动画演示图,导航栏位置卡片需增加功耗提示
- 修改:
- 新增
WorkbenchModeAnimationDemos:工作台↔App模式切换动画(三栏收缩/展开) - 新增
SplitViewAnimationDemos:竖屏↔横屏切换动画(上下/左右分栏淡入淡出) - 新增
PowerConsumptionTip:功耗内存占用提示标签 _SliderTile增加trailing参数支持右下角附加组件
- 新增
- 涉及文件:
- 新增
lib/features/settings/presentation/workbench/workbench_animation_demos.dart - 修改
lib/features/settings/presentation/workbench/workbench_settings_page.dart
- 新增
🐛 修复(窗口尺寸 + 横屏布局 + 路由匹配 + 骨架超时)
3. macOS/Win窗口尺寸选择异常
- Issue: 12-13寸笔记本选择1920×1080后窗口比屏幕大;4K/2K大显示器选择800×600后窗口很小
- 修改:
- 将绝对像素预设改为屏幕比例预设(50%/65%/75%/85%/95%/100%)
- 新增
_refreshScreenWorkArea检测屏幕工作区(macOS扣28px菜单栏,Win扣48px任务栏) _applySize按比例计算目标尺寸并 clamp 到屏幕安全区,应用后居中- UI 显示比例标签+动态像素值+屏幕尺寸
- 涉及文件:
lib/shared/widgets/window_size_popup.dart
4. 移动端横屏左侧空白
- Issue: 横屏窄屏(600<width<768)时使用 Center+ConstrainedBox 导致两侧空白
- 修改: 改为
Row[_buildVerticalTabBar(), Expanded(content)]布局,左侧显示垂直tab栏 - 涉及文件:
lib/app/layout/app_shell.dart
5. 工作台切换App模式后按钮残留选中态
- Issue: 从工作台模式切换成app模式后,已打开页面的按钮仍显示选中着重色
- 修改:
activeRightPanelRouteProvider增加工作台模式守卫,非工作台模式返回 nullRightPanelStackNotifier新增clearAll()方法清空所有Tab右栏栈setWorkbenchEnabled关闭工作台模式时调用clearAll()
- 涉及文件:
lib/core/layout/workbench/right_panel_navigator.dartlib/core/providers/split_view_provider.dart
6. 嵌套子路由匹配失败
- Issue: 闲情逸致页面点击设置icon无法跳转到设置页面
- 根因:
_findInChildren比较def.path == path,但子路由路径是相对的(如settings),搜索路径是绝对的(如/leisure/settings) - 修改: 新增
_joinPath辅助函数拼接父路径和子路径,_findInChildren和_findInChildrenParam增加parentPath命名参数 - 涉及文件:
lib/core/router/route_registry.dart
7. 闲情逸致骨架持续显示
- Issue: 工作台模式下闲情逸致页面有时一直显示骨架不显示内容
- 根因:
_init()中的数据加载操作没有超时保护,可能挂起导致isLoading永远为 true - 修改: 为每个
loadIndex()和loadMonth()调用添加3秒超时;build()中添加5秒安全兜底强制结束 loading - 涉及文件:
lib/features/tool_center/leisure/providers/leisure_timeline_provider.dart
8. 日签卡片换一句无效
- Issue: 点击换一句后卡片内容未更换
- 根因:
refreshCurrentType()优先调用_fetchByType(每日API),同一天返回相同内容 - 修改: 改为优先使用
_fetchFromChannel(带去重+重试的频道随机接口),失败时回退到每日API;新增内容相同检测,若相同再尝试一次 - 涉及文件:
lib/features/daily_card/daily_card_provider.dart
9. 导出个人信息页面布局错误
- Issue:
[ERR-MQPK2MM9]proxy_box.dart!debugNeedsLayout断言错误 - 根因:
Flexible+shrinkWrap: trueListView 在Column中导致布局问题 - 修改: 改为
Expanded(移除shrinkWrap),提供固定高度约束 - 附加: 列表底部新增 tips 气泡提示,URL 使用强调色可点击复制
- 涉及文件:
lib/features/settings/presentation/account/account_export_info_sheet.dart
📝 文案修改
10. 了解我们页面文案更新
- "官网首页"改为"在 闲言App",增加副标题"在其他设备上下载闲言app"
- URL 改为
https://s2ss.com/app.html - 团队签名更新:无书的书→"不会写代码的小书",伯乐不相马→"这个bug有力气👍"
- 涉及文件:
lib/features/profile/presentation/learn_us_sections.dart,lib/features/profile/presentation/learn_us_widgets.dart,lib/l10n/languages/zh_cn.dart
11. 工作台模式文案更新
- "微信PC"改为"studio"
- 涉及文件:
lib/l10n/languages/zh_cn.dart,lib/l10n/languages/zh_tw.dart
🎨 新功能预告
12. 新版本功能介绍增加预告视图
- 新增预告卡片:"下个版本,即将支持在应用内加载网页url"
- 涉及文件:
lib/features/home/presentation/widgets/new_features_dialog.dart
[v6.108.0] - 2026-06-23
🐛 修复(布局溢出 + 运行时错误)
1. 翻译助手页面底部溢出 29px
- Issue: 分栏模式下空状态内容(图标+文字+快捷翻译芯片)超出可用高度导致 BOTTOM OVERFLOWED BY 29 PIXELS
- 修改:
_buildEmptyState包裹SingleChildScrollView(physics: NeverScrollableScrollPhysics)允许内容在受限空间内自适应收缩 - 涉及文件:
lib/features/discover/presentation/pages/translate/translate_page.dart
2. 情景诗词页面右侧溢出 2px
- Issue: 诗词卡片 padding(AppSpacing.md) + ListView 水平 padding 叠加后总宽度超出 2px
- 修改: 卡片水平 padding 从
AppSpacing.md(16) 缩减为AppSpacing.sm(8),垂直保持不变 - 涉及文件:
lib/features/poetry/presentation/poetry_page.dart
3. 发现页松手打开区域底部溢出 38px
- Issue: 下拉刷新指示器容器使用固定
height但内部内容(气泡+精灵角色+进度条)实际高度超出容器 - 修改: 容器从固定
height改为constraints: BoxConstraints(minHeight:),允许内容撑开 - 涉及文件:
lib/features/discover/presentation/pages/home/discover_page.dart
4. Quick Card 编辑器右侧溢出
- Issue: 预览区宽度计算
screenWidth - 16未考虑父容器padding: AppSpacing.md(双侧共32px),分栏模式下溢出 - 修改: 预览最大宽度改为
(screenWidth - 32).clamp(200, ∞),预留父容器双边距 - 涉及文件:
lib/features/home/presentation/widgets/quick_card_preview.dart
5. 灵感页面关联推荐卡片底部溢出 12px
- Issue: 关联推荐横向列表容器
SizedBox(height: 140)小于FeedItemChip(normal)模式实际内容高度 - 修改: 容器高度从 140 增加到 156
- 涉及文件:
lib/features/discover/presentation/pages/home/related_recommend_section.dart
6. RenderFractionalTranslation hitTestChildren 断言错误
- Issue: 灵感页面使用
Transform.translate包裹CustomScrollView,下拉刷新时 offset 动态变化触发布局断言!debugNeedsLayout - 修改: 用
Padding(padding: EdgeInsets.only(top: offsetY))替代Transform.translate(offset: Offset(0, offsetY)),实现相同视觉效果且不触发断言 - 涉及文件:
lib/features/discover/presentation/pages/home/inspiration_page.dart
7. Scrollbar ScrollController 无 ScrollPosition 错误
- Issue: 金币记录页
CupertinoScrollbar未指定 controller 参数,默认使用 PrimaryScrollController 导致无 ScrollPosition 可绑定 - 修改: 新增
_scrollController并同时传给CupertinoScrollbar(controller:)和CustomScrollView(controller:) - 涉及文件:
lib/features/user_center/presentation/coin_log_page.dart
[v6.107.0] - 2026-06-22
🏗️ 重构(应用根组件深度职责分离)
1. 快捷操作处理器提取
- Issue: 搜索快捷方式逻辑(
_handleSearchShortcut)和路由导航仍内联在根组件 - 修改:
- 提取
QuickActionsHandler:封装快捷方式回调逻辑(搜索快捷方式 + 路由导航),处理白屏修复逻辑 - 根组件仅调用
_quickActionsHandler.initialize()
- 提取
- 涉及文件: 新增
lib/app/services/quick_actions_handler.dart,修改lib/app/app.dart
2. 小组件导航服务提取
- Issue:
_handlePendingWidgetNavigation仍留在根组件 - 修改:
- 提取
WidgetNavigationService:封装小组件点击后的待处理导航逻辑 - 生命周期恢复时调用
_widgetNavigationService.handlePendingNavigation()
- 提取
- 涉及文件: 新增
lib/app/services/widget_navigation_service.dart,修改lib/app/app.dart
3. 应用锁生命周期服务提取
- Issue:
didChangeAppLifecycleState中的应用锁暂停/恢复逻辑仍内联 - 修改:
- 提取
AppLockLifecycleService:封装应用锁在前后台切换时的处理逻辑 - 生命周期回调简化为
_appLockLifecycleService.onAppPaused()/onAppResumed()
- 提取
- 涉及文件: 新增
lib/app/services/app_lock_lifecycle_service.dart,修改lib/app/app.dart
4. ThemeSettingsState.toThemeData() 方法
- Issue:
AppTheme.buildFromSettings在 build 方法中被调用两次(light+dark),参数传递冗长 - 修改:
- 在
ThemeSettingsState上添加toThemeData()方法,封装主题构建逻辑 - build 方法中主题构建从 30+ 行参数简化为 3 行方法调用
- 支持
isDark参数覆盖,用于构建 darkTheme
- 在
- 涉及文件: 修改
lib/features/settings/providers/theme_settings_provider.dart
[v6.106.0] - 2026-06-22
🏗️ 重构(应用根组件职责分离)
1. 根组件职责过重问题
- Issue:
XianyanApp承担了10+个不同职责(主题同步、动画配置、数据管理、快捷方式、桌面服务等),违反单一职责原则,代码复杂度高、难以维护和测试 - 修改:
- 提取
ThemeSyncService:管理主题状态同步到桌面端(macOS/Windows),包含窗口特效和托盘图标主题同步,内置去重机制 - 提取
AnimationConfigService:管理 flutter_animate 全局动画配置(时长、曲线),仅在设置变化时更新 - 提取
DataManagementService:管理原生数据管理通道(MethodChannel),处理系统存储清理、数据清除、页面导航 - 提取
DesktopServicesManager:统一管理桌面端服务初始化和生命周期(托盘、窗口特效、菜单栏) - 重构
app.dart:使用4个服务类替代原有内联逻辑,代码量从874行降至689行(减少约21%) - 提取
_buildOhosApp/_buildStandardApp/_buildGlassThemeData/_buildOfflineBanner方法,提高 build 方法可读性
- 提取
- 涉及文件:
- 新增:
lib/app/services/theme_sync_service.dart - 新增:
lib/app/services/animation_config_service.dart - 新增:
lib/app/services/data_management_service.dart - 新增:
lib/app/services/desktop_services_manager.dart - 修改:
lib/app/app.dart
- 新增:
[v6.105.0] - 2026-06-22
✨ 增强(情景诗词交互重构 + 数据管理 + 功能补全)
1. 预选词选择器重构
- Issue: 展开分组宽度变化造成视觉跳动,横向滚动单手操作不便,无搜索功能
- 修改:
- 底部选择器改为纵向网格布局:搜索框 + 分组标题 + 标签芯片网格
- 搜索框实时过滤所有标签
- 分组标题仅视觉分隔,不可点击展开(消除跳动)
- 标签芯片直接点击选中/取消,无需展开/收起
- 涉及文件:
poetry_widgets.dart(PoetryTagSelector)
2. 标签组合选择
- Issue: 只能选择单个标签
- 修改:
- 支持同时选择多个标签(如「秋+雨」组合筛选)
- 已选标签显示在搜索框下方,支持点击取消/清除全部
PoetryState.selectedTags从String?改为List<String>PoetryNotifier新增clearSelectedTags()/removeSelectedTag()方法
- 涉及文件:
poetry_provider.dart,poetry_widgets.dart
3. 诗词卡片长按菜单
- Issue: 底部快捷按钮占用空间且不符合 iOS 交互习惯
- 修改:
- 使用
CupertinoContextMenu包裹诗词卡片,长按弹出收藏/复制/分享/朗读菜单 - 删除底部快捷按钮(
_buildQuickActions/_buildQuickButton)
- 使用
- 涉及文件:
poetry_page.dart
4. 手势操作
- Issue: 无法删除单条聊天记录或快速收藏
- 修改:
- 诗词卡片使用
Dismissible组件 - 右滑显示收藏图标(收藏不移除卡片)
- 左滑显示红色删除按钮(删除该条记录)
PoetryNotifier新增removeChatRecord(id)方法
- 诗词卡片使用
- 涉及文件:
poetry_page.dart,poetry_provider.dart
5. 聊天记录清空按钮
- Issue: 无清空聊天记录入口
- 修改:
- 诗词页面导航栏添加垃圾桶图标按钮
- 设置页面「数据管理」卡片添加清空按钮
- 点击弹出确认对话框,确认后调用
clearChatRecords()
- 涉及文件:
poetry_page.dart,poetry_settings_page.dart
6. 聊天记录上限提示
- Issue: 聊天记录上限 200 条但无提示
- 修改:
- 当
chatRecords.length > 180时,列表顶部显示黄色提示条 - 设置页面「数据管理」卡片显示 N/200 进度指示
- 当
- 涉及文件:
poetry_page.dart,poetry_settings_page.dart
7. 诗词日历视图
- Issue: 无历史诗词查看入口
- 修改:
- 导航栏添加日历图标按钮
- 点击弹出底部弹窗,按日期分组展示历史诗词
- 使用
poetryState.poetryRecords获取所有诗词记录
- 涉及文件:
poetry_widgets.dart(PoetryCalendarSheet)
8. 统一聊天记录系统
- Issue:
poetryHistory和chatRecords两套独立系统,数据冗余 - 修改:
- 合并为统一的
chatRecords,删除poetryHistory字段 PoetryChatRecord直接存储JinrishiciPoetry对象(替代poetryJsonMap)- 缓存 key 升级为
poetry_cache_v2
- 合并为统一的
- 涉及文件:
poetry_provider.dart
9. 功能补全
- Issue: 设置开关存在但 UI 未渲染(标签、译文、城市/天气)
- 修改:
- 诗词气泡中根据
showTags渲染标签芯片 - 诗词气泡中根据
showTranslate渲染译文内容 - 聊天列表顶部显示城市/天气信息
- 诗词气泡中根据
- 涉及文件:
poetry_page.dart
10. 设置页面增强
- 修改:
- 新增「使用提示」卡片,包含 7 条功能说明
- 新增「数据管理」卡片,显示聊天记录统计和清空按钮
- 涉及文件:
poetry_settings_page.dart
11. 文件拆分
- 修改:
poetry_page.dart(586 行)拆分出poetry_tags.dart(标签定义)和poetry_widgets.dart(选择器+日历组件)- 所有文件均低于 1000 行限制
- 涉及文件: 新增
poetry_tags.dart,poetry_widgets.dart
[v6.104.0] - 2026-06-22
✨ 增强(情景诗词预选词选择器 + 城市设置 + 聊天记录持久化)
1. 情景诗词输入框改为预选词芯片选择器
- Issue: 情景诗词页面原发送框为自由文本输入,无法有效按标签筛选诗词
- 修改:
- 将底部输入框替换为预选词芯片选择器,只能选择预定义标签
- 7 个标签分组:气象🌤、时辰🕐、季节🌸、节日🎉、地理🏔、花木🌺、山水⛰
- 标签基于 jinrishici API 推荐关联标签体系(气象/时间/日期/地理/混合标签)
- 点击分组展开标签列表,选择标签后触发诗词刷新
- 当前选中标签高亮显示,支持清除
- 涉及文件:
poetry_page.dart
2. 预选词选择后按标签刷新诗词
- Issue: 选择预选词后需根据标签获取对应诗词
- 修改:
JinrishiciSdkService新增fetchSentenceByTag()方法PoetryService新增fetchPoetryByTag()方法PoetryNotifier新增loadPoetryByTag()方法- 选择标签后清除旧 Token 重新请求,触发 API 生成新推荐
- 聊天界面显示用户选择的标签和系统返回的诗词
- 涉及文件:
jinrishici_sdk_service.dart,poetry_service.dart,poetry_provider.dart
3. 设置页面城市选择,影响诗词页面显示
- Issue: 情景诗词设置页面城市功能为空壳,修改城市后诗词页面无变化
- 修改:
PoetrySettings新增city字段,持久化到 KvStorage- 设置页面新增「城市设置」分组卡片
- 城市选择弹窗提供 24 个古诗词名城(长安/洛阳/金陵/临安/姑苏/扬州等)
- 选择城市后同步到
poetryProvider,诗词页面显示对应城市 - 城市标签同时触发
loadPoetryByTag()获取对应地域诗词
- 涉及文件:
poetry_settings_page.dart,poetry_provider.dart
4. 聊天记录持久化保存
- Issue: 情景诗词页面聊天记录仅保存在内存,退出即丢失
- 修改:
PoetryState新增chatRecords字段- 新增
PoetryChatRecord模型(type/content/time/poetryJson) - 用户发送的标签、系统提示、返回的诗词全部持久化到缓存
- 最多保留 200 条记录,超出自动清理旧记录
- 下次打开软件可看到历史聊天记录,最新消息在最下面(类似微信/QQ)
PoetryNotifier新增addChatRecord()和clearChatRecords()方法
- 涉及文件:
poetry_provider.dart,poetry_page.dart
[v6.103.0] - 2026-06-22
✨ 增强(快速卡片多语言全量补全 + 液态玻璃预设视觉实现 + 样式区翻译接入)
1. 12 种语言 quickCard 翻译补全
- Issue: 12 种语言(zh_tw/ja/ko/fr/de/es/it/pt/ru/ar/hi/bn)的 quickCard 字段为英文占位,非中英用户看到英文
- 修复:
- 12 个语言文件全部翻译为各自语言,覆盖 100+ 翻译键
- zh_tw 使用台湾繁体习惯(儲存/相簿/範本/重設/套用/字級)
- ja 使用日文习惯(保存/共有/キャンセル/リセット/テンプレート)
- ko 使用韩文习惯(저장/공유/취소/초기화/템플릿)
- fr/de/es/it/pt/ru/ar/hi/bn 均使用各自语言习惯
- 品牌名
✨ Slight editor mini和Xianyan保持不变 - 中文字体名(宋体/楷体等)翻译为对应语言的字体描述
- 验证:
flutter analyze14 个语言文件全部通过
2. 液态玻璃预设视觉实现(iOS 26 风格)
- Issue:
CardPresetStyle.liquidGlass预设已存在但无液态玻璃视觉效果,仅显示普通渐变 - 修复:
QuickCardPreview新增_buildCardContent()方法,当presetStyle == liquidGlass且平台支持时,使用AdaptiveLiquidGlassLayer包裹卡片内容LiquidGlassSettings参数:blur=1.2 / refractiveIndex=1.45 / chromaticAberration=0.6 / lightIntensity=1.0 / ambientStrength=0.5- 使用
LiquidRoundedSuperellipse(borderRadius: 12)与卡片圆角统一 - 通过
PlatformCapabilities.supports(CapabilityKey.liquidGlass)检测平台能力,不支持时降级为普通渐变 applyPreset(liquidGlass)补充gradientColors默认值和gradientBegin/End方向
- 效果: 选择液态玻璃预设后,卡片预览区呈现 iOS 26 液态玻璃折射效果
3. 样式调整区全量翻译接入
-
Issue:
quick_card_style_sections.dart中 31 处硬编码中文(栏样式/信息/字体/色深/字号/大小/功能开关/朗读 等) -
修复:
QuickCardStyleSection/QuickCardToggleSection/QuickCardPresetSection新增TQuickCard t参数_BarStyleRow/_BottomInfoRow/_FontRow/_ColorDepthRow/_FontSizeRow/_CardSizeRow/_TtsToggleItem全部接收t参数_FontRow分离_fontKeys(不可翻译的标识符)和_fontLabels(翻译后的显示标签)PresetCard新增t参数,_label使用翻译键quick_card_layouts.dart两处调用点传入t参数
-
文件:
- lib/l10n/languages/zh_tw.dart(翻译补全)
- lib/l10n/languages/ja.dart(翻译补全)
- lib/l10n/languages/ko.dart(翻译补全)
- lib/l10n/languages/fr.dart(翻译补全)
- lib/l10n/languages/de.dart(翻译补全)
- lib/l10n/languages/es.dart(翻译补全)
- lib/l10n/languages/it.dart(翻译补全)
- lib/l10n/languages/pt.dart(翻译补全)
- lib/l10n/languages/ru.dart(翻译补全)
- lib/l10n/languages/ar.dart(翻译补全)
- lib/l10n/languages/hi.dart(翻译补全)
- lib/l10n/languages/bn.dart(翻译补全)
- lib/features/home/presentation/widgets/quick_card_preview.dart(液态玻璃效果)
- lib/features/home/presentation/widgets/quick_card_style_sections.dart(翻译接入)
- lib/features/home/presentation/widgets/quick_card_widgets.dart(PresetCard 翻译)
- lib/features/home/presentation/widgets/quick_card_state_logic.dart(liquidGlass 预设补全)
- lib/features/home/presentation/widgets/quick_card_layouts.dart(t 参数传递)
[v6.102.0] - 2026-06-22
✨ 增强(快速卡片创作 Sheet 拆分 + 多语言全量接入 + A/B 对比模式 UI 补全)
1. 文件拆分(quick_card_sheet.dart 1345行 → 5 个文件均 < 1000 行)
- Issue:
quick_card_sheet.dart单文件 1345 行,违反项目"文件不超过 1000 行"规则 - 修复:
quick_card_sheet.dart(921 行)— 主入口,保留状态字段、回调、构建方法quick_card_layouts.dart(705 行)—QuickCardStackedLayout+QuickCardSplitLayout两种布局quick_card_bars.dart(349 行)—QuickCardNavBar+QuickCardActionBar+QuickCardSplitTopBarquick_card_state_logic.dart(194 行)— 纯逻辑:stateToJson/stateFromJson/applyPreset/applyAutoPalette/resetState/resetHomeStylequick_card_dialogs.dart(362 行)— 文字编辑对话框 + 更多操作 Sheet + 结果提示
- 验证:
flutter analyze9 个文件全部通过,No issues found!
2. 多语言全量接入(TQuickCard 翻译类型)
- Issue: Sheet 内所有用户可见文案为硬编码中文,不支持多语言切换
- 修复:
- 新增
lib/l10n/types/t_quick_card.dart(525 行)— 定义 100+ 翻译键 T根类新增quickCard字段,集成到T.fromMap/toMapzh_cn.dart/en.dart新增quickCard: TQuickCard(...)完整翻译- 主 Sheet 新增
_tgetter:TQuickCard get _t => ref.read(translationsProvider).quickCard; - 18 处硬编码中文文案全部迁移至翻译键(保存失败/已保存到相册/已应用到主页/已复制/已粘贴/剪贴板为空/已清空/已重置/模板保存/模板加载/自动配色/A-B 进入/A-B 恢复/A-B 应用新样式 等)
- 布局组件
QuickCardStackedLayout/QuickCardSplitLayout/QuickCardNavBar/QuickCardActionBar/QuickCardSplitTopBar全部接收TQuickCard t参数 QuickCardTextEditorDialog.show()/showQuickCardMoreSheet()/showQuickCardResult()全部接收TQuickCard t参数
- 新增
- 动态主题: 通过
AppTheme.ext(context)获取主题扩展,所有颜色/圆角/阴影均来自主题系统 - 动态样式: 通过
ref.watch(translationsProvider)实现运行时切换语言无需重启
3. A/B 对比模式 UI 补全(空壳功能完善)
-
Issue: A/B 对比模式已保存快照,但缺少切换 A/B 视图的 UI 入口
-
修复:
- 预览区新增长按手势
_toggleAbView(),切换显示 A 原样式 / B 新样式 - 预览右上角显示当前视图角标(A 原样式 / B 新样式),带动画切换
_LayoutCallbacks新增onToggleAbView回调- 布局组件接收
isAbMode/abShowOriginal/abSnapshotState/abSnapshotHomeStyle参数
- 预览区新增长按手势
-
文件:
- lib/features/home/presentation/widgets/quick_card_sheet.dart(重写)
- lib/features/home/presentation/widgets/quick_card_layouts.dart(新建)
- lib/features/home/presentation/widgets/quick_card_bars.dart(新建)
- lib/features/home/presentation/widgets/quick_card_state_logic.dart(新建)
- lib/features/home/presentation/widgets/quick_card_dialogs.dart(修改)
- lib/l10n/types/t_quick_card.dart(新建)
- lib/l10n/types/t_root.dart(修改)
- lib/l10n/languages/zh_cn.dart(修改)
- lib/l10n/languages/en.dart(修改)
[v6.101.2] - 2026-06-22
🐛 修复(托盘导航进入错误 Tab 栈)
0. 托盘菜单点击跳转使用错误 context 导致页面进入错误 Tab 栈
- Issue: 托盘 pop 菜单点击跳转时,
DesktopTrayController._navigateTo使用_ref.context调用context.appPush(route)。但_ref.context可能不属于当前活动 Tab(例如窗口失焦期间 Tab 已切换,但 controller 持有的 context 仍是旧 Tab 的),导致非工作台模式下GoRouter.push把页面压入错误 Tab 的 Navigator。 - 修复:
app_router.dart新增公开函数tabNavigatorKeyFor(int tabIndex),按 Tab 索引(0=首页/1=发现/2=我的)返回对应的GlobalKey<NavigatorState>,原先_homeNavigatorKey/_discoverNavigatorKey/_profileNavigatorKey仍为私有。desktop_tray_controller.dart的_navigateTo方法改为:- 显式读取
splitViewProvider.currentTab获取当前活动 Tab - 通过
tabNavigatorKeyFor(currentTab)拿到当前活动 Tab 的navigatorKey.currentContext - 优先使用该 context 进行
appPush,确保非工作台模式下 GoRouter.push 进入正确的 Tab 栈 - 若 tabNavigatorKey 的 context 不可用或未 mounted,回退到
_ref.context(原逻辑),并打印警告日志 - 新增
Log.i记录导航目标和当前 Tab,便于追踪
- 显式读取
- 工作台模式下
appPush内部已通过splitViewProvider.currentTab决定右栏栈归属,本次修复主要覆盖非工作台模式 / 全屏路由场景
- 文件:
- lib/core/router/app_router.dart(新增
tabNavigatorKeyFor公开函数) - lib/features/desktop/desktop_tray_controller.dart(_navigateTo 重构 + 文件头注释更新 + 新增 flutter/widgets.dart 导入)
- lib/core/router/app_router.dart(新增
[v6.101.1] - 2026-06-22
🐛 修复(纯黑模式下 Mac 端托盘图标不可见)
0. 纯黑模式(amoled)下 Mac 端托盘图标手动切换为白色 PNG
- Issue: Mac 端使用
isTemplate: true让系统自动反色,但纯黑模式下系统可能将黑色图标保持黑色(因为背景也是黑色),导致托盘图标不可见 - 修复:
DesktopTrayService.setIcon接口新增isAmoled参数(默认 false,向后兼容)TrayManagerTrayService.setIconMac 端分支逻辑更新:- light 模式:
tray_icon_light.png(黑色图标)+isTemplate: true - dark 模式:
tray_icon_light.png(黑色图标)+isTemplate: true(系统自动反色为白色) - amoled 模式:
tray_icon_dark.png(白色图标)+isTemplate: false(手动指定白色,不依赖系统反色)
- light 模式:
DesktopTrayController.onThemeChanged新增isAmoled参数透传app.dart新增_lastDesktopAmoledState字段,单独跟踪 amoled 状态 (dark 和 amoled 的effectiveIsDark均为 true,需单独检测 dark↔amoled 切换)- Windows/Linux 端逻辑保持不变
- 文件:
- lib/core/services/desktop/desktop_tray_service.dart(接口签名 + Stub 实现)
- lib/core/services/desktop/implementations/tray_manager_tray_service.dart(Mac 端逻辑)
- lib/features/desktop/desktop_tray_controller.dart(onThemeChanged 透传 isAmoled)
- lib/app/app.dart(跟踪 amoled 状态并传入 onThemeChanged)
[v6.101.0] - 2026-06-22
🐛 修复(鸿蒙端"编辑此句"按钮解除限制)
0. 鸿蒙端"编辑此句"按钮解除限制
- Issue: 创作卡片页面的"编辑此句"按钮,鸿蒙端点击会显示"敬请期待",无法进入编辑器
- 修复:
- 移除
sentence_detail_actions.dart中if (pu.isOhos) { AppToast.showInfo('敬请期待'); return; }限制 - 移除
sentence_detail_sheet.dart中相同的限制逻辑 - 清理未使用的
platform_utils导入 - 鸿蒙端现在可以直接跳转到
/editor?text=...进入编辑器
- 移除
- 依据:
/editor路由在鸿蒙端正常注册(route_registry.dart:1130-1138),EditorPage无平台限制 - 文件:
- lib/features/home/presentation/panels/sentence_detail_actions.dart(修改)
- lib/features/home/presentation/providers/sentence_detail_sheet.dart(修改)
✨ 增强(快速卡片创作 Sheet 功能升级 — 模板/壁纸/取色/A-B 对比/动效)
1. 模板管理 UI 完善
- Issue:
_saveAsTemplate已实现保存,但"加载模板"在更多操作菜单中只是占位,未实现模板列表选择对话框 - 修复:
- 新增
quick_card_template_sheet.dart(~400 行)— 模板管理底部面板 - 数据模型
QuickCardTemplate:key/stateJson/homeStyleJson/savedAt/isFavorite - 列表排序:收藏优先 + 时间倒序
- 使用
AppSlidable实现左滑收藏/取消收藏 + 右滑删除 - 模板项含预览缩略图(背景色/渐变 + 文字摘要)
- 点击模板项返回并还原 QuickCardState + DailyCardStyle
- 通过
Hive.box<dynamic>('app').keys直接获取所有模板键
- 新增
- 更多操作菜单新增:
loadTemplate('📂 加载模板')、abCompare('⚖️ A/B 对比')
2. 颜色选择器升级(最近使用 + 吸管取色)
- Issue: 28 色预设 + HSL 滑块交互偏简陋,缺少吸管取色和最近使用记录
- 修复:
- 新增
quick_card_color_section.dart(~480 行)— 独立颜色选择模块 - 顶部增加最近 6 色横条,持久化到 KvStorage(
quick_card_recent_colors键) - 吸管取色:
image_picker选图 →package:image解码 → 3x3 网格采样取平均色 - 颜色选择器对话框升级:28 色预设 + 最近使用 + HSL 三滑块
- 7 预设色 + 自定义入口 + 吸管取色按钮
- 新增
- 修复 CupertinoIcons eyedropper 未定义:改为
Icons.colorize(Material 图标)
3. 壁纸库接入
- Issue: 背景图片选择路径单一,仅支持从相册选择,未支持从项目内置壁纸库选择
- 修复:
- 新增
quick_card_background_section.dart(~560 行)— 独立背景选择模块 _WallpaperLibrarySheet底部面板:来源切换栏(12 源)+ 网格 + 长按预览- 复用
features/template的wallpaperProvider+WallpaperPreviewSheet - 背景选择行新增"从壁纸库选择"入口
- 网络壁纸 URL 通过
imagePath字段存储
- 新增
4. 文件拆分(quick_card_style_sections.dart 917行 → 430行)
- Issue:
quick_card_style_sections.dart文件过大,违反单一职责 - 修复:
_BackgroundRow+_GradientAngleChip→quick_card_background_section.dart_ColorRow→quick_card_color_section.dartQuickCardStyleSection新增onAutoPalette参数- 移除
image_picker和logger导入(已迁移到子文件)
5. A/B 对比模式
- Issue: 调整样式时无法对比"原样式"与"新样式"
- 修复:
- 新增
_abSnapshotState、_abSnapshotHomeStyle、_isAbMode字段 _enterAbMode():保存当前样式快照_exitAbMode({bool restore}):恢复原样式或保留新样式- 更多操作菜单新增
⚖️ A/B 对比切换项
- 新增
6. adaptive_palette 自动配色
- Issue: 用户配色困难,需要手动调整
- 修复:
- 背景选择行新增"自动配色"入口
_extractAutoPalette调用AdaptiveThemeService.extractFromProvider(provider)- 提取主色/辅助色/表面色应用到背景渐变 + 文字颜色
BackgroundLayerPipe扩展支持链式调用
7. 交错入场动画(flutter_staggered_animations)
- 样式调整区各项使用
AnimationLimiter+AnimationConfiguration.staggeredList SlideAnimation+FadeInAnimation实现交错入场
8. Hero 过渡动画
SafePreview外包裹Hero(tag: 'quick_card_preview', flightShuttleBuilder: ...)- 从首页点击创建到 Sheet 弹出使用 Hero 过渡
9. 触觉反馈增强
- 新增差异化触觉方法:
_fireLightHaptic()— 滑块/微调(HapticService.light)_fireMediumHaptic()— 选择/确认(HapticService.medium)_fireSuccessHaptic()— 保存/完成(HapticService.success)
- 滑块类回调(字号/色深)调用
_fireLightHaptic() - 分享调用
_fireMediumHaptic(),保存/应用调用_fireSuccessHaptic()
10. 网络图片背景支持
-
Issue:
quick_card_preview.dart使用Image.file渲染背景,壁纸库返回的 URL 无法加载 -
修复:
- 新增
_buildImage(path, fallback)辅助方法 - 自动识别
http:///https://前缀,分别使用Image.network/Image.file - 错误回退到纯色背景
- 新增
-
文件:
- lib/features/home/presentation/widgets/quick_card_sheet.dart(修改)
- lib/features/home/presentation/widgets/quick_card_style_sections.dart(修改)
- lib/features/home/presentation/widgets/quick_card_background_section.dart(新建)
- lib/features/home/presentation/widgets/quick_card_color_section.dart(新建)
- lib/features/home/presentation/widgets/quick_card_template_sheet.dart(新建)
- lib/features/home/presentation/widgets/quick_card_dialogs.dart(修改)
- lib/features/home/presentation/widgets/quick_card_preview.dart(修改)
[v6.100.0] - 2026-06-22
🐛 修复(API 拦截器 401 错误处理优化)
1. Token 静默刷新(提前 5 分钟)
- Issue: 之前移除了 token 自动刷新逻辑,用户长时间使用后 token 过期需手动重新登录,体验不好
- 修复:
TokenService新增_cachedExpiresAt缓存字段,由checkToken/refreshToken在获取expires_in后自动更新TokenService新增silentRefreshIfExpiringSoon()方法:基于缓存的过期时间判断是否即将过期(提前 5 分钟 = 300 秒),若即将过期则调用refreshToken静默刷新ApiInterceptor.onRequest在每次请求前 fire-and-forget 调用静默刷新(不阻塞当前请求)- 跳过
/api/token/开头的请求,避免对 token 管理接口本身触发刷新(防止递归) - 并发安全:复用
TokenService._isRefreshing锁,多个请求同时触发只刷新一次 - 刷新失败不阻塞:原 Token 继续使用直到 401,由 401 处理逻辑引导用户重新登录
- 刷新成功后若响应未包含
expires_in,设置默认过期时间(2 小时)避免重复触发刷新
2. 401 友好提示(Toast 替代对话框)
-
Issue: 401 时无任何提示,用户不知道需要重新登录
-
修复:
_handleAuthExpired新增AppToast.showWarning('登录已过期,请重新登录')友好提示- 使用 Toast(bot_toast)而非对话框,不打断用户当前操作
- 带节流机制:3 分钟内不重复提示,避免多个并发请求同时 401 时弹出多次 Toast
- 保留 warning 级别日志(不恢复 error 级别)
- 不重试请求(避免死循环)
-
文件:lib/core/network/api_interceptor.dart、lib/core/services/auth/token_service.dart
v6.99.0 及更早版本(v6.87.0 ~ v6.99.0)已归档至软件特性功能文档。 主要特性概览:
- v6.99.0: 快速卡片创作 Sheet 拆分(1547行→4文件)+ 空壳功能补全(11项:字号滑块/背景图片/渐变方向/自定义颜色器/字体扩展/更多操作菜单/导出格式区分/自动播放循环/TTS朗读指示/模板保存/重置确认)+ 拆分过程修复(触觉音效补回/滑块过度反馈/TTS订阅泄漏/色深滑块宽度)+ 文本编辑对话框升级
- v6.98.0: 10项桌面端问题集中修复(窗口关闭对话框/托盘工作台模式/创作卡片侧栏/编辑器按钮/macOS窗口大小/托盘三段式深色/托盘icon/401错误)
- v6.97.1: 7项问题修复后的体验优化扩展(密码强度检测/稍后读气泡卡片交互/灵感朗读/情景诗词滑动/设置交互/日签换一句/使用报告性能与CSV导出)
- v6.97.0: 7项软件问题集中修复(密码修改前端/稍后读气泡卡片按钮/灵感朗读/情景诗词滑动空白/情景诗词设置/日签换一句/使用报告数据为空)
- v6.96.0: Windows 桌面端窗口大小预设菜单(3×2 网格)+ 托盘菜单窗口大小子菜单 + 工作台模式导航栏位置切换
- v6.95.0: 鸿蒙端专项修复(横屏翻转/复制粘贴/设备信息/键盘可见性/READ_PASTEBOARD 权限/正则崩溃)+ SDK 零修改原则
- v6.94.5: 工作台设置页 Slider 崩溃修复(CupertinoSlider 替换)+ 移动端横屏工作台布局空白修复
- v6.94.4: 工作台布局修复(拖拽 clamp 逻辑/双栏注释/pop canPop 检查)
- v6.94.3: 工作台模式白屏修复(appPop/appCanPop 工作台感知)+ 闲情逸致页面 ref 卸载报错修复
- v6.93.1: MethodChannel 命名风格统一为
apps.xy.xianyan/{feature}风格- v6.93.0: 桌面端原生功能扩展第二批(剪贴板富文本HTML/侧边栏折叠记忆/分屏记忆/可拖拽导航栏/Windows Mica Alt 特效)
- v6.92.0: macOS 原生功能扩展(Touch Bar/NSSharingService 共享面板/NSDockTile 徽章/NSStatusItem 菜单栏金句/CoreSpotlight 索引)
- v6.91.2: 深度链接服务完善(xianyan:// scheme 跳转,note/sentence/readlater 路由映射)
- v6.91.1: 笔记编辑页桌面端拖拽文件接入(图片 base64/文本追加/文件链接)
- v6.91.0: 桌面端原生增强(系统托盘/macOS 菜单栏/自定义标题栏/Windows 原生能力/窗口特效/动态主题/工作台设置页)
- v6.90.1: 工作台模式多语言支持 + 中栏宽度 KvStorage 持久化
- v6.90.0: PC工作台布局重构(微信PC式三栏 WorkbenchLayout + RightPanelStackNotifier + 路由拦截)
- v6.89.1: macOS MissingPluginException 修复 + Expanded 布局错误修复
- v6.89.0: 评分弹窗商店名称多语言 + Beta问卷按钮隐藏跨平台修复
- v6.88.0: 闲情逸致价格档位扩展(6档)+ 纠错历史本地缓存(drift)+ 学习计划详情页 + 闲情逸致全模块多语言
- v6.87.0: 多平台应用商店统一服务(AppStoreService)+ 学习计划重构预告 + 闲情逸致"免费"改"平价" + 纠错页全面多语言