fix(ncm): 歌单详情LoadFailed——track/all端点不存在(404)回退detail+分批song_detail已验证链路; 列表误触改按下锁定行+拖动抑制 (agent-227, 真机验证256首出曲) + perf(meowpanel): 屏幕帧整数定点DCT(无FPU软浮点3.96s→0.19s/帧,实测4-5fps)+前端链式轮询防堆积+实测fps显示 (agent-228)

ncm→73422166 已部署; meowpanel→f310a00e 已部署
This commit is contained in:
MeowOS committed 2026-08-31 17:40:04 +08:00
1 parent d394c73a7c
commit c041facd89
13 files changed
+447 -65

No files matched your search

+26 -17
View File
@@ -126,25 +126,34 @@ int appstate_load_playlist_songs_page(int idx, int offset, int limit)
if (limit <= 0 || limit > NCM_SONG_BATCH) limit = NCM_SONG_BATCH;
if (offset < 0) offset = 0;
/* 二期:改走 /api/playlist/track/all 服务端分页(REPORT §11)。
* 相对旧 /v6/playlist/detail 的「全量 trackIds(5191 首 ≈900KB)」本端点直接按页返回歌曲
* 对象(含 al.picUrl),无需 detail 瓶颈 + 二次 song_detail。 */
ncm_song_t tmp[NCM_SONG_BATCH];
int n = 0; int64_t total = 0;
int rc = ncm_api_playlist_track_all(g_st.ctx.device_id, g_st.ctx.cookie, pl->id,
offset, limit, tmp, NCM_SONG_BATCH, &n, &total);
if (rc != NCM_OK) { if (offset == 0) g_st.song_count = 0; return rc; }
/* 二期曾改走 /api/playlist/track/all 服务端分页(REPORT §12.3),但真机实测该端点
* (eapi/weapi、v6/无v6 四种路由)全部返回 code 404「接口未找到」——NCM 服务端无此路由,
* 故回退到 REPORT §10.11 已验证的 /api/v6/playlist/detail(trackIds) + /api/v3/song/detail 分批。
* detail 一次取回前 NCM_SONG_MAX 首 trackIds;song_detail 分批取歌曲对象(含 al.picUrl)。
* offset==0 重头清空并整批载入;offset>0(触底“加页”)时 detail 已一次取满,无独立分页,
* 直接返回 NCM_OK(歌单数 ≤NCM_SONG_MAX 时已全部在列,song_count 不变)。 */
if (offset != 0) return NCM_OK;
if (offset == 0) g_st.song_count = 0; /* 重头:清空旧歌单(含此前打开的另一歌单) */
memset(g_st.song_ids, 0, sizeof g_st.song_ids);
int idn = 0;
int rc = ncm_api_playlist_detail(g_st.ctx.device_id, g_st.ctx.cookie, pl->id,
NULL, 0, NULL, 0,
g_st.song_ids, NCM_SONG_MAX, &idn);
if (rc != NCM_OK) { g_st.song_count = 0; return rc; }
/* 追加到 g_st.songs[offset..],封顶 NCM_SONG_MAX(内存纪律) */
int cap = NCM_SONG_MAX - offset;
if (cap <= 0) return NCM_OK;
if (n > cap) n = cap;
memcpy(&g_st.songs[offset], tmp, sizeof(ncm_song_t) * (size_t)n);
int end = offset + n;
if (end > NCM_SONG_MAX) end = NCM_SONG_MAX;
g_st.song_count = end;
memset(g_st.songs, 0, sizeof g_st.songs);
int outn = 0;
for (int off = 0; off < idn; off += NCM_SONG_BATCH) {
int batch = idn - off;
if (batch > NCM_SONG_BATCH) batch = NCM_SONG_BATCH;
int bn = 0;
rc = ncm_api_song_detail(g_st.ctx.device_id, g_st.ctx.cookie, &g_st.song_ids[off],
batch, &g_st.songs[off], NCM_SONG_MAX - off, &bn);
if (rc != NCM_OK) break;
outn += bn;
if (bn < batch) break;
}
g_st.song_count = outn;
appstate_apply_playlist_cover(idx);
return NCM_OK;
}
+5 -2
View File
@@ -259,9 +259,12 @@ int home_on_tap(int x, int y)
}
if (g_load_err != 0 || g_st.playlist_count == 0) return 0;
if (meow_widget_hit(g_list, x, y)) {
int row = meow_listview_hit(g_list, x, y);
if (row < 0) { home_drag_reset(); return 1; }
/* 误触修复(同 playlist.c):小拖动滚动列表后 release 被 SDK 判成 TAP,旧命中用“释放点 +
* 新 scroll”,打到非按下行;改用按下行 g_press_row,移动超阈值(>10)视为滚动不触发。 */
int was_drag = (g_press_delta > 10);
int row = (g_press_row >= 0) ? g_press_row : meow_listview_hit(g_list, x, y);
home_drag_reset();
if (row < 0 || was_drag) return 1;
playlist_open(tab_global_idx(g_tab, row));
return 1;
}
+7 -2
View File
@@ -291,9 +291,14 @@ int playlist_on_tap(int x, int y)
}
if (g_load_err != 0 || g_st.song_count == 0) return 0;
if (meow_widget_hit(g_list, x, y)) {
int row = meow_listview_hit(g_list, x, y);
if (row < 0) { pl_drag_reset(); return 1; }
/* 误触修复:小拖动(<SWIPE_THRESH)会先滚动列表、release 又被 SDK 判成 TAP,旧的
* meow_listview_hit(x,y) 用“释放点 + 更新后的 scroll”命中 → 打到“已移动到手指下”的行,
* 与按下点不一致(“点到非触摸坐标的行”)。按下行 g_press_row 才是用户真正按的行;
* 移动量超过阈值(g_press_delta>10,与按压红条清行同阈值)视为滚动收尾,不触发点行。 */
int was_drag = (g_press_delta > 10);
int row = (g_press_row >= 0) ? g_press_row : meow_listview_hit(g_list, x, y);
pl_drag_reset();
if (row < 0 || was_drag) return 1;
player_play_song(row);
return 1;
}