# 需求进度

## 当前总目标
- 控制当前 Flutter Android 发包体积，持续定位冗余组件、超大资源和不合理构建配置，并把每一步处理结果落盘记录。

## 本轮启动优化（非网络）
- 已移除启动页固定 `6` 秒倒计时，改为最短约 `900ms` 展示后继续路由判断，避免人为等待直接拉长入 app 时间。
- 已将 Firebase / Crashlytics 从 `runApp` 前阻塞初始化改为首帧后后台预热，并补充“未就绪时仅本地打印”的异常兜底，减少首屏前平台初始化阻塞。
- 已将 `SocialChatAuthenticationManager`、`SocialChatUserProfileManager` 改为按需创建，避免 splash 阶段就提前触发 Google Sign-In / Firebase 会话检查。
- 已将 deep link、设备信息、缓存目录创建等非首帧必需动作延后到首帧后执行，降低首屏竞争。
- 已优化本地语言初始化：启动时不再重复写入 `SharedPreferences` 并触发一次无意义的 `notifyListeners`。
- 已优化首页容器与 Home 首屏：去掉首次进入时“先 loading 再建 tab”的本地跳变，并将首页 page 列表、底部导航项从 `build` 阶段的重复重建改为复用。
- 本轮按需求暂未处理网络链路上的启动等待，例如审核态检查或远端启动页配置请求。

## 已完成模块
- 已为语言房页面补充右下方 `game` 悬浮入口：入口位于聊天区右下侧、距右侧约 `15.w`、位于底部操作栏上方约 `100.w`，当前先使用代码绘制的 `🎮` 占位图标，并已在实现处标注后续替换为正式 UI 图片资源。
- 已新增语言房游戏底部弹窗：点击 `game` 入口后会从底部弹出约三分之一屏高的面板，采用房间页现有半透明磨砂风格，便于后续继续沿用当前视觉体系。
- 已补齐语言房游戏列表占位结构：弹窗内部先用静态游戏数据驱动，并按“`ListView` 可上下滑动 + 每行 `5` 个图标位”的方式实现，后续只需替换入口图、列表图标和真实接口数据即可继续开发。
- 创建并持续维护进度跟踪文件。
- 已继续排查语言房 gift 动画链路：确认送礼后会同时走本地房间消息、滚屏礼物条和大额礼物全局飘屏三条路径，并修复动画管理器在控制器尚未绑定完成时提前消费队列导致后续动画不再播放的问题。
- 已定位并修复语言房礼物飘屏资源引用错误：代码里误写 `sc_icon_gift_flosc_bg` / `sc_icon_luck_gift_flosc_*`，实际资源文件名为 `float`，导致点击送礼后飘屏背景图加载失败，相关动画无法正常显示。
- 已继续定位语言房礼物特效不播放的根因：后端礼物配置返回的特效标记为 `ANIMATION`，而前端历史代码只识别拼写错误的 `ANIMSCION`，导致送礼后直接跳过全屏/半屏特效播放；现已改为同时兼容两种标记。
- 已继续优化语言房礼物特效播放性能：将礼物资源预热改为“后台串行预加载 + 选中礼物高优先级预加载 + 播放阶段复用同一解码/下载任务”，避免送礼时重复下载或重复解码同一个 `.svga/.mp4`；同时为全屏播放器增加 `RepaintBoundary`，并改为按原始比例渲染、关闭越界绘制，减少整页重绘和过度放大带来的卡顿。
- 已继续优化礼物二级页首屏与翻页加载体验：礼物配置改为会话内复用，避免每次打开礼物面板都重新拉列表；首屏与翻页页卡增加整页骨架态，页面图片预热改为“当前页并发预热 + 下一页提前预热”，并增加“最短可感知骨架时长 + 最长骨架保护窗口”，避免整页骨架一闪而过；超过上限后再切换到真实卡片，并让单个礼物继续使用小 `loading` 占位补齐，整体交互对齐常见直播 app 的礼物面板体验。
- 已修复首页房间封面显示链路：兼容接口 `roomCover/cover` 双字段，并补齐编辑房间成功后的封面内存回写。
- 已继续修复房间设置保存封面后丢失的问题：房间保存接口改为兼容提交 `id/roomId` 与 `roomCover/cover`，并在保存成功后优先保留刚提交的封面、名称、公告，避免被空响应覆盖。
- 已新增按房间 ID 的本地房间资料缓存兜底：首页、我的房间、历史/关注、搜索和再次进入房间都会优先回填最近一次本地保存的封面；同时已将房间封面空态图替换为新的 `sc_no_data.png`。
- 已确认房间封面上传接口与 `PUT /room/profile` 保存接口都返回了正确图片地址，并修正首页/重进房间的取值优先级，避免被列表接口短时间返回的旧封面或无效封面重新覆盖。
- 已继续完善个人主页头像与滚动表现：顶部小头像保持纯头像，主头像恢复头像框叠加；同时将个人主页背景并入可滚动 header，修复滑动时内容与背景不同步的问题。
- 已进一步统一头像框方案：共享头像组件改为“头像居中 + 头像框包边”结构，并对这类静态头像框资源增加白底去除处理，不再简单把头像框整张盖在头像上；个人主页主头像与房间麦位头像现已同步采用这一展示方式。
- 已修复静态头像框透明区域误变黑的问题：调整头像框白底透明化公式后，进入房间时不再出现只有头像附近有颜色、其余房间背景被黑块覆盖的现象。
- 已修复个人主页首屏黑屏与内容区多余圆角问题：为个人页补充稳定的底图/底色占位，避免进入页面时先出现黑屏；同时移除资料内容区顶部多余圆角。
- 已将个人主页首屏占位升级为骨架屏：进入个人页时会先按真实版式展示头像、昵称、计数区、Tab 和资料内容的骨架块，不再先露默认背景等待约 1 秒。
- 已为首页 Party 页补齐首屏骨架屏：顶部 H5 榜单现按三列奖杯卡位展示头像/标题骨架，下方房间区改为双列房卡骨架，并采用深绿底 + 金色描边的项目内风格；同时拆分榜单与房间列表加载态，仅在“首屏无内容加载”时展示骨架，避免下拉刷新时整页闪烁。
- 已为首页 My 板块补齐首屏骨架屏：`My room` 顶部房间卡片改为独立加载态，避免首屏把“正在加载我的房间”误显示成“去创建房间”；`Recent/Followed` 两个子页也已改成同风格双列房卡骨架，进入 tab 时会先展示完整结构占位，再按真实数据切换。
- 已为 `Me` 入口下的 `Store / Bag` 页面补齐首屏骨架屏：四类 `store` 商品页和四类 `bag` 物品页在“首屏空数据加载”阶段都会先展示同风格的三列卡片骨架，不再只显示小菊花；同时已为商品/物品名称补齐宽度约束与省略号处理，避免超长文案顶出卡片。
- 已将通用图片加载占位从静态 `loading` 图片升级为代码绘制的环形转点组件：礼物二级页单卡封面、`Store / Bag` 商品图以及复用共享图片组件的网络图，在“加载中”阶段都会显示动态转圈效果；而图片失败或 `no data` 时仍保持原有占位图，不混淆加载态与空态。
- 已继续细化首页房卡体验：`My` 板块房卡骨架数量已从 `4` 个补齐到 `6` 个，与首页 Party 首屏保持一致；同时将房卡右下角原本的静态绿色“直播中”图片替换为代码驱动的三段式动态音频条，首页、我的、搜索结果和房间浮窗现都会展示跳动效果，不再依赖静态资源图；最新已把动效调整为“单周期完整峰谷 + A/B/C 错峰起伏”的连续波形，观感更接近直播音频电平。
- 已继续微调首页房卡信息密度：房卡底部房名与在线人数字号已统一调小，和动态音频条更协调；同时已移除 `My` 板块顶部 `my room` 标题及其占位，让房间卡片整体上移，对齐更紧凑。
- 已继续微调首页视觉细节：房卡底栏房名再次缩小并轻微上移，和国旗、动态音频条、人数的中线更一致；首页顶部排行骨架也已简化为“3 个圆形头像 + 1 根文本条”，更贴近真实卡片结构。
- 已补回首页 Party 顶部 banner 展示链路：顶部现优先显示原有 `explore` banner，并在该分组为空时自动兜底使用首页 `home` banner，避免整块区域消失；同时首屏 banner 空数据加载阶段已补充同风格骨架占位，不再直接塌陷为零高度。
- 已继续微调首页 Party 顶部 banner 体验：banner 与下方排行组件之间已补齐接近房卡区的纵向间距；当 banner 只有 `1` 张时，会关闭无限轮播与横向回弹，左右滑动不再弹回中间。
- 已继续收窄首页 Party 顶部 banner 骨架样式：banner 骨架现改为更干净的整块占位，不再在中间叠加长方形白条，首屏观感更接近真实 banner 的整体加载。
- 已优化语言房顶部成员入口的点击范围：右上角在线成员区域现已将左侧头像堆叠区与右侧成员图标统一为同一点击热区，用户点击头像区也可直接打开成员列表页。
- 已继续修复房间封面跨用户不同步问题：当列表或进房返回空封面时，客户端会自动补拉 `room/profile/specific` 详情并缓存真实封面；同时房主保存房间资料后会向房间内其他用户派发资料刷新消息，避免只有自己能看到新封面、其他用户仍显示 `no data`。
- 已修复个人主页编辑页头像上传后无变化的问题：上传成功后会先本地回写新头像地址并立即提交；资料更新接口现同时兼容 `userAvatar/avatar` 字段，且不再被紧接着的旧资料回拉覆盖，返回个人主页后头像会即时更新。
- 已进一步定位图片 `no data` 根因并修复客户端加载链：日志确认房间封面详情接口可返回正确公网 `media...` 地址，但用户头像接口会返回 `jvapi.../external/oss/local/...` 这类受保护资源地址；共享图片组件现已对这类地址自动补齐鉴权请求头，避免其它用户侧加载时直接失败为 `no data`。
- 已直接校验头像异常地址的服务端返回：`jvapi.../external/oss/local/...` 当前会返回 `500 local disk file does not exist`，并非单纯鉴权缺失；前端现已在编辑资料成功后与本人资料回拉时优先保留刚上传成功的公网头像，避免再次被这类坏地址覆盖，同时修复了房间消息用户资料缓存未真正失效的笔误。
- 已继续修正个人资料更新接口的提交结构：排查发现注册接口使用嵌套 `profile`，而资料更新接口此前只发扁平字段；现已改为同时提交 `id + 扁平字段 + profile`，并在 `profile` 内同步带上 `userAvatar/avatar`，用于兼容后端可能按嵌套对象取值的情况。
- 已按最新联调结果再次收窄个人资料更新参数：日志已证明后端能收到请求但会忽略新头像地址，当前已改为头像相关只提交单一 `userAvatar` 字段，并移除 `avatar/profile` 冗余结构，便于继续验证后端是否对字段名或重复参数敏感。
- 已继续将个人页头像上传链路与通用资料提交拆开：上传成功后当前会单独触发一次仅含 `userAvatar` 的更新请求，不再混带昵称、性别、年龄、国家等字段，便于排除其它参数对头像更新接口的干扰。
- 完成仓库结构、依赖引用、资源体积和 APK 组成的第一轮排查。
- 移除 4 个当前未在业务层直接使用的插件依赖：`loading_indicator_view_plus`、`social_sharing_plus`、`flutter_foreground_task`、`on_audio_query`，并清理相关平台声明。
- 修补 `image_cropper 5.0.1` Android 兼容问题，切换到本地 path 依赖以恢复构建。
- 完成 Android release 签名回退配置，解决仓库缺少 `yumi.jks` / `yumi_debug.jks` 时无法继续本地构建分析的问题。
- 完成 release 包体分析，确认 universal APK 过大主要由多 ABI 与 Agora/Tencent 原生 so 导致。
- 去除 Gradle 中与 Flutter 冲突的硬编码 `abiFilters`，确认 `--split-per-abi` 可以正常产出分架构 APK。
- 完成 TinyPNG 环境核查，并接入可执行的 Ruby 批量压缩脚本。
- 已完成 TinyPNG 第一轮批量压缩，`sc_images + assets` 总量已从 `47.25 MB` 降到 `22.54 MB`。
- 已增强 TinyPNG 脚本，支持断点续跑、单文件目标和失败项重试。
- 已完成 TinyPNG 网络失败项补跑，6 张 `SSL_connect` 异常图片已全部压缩成功。
- 已完成图片压缩后的 release 复测，确认分 ABI APK 体积继续显著下降。
- 已切换 Android `release` 为真正的瘦身模式：开启 `minify`、`shrinkResources`、`zipAlign`。
- 已完成开启瘦身配置后的 Android release 复测，并接入 `split-debug-info` 保存 Dart symbols。
- 已生成统一的 Python 打包脚本 `scripts/build_release.py`，开始接管 `AAB`、分 ABI APK 与 iOS 包流程。
- 已完成 `scripts/build_release.py` 的 Android / iOS 真机冒烟验证，产物归档目录与 manifest 均已生成。
- 已按当前需求再次完成正式 `AAB` 出包。
- 已定位 Google Play 上传阻塞点：当前 `AAB` 使用的是 `Android Debug` 证书签名，不是正式 upload key。
- 已确认当前项目属于“首次上架的新应用”，后续应走 Play App Signing 首发流程，而不是兼容老签名迁移流程。
- 已梳理 Google Play 首次上架所需的 `Play App Signing`、`upload key`、重新打包与提审步骤。
- 已澄清首次生成 `upload keystore` 时的“密钥库口令”是本地自行设置的密码，与 Google 提供的 `deployment_cert.der` 证书文件无关。
- 已为新应用生成正式 `upload keystore`，并接入工程的 release 签名配置。
- 已重新打出正式 `AAB`，并确认其签名已经从 `Android Debug` 切换到新的 upload key。
- 已定位 `FOREGROUND_SERVICE_MEDIA_PROJECTION` 的来源为 Agora `full-screen-sharing` 依赖，并开始从主 Manifest 覆盖移除。
- 已移除 `FOREGROUND_SERVICE_MEDIA_PROJECTION` 相关声明并重新打出正式 `AAB`。
- 已按当前需求打出正式 `arm64-v8a` 单架构 `APK`。
- 已将新的 `google-services.json` 替换进工程，准备重新打包验证。

## 进行中模块
- 评估 iOS 正式签名参数接入后导出 `.ipa` 的流程。
- 继续评估 Agora 扩展 so 与 release shrink 策略是否还能进一步裁剪。
- 评估 12 张 TinyPNG 不支持解码的特殊 `webp` 是否需要改格式或换工具处理。

## 关键技术决策
- 先做高置信度瘦身：优先清理未使用插件、ABI 配置和超大图片，暂不贸然删除核心业务能力。
- 避开仓库中用户已有未提交改动，只改必要文件并持续把结果写入本文件。
- 包体分析聚焦 release 产物，不被 `build/`、iOS 中间产物等本地缓存误导。
- Android 架构裁剪交给 Flutter 构建命令驱动，不再在 Gradle 中硬编码 `abiFilters`。
- 对 `image_cropper` 采用本地 path 依赖加最小补丁策略，避免升级带来的业务回归面。
- Android 签名配置采用条件回退：正式 keystore 不存在时自动回退到 debug 签名，仅用于本地分析验证。
- 图片压缩优先走 TinyPNG，以尽量保持画质稳定；失败项按原因分流处理。
- TinyPNG 的 `SSL_connect` 视为可重试网络抖动；`Image could not be decoded` 视为 TinyPNG 对特殊/动图 WebP 的能力边界，先记录不阻塞其余压缩。

## 已改动文件
- `需求进度.md`
- `lib/shared/data_sources/models/enum/sc_gift_type.dart`
- `lib/shared/tools/sc_network_image_utils.dart`
- `lib/shared/tools/sc_gift_vap_svga_manager.dart`
- `lib/services/general/sc_app_general_manager.dart`
- `lib/ui_kit/widgets/room/floating/floating_gift_screen_widget.dart`
- `lib/ui_kit/widgets/room/floating/floating_luck_gift_screen_widget.dart`
- `lib/services/room/rc_room_manager.dart`
- `lib/services/audio/rtc_manager.dart`
- `lib/modules/room/edit/room_edit_page.dart`
- `lib/shared/data_sources/sources/repositories/sc_user_repository_impl.dart`
- `lib/shared/data_sources/sources/repositories/sc_room_repository_imp.dart`
- `lib/shared/tools/sc_room_profile_cache.dart`
- `lib/shared/business_logic/models/res/room_res.dart`
- `lib/shared/business_logic/models/res/follow_room_res.dart`
- `lib/shared/business_logic/models/res/my_room_res.dart`
- `lib/shared/business_logic/models/res/sc_edit_room_info_res.dart`
- `lib/shared/business_logic/models/res/join_room_res.dart`
- `lib/ui_kit/components/sc_compontent.dart`
- `lib/ui_kit/components/sc_float_ichart.dart`
- `lib/ui_kit/widgets/room/room_head_widget.dart`
- `lib/modules/room/detail/room_detail_page.dart`
- `lib/modules/home/popular/party/sc_home_party_page.dart`
- `lib/modules/home/popular/mine/sc_home_mine_skeleton.dart`
- `lib/modules/home/popular/follow/sc_room_follow_page.dart`
- `lib/modules/home/popular/history/sc_room_history_page.dart`
- `lib/modules/home/popular/mine/sc_home_mine_page.dart`
- `lib/ui_kit/widgets/room/room_live_audio_indicator.dart`
- `lib/modules/search/sc_search_page.dart`
- `lib/modules/store/headdress/store_headdress_page.dart`
- `lib/modules/store/mountains/store_mountains_page.dart`
- `lib/modules/store/theme/store_theme_page.dart`
- `lib/modules/store/chatbox/store_chatbox_page.dart`
- `lib/modules/user/my_items/headdress/bags_headdress_page.dart`
- `lib/modules/user/my_items/mountains/bags_mountains_page.dart`
- `lib/modules/user/my_items/chatbox/bags_chatbox_page.dart`
- `lib/modules/user/my_items/theme/bags_theme_page.dart`
- `lib/ui_kit/widgets/store/store_bag_page_helpers.dart`
- `sc_images/general/sc_no_data.png`
- `.gitignore`
- `android/key.properties`
- `pubspec.yaml`
- `pubspec.lock`
- `lib/ui_kit/components/dialog/dialog.dart`
- `android/app/src/main/AndroidManifest.xml`
- `android/app/google-services.json`
- `ios/Runner/Info.plist`
- `scripts/tinypng_batch.rb`
- `scripts/build_release.py`
- `tinypng-progress.json`
- `tinypng-report.json`
- `local_packages/image_cropper-5.0.1-patched/android/src/main/java/vn/hunghd/flutter/plugins/imagecropper/ImageCropperPlugin.java`
- `local_packages/image_cropper-5.0.1-patched/`
- `android/app/build.gradle.kts`
- `android/app/upload-keystore.jks`
- `android/app/upload_certificate.pem`
- `build/symbols/android/`
- `build/symbols/ios/`
- `dist/release/smoke-android/`
- `dist/release/smoke-ios/`
- `sc_images/`
- `assets/`

## 已验证结果
- 已通过代码与资源目录交叉核对确认：房内礼物飘屏当前报错 `Unable to load asset: "sc_images/room/sc_icon_gift_flosc_bg.png"` 的根因是资源名拼写错误，而不是消息未下发；工程内实际存在的资源文件为 `sc_icon_gift_float_bg.png`、`sc_icon_luck_gift_float_bg1~5.png`、`sc_icon_luck_gift_float_n_bg.png`。
- 已确认当前“点击赠送没有动画”至少包含一类前端资源问题：大额礼物/幸运礼物飘屏 widget 已进入渲染，但因为背景图 asset 路径写错而无法显示；全屏 `SVGA/VAP` 特效是否播放仍取决于具体礼物是否带有 `giftSourceUrl`，且 `special` 包含 `ANIMSCION/ANIMATION/GLOBAL_GIFT` 之一。
- 已完成一轮针对卡顿的代码级优化：礼物列表现在只会对真正需要全屏特效的礼物做受控预热；用户选中礼物时会立即高优先级预热该礼物；播放器播放时优先复用内存里的 `MovieEntity` 或同一路径的在途任务，不再重复发起网络下载/重复解码；渲染层也已改为独立重绘边界以减少房间整页跟随重绘。
- 已通过 GiftFX 调试日志确认：示例礼物 `阿拉伯舞蹈` 实际返回 `giftSourceUrl=.svga` 且 `special=ANIMATION`，此前前端因为不识别该标记而输出 `skip local play because special does not include ANIMSCION/GLOBAL_GIFT`；本轮已补齐 `ANIMATION` 兼容判断。
- 礼物二级页当前已按“整页骨架 + 当前页并发预热 + 下一页提前预热 + 单卡小 loading 占位”的方式重构首屏加载策略：首次进入和翻页时不会再直接暴露 `noData` 图，且整页骨架会保留一个可感知时长，不再一闪而过；当前页礼物封面会并发预热而不是等每个格子各自串行体感加载。
- 当前工作区存在用户已有未提交改动，后续处理均避开覆盖。
- 首页 `party/follow/history/mine` 以及房间详情使用的房间封面模型已兼容 `roomCover` 与 `cover` 两种返回字段，上传封面后不会再因为字段名不一致掉回空占位。
- 房间设置保存封面时，前端现在会同时兼容提交和读取两套字段，并在 `PUT /room/profile` 响应或紧接着的房间详情刷新返回空封面时保留刚上传的封面，不再被空值冲掉。
- 已新增本地房间封面兜底缓存：即使服务端短时间仍返回空封面，首页列表、我的房间、搜索结果、房间头部、房间详情和再次进入房间也会继续显示最近一次本地成功保存的封面。
- 已通过实际请求日志确认：`POST /external/oss/upload`、`PUT /room/profile` 和随后 `GET /room/profile/specific` 都已返回正确封面 URL；本轮问题的根因已收敛为首页/列表链路仍可能使用接口短时间回传的旧值，因此本地成功保存的封面现已提升为更高优先级。
- 房间封面空态图已切换为新的 `sc_images/general/sc_no_data.png`，其资源尺寸为 `288x288`。
- 房间资料卡与个人主页使用的用户资料链路已重新对齐：个人页现兼容 `avatar` 别名；顶部小头像不叠加头像框，但主头像会继续叠加头像框资源，且个人页背景已随 header 一起滚动，不再出现内容先滑动、背景停留不动的现象。
- 头像框显示逻辑已改为“框在外、头像在内”的常见样式；针对当前这类带白底的静态头像框资源，已增加白底透明化处理，因此个人主页主头像与房间麦位头像都不会再留下明显白边。
- 静态头像框的透明区域现已保持透明，不会再被错误算成黑色；房间麦位头像、个人主页主头像和其它复用 `head()` 的头像组件进入房间后不会再出现大块黑底遮罩。
- 个人主页现在在数据加载前也会先展示默认背景和底色，不会再闪黑；“About me / Giftwall” 内容区顶部边缘已改为直角，不再额外出现一个圆角缺口。
- 个人主页当前已接入贴合页面结构的骨架屏，占位期间不会先看到背景图单独显示；资料接口返回后再无缝切到真实内容，首屏观感更平滑。
- 首页 Party 页当前已接入贴合真实版式的骨架屏：进入首页首屏时会先看到三张排行卡位与双列房卡占位，骨架配色已跟随页面深绿+鎏金主视觉，不再只显示居中的白色 `loading`；且排行榜与房间区会按各自请求结果独立切换，先返回的区域会先显示真实内容。
- 首页 My 板块当前已接入贴合真实版式的骨架屏：顶部 `My room` 现区分“首次加载中”和“确实未创建房间”，不会再先闪出创建房间卡；`Recent/Followed` 在首屏空数据加载时也会先展示双列房卡骨架，不再只显示小菊花或局部空白。
- `Me` 入口下的 `Store / Bag` 页面当前也已接入深绿主题的三列卡片骨架：首次进入并且列表尚未返回时，会先显示与正式卡片比例一致的占位；接口返回后再切到真实商品/物品卡片。`store` 与 `bag` 卡片标题现都带宽度约束和单行省略，类似截图里的长名称不会再横向撑破布局。
- 图片加载态与空态当前已拆分：共享网络图组件和礼物二级页单卡封面加载时会显示代码绘制的环形转点，不再继续复用 `sc_icon_loading.png`；若图片失败或确实无数据，仍旧保留原先那张占位图，避免把 `loading` 和 `no data` 看成同一种状态。
- 首页与搜索等房卡右下角的在线状态图标当前已改为代码绘制的动态音频条：三根绿条会按不同相位走完整的波峰波谷周期，错峰连续起伏，视觉上更接近直播/语聊房的实时状态；`My` 板块骨架数量也已与 Party 页对齐为 `6` 个。
- 首页房卡底部信息当前已进一步收紧：房名和人数文字比上一版更小，底栏与动态音频条的视觉重心更一致；`My` 页顶部 `my room` 标题也已移除，下方卡片和 tab 会自然上移填充。
- 首页顶部排行骨架当前已进一步收窄为单条标题占位，不再保留两条文本骨架；房卡底栏房名也已再次缩一号并做轻微上移，对齐更贴近设计稿观感。
- 目录体积排查显示：`build/` 约 `4.7G`、`.dart_tool/` 约 `347M`、`ios/` 约 `250M`、`sc_images/` 约 `48M`、`local_packages/` 约 `6.1M`。
- 当前包体过大的主要原因已经确认：
- universal APK 带入了 `arm64-v8a`、`armeabi-v7a`、`x86_64` 三套 ABI。
- Agora 与腾讯 IM 原生 so 很大，其中 `libagora-rtc-sdk.so` 合计约 `79.4MB`，`libImSDK.so` 合计约 `10.2MB`。
- 资源目录中 `sc_images/index`、`sc_images/room`、`sc_images/person`、`sc_images/splash` 是最主要的大图来源。
- `flutter build apk --release --target-platform android-arm64 --analyze-size` 已成功执行，当前 universal release APK 约 `271MB`。
- `flutter build apk --release --split-per-abi` 已成功执行，压缩前分架构 APK 约为：
- `app-arm64-v8a-release.apk` 约 `161.4MB`
- `app-armeabi-v7a-release.apk` 约 `138.8MB`
- `app-x86_64-release.apk` 约 `148.6MB`
- `loading_indicator_view_plus`、`social_sharing_plus`、`flutter_foreground_task`、`on_audio_query` 已从当前依赖链路中移除。
- 当前图片资源统计为 `412` 张，TinyPNG 两轮处理后总量已从 `47.25 MB` 降到 `22.27 MB`，累计节省约 `24.99 MB`。
- 当前 TinyPNG 已成功压缩 `400` 张图片，剩余失败 `12` 张。
- 当前压缩收益最大的图片包括：
- `sc_images/person/sc_icon_edit_userinfo_bg.png`：`2640776 -> 436823`，节省约 `2.10 MB`
- `sc_images/splash/sc_splash.png`：`2373335 -> 379804`，节省约 `1.90 MB`
- `sc_images/room/sc_icon_room_defaut_bg.png`：`2243222 -> 704696`，节省约 `1.47 MB`
- `sc_images/index/sc_icon_index_bg.png`：`1422169 -> 420635`，节省约 `0.96 MB`
- 失败项已分型：
- `12` 张为 TinyPNG 无法解码的特殊/动图 `webp`
- 当前 TinyPNG 进度与统计文件已落盘：`tinypng-progress.json`、`tinypng-report.json`
- 图片压缩后再次执行 `flutter build apk --release --split-per-abi`，当前分架构 APK 已下降到：
- `app-arm64-v8a-release.apk` 约 `135.2MB`，比压缩前少 `26.2MB`
- `app-armeabi-v7a-release.apk` 约 `112.6MB`，比压缩前少 `26.2MB`
- `app-x86_64-release.apk` 约 `122.4MB`，比压缩前少 `26.2MB`
- 可以确认：这轮图片压缩带来的资源收益已经真实反映到最终 APK 体积中。
- 在开启 `minify`、`shrinkResources`、`zipAlign` 并追加 `--split-debug-info=build/symbols/android` 后，Android release 继续下降为：
- `app-release.aab` 约 `181.8MB`
- `app-arm64-v8a-release.apk` 约 `128.7MB`，比上一轮 `135.2MB` 再少 `6.5MB`
- `app-armeabi-v7a-release.apk` 约 `105.8MB`，比上一轮 `112.6MB` 再少 `6.8MB`
- `app-x86_64-release.apk` 约 `115.8MB`，比上一轮 `122.4MB` 再少 `6.6MB`
- `build/symbols/android` 已生成 3 份符号文件，总计约 `14MB`，后续可用于 Dart 堆栈还原。
- `scripts/build_release.py --platform android --output-dir dist/release/smoke-android` 已验证通过，归档结果为：
- `android/google-play/` 下输出 `yumi-v1.0.0-b1-google-play.aab` 与 Dart symbols
- `android/local/` 下输出 `arm64-v8a.apk` 与 `armeabi-v7a.apk`
- `android/testing/` 下单独输出 `x86_64-test.apk`
- 同时生成 `build_manifest.json`，已记录产物路径、大小和 `sha256`
- `scripts/build_release.py --platform ios --output-dir dist/release/smoke-ios` 已验证通过，当前无签名模式下输出：
- `ios/archive/yumi-v1.0.0-b1.xcarchive`
- `ios/symbols/app.ios-arm64.symbols`
- 当前 iOS 无签名构建会跳过 `.ipa` 导出；如需正式 `.ipa`，脚本需追加 `--ios-codesign`
- 已将 `dist/` 加入 `.gitignore`，避免打包产物持续污染工作区状态
- 本轮按需执行 `flutter build appbundle --release --split-debug-info=build/symbols/android` 已成功，产物为：
- `build/app/outputs/bundle/release/app-release.aab`
- 当前 AAB 体积约 `181.8MB`
- 本地校验 `app-release.aab` 证书后确认：
- 证书所有者为 `C=US, O=Android, CN=Android Debug`
- 当前 AAB 的 `SHA1` 为 `6B:72:BF:6F:D1:7A:F2:99:CD:F3:14:EE:18:A6:29:67:F8:05:E6:B4`
- 这说明当前 release 构建仍在回退使用 debug signing，无法直接作为 Google Play 正式发布包
- 已生成新的 upload 证书文件：
- `android/app/upload-keystore.jks`
- `android/app/upload_certificate.pem`
- 新 upload key 当前指纹为：
- `SHA1: C1:80:AF:BF:6E:1F:F2:F4:49:58:72:87:A2:BC:54:07:E7:D2:D9:A3`
- `SHA256: 81:D6:3A:43:31:FA:83:87:0E:C3:5B:52:B8:C1:05:7C:3A:32:EC:24:37:0B:11:E4:2F:8C:62:4E:D4:AC:0C:3B`
- release 构建已改为从 `android/key.properties` 读取正式 upload keystore，不再依赖当前的 debug 回退配置
- `flutter build appbundle --release --split-debug-info=build/symbols/android` 已重新执行，当前正式产物仍为：
- `build/app/outputs/bundle/release/app-release.aab`
- 当前 AAB 体积约 `181.8MB`
- 重新校验该 AAB 后，签名者已变为：
- `CN=Yumi Upload, OU=Mobile, O=Yumi, L=Shanghai, ST=Shanghai, C=CN`
- `deployment_cert.der` 已核实为 Google 侧 app signing 证书，指纹为：
- `SHA1: 3F:E1:78:DC:C3:29:4F:74:20:DF:27:54:CF:AF:46:46:D6:A1:94:78`
- `SHA256: F9:BF:D0:89:F9:D7:FD:B2:53:24:A7:DB:59:E1:52:6F:54:A3:93:95:4E:88:7F:1C:4B:D6:03:66:E7:1A:1F:85`
- 已确认当前存在两套不同证书：
- 本地 `upload key`：用于你上传 AAB 到 Google Play
- Google `app signing key`：用于 Google Play 最终给用户分发签名包
- `FOREGROUND_SERVICE_MEDIA_PROJECTION` 在当前 release 合并报告中的来源已确认是 `io.agora.rtc:full-screen-sharing:4.5.2`
- 该依赖同时还带入了：
- `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenCaptureAssistantActivity`
- `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenSharingService`
- 主 Manifest 已添加 `tools:node="remove"` 覆盖规则，准备重新打包验证最终合并结果
- 重新打包后，release manifest merger 报告已显示：
- `uses-permission#android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION`
- `REJECTED from [io.agora.rtc:full-screen-sharing:4.5.2]`
- 当前 release 中已不再检测到以下声明：
- `android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION`
- `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenCaptureAssistantActivity`
- `io.agora.rtc2.extensions.MediaProjectionMgr$LocalScreenSharingService`
- 新的正式产物已重新生成：
- `build/app/outputs/bundle/release/app-release.aab`
- 当前 AAB 体积仍约 `181.8MB`
- 新 AAB 证书仍为本地 upload key：
- `SHA1: C1:80:AF:BF:6E:1F:F2:F4:49:58:72:87:A2:BC:54:07:E7:D2:D9:A3`
- 本轮按需执行 `flutter build apk --release --split-per-abi --target-platform android-arm64 --split-debug-info=build/symbols/android` 已成功，产物为：
- `build/app/outputs/flutter-apk/app-arm64-v8a-release.apk`
- 当前 `arm64-v8a` APK 体积约 `128.7MB`
- 已核对新旧 `google-services.json`：
- 原文件与新文件都匹配包名 `com.org.yumi`
- 下载文件已成功覆盖到 `android/app/google-services.json`
- 当前工程内文件 `SHA256` 为：
- `a1706496a01f74d27e6c60598144cecc978934b02a87567e1ced887b5b0185d5`

## 已知问题
- `ios/Podfile.lock` 还保留旧插件记录，因为本轮未执行 `pod install`；但 Flutter 当前依赖链路已经不再包含已移除插件。
- universal APK 仍然会非常大；当前正确发包方式应优先使用 `--split-per-abi` 或直接产出 `aab`。
- 仍有 `12` 张 `webp` 被 TinyPNG 拒绝解码，推测是动画或特殊编码格式，不能继续直接走 TinyPNG 常规压缩。
- `split-debug-info` 会把 Dart symbols 额外落到构建目录，发包时需要和正式包一起留档，不能丢。
- iOS 当前验证走的是 `--no-codesign`，因此只产出 `.xcarchive`，不会自动导出可直接分发的 `.ipa`。
- Flutter/Xcode 当前给出两条 iOS 提醒：
- 未来 iOS 版本将要求 `UIScene` 生命周期支持
- Launch image 仍是默认占位资源，提交前建议替换
- `android/key.properties` 保存了本地 upload keystore 口令，必须自行妥善备份，且不要提交到仓库
- 由于已显式移除 Agora 本地屏幕共享相关组件，如果业务后续要启用“屏幕共享/录屏推流”，需要再单独恢复相关 manifest 声明

## 下一步要做什么
- 将新的 `AAB` 上传到 Play Console，并在首发流程中继续使用 Google 管理的 app signing key。
- 在需要配置 Google 登录、Firebase、支付等生产环境指纹时，优先登记 Google 的 `deployment_cert.der` 指纹；如平台要求上传者证书，再额外登记本地 upload key 指纹。
- 如果需要正式 iOS 分发包，为 `scripts/build_release.py` 补入 `--ios-codesign` 所需签名参数并导出 `.ipa`。
- 继续评估 Agora 扩展库是否都需要，优先核查 `lip sync`、`spatial audio`、`clear vision`、`segmentation`、`face capture` 等扩展 so 能否裁剪。
- 决定是否处理剩余 12 张特殊 `webp`：改格式、换压缩工具，或维持现状。
