Files
xianyan/CHANGELOG.md
Developer f7520b17b2 win提交
2026-06-22 03:50:59 +08:00

500 lines
35 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
所有重要变更均记录于此文件。格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/)。
> 保留最近 10 个版本v6.89.1 ~ v6.96.0。更早版本v6.87.0 ~ v6.89.0)的特性已合并进软件特性功能文档,详见各版本条目。
***
## [v6.96.0] - 2026-06-22
### ✨ 新增Windows 桌面端)
#### 窗口大小预设菜单3×2 网格)
- **功能**: 点击窗口标题栏"口"按钮(最小化与关闭之间),在按钮下方弹出 3 列 × 2 行的窗口大小预设网格菜单
- **预设尺寸**: 小窗 800×600 / 标准 1024×768 / 宽屏 1280×720 / 大屏 1440×900 / 全高清 1920×1080 / 最大化·还原
- **交互**:
- 弹出位置自动右对齐按钮,带边界自适应(防止溢出屏幕)
- 入场动画:缩放 + 淡入从右上角展开180ms easeOutCubic
- 退出动画:缩放 + 淡出120ms
- 点击外部区域自动关闭
- 每个单元格悬停时高亮accent 色 14% 背景 + 45% 边框)
- **设计**: iOS 26 Liquid Glass 风格 — Alert 层级毛玻璃blur 40px、圆角 16px、GlassTokens 边框 + 阴影
- **技术方案**:
- 提取共享组件 `shared/widgets/window_size_popup.dart`,供 `DesktopWindowTitleBar``AdaptiveNavBar` 复用
- 使用 `OverlayEntry` + `Positioned` 实现精确定位弹出
- `_WindowsControlButton.onPressed` / `_WindowControlBtn.onPressed` 签名改为 `void Function(BuildContext)` 以传递按钮自身 context 用于定位
- **文件**:
- lib/shared/widgets/window_size_popup.dart新增
- lib/features/desktop/desktop_window_title_bar.dart"口"按钮改为弹出菜单)
- lib/app/layout/adaptive_nav_bar.dart引用共享组件删除本地重复定义
***
## [v6.95.0] - 2026-06-21
### 🐛 修复(鸿蒙端专项)
#### 鸿蒙端横屏翻转失效
- **Issue: 鸿蒙端横屏时软件没有翻转,安卓/iOS 正常**
- **根因**`EntryAbility.ets` 注册了 `flutter/platform` 通道拦截器,其 `default` 分支调用 `result.notImplemented()`,导致 `SystemChrome.setPreferredOrientations` 等平台方法全部失效
- **修复**:移除 `flutter/platform` 通道拦截器,由 Flutter 鸿蒙引擎原生 `PlatformChannel.ets` 处理所有平台方法
- **文件**ohos/entry/src/main/ets/entryability/EntryAbility.ets
#### 鸿蒙端复制粘贴不生效
- **Issue: 点击复制按钮显示成功但实际未复制;输入框长按粘贴无反应**
- **根因1复制**:同上,`flutter/platform` 拦截器覆盖了引擎原生 `Clipboard.setData` 实现
- **根因2粘贴**`READ_PASTEBOARD``system_basic` 级系统权限,普通应用无法通过 `requestPermissionsFromUser` 申请;引擎原生 `getClipboardData` 因权限缺失返回 `null`
- **修复**
- 复制:移除拦截器后由引擎原生 `PlatformChannel.ets` 处理 `Clipboard.setData`(无需权限)
- 粘贴:创建 `CustomPlatformPlugin.ets` 中间件,继承 `PlatformPlugin``PlatformPluginCallback`,覆盖 `getClipboardData` 方法,使用系统安全控件 `PasteButton` 获取临时剪贴板读取授权(点击后授权持续到灭屏/切后台/退出)
- 覆盖 `clipboardHasStrings` 返回 `true`,确保输入框工具栏粘贴按钮显示
-`EntryAbility.ets` 覆盖 `providePlatformPlugin` 返回 `CustomPlatformPlugin`
- **架构亮点**:不修改 SDK 源码通过继承实现中间件过渡层SDK 升级不受影响
- **文件**ohos/entry/src/main/ets/entryability/CustomPlatformPlugin.ets新增、ohos/entry/src/main/ets/entryability/EntryAbility.ets
#### 鸿蒙端设备信息显示"未知设备"
- **Issue: 我的设备页面鸿蒙端显示"未知设备",安卓/iOS 正常**
- **根因**`DeviceMethodHandler.ets` 返回鸿蒙原生字段名(`manufacture``marketName``productModel` 等),与 `AndroidDeviceInfo.fromMap` 期望的 Android 字段名(`manufacturer``name``model` 等)不匹配
- **修复**
-`DeviceMethodHandler.ets` 增加 Android 兼容字段映射,保留原生鸿蒙字段的同时补充 `board`/`bootloader`/`brand`/`device`/`display`/`fingerprint`/`hardware`/`host`/`id`/`manufacturer`/`model`/`product`/`name`/`tags`/`type`/`isPhysicalDevice` 等字段
-`AndroidDeviceInfo.fromMap` 增加防御性默认值(`?? ''``?? 0``?? true`),防止 `type 'Null' is not a subtype of type 'String'` 崩溃
- **文件**packages/device_info_plus/ohos/.../DeviceMethodHandler.ets、packages/device_info_plus/lib/src/model/android_device_info.dart
#### 鸿蒙端搜索页 flutter_keyboard_visibility 崩溃
- **Issue: 搜索页面报 `MissingPluginException(No implementation found for method listen on channel flutter_keyboard_visibility)`**
- **根因**`flutter_keyboard_visibility` 插件无鸿蒙原生实现,`EventChannel.listen` 抛出 `MissingPluginException`
- **修复**`KeyboardManager` 延迟初始化 `KeyboardVisibilityController` 并捕获异常,鸿蒙端降级为 `MediaQuery.of(context).viewInsets.bottom > 0` 检测键盘可见性
- **文件**lib/shared/widgets/adaptive/keyboard_safe_sheet.dart
#### 鸿蒙端安装失败READ_PASTEBOARD 权限)
- **Issue: 声明 `ohos.permission.READ_PASTEBOARD` 后安装失败,报 `grant request permissions failed`**
- **根因**`READ_PASTEBOARD``system_basic` 级权限,普通应用无法通过 `module.json5``requestPermissions` 声明
- **修复**:从 `module.json5` 移除 `READ_PASTEBOARD` 权限声明,改用 `PasteButton` 安全控件获取临时授权
- **文件**ohos/entry/src/main/module.json5
#### 新特性轮播正则表达式崩溃
- **Issue: `FormatException: Range out of order in character class ^([\u{1F300}-\u{1FAFF}\u{2600}-\u{27BF}]+)\s*`**
- **根因**Dart raw string (`r'...'`) 中 `\u{1F300}` 不会被解析为 Unicode 转义,导致正则引擎看到无效字符范围
- **修复**:改用 `Runes` 逐字符检测 code point 范围,避免正则 Unicode 转义兼容性问题
- **文件**lib/features/home/presentation/widgets/new_features_dialog.dart
### 🔧 架构改进
#### SDK 零修改原则
- **原则**:所有鸿蒙端修复均不修改 Flutter 鸿蒙 SDK 源码(`e:\sdk\flutter-ohos\`),通过项目内中间件继承实现
- **中间件**`CustomPlatformPlugin.ets` 继承 `PlatformPlugin` + `PlatformPluginCallback`,覆盖剪贴板方法
- **优势**SDK 升级时无需合并冲突,中间件代码完全在项目可控范围内
***
## [v6.94.5] - 2026-06-19
### 🐛 修复
#### 工作台设置页 Slider 报错No Material widget found
- **Issue: 工作台设置页打开即崩溃,报 "No Material widget found. Slider widgets require a Material widget ancestor"**`WorkbenchSettingsPage` 使用 `CupertinoPageScaffold`(无 Material 祖先),但 `_SliderTile` 使用 Material 组件 `Slider`,导致断言失败。
- **修复**:将 `Slider` 替换为 `CupertinoSlider`,符合项目规则"优先使用 Cupertino 组件",并使用 `ext.accent` 作为激活色保持主题一致
- **文件**lib/features/settings/presentation/workbench/workbench_settings_page.dart
#### 移动端横屏工作台布局空白问题
- **Issue: 移动端横屏工作台模式中栏左右两边有空白,要求缩短空白用来显示中栏页面**
- **根因1**:双栏模式中栏宽度被 `* 0.75` 缩放,导致中栏宽度不足,页面内容两侧出现空白
- **根因2**中栏内嵌页面HomePage/DiscoverPage 等)使用 `SafeArea(bottom: false)`,横屏时 `left`/`right` 默认为 `true`,会添加水平 padding 导致左右空白
- **修复1**:移除双栏模式 `* 0.75` 缩放,中栏使用完整宽度(与三栏模式一致)
- **修复2**`_buildMiddlePanel` 使用 `MediaQuery.removePadding` 移除水平 SafeArea padding避免横屏时左右空白
- **文件**lib/core/layout/workbench/workbench_layout.dart
***
## [v6.94.4] - 2026-06-19
### 🐛 修复
#### 工作台布局修复3处
- **Issue1: 拖拽宽度 clamp 逻辑冗余且极端小屏可能抛异常**`_onDragUpdate` 两次 clamp 冗余(先 clamp 到屏幕允许值,再 clamp 到硬编码 `_maxMiddleWidth`),且极端小屏(`screenMax < _minMiddleWidth`)时第一次 clamp 上限 < 下限会抛 `ArgumentError`
- **说明**:原 Issue 描述"第二次 clamp 反向扩大宽度导致溢出"有误——Dart `clamp` 不会扩大值,只限制值。真正问题是冗余 + 极端小屏异常。
- **修复**:合并为单次 clamp`screenMax``_maxMiddleWidth` 的较小值作为有效上限,并用 `safeMax` 保护下限(避免 `ArgumentError`
- **文件**lib/core/layout/workbench/workbench_layout.dart
- **Issue2: 双栏模式注释与实现不符**:注释称"隐藏中栏",但实际代码显示中栏(宽度*0.75)。
- **修复**:更新注释为"中栏紧凑显示(宽度*0.75+ 分割条 + 右栏",匹配实际实现
- **文件**lib/core/layout/workbench/workbench_layout.dart
- **Issue3: pop 操作未检查 canPop 导致根级页面被意外弹空**`pop` 仅检查 `entries.isEmpty`,栈深 1 时 `canPop=false` 但 pop 仍执行 `removeLast` 导致栈变空,与 `canPop` 判断不一致。
- **修复**`pop` 改为 `if (!currentStack.canPop) return`,与 `canPop` 保持一致
- **联动修复**v6.94.2 的 Issue3构建失败移除无效条目原直接调用 `pop`,在栈深 1 时会因 canPop 检查不执行导致无效条目残留。改为 `canPop``pop`、否则 `clear`(栈深 1 的无效条目即根级,清空回仪表盘)
- **文件**lib/core/layout/workbench/right_panel_navigator.dart、lib/core/layout/workbench/workbench_layout.dart
***
## [v6.94.3] - 2026-06-19
### 🐛 修复
#### 工作台模式白屏问题(搜索取消导致根栈弹空)
- **Issue: 仪表盘点搜索→取消后白屏**:工作台模式下,搜索页通过 `rightPanelStackProvider` 推入右栏嵌套栈渲染(非 GoRouter Navigator但页面内取消按钮调用 `Navigator.pop(context)` 误弹根 GoRouter 栈,触发 `currentConfiguration.isNotEmpty` 断言错误,导致白屏。
- **根因**:右栏页面直接使用 `Navigator.pop(context)` 操作根 GoRouter Navigator而非右栏嵌套栈
- **修复**:在 `AppNavExtension` 新增工作台感知的 `appPop()`/`appCanPop()` 方法(宽屏工作台模式 pop 右栏栈,否则回退 `Navigator.pop`);同步在 `WorkbenchNavExtension` 新增 `WidgetRef` 版本
- **文件**lib/core/router/app_nav_extension.dart
- **AdaptiveBackButton 工作台感知**:统一返回按钮组件接入 `appCanPop`/`appPop`,正确感知右栏栈状态
- **文件**lib/shared/widgets/adaptive/adaptive_back_button.dart
- **SearchPage 取消按钮**:改用 `context.appPop()` 替代 `Navigator.pop(context)`
- **文件**lib/features/search/presentation/search_page.dart
- **举一反三12处页面级返回按钮**:批量修复 member_page、category_detail_page、article_edit_page、article_detail_page、screen_share_page、crash_log_page、ctc_note_list_page、tool_bottom_bar、qrcode_login_page、qr_code_tab、device_pairing_page、study_plan_page 的页面级返回按钮(仅页面级,对话框/sheet 内的 pop 保持不变)
- **文件**:见上述各文件
#### 闲情逸致页面卸载后 ref 报错
- **Issue: 闲情逸致页面报错 "Using ref when widget is about to or has been unmounted"**`_scrollToToday``Future.delayed` 回调中使用 `ref.read()` 未检查 `mounted`widget 卸载后 ref 不安全。
- **修复**`_scrollToToday``_scrollToDate` 异步回调前增加 `mounted` 检查
- **文件**lib/features/tool_center/leisure/presentation/pages/leisure_timeline_page.dart
***
## [v6.94.2] - 2026-06-19
### 🐛 修复
#### 右栏返回栈行为修复3处同源问题
- **Issue1: 返回按钮行为不符合预期**:原 `_onRightPanelPop` 误用 `clear` 清空整个栈,导致已打开页面全部丢失,与"逐步返回上一页"预期不符。
- **根因**`_onRightPanelPop` 误用 `clear` 而非 `pop`,无论栈深多少都一次清空
- **修复**:拆分为双按钮交互(左侧按钮组,栈深>1 时显示):
- 返回上一页(`CupertinoIcons.back` chevron 图标):调用 `pop` 逐页返回,符合 iOS `UINavigationController` 标准语义
- 回仪表盘(`CupertinoIcons.house_fill` 房子图标):调用 `clear` 快捷回根,解决栈深较大时多次点击痛点
- **文件**lib/core/layout/workbench/workbench_layout.dart
- **Issue2: 快捷键返回行为错误**`_RightPanelBackAction.invoke`Ctrl/Cmd+←、Esc同样误用 `clear`,与返回按钮同源问题。
- **修复**:改为 `pop` 逐页返回,与 UI 返回按钮语义保持一致
- **文件**lib/app/layout/app_shell.dart
- **Issue3: 页面构建失败保留无效条目**`pageWidget == null` 时仅返回默认面板,但无效条目残留在栈中,导致后续返回行为异常(脏栈)。
- **修复**:构建失败时通过 `WidgetsBinding.instance.addPostFrameCallback` 延迟 `pop` 无效条目(避免 build-during-build 异常),再返回默认面板
- **文件**lib/core/layout/workbench/workbench_layout.dart
***
## [v6.94.1] - 2026-06-19
### ✨ 交互增强与类型安全巡检6项
#### 新功能
- **富媒体新功能弹窗**:引导页"了解新功能"弹窗重构为图文卡片轮播PageView支持 emoji 解析+关键词图标匹配+光晕效果+动态主题色+手势滑动+页码指示器
- **动态主题色图标组件**:新增 `ThemedIcon` 组件shared/widgets/display/themed_icon.dart支持 15 种颜色映射+圆形背景+光晕效果,随主题动态变化
- **壁纸离线浏览**:壁纸画廊新增"💾 已缓存"离线模式,无网络环境下可浏览已加载壁纸,支持空状态提示+动态标题+自动退出离线模式
#### 功能完善
- **稍后读批量管理持久化**`toggleRead`/`markAllRead`/`markSelectedRead` 从仅内存更新升级为持久化到 DB调用 `ChatMessageService.markIsRead`),采用乐观更新策略+`Future.wait` 并行执行
- **Provider 生命周期修复**:修复 5 个非 autoDispose provider 重复进入页面不刷新的隐患:
- `chatMessagesProvider`:普通会话进入时主动 reload原仅稍后读会话 reload
- `chatAttachmentProvider`:进入聊天页时主动 `loadAttachments`
- `chatSessionProvider`:发现页 initState 主动 `refresh`
- `translateRecordListProvider`/`ttsRecordListProvider`:插件页 initState 主动 `refresh`
- `readLaterProvider`:稍后读页 initState 主动 `loadItems(refresh: true)` 兜底
#### 类型安全巡检139处修复
- **根因**PHP/JSON 返回的数字可能被解析为 `int``double(num)`,直接 `as int` / `as int?` 会崩溃(`?? 0` 无法挽救,因为强转在 `??` 之前已抛异常)
- **修复模式**:统一使用 `SafeJson.parseInt()`core/utils/safe_json.dart替代 `as int` / `as int?`
- **P0 高风险修复60处**task_core.dart(10)、daily_task_page.dart(2)、cloud_cache_record.dart(5)、cloud_cache_service.dart(1)、signaling_service.dart(2)、input_action.dart(2)、transfer_task.dart(1)、anonymous_submit_page.dart(2)、interaction_provider.dart(1)、offline_manager.dart(1)、spotlight_search_provider.dart(1)、chat_session_provider.dart(2)、weather_settings_page.dart(1)、poetry_settings_page.dart(1)、theme_sections_preview.dart(3)、image_cache_models.dart(2)、pomodoro_core.dart(1)、image_cache_metadata_service.dart(1)、permission_service.dart(1)、kv_storage.dart(1)、notification_center.dart(6)、solar_term_core.dart(12)
- **P1 中风险修复79处**user_center_models.dart(4)、user_stats_provider.dart(9)、user_center_service.dart(7)、favorite_repository.dart(4)、correction_provider.dart(4)、ctc_api_client.dart(2)、ctc_note_provider.dart(4)、interaction_provider.dart(1)、coin_provider.dart(1)、public_profile_page.dart(1)、learning_progress_page.dart(3)、learning_center_page.dart(7)、statistics_page.dart(14)、leisure_card.dart(2)、wallpaper_health_service.dart(2)、settings_change_logger.dart(1)、cache_config.dart(5)、weather_provider.dart(2)、appbar_date_display.dart(1)、qrcode_scanner_page.dart(1)、user_model.dart(4)
#### 涉及文件
| 模块 | 文件 | 变更类型 |
|------|------|----------|
| 新功能弹窗 | new_features_dialog.dart | 重构为图文卡片轮播 |
| 主题色图标 | themed_icon.dart(新) | 新增动态主题色图标组件 |
| 壁纸离线 | wallpaper_gallery_view.dart, wallpaper_source_bar.dart | 离线模式+缓存chip |
| 稍后读持久化 | readlater_provider.dart | 批量已读持久化到DB |
| Provider生命周期 | chat_flow_page.dart, discover_page.dart, translate_plugin_page.dart, tts_plugin_page.dart, readlater_page.dart | initState主动reload |
| 类型安全P0 | 22个文件 | as int → SafeJson.parseInt() |
| 类型安全P1 | 21个文件 | as int? → SafeJson.parseInt() |
***
## [v6.94.0] - 2026-06-19
### 🔧 批量Bug修复与功能增强16项
#### 新功能
- **引导页新功能开关**:引导页第三页(个性化设置)新增"了解 V{版本号} 新功能"开关默认关闭开启后进入主页弹出当前版本更新日志弹窗支持动态主题和14种多语言
- **闲情逸致emoji统一替换**将闲情逸致页面含设置页、聊天气泡、输入面板约55处emoji替换为CupertinoIcons保留社交互动点赞、⭐收藏和个性化按钮的emoji
#### Bug修复
- **Beta页面问卷按钮**:增加右上角可关闭小角标,点击后临时隐藏问卷入口
- **Windows分发渠道文案**软件信息页平台兼容卡片点击Windows的toast改为"由Microsoft Store分发"14种语言同步
- **稍后读不显示**:修复主页卡片详情添加稍后读后,发现-稍后读页面不显示的问题ChatFlowPage每次进入主动reload + notifyReadlaterRefresh确保执行
- **情景诗词无响应**:修复输入框发送内容页面无变化、收藏与分享按钮无响应(接入诗词刷新+本地DB收藏+ShareSheet分享
- **日签卡片换一句无响应**添加isRefreshing加载态、错误反馈、空内容检查接入频道句子切换
- **使用报告数据为空**修复阅读趋势和活跃热力图数据解析传year参数、多键名兼容、字段名兼容、List包装
- **阅读目标无变化**重写reading_goal_provider从本地DB获取今日进度viewsToday/favoritesToday添加连续天数更新逻辑
- **灵感朗读音频无关**修复TTS朗读音频与实际内容无关_mySpokenText文本匹配 + 先stop再speak
- **壁纸筛选不一致**添加supportsCategory getter区分源是否支持分类筛选客户端二次过滤确保结果一致
- **取消收藏数据仍在**增强setFavoriteFlagForTarget第三种匹配策略feedType+ID后缀mergeWithLocalDb改为追加尾部
- **密保问题设置失败**修复_parseSecQuestion类型安全int vs num添加_toSafeInt安全转换refreshUser错误处理增强
#### 涉及文件
| 模块 | 文件 | 变更类型 |
|------|------|----------|
| Beta页面 | experimental_features_page.dart | 添加关闭角标 |
| 引导页 | onboarding_provider.dart, personalization_page.dart, t_onboarding.dart | 新功能开关 |
| 引导页弹窗 | new_features_dialog.dart(新), home_page.dart, kv_storage.dart | 弹窗+触发逻辑 |
| 闲情逸致 | 21个chat相关文件 | emoji→CupertinoIcons |
| 稍后读 | chat_flow_page.dart, home_interaction_mixin.dart | reload+通知修复 |
| 情景诗词 | poetry_page.dart | 发送/收藏/分享实现 |
| 日签卡片 | daily_card_provider.dart, daily_card_page.dart | 加载态+错误反馈 |
| 使用报告 | reading_report_core.dart | 数据解析修复 |
| 阅读目标 | reading_goal_provider.dart | 完全重写 |
| 灵感TTS | inspiration_detail_sheet.dart | 文本匹配修复 |
| 壁纸 | template_models.dart, wallpaper_gallery_view.dart | 分类筛选修复 |
| 收藏 | app_database.dart, favorite_repository.dart | 匹配策略增强 |
| 密保 | user_model.dart, security_question_page.dart | 类型安全修复 |
| 多语言 | 14个语言文件 | Windows文案+knowNewFeatures |
***
## [v6.93.1] - 2026-06-19
### 🔧 MethodChannel 命名风格统一
将所有自定义 MethodChannel/EventChannel 名称统一为 `apps.xy.xianyan/{feature}` 风格,与应用包名 `apps.xy.xianyan` 保持一致。
#### 变更清单
| 旧名称 | 新名称 | 涉及文件 |
|--------|--------|---------|
| `com.xianyan.macos` | `apps.xy.xianyan/macos` | macos_platform_service.dart + MainFlutterWindow.swift |
| `com.xianyan.macos.app` | `apps.xy.xianyan/macos.app` | macos_platform_service.dart + AppDelegate.swift |
| `com.xianyan.windows` | `apps.xy.xianyan/windows` | windows_platform_service.dart + flutter_window.cpp |
| `com.xianyan.clipboard` | `apps.xy.xianyan/clipboard` | clipboard_bridge.dart |
| `xianyan/usb_transport` | `apps.xy.xianyan/usb_transport` | usb_transport_service.dart |
| `xianyan/usb_events` | `apps.xy.xianyan/usb_events` | usb_discovery_service.dart |
| `com.xianyan.touchbar.*` | `apps.xy.xianyan.touchbar.*` | MainFlutterWindow.swift (NSTouchBar 标识符) |
#### 不变项
- Android 通道 `apps.xy.xianyan/{feature}` — 已是正确风格
- 鸿蒙通道 `plugins.flutter.io/{plugin}_ohos` — 模拟 Flutter 标准插件,保持不变
#### 影响
- **功能无影响**MethodChannel 名称只需 Dart 端与原生端一致即可
- **可维护性提升**:消除 4 种命名风格混用,统一为 `apps.xy.xianyan/{feature}`
***
## [v6.93.0] - 2026-06-19
### 🖥️ 桌面端原生功能扩展(第二批)
#### 剪贴板富文本HTML支持
- `lib/core/utils/platform/clipboard_bridge.dart` 新增 `setRichText({text, html})` / `getHtml()` / `hasHtml()` 三个方法
- 桌面端通过 `com.xianyan.clipboard` MethodChannel 调用原生 NSPasteboard/CF_HTML
- 移动端/Web 降级为纯文本(`_htmlToPlainText` 工具方法去除标签+反转义实体)
- 鸿蒙端仅支持纯文本HTML 读写返回 null/false
- 保持隐私协议守卫(读操作需同意协议)
#### 侧边栏折叠记忆
- `SplitViewState` 新增 `navBarCollapsed` (bool) / `navBarWidth` (double) / `tabSplitRatios` (Map<int,double>) 三个字段
- `SplitViewNotifier` 新增 `setNavBarCollapsed` / `toggleNavBarCollapsed` / `setNavBarWidth` / `saveCurrentTabSplitRatio` / `setCurrentTabWithMemory` 方法
- `adaptive_nav_bar.dart` 垂直导航栏支持折叠态48px 仅图标)/ 展开态72px 图标+文字),底部新增折叠按钮
- 折叠状态持久化到 KvStorage`nav_bar_collapsed` / `workbench_nav_bar_width`
#### 分屏记忆
- 每个 Tab 独立分屏比例,切换 Tab 时自动保存当前比例并恢复目标 Tab 比例
- `tabSplitRatios` 以 JSON 序列化存储到 `tab_split_ratios` key
- `setCurrentTabWithMemory(index)` 方法实现保存+恢复逻辑
#### 可拖拽导航栏宽度
- `workbench_layout.dart``_navBarWidth()` 改为从 `splitViewProvider` 读取动态宽度
- 折叠态 48px / 展开态使用持久化的 `navBarWidth`(默认 72px范围 48~240px
- `_assembleLayout` 垂直导航栏 SizedBox 改用动态宽度
#### Windows Mica Alt 特效
- `windows_acrylic_service.dart` 新增 `_isMicaAltSupported()` 方法,检测 Win11 build >= 22621
- `applyEffect` 新增 Mica Alt 分支优先级Mica Alt → Mica → Acrylic自动降级
- 使用 `WindowEffect.tabbed` 作为 Mica Alt 等价实现flutter_acrylic 1.1.4 的最接近选项)
- `effectName` getter 新增 `windows_mica_alt` 标识
- buildNumber 检测结果缓存,避免重复读取
#### Spec 文档
- 新增 `docs/desktop_native_expansion_spec.md`14 项功能实施方案,开发完成后删除)
***
## [v6.92.0] - 2026-06-19
### 🍎 macOS 原生功能扩展5 项)
#### Touch Bar 支持NSTouchBar
- `MainFlutterWindow.swift` 新增 `setTouchBarItems` 方法,创建 NSTouchBar + NSButton 项
- 按钮点击通过 `channel.invokeMethod("touchBarAction", action)` 回调 Dart
- 仅带 Touch Bar 的 MacBook 显示,无 Touch Bar 设备自动忽略
- `MainFlutterWindow` 实现 `NSTouchBarDelegate`,按索引创建按钮
#### NSSharingService 共享面板
- `MainFlutterWindow.swift` 新增 `showShareSheet` 方法,弹出 NSSharingServicePicker
- 支持 text/url/imageBytes 三种内容类型组合
- 图片通过 `FlutterStandardTypedData``NSImage` 转换
#### NSDockTile 徽章
- `AppDelegate.swift` 新增 `setDockBadge` 方法,设置 Dock 图标数字徽章
- count <= 0 时清除徽章
#### NSStatusItem 菜单栏金句
- `AppDelegate.swift` 新增 `updateStatusBarSentence` 方法,菜单栏显示金句
- 超过 30 字符截断显示,前缀 💬 emoji
- 点击金句复制完整内容到剪贴板(`currentSentence` 属性存储完整内容)
- `statusItem` 强引用持有,防止被释放
#### CoreSpotlight 索引
- `AppDelegate.swift` 新增 `indexSpotlightItems` / `clearSpotlightIndex` 方法
- 使用 `CSSearchableIndex.default()` 索引条目id/title/content/type
- 沙盒内可直接使用,无需额外 entitlements
- 异步操作,不阻塞 UI
#### 应用级通道架构
- 新增 `com.xianyan.macos.app` MethodChannelAppDelegate 注册)
- `applicationShouldTerminateAfterLastWindowClosed` 改为 `false`,支持托盘常驻
- `MacosPlatformService` 新增 `_appChannel` 常量 + 6 个静态方法
***
## [v6.91.2] - 2026-06-19
### 🔗 深度链接服务完善 — xianyan:// scheme 跳转
- `lib/core/services/network/deep_link_service.dart` 新增 `_preResolve` 预解析方法,处理需要特殊路由映射的 scheme
- `xianyan://note/{id}``/notes/edit?id={id}`(笔记编辑页用 query param无法通过配置驱动解析器的子路径匹配处理
- `xianyan://note``/notes`(笔记列表页)
- `xianyan://sentence/{id}``/home`(句子详情 Sheet 需 HomeSentence 对象,暂导航到首页)
- `lib/core/router/route_registry.dart` 稍后阅读路由新增 `xianyan://readlater` 别名
- `macos/Runner/Info.plist` 新增 `CFBundleURLTypes` 注册 `xianyan` URL Scheme此前 macOS 端未注册)
- `ios/Runner/Info.plist` 在现有 `CFBundleURLSchemes` 数组中追加 `xianyan` scheme此前仅注册 ShareExtension
- Android 端 `AndroidManifest.xml` 已有 `xianyan` scheme intent-filter无需修改
- `DeepLinkService.init()` 已在 `main.dart:236` 调用,无需重复初始化
***
## [v6.91.1] - 2026-06-19
### 📝 笔记编辑页 — 桌面端拖拽文件接入
- 笔记编辑页(`lib/features/note/presentation/note_edit_page.dart`)接入 `desktop_drop`,桌面端(`pu.isDesktop`)支持拖拽文件到笔记
- 拖拽视觉反馈:半透明遮罩 + 虚线边框(`_DashedBorderPainter`+ "拖放文件到笔记"提示,`AnimatedContainer` 200ms 过渡,`Positioned.fill` + `IgnorePointer` 不阻挡正常操作
- 文件处理逻辑(`_handleDrop`
- 图片(.png/.jpg/.jpeg/.gif/.webp读取为 base64插入 Markdown 图片语法 `![文件名](data:image/png;base64,...)`
- 文本(.txt/.md读取内容追加到笔记末尾
- 其他文件:插入 Markdown 链接 `[文件名](file:///路径)`
- 错误处理:读取失败时 `AppToast.showError` 提示
- 移动端不包裹 `DropTarget`,不影响现有自动保存/Markdown 预览功能
***
## [v6.91.0] - 2026-06-18
### 📦 依赖同步修复
- `pubspec.ohos.yaml` 补齐 `tray_manager`/`macos_window_utils`/`flutter_acrylic` 三库声明
- 原因Dart 编译时静态解析 import 链(`app.dart``desktop_service_registry.dart` → 实现文件 → 三库),鸿蒙端虽 no-op 但必须声明,否则报 `Target of URI doesn't exist`
- `iOS_macOS_Developer_Guide.md` §5.5 新增特殊案例说明 + §5.6 新增常见问题条目
### 🖥️ 桌面端原生增强macOS/Windows
#### 系统托盘tray_manager
- 跨平台系统托盘服务:图标 + Tooltip + 未读角标 + 右键菜单
- 托盘右键菜单 4 组分隔线分组:主操作/快速访问(最近阅读子菜单)/模式切换/系统
- 未读角标:合并稍后阅读 + 每日拾句未读数macOS setTitle 数字显示
- 每日拾句未读概念DailySentenceViewedService 本地存储已查看 id 列表
- 托盘事件处理:单击切换窗口可见性、双击聚焦、右键弹出菜单
- 托盘图标:自绘 SVG + Pillow 生成 PNG浅色/深色两套16x16/32x32
- 多语言支持TrayMenuLabelszhCN/enUS
#### macOS 原生菜单栏PlatformMenuBar
- MacosMenuBarWrapper6 个顶级菜单(闲言/文件/编辑/视图/窗口/帮助)
- 业务功能入口:新建笔记/灵感、打开稍后阅读、偏好设置、每日拾句
- 模式切换:深色模式、工作台模式(带勾选状态)
- 系统标准项:关于/隐藏/退出/全屏/最小化/缩放PlatformProvidedMenuItem
#### 自定义窗口标题栏(软件样式)
- DesktopWindowTitleBar替代系统默认标题栏支持动态主题+动态样式
- macOS 风格左侧红黄绿三圆点按钮hover 显示图标)
- Windows 风格:右侧最小化/最大化/关闭方按钮hover 背景变化)
- 毛玻璃效果BackdropFilter、双击最大化/还原、拖拽移动窗口
- DesktopTitleBarStyle动态样式配置高度/透明度/模糊/按钮大小等)
- main.darttitleBarStyle: TitleBarStyle.hidden 隐藏系统标题栏
- macOS 原生titlebarAppearsTransparent=true + 隐藏系统红黄绿按钮
#### Windows 原生侧能力补齐6 个 MethodChannel 方法)
- setWindowTitleSetWindowTextW 设置窗口标题
- setFullscreen/isFullscreen保存/恢复窗口 RECT+样式,全屏切换
- setMinSizeWM_GETMINMAXINFO 处理最小尺寸限制DPI 缩放)
- performHapticFeedbackMessageBeep 模拟触觉反馈4 种类型)
- getSystemAppearance读取注册表 AppsUseLightTheme
#### 窗口特效(毛玻璃/亚克力)
- macOSMacosWindowEffectService 标题栏融合 + 侧边栏毛玻璃NSVisualEffectView sidebar 材质)
- Windows 11WindowsAcrylicService Mica 背景
- Windows 10Acrylic 效果(深色 0xCC1F1F1F / 浅色 0xCCF3F3F3
- Win11 版本检测:解析 operatingSystemVersionbuild>=22000
- 主题切换时同步窗口特效build + didChangePlatformBrightness
#### 动态主题
- 窗口特效随主题变化DesktopWindowEffectService.applyEffect(isDark)
- 托盘图标随主题变化macOS isTemplate 自动反色Windows 明暗两套图标
- 标题栏随主题变化:深色/浅色/AMOLED 三种背景色
#### 依赖变更
- 新增tray_manager ^0.5.3 / macos_window_utils ^1.9.1 / flutter_acrylic ^1.1.4
- 移除nearby_connections ^4.1.1三处模板同步pubspec.yaml/pubspec.ohos.yaml/pubspec.macos.yaml
#### 新增文件
| 文件 | 作用 |
|---|---|
| `lib/core/services/desktop/desktop_tray_service.dart` | 托盘服务抽象 + TrayMenuItem 模型 |
| `lib/core/services/desktop/desktop_window_effect_service.dart` | 窗口特效服务抽象 |
| `lib/core/services/desktop/desktop_service_registry.dart` | 服务注册表(按平台注入实现) |
| `lib/core/services/desktop/desktop_tray_menu_builder.dart` | 托盘菜单构建器4 组分隔线分组) |
| `lib/core/services/desktop/daily_sentence_viewed_service.dart` | 每日拾句已查看服务 |
| `lib/core/services/desktop/implementations/tray_manager_tray_service.dart` | tray_manager 托盘服务实现 |
| `lib/core/services/desktop/implementations/macos_window_effect_service.dart` | macOS 窗口特效实现 |
| `lib/core/services/desktop/implementations/windows_acrylic_service.dart` | Windows Acrylic/Mica 实现 |
| `lib/features/desktop/desktop_tray_controller.dart` | 托盘控制器(整合服务+菜单+未读数) |
| `lib/features/desktop/macos_menu_bar_wrapper.dart` | macOS 原生菜单栏包装器 |
| `lib/features/desktop/desktop_window_title_bar.dart` | 自定义窗口标题栏 Widget |
| `lib/features/home/presentation/providers/readlater/tray_unread_count_provider.dart` | 托盘未读数 Provider |
| `assets/svgs/tray_icon.svg` | 托盘图标 SVG 源文件 |
| `scripts/generate_tray_icons.py` | 托盘图标 PNG 生成脚本 |
#### 修改文件
| 文件 | 变更 |
|---|---|
| `lib/main.dart` | 新增 titleBarStyle: TitleBarStyle.hidden |
| `lib/app/app.dart` | 初始化桌面服务、窗口特效、托盘控制器、MacosMenuBarWrapper、主题同步 |
| `lib/app/layout/app_shell.dart` | 集成 DesktopWindowTitleBar |
| `lib/core/services/device/windows_platform_service.dart` | 新增 6 个 MethodChannel 方法 |
| `macos/Runner/MainFlutterWindow.swift` | titlebarAppearsTransparent=true + 隐藏系统按钮 |
| `windows/runner/win32_window.h` | 新增 6 个方法声明 + 全屏状态成员变量 |
| `windows/runner/win32_window.cpp` | 实现 6 个方法 + WM_GETMINMAXINFO |
| `windows/runner/flutter_window.cpp` | 扩展 MethodChannel 处理 6 个方法 |
| `pubspec.yaml/pubspec.ohos.yaml/pubspec.macos.yaml` | 新增 3 库 + 移除 nearby_connections |
#### 工作台设置页P0-8
- 新增独立页面 `WorkbenchSettingsPage`:整合 4 项迁移设置 + 7 项交互/视觉增强
- 迁移项:工作台模式开关、分屏开关、导航栏位置、分屏比例
- 新增交互增强(持久化):专注阅读模式、右栏分屏、拖拽出窗(占位)、右栏标签页(占位)、中栏拖拽排序
- 新增视觉增强(持久化):工作台毛玻璃背景、空状态动画
- `SplitViewState` 扩展 7 个 freezed 字段 + 对应 setterKvStorage 持久化)
- 通用设置"显示"组:移除 4 项迁移项,新增"工作台模式"导航入口
- 路由注册:`AppRoutes.workbenchSettings` + `route_registry.dart` + deepLink `xianyan://settings/workbench`
| 文件 | 变更 |
|---|---|
| `lib/features/settings/presentation/workbench/workbench_settings_page.dart` | 新增工作台设置页4 组设置 + 私有组件) |
| `lib/core/router/app_routes.dart` | 新增 `workbenchSettings` 路由常量 |
| `lib/core/router/route_registry.dart` | 注册 workbench-settings 路由 |
| `lib/core/providers/split_view_provider.dart` | 扩展 7 个交互增强字段 + setter |
| `lib/core/providers/split_view_provider.freezed.dart` | 同步 freezed 生成代码 |
| `lib/features/settings/presentation/general/general_settings_sections.dart` | 移除 4 项迁移项 + 新增导航项 |
| `lib/features/settings/presentation/general/general_settings_page.dart` | `_onNavigate` 新增 workbench_settings case |
***
> v6.90.1 及更早版本v6.87.0 ~ v6.90.1)已归档至软件特性功能文档。
> 主要特性概览:
> - **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+ 学习计划重构预告 + 闲情逸致"免费"改"平价" + 纠错页全面多语言