iOS 提交
This commit is contained in:
265
CHANGELOG.md
265
CHANGELOG.md
@@ -6,6 +6,271 @@
|
||||
|
||||
***
|
||||
|
||||
## [v6.144.0] - 2026-06-27
|
||||
|
||||
### 🐛 修复句子广场已收藏句子重复出现且未显示状态 + 按钮轮廓不清
|
||||
|
||||
#### 问题现象
|
||||
1. 句子广场中已收藏的句子在循环加载时重复出现,且未显示"已收藏"状态
|
||||
2. 未点赞/未收藏时按钮轮廓过淡(边框 0.5px + 25% white),用户无法辨识可点击区域
|
||||
|
||||
#### 根因分析
|
||||
1. **服务端根因**:`/api/feed/list` 接口 `_batchAttachInteractionCounts` 只回填聚合计数(like_count 等),不返回当前用户的 `is_liked`/`is_favorited` 状态。客户端 `HomeSentence.fromFeedItem` 解析时降级为 false,导致已收藏句子重复出现时显示"未收藏"。
|
||||
2. **客户端根因**:`fetchRefreshSentences`/`fetchNewSentences` 直接使用服务端返回的 `isLiked`/`isFavorited`,未合并本地 DB 的互动状态。未登录用户服务端始终返回 false,本地 DB 是唯一状态来源但未被读取。
|
||||
3. **循环加载根因**:`cycleRound >= 3` 时 `allSeenIds.clear()` 清空所有已见 ID,已收藏句子的去重记录也一并清除,导致循环加载时已收藏内容重复出现。
|
||||
4. **按钮样式根因**:`LiquidGlassActionButton` 未激活态边框仅 0.5px + 25% white 透明度,视觉上几乎不可见。
|
||||
|
||||
#### 服务端修复
|
||||
**`docs/toolsapi/application/api/controller/Feed.php`**
|
||||
- `_batchAttachInteractionCounts(&$items, $userId = 0)`:新增 `$userId` 参数,当用户已登录时批量查询 `feed_interaction` 表中该用户的 like/favorite 记录,回填 `is_liked`/`is_favorited` 字段。
|
||||
- `list()` 方法:调用处从 `$this->_batchAttachInteractionCounts($items, $userId)` 改为 `$this->_batchAttachInteractionCounts($items, $this->_getUserId())`(修复未定义变量 `$userId`)。
|
||||
- `_batchLoadFeedItems()` 方法:同样传入 `$this->_getUserId()`。
|
||||
- **缓存隔离**:缓存命中后重新调用 `_batchAttachInteractionCounts` 按当前用户重查 per-user 字段;缓存写入前剥离 `is_liked`/`is_favorited` 为 false,避免不同用户串状态。
|
||||
|
||||
#### 客户端修复
|
||||
**`lib/core/storage/database/app_database.dart`**
|
||||
- 新增 `getSentencesByIds(List<String> ids)` 批量查询方法,返回 `Map<String, Sentence>`,用于合并本地 DB 互动状态。
|
||||
|
||||
**`lib/features/home/providers/home_feed_mixin.dart`**
|
||||
- 新增 `_mergeLocalInteractionState(sentences)` 私有方法:批量查询本地 DB,采用 OR 合并策略(`local true wins`)——服务端 true 或本地 true 均为 true。覆盖未登录场景(服务端始终 false,本地 DB 是唯一来源)和登录场景(本地兜底未同步的离线操作)。
|
||||
- `fetchRefreshSentences`:`result.list.map(HomeSentence.fromFeedItem)` 后调用 `_mergeLocalInteractionState` 合并本地状态。
|
||||
- `fetchNewSentences`:同上,生成 `mergedSentences` 供后续去重/循环加载使用。
|
||||
- `cycleRound >= 3` 循环加载:清空 `allSeenIds`/`allSeenTexts` 前保留已收藏句子的 ID 和文本,恢复到去重集合中;`recentIds`/`recentTexts` 合并已收藏内容,确保循环加载时跳过已收藏句子。
|
||||
|
||||
**`lib/features/home/presentation/home_sentence_card.dart`**
|
||||
- `LiquidGlassActionButton` 未激活态:边框宽度 0.5px → 1.2px;背景透明度加深(深色 8%→15% white,浅色 18%→28% white);边框透明度加深(深色 12%→30% white,浅色 25%→50% white)。
|
||||
|
||||
#### 验证
|
||||
- `flutter analyze` 三个修改文件 0 issues
|
||||
- curl 验证服务端:`limit=8` 非缓存路径返回 `"is_liked":false,"is_favorited":false`(未登录正确);缓存命中路径 `"成功(cache)"` 同样返回字段(重新附加 per-user 状态)
|
||||
- 缓存隔离验证:缓存写入前剥离 per-user 字段,命中后按当前用户重查,杜绝跨用户串状态
|
||||
|
||||
#### 不足与建议
|
||||
- **缓存命中额外查询**:每次缓存命中调用 `_batchAttachInteractionCounts` 会重新查询聚合计数(冗余),可后续拆分为仅查询 per-user 状态的轻量方法。
|
||||
- **跨设备同步延迟**:未登录用户依赖本地 DB,登录用户首次加载时服务端返回正确状态,但缓存命中时 per-user 状态依赖 `_batchAttachInteractionCounts` 重查,若 DB 负载高可能增加延迟。
|
||||
- **循环加载已收藏保留策略**:当前保留全部已收藏 ID 在 `allSeenIds` 中,若用户收藏量极大(>300),`_buildSeenIdList` 会截断为最近 300 条,早期收藏可能再次出现。可考虑按收藏时间分页保留。
|
||||
|
||||
***
|
||||
|
||||
## [v6.143.0] - 2026-06-27
|
||||
|
||||
### 🐛 修复 lite 模式点赞/取消点赞后 like_count 不更新的问题
|
||||
|
||||
#### 问题现象
|
||||
- 主页句子广场(lite 模式,limit=5)点赞或取消点赞后,like_count 不变化
|
||||
- curl 实测:unlike 后 lite list 返回 `msg=成功(cache)`,like_count 仍为旧值
|
||||
- 非 lite 模式(limit=10/20)正常,仅 lite 模式 + limit=5 异常
|
||||
|
||||
#### 根因分析(三层 bug)
|
||||
1. **真正根因(核心)**:`_clearFeedCache` 的 `$limits = [10, 20, 30, 50]` **不包含 5**,而客户端 lite 模式请求用 limit=5,导致 `feed_list_hitokoto_newest_1_5_lite` 这个 cacheKey 从未被清理。互动操作后旧缓存仍然命中,返回过期数据。
|
||||
2. **潜在 bug(已兜底)**:`Cache::rm` 在某些环境(opcache 缓存旧代码 / ThinkPHP complex 驱动异常)下不删除文件。诊断脚本中 `Cache::rm` 返回 true 但文件仍在。
|
||||
3. **历史遗漏**:`_clearFeedCache` 之前未覆盖 `_lite` 后缀的 cacheKey(v6.142.0 已加,但 limit=5 才是关键阻塞点)。
|
||||
|
||||
#### 服务端修复
|
||||
**`docs/toolsapi/application/api/controller/Feed.php`**
|
||||
- `_clearFeedCache`:`$limits` 从 `[10, 20, 30, 50]` 扩展为 `[5, 10, 15, 20, 25, 30, 40, 50]`,覆盖客户端所有可能的 limit 值(含 5)。同步修复 `_clearWeightCache` 的同名数组。
|
||||
- 新增 `_unlinkCacheFile($cacheKey)` 私有方法:在 `Cache::rm` 之后兜底,按 ThinkPHP 5 File 驱动路径规则(`CACHE_PATH/前2位md5/剩余30位md5.php`)直接 `unlink` 缓存文件,绕过 opcache 缓存旧代码 / complex 驱动异常。
|
||||
- `_clearFeedCache` 所有 `Cache::rm` 调用后均追加 `$this->_unlinkCacheFile()` 兜底,覆盖 singleKeys / list 列表 / trending / 平台后缀 全部缓存 key。
|
||||
- 移除 v6.142.0 排查期间遗留的 7 处临时调试代码(`file_put_contents` 写入 unlike_debug/clearcache_debug/feed_cache_debug 日志)。
|
||||
|
||||
#### 验证
|
||||
自动化测试脚本 `/tmp/test_lite_cache.py` 全流程验证通过:
|
||||
```
|
||||
[stepA] 预热: msg='成功' feed_id=8812 like_count=3
|
||||
[stepB] like: msg='操作成功'
|
||||
[stepC] like后: msg='成功' like_count=4 期望=4 cache命中=False [OK]
|
||||
[stepD] unlike: msg='操作成功'
|
||||
[stepE] unlike后: msg='成功' like_count=3 期望=3 cache命中=False [OK]
|
||||
=== 全部通过: lite 模式缓存清理修复成功 ===
|
||||
```
|
||||
关键验证点:
|
||||
- stepC/stepE 的 `msg` 不再包含 `cache`,证明缓存已被清理、强制重新查库
|
||||
- like_count 正确递增(3→4)和递减(4→3)
|
||||
|
||||
#### 排查过程经验
|
||||
- 最初误判"unlike 不递减",实际是缓存竞态。加 sleep 2 秒重测发现 unlike 本身工作正常。
|
||||
- 调试日志(file_put_contents)全部为空,误导排查方向。根因是 opcache 缓存了旧 Feed.php(不含调试日志的版本),PHP-FPM 重启后 opcache 未彻底清理。通过 `opcache_invalidate(Feed.php, true)` + `opcache_reset()` 解决。
|
||||
- 最终通过在 `_unlinkCacheFile` 中加 trace 日志,对比 `newest_1_5_lite` 和 `newest_1_10_lite` 的记录,发现 limit=5 的 key 从未被处理,定位到 `$limits` 数组遗漏。
|
||||
|
||||
#### 文档同步
|
||||
- `API_FEED_DOC.md` 头部版本号 v2.4 → v2.5
|
||||
- 修正 v6.142.0 中关于 unlike 的错误结论(标注为已修复,指向本版本)
|
||||
|
||||
#### 不足与建议
|
||||
- **$limits 仍为枚举**:若未来客户端新增 limit=35 等值,需同步更新数组。建议后续改为 `range(5, 50, 5)` 或用 glob 扫描缓存文件前缀的方式彻底规避。
|
||||
- **opcache 自动清理依赖**:当前依赖 `validate_timestamps=1` + `revalidate_freq=3`,文件更新后最多 3 秒延迟。若部署后 3 秒内有请求命中旧 opcache,仍可能用旧代码。建议部署脚本中调用 `opcache_reset` 或重启 PHP-FPM。
|
||||
- **Cache::rm 与 unlink 双写**:当前每次互动操作执行约 320 次 `Cache::rm + unlink`,性能可接受但略显冗余。可考虑用 `Cache::clear()` 清空整个缓存目录,但会影响其他模块缓存命中率。
|
||||
|
||||
***
|
||||
|
||||
## [v6.142.0] - 2026-06-27
|
||||
|
||||
### 🐛 修复主页句子广场点赞按钮显示 0 的问题
|
||||
|
||||
#### 根因分析(双重 bug)
|
||||
1. **服务端根因**:`/api/feed/list` 接口 `_formatItem` 默认不返回 `like_count/favorite_count/comment_count/share_count` 字段,只有 `/api/feed/detail` 才附加。客户端 `FeedItem.fromJson` 解析 `null` → 默认 0 → 按钮显示 0。
|
||||
2. **客户端根因**:`toggleLike`/`toggleFavorite` 乐观更新时只翻转 `isLiked/isFavorited`,未递增/递减 `likeCount/favoriteCount`,导致即使点击点赞数字也不变。
|
||||
|
||||
#### 服务端修复
|
||||
**`docs/toolsapi/application/api/controller/Feed.php`**
|
||||
- 新增 `_batchAttachInteractionCounts(&$items)` 私有方法:
|
||||
- 收集所有 `(feed_type, feed_id)` 对
|
||||
- 按 feed_type 分组批量查询 `feed_interaction` 表,`GROUP BY feed_id, action` 一次性获取 like/favorite/comment/share 计数
|
||||
- 回填到 items 的 `like_count/favorite_count/comment_count/share_count` 字段
|
||||
- 避免 N+1 查询,列表接口性能影响极小
|
||||
- `list()` 方法末尾调用,`_batchLoadFeedItems()` 末尾也调用(覆盖 favorites/likes/history/readlater 列表)
|
||||
- 查询失败时降级填充 0,保证字段始终存在(客户端不再解析 null)
|
||||
|
||||
#### 客户端修复
|
||||
**`lib/features/home/providers/home_interaction_mixin.dart`**
|
||||
- `toggleLike` 乐观更新:除翻转 `isLiked` 外,同步递增/递减 `likeCount`(点赞 +1,取消点赞 -1,下限 0)
|
||||
- `toggleFavorite` 乐观更新:除翻转 `isFavorited` 外,同步递增/递减 `favoriteCount`(举一反三,同类问题)
|
||||
- `_persistLikeLocally` 兜底插入分支:调用新增的 `setLikesCount` 同步写入本地 DB 的 `likes` 字段
|
||||
|
||||
**`lib/core/storage/database/app_database.dart`**
|
||||
- 新增 `setLikesCount(id, count)` 方法:
|
||||
- 由于 `.g.dart` 未重新生成(`build_runner` 受 freezed/analyzer 版本冲突阻塞),`SentencesCompanion` 缺少 `likes` 命名参数
|
||||
- 改用 `customStatement` 直接执行 SQL:`UPDATE sentences SET likes = ?, updated_at = ? WHERE id = ?`
|
||||
- 自动 clamp 负数为 0
|
||||
|
||||
**`lib/features/home/providers/home_sentence_model.dart`**
|
||||
- `HomeSentence.fromDb` 添加注释说明 `likes` 字段未读取原因(Sentence 类缺 `likes` getter,.g.dart 未重新生成)
|
||||
- 兜底场景保持 likeCount=0,主场景由服务端返回真实数据
|
||||
|
||||
#### 验证
|
||||
- curl 实测 `/api/feed/list` 修复前:`like_count= MISSING favorite_count= MISSING`
|
||||
- curl 实测 `/api/feed/list` 修复后:`like_count= 4 favorite_count= 3 comment_count= 0`(真实数据)
|
||||
- 端到端验证:登录 → 查询 detail(like_count=4, is_liked=True)→ list 接口返回一致 like_count=4
|
||||
- `flutter analyze` 三个修改文件零警告
|
||||
|
||||
#### 文档同步
|
||||
- `API_FEED_DOC.md` 头部版本号 v2.3 → v2.4
|
||||
- 3.4 节响应字段说明新增 v2.4 更新提示
|
||||
|
||||
#### 不足与建议
|
||||
- ~~**服务端 unlike 潜在 bug**:curl 实测 unlike 后 list 接口的 like_count 仍为 4,没有递减。可能 feed_interaction 表的 unlike 操作未真正删除记录(待排查 action 方法逻辑)。~~ **[v6.143.0 已修复]** 实际根因是 `_clearFeedCache` 的 `$limits` 数组不含 5,导致 lite 模式 limit=5 的缓存未被清理,详见 v6.143.0。
|
||||
- **`build_runner` 阻塞**:导致 `SentencesCompanion`/`Sentence` 类缺少 `likes` 字段,本地兜底场景 likeCount 显示 0。建议解决 freezed 3.2.5/analyzer 12.1.0 版本冲突后重新生成。
|
||||
- **可扩展**:`_batchAttachInteractionCounts` 可进一步附加 `is_liked`/`is_favorited` 字段(需登录用户ID),让 list 接口也能返回用户个人互动状态,避免客户端依赖 detail 接口。
|
||||
|
||||
***
|
||||
|
||||
## [v6.141.0] - 2026-06-27
|
||||
|
||||
### ✨ LiquidGlassActionButton 深度升级 + 触觉音效 + 长按交互
|
||||
|
||||
#### 背景
|
||||
v6.140.0 完成句子卡片按钮重设计与收藏 Bug 修复后,识别出 5 项不足。本版本逐一解决。
|
||||
|
||||
#### 改进清单
|
||||
|
||||
##### 1. 真正的 BackdropFilter 液态玻璃
|
||||
**`lib/features/home/presentation/home_sentence_card.dart`**
|
||||
- `LiquidGlassActionButton` 未激活态改用真正的 `BackdropFilter` + `ImageFilter.blur`
|
||||
- sigma 计算:`GlassTokens.baseBlur * ext.glassBlurMultiplier`(按钮较小用 base 层 10.0)
|
||||
- 性能降级链路:
|
||||
- 鸿蒙端 `OhosDeviceCapabilities.supportsBackdropFilter` 判断
|
||||
- `PerformanceOptimizer.instance.shouldEnableBackdropFilter` 省电模式降级
|
||||
- `PerformanceOptimizer.instance.suggestedBlurSigma()` 低端设备 sigma 缩放
|
||||
- `RepaintBoundary` 隔离重绘,避免列表滚动重复模糊
|
||||
- 激活态仍用渐变填充(无需模糊)
|
||||
|
||||
##### 2. 统一动画驱动
|
||||
- 移除 `AnimatedScale` + `ScaleTransition` 双重叠加
|
||||
- 改为单一 `AnimatedBuilder` + `Transform.scale` 统一缩放整个按钮(icon + 文字)
|
||||
- 动画曲线 `Curves.easeInOutBack`,时长 400ms
|
||||
|
||||
##### 3. 跨模块文案依赖修复
|
||||
- `t.discover.base.favorite/favorited` → `t.home.sentenceDetail.favorite/favorited`
|
||||
- home 模块不再依赖 discover 模块翻译,符合 AGENTS.md 架构约束
|
||||
- `THomeBase` 无 favorite 字段,但 `TSentenceDetail`(home.sentenceDetail)已有完整字段
|
||||
|
||||
##### 4. 稍后读同类 Bug 排查(无需修复)
|
||||
- 调查发现 `_persistReadLaterLocally` **不写 sentences 表**
|
||||
- 稍后读状态通过 `ChatMessageService.sendReadLaterSentence` 写入 ChatMessage 表(会话 ID `'readlater'`)
|
||||
- 取消时调 `db.softDeleteChatMsgRecord` 软删除
|
||||
- 已有 try-catch + `inserted = true` 兜底,逻辑鲁棒
|
||||
- **结论**:稍后读不存在 UPDATE 静默失败问题,无需修复
|
||||
|
||||
##### 5. HapticService + SfxService 触觉音效接入
|
||||
**`lib/features/home/presentation/home_sentence_card.dart`**
|
||||
- 新增 `HapticType` 枚举(like / favorite)
|
||||
- `LiquidGlassActionButton` 新增 `hapticType` 参数
|
||||
- 激活态:`HapticService.medium()` + `SfxService.instance.play(SfxType.like/favorite)`
|
||||
- 取消态:`HapticService.light()` + `SfxService.instance.play(SfxType.unlike/unfavorite)`
|
||||
- 反馈在 `didUpdateWidget` 中根据状态变化触发,与动画同步
|
||||
|
||||
##### 6. 长按卡片触发重冲击
|
||||
**`lib/core/utils/ui/interaction_animations.dart`**
|
||||
- `PressableCard` 新增 `onLongPress` 参数
|
||||
- 长按触发时自动回弹(避免停留在按压态)
|
||||
**`lib/features/home/presentation/home_sentence_card.dart`**
|
||||
- `SentenceCard` 接入长按:`HapticService.heavy()` + 触发详情面板
|
||||
- 与点击效果一致,但提供差异化触觉反馈(重冲击 vs 无冲击)
|
||||
|
||||
##### 7. 服务端 /api/feed/favorites 验证
|
||||
- 服务端代码审查:`Feed.php::_formatItem` 第 2186 行明确返回 `'feed_type' => $type`
|
||||
- 客户端解析:`FeedItem.fromJson` 第 295 行 `feedType: json['feed_type'] as String? ?? ''`
|
||||
- 接口在线验证:curl 返回 401(未登录,非 404),接口正常
|
||||
- **结论**:feed_type 字段链路完整,无需修复
|
||||
|
||||
#### 验证
|
||||
- `flutter analyze` 通过,0 error / 0 warning
|
||||
- 2 个修改文件的 IDE 诊断全部通过
|
||||
|
||||
#### 改动文件
|
||||
| 文件 | 改动 |
|
||||
|------|------|
|
||||
| [home_sentence_card.dart](file:///Users/wushu/Documents/trae_projects/project/xianyan/lib/features/home/presentation/home_sentence_card.dart) | LiquidGlassActionButton 重构 + HapticType + 长按接入 + 文案改用 home.sentenceDetail |
|
||||
| [interaction_animations.dart](file:///Users/wushu/Documents/trae_projects/project/xianyan/lib/core/utils/ui/interaction_animations.dart) | PressableCard 新增 onLongPress 支持 |
|
||||
|
||||
---
|
||||
|
||||
## [v6.140.0] - 2026-06-27
|
||||
|
||||
### 🐛 修复句子广场收藏在「我的收藏」页面不显示的 Bug + 卡片按钮重设计
|
||||
|
||||
#### 背景
|
||||
用户反馈主页「句子广场」的句子卡片点击收藏后,在「我的收藏」页面没显示收藏的句子。同时要求重新设计点赞/收藏按钮为长方形 icon+文字 样式,去掉分享 icon 按钮。
|
||||
|
||||
#### Bug 根因(多重故障叠加)
|
||||
1. **本地数据库 UPDATE 静默失败**:`home_interaction_mixin._persistFavoriteLocally` 直接调用 `interactionDb.toggleFavorite(id)` UPDATE,若 sentences 表中不存在该 id 的记录(Feed 列表未缓存/缓存被清),UPDATE 静默失败,本地 isFavorite 字段从未被设置。
|
||||
2. **Legacy API 硬编码 `targetType: 'article'`**:`favorite_repository._loadLegacyFavorites` 中硬编码 `targetType: 'article'`,但句子广场的 feedType 是 `hitokoto`/`chengyu`/`hanzi`/`poetry` 等,降级 Legacy API 永远查不到句子收藏。
|
||||
3. **`mergeWithLocalDb` 去重 key 不鲁棒**:仅用 `content+author` 作为去重 key,空 content 时退化为 `|title`,多条空 content 条目互相误去重;且未利用 id 信息,服务端和本地同一句子(id 相同但 content 微小差异)会被当作两条。
|
||||
4. **降级条件过激**:`_loadFeedFavorites` 中 `result.list.isEmpty && result.total == 0 && page == 1` 触发立即降级 Legacy API,在服务端 bug / 缓存延迟 / 新用户无收藏等场景下误降级。
|
||||
|
||||
#### 修复
|
||||
| 文件 | 修复 |
|
||||
|------|------|
|
||||
| `lib/features/home/providers/home_interaction_mixin.dart` | `_persistFavoriteLocally` 改为先查再决定 `setFavoriteFlag` 或 `insertOrUpdateSentence` upsert 兜底;举一反三同步修复 `_persistLikeLocally` 相同问题 |
|
||||
| `lib/core/storage/database/app_database.dart` | 新增 `setLikeFlag(id, value)` 方法(与 `setFavoriteFlag` 对称),避免 `toggleLike` 在记录不存在时静默失败 |
|
||||
| `lib/features/home/favorite_repository.dart` | `_loadLegacyFavorites` 移除硬编码 `targetType: 'article'`,让服务端返回所有类型收藏 |
|
||||
| `lib/features/home/favorite_repository.dart` | `mergeWithLocalDb` 改为双重去重策略:主 key 用 `targetType\|targetId`,副 key 用 `content\|title`(空 content 不参与去重) |
|
||||
| `lib/features/home/favorite_repository.dart` | `_loadFeedFavorites` 空结果时先检查本地数据库,本地有则兜底返回,避免误降级 Legacy API |
|
||||
|
||||
#### 卡片按钮重设计(方案 C · 液态玻璃)
|
||||
**`lib/features/home/presentation/home_sentence_card.dart`**:
|
||||
- 移除分享 icon 按钮(分享功能保留在左滑手势和详情面板入口)
|
||||
- 移除 `_shareAsImage` / `_shareAsText` / `_isSharing` / `_repaintKey` 及相关 import(dart:io / dart:ui / path_provider / share_plus / kIsWeb)
|
||||
- 新增 `LiquidGlassActionButton` 组件(iOS 26 Liquid Glass 风格):
|
||||
- 长方形 icon + 文字 按钮
|
||||
- 未激活:半透明玻璃材质 + 微高光 + 中性色
|
||||
- 已激活:渐变填充 + 内嵌高光 + 投射阴影 + 白色 icon/文字
|
||||
- 点击触发弹跳动画(AnimationController + easeInOutBack 曲线)
|
||||
- 自动跟随 `AppThemeExtension` 切换明/暗/AMOLED/主色
|
||||
- 点赞按钮:❤️ + 数字(用 `NumberFormatter.formatCount`),激活态 iOS systemRed 渐变
|
||||
- 收藏按钮:★ + 文字"收藏"/"已藏"(用 `t.discover.base.favorite/favorited`),激活态 iOS systemOrange 渐变
|
||||
- 新增 `_ToolIconButton` 抽出拼音/翻译/TTS 工具图标共用组件,添加无障碍语义标签
|
||||
- HTML 设计原型:`docs/prototypes/sentence_card_redesign.html`(4 种方案 + 动态主题切换预览)
|
||||
|
||||
#### 验证
|
||||
- `flutter analyze` 通过,0 error / 0 warning
|
||||
- 4 个修改文件的 IDE 诊断全部通过
|
||||
|
||||
#### 不足与扩展建议
|
||||
详见本次会话末尾的「审计验收」总结。
|
||||
|
||||
---
|
||||
|
||||
## [v6.139.0] - 2026-06-26
|
||||
|
||||
### 🧹 macOS 编译验证 + 静态分析清理
|
||||
|
||||
Reference in New Issue
Block a user