feat(ncm): 断网保持登录态 + 离线模式(可见提示/缓存可播/联网自动回在线)(M9)

用户报告:「一断网就退出到扫码登录界面,不会保持账号态切离线,缓存列表形同虚设」。
上一条已把失败分成 NETWORK/AUTH;本条把结论落到 App 状态与 UI。

- 会话状态机(appstate.c):只有 NCM_ERR_AUTH(401/403/301/302)清 cookie;网络类失败
  (不可达/超时/TLS/5xx/-460)只置 g_st.offline,账号态与 session.enc 一律保留;
  appstate_ensure_uid 同语义(原先任何 AUTH 都清 cookie,网络故障不得进入该分支)。
- 启动(app.c):根页改由 ncm_session_boot_decide 决定——有本地会话就进 home(无网也是),
  只有无本地会话才进扫码;打印 boot 决策日志。
- 离线 UX:首页个人卡「离线模式」红标 + 页脚提示 + 空态「离线模式/可播放已缓存」;
  歌单页/搜索页/播放页/缓存页分别给出离线文案(缓存页点播照旧走 NCM_QUEUE_CACHE,本地可播)。
- 恢复:home 可见时每 30s 静默重试一次(强制绕过接口缓存,成功即回在线并重绘);
  任何真实网络成功(home/playlist worker)也会清离线态。
- 防误判:接口缓存命中(120s 旧响应)不算「回在线」——home_worker 用
  ncm_apicache_hits() 差分识别,避免离线提示被缓存命中闪掉。
This commit is contained in:
AskaEth committed 2026-11-05 11:45:20 +08:00
1 parent 8557da6fca
commit 707bbd8a02
8 files changed
+111 -10

No files matched your search

+9 -2
View File
@@ -242,8 +242,15 @@ int main(void)
g_cache_view = cache_view_create(); /* M5 已缓存列表页 */
mini_bar_init(); /* mini 播放栏:登记跨 Activity 绘制物(进 root 页前,首帧即参与重画) */
/* 进入根页:已登录→home,否则→login */
meow_view_page_push(g_st.logged_in ? ACT_HOME : ACT_LOGIN);
/* 进入根页(M9 启动决策):本地有会话就先信它——无网也进 home(缓存可看可播),
* 只有「无本地会话」才进扫码页。网络类失败在首个请求后由 appstate_session_gate
* 切离线模式,不再把「连不上」当登录过期。 */
{
ncm_gate_t boot = ncm_session_boot_decide(g_st.logged_in, NCM_OK);
meow_log(MEOW_LOG_INFO, "boot: session gate=%s (cookie=%d uid=%s)",
ncm_gate_name(boot), g_st.logged_in, g_st.uid[0] ? g_st.uid : "-");
meow_view_page_push(boot == NCM_GATE_RELOGIN ? ACT_LOGIN : ACT_HOME);
}
meow_ui_events ev = {
app_on_key, app_on_tap, app_on_swipe, app_on_tick, app_on_swipe_progress,