diff --git a/patch_v2/ncm_app/app/app.c b/patch_v2/ncm_app/app/app.c index a18ad17..2a7c2da 100644 --- a/patch_v2/ncm_app/app/app.c +++ b/patch_v2/ncm_app/app/app.c @@ -86,6 +86,8 @@ static void app_on_key(int keycode, int is_down) static void app_on_tap(int x, int y) { + /* mini 播放栏:非播放页底部常驻,顶层先拦(点钮 toggle / 点栏体进播放页),不落页面 on_tap。 */ + if (mini_bar_hit(x, y)) return; if (login_is_active()) { login_on_tap(x, y); return; } if (player_is_active()) { player_on_tap(x, y); return; } if (settings_is_active()) { settings_on_tap(x, y); return; } @@ -158,6 +160,7 @@ static void app_on_tick(void) if (act != g_reported_act) { g_reported_act = act; ipc_act_report(act); } } uint64_t now = meow_ui_time_ms(); + mini_bar_tick(now); /* mini 播放栏:可见性/歌曲/暂停态/进度变化 → 失效栏带并重绘 */ /* §NEW cookie 续期判会话失效 → 清登录态回登录页(worker 在后台续期发现 301/-460 时置标志; * 在此 UI 线程执行 logout+切页——meow_view_page_replace 非线程安全,只能 UI 线程做) */ if (account_cookie_need_relogin()) { @@ -223,6 +226,7 @@ int main(void) g_plr_view = player_view_create(); g_set_view = settings_view_create(); g_search_view = search_view_create(); + mini_bar_init(); /* mini 播放栏:登记跨 Activity 绘制物(进 root 页前,首帧即参与重画) */ /* 进入根页:已登录→home,否则→login */ meow_view_page_push(g_st.logged_in ? ACT_HOME : ACT_LOGIN); @@ -237,6 +241,7 @@ int main(void) g_app_quit = 1; player_manager_stop_thread(); ipc_media_stop(); + mini_bar_shutdown(); meow_view_free(g_set_view); meow_view_free(g_plr_view); meow_view_free(g_pl_view); diff --git a/patch_v2/ncm_app/app/ncm_app_internal.h b/patch_v2/ncm_app/app/ncm_app_internal.h index 144f131..eeb5fe9 100644 --- a/patch_v2/ncm_app/app/ncm_app_internal.h +++ b/patch_v2/ncm_app/app/ncm_app_internal.h @@ -349,6 +349,12 @@ void settings_touch_move(int x, int y); void settings_open(void); /* 进设置页 */ void settings_reload(void); +/* mini 播放栏(ui/minibar.c,跨 Activity 常驻;非播放页 + 有活动播放会话时显示)*/ +void mini_bar_init(void); /* 登记 CUSTOM 绘制物(main 建页后调) */ +void mini_bar_shutdown(void); /* 注销(app 退出前) */ +void mini_bar_tick(uint64_t now);/* 每帧:可见性/歌曲/暂停态/进度变化 → 失效栏带并重绘 */ +int mini_bar_hit(int x, int y); /* app_on_tap 顶层先行拦截:1=消费(toggle/进播放页) */ + /* search */ meow_view *search_view_create(void); int search_is_active(void); diff --git a/patch_v2/ncm_app/app/test/test_ncm_app.c b/patch_v2/ncm_app/app/test/test_ncm_app.c index 7480070..9394139 100644 --- a/patch_v2/ncm_app/app/test/test_ncm_app.c +++ b/patch_v2/ncm_app/app/test/test_ncm_app.c @@ -95,6 +95,9 @@ static int page_id(const char *name) if (strcmp(name, "grid") == 0) return ACT_PLAYER; /* 保留:旧横屏(重做后恒竖屏) */ if (strcmp(name, "playerbuf") == 0) return ACT_PLAYER; /* §18 缓冲态 */ if (strcmp(name, "playererr") == 0) return ACT_PLAYER; /* §18 错误态 */ + if (strcmp(name, "plsplay") == 0) return ACT_PLAYLIST; /* mini 栏目检(非播放页+播放态) */ + if (strcmp(name, "homeplay") == 0) return ACT_HOME; /* mini 栏目检(首页+播放态) */ + if (strcmp(name, "barhit") == 0) return ACT_PLAYLIST; /* mini 栏命中自检 */ if (strcmp(name, "settings") == 0) return ACT_SETTINGS; if (strcmp(name, "search") == 0) return ACT_SEARCH; if (strcmp(name, "searchhist") == 0) return ACT_SEARCH; /* §23 空态=历史列表 */ @@ -123,6 +126,7 @@ int main(int argc, char **argv) g_dark = dark; meow_theme_add_listener(ncm_on_theme); ncm_on_theme(dark ? MEOW_THEME_DARK : MEOW_THEME_LIGHT); /* 同步初始 g_dark */ + mini_bar_init(); /* mini 播放栏:登记跨 Activity 绘制物(真实页面 + 真实 SDK 绘制物注册表) */ /* mock 状态 */ if (g_st.cache_dir[0] == 0) { @@ -229,6 +233,18 @@ int main(int argc, char **argv) appstate_search_history_add("Jay \u5553\u8868"); appstate_search_history_add("lofi beat"); appstate_search_history_add("Jay \u5553\u8868"); /* 去重 → 仍 3 条 */ + } else if (strcmp(name, "plsplay") == 0 || strcmp(name, "homeplay") == 0 || + strcmp(name, "barhit") == 0) { + /* mini 播放栏目检/命中自检:非播放页(歌单/首页)+ 播放态 → 底部显示 mini 栏 */ + mock_playlists(); mock_songs(); + pthread_mutex_lock(&g_play.mu); + g_play.state = NCM_PC_PLAYING; + g_play.cur_song = 0; + g_play.pos_ms = 94000; + g_play.dur_ms = 180000; + g_play.play_song = g_st.songs[0]; /* 播放快照(§17) */ + g_play.play_song_valid = 1; + pthread_mutex_unlock(&g_play.mu); } else { mock_playlists(); } @@ -236,7 +252,8 @@ int main(int argc, char **argv) meow_view *v = NULL; if (strcmp(name, "login") == 0 || strcmp(name, "loginlive") == 0) v = login_view_create(); else if (strcmp(name, "home") == 0) v = home_view_create(); - else if (strcmp(name, "playlist") == 0) v = playlist_view_create(); + else if (strcmp(name, "playlist") == 0 || strcmp(name, "plsplay") == 0 || + strcmp(name, "barhit") == 0) v = playlist_view_create(); else if (page_id(name) == ACT_PLAYER) v = player_view_create(); /* player/lands/playerbuf/playererr */ else if (strcmp(name, "settings") == 0) v = settings_view_create(); else if (strcmp(name, "search") == 0 || strcmp(name, "searchhist") == 0 || @@ -277,6 +294,8 @@ int main(int argc, char **argv) p0, p1, p2, latched_change, ok ? "PASS" : "FAIL"); if (!ok) return 1; } + /* 任意页先喂一次 mini 栏 tick:可见性/歌曲/进度变化 → 失效栏带,随后整帧重画包含 mini 栏 */ + mini_bar_tick(meow_ui_time_ms()); /* player 页:其 on_tick 通常驱动进度;这里直接再画一次确保状态就绪 */ meow_ui_paint_full(); if (page_id(name) == ACT_PLAYER) { @@ -316,6 +335,28 @@ int main(int argc, char **argv) (ok1 && ok2) ? "PASS" : "FAIL"); if (!(ok1 && ok2)) return 1; } + if (strcmp(name, "barhit") == 0) { + /* mini 播放栏命中自检(几何与 minibar.c 同口径:W=480 H=720 → 栏带 (0,656,480,64), + * 播放钮中心 (446,688),命中半径 22;栏体外 (100,600) 不消费): + * ① 播放态下点播放钮 → 暂停;再点 → 恢复(toggle); + * ② 点栏体 → 消费并 push(ACT_PLAYER)(进播放页);进播放页后 active=ACT_PLAYER → 栏隐藏(不消费); + * ③ 点播放钮回到非播放页后,栏体外点按不消费(0,落页面 on_tap)。 */ + int w = APP_W, h = APP_H, bh = 64, by = h - bh; + int bx = w - 12 - 32 / 2 - 12 / 2, bcy = by + 32; /* 与 minibar.c MINI_* 一致 */ + pthread_mutex_lock(&g_play.mu); int s0 = g_play.state; pthread_mutex_unlock(&g_play.mu); + int h1 = mini_bar_hit(bx, bcy); /* 播放钮:toggle */ + pthread_mutex_lock(&g_play.mu); int s1 = g_play.state; pthread_mutex_unlock(&g_play.mu); + int h2 = mini_bar_hit(bx, bcy); /* 再点:toggle 回 */ + pthread_mutex_lock(&g_play.mu); int s2 = g_play.state; pthread_mutex_unlock(&g_play.mu); + int ok_tg = (h1 == 1 && s1 == NCM_PC_PAUSED) && (h2 == 1 && s2 == NCM_PC_PLAYING); + int h3 = mini_bar_hit(100, bcy); /* 栏体 → 进播放页 */ + int act_after = meow_ui_activity_active(); /* 应为 ACT_PLAYER */ + int h4 = mini_bar_hit(100, bcy); /* 已在播放页 → 栏隐藏 → 不消费 */ + printf("barhit: toggle %d->%d->%d=%s consume-body=%d act=%d(PLAYER) hidden=%d -> %s\n", + s0, s1, s2, ok_tg ? "PASS" : "FAIL", h3, act_after, h4, + (ok_tg && h3 == 1 && act_after == ACT_PLAYER && h4 == 0) ? "PASS" : "FAIL"); + if (!ok_tg) return 1; + } meow_ui_shutdown(); printf("dumped %s -> %s\n", name, dump); diff --git a/patch_v2/ncm_app/app/ui/minibar.c b/patch_v2/ncm_app/app/ui/minibar.c new file mode 100644 index 0000000..c0f82d8 --- /dev/null +++ b/patch_v2/ncm_app/app/ui/minibar.c @@ -0,0 +1,224 @@ +/* ui/minibar.c — 底部 mini 播放栏(跨 Activity 常驻;非播放页 + 有活动播放会话时显示)。 + * + * 需求(用户定案 2026-09-03):ncm 首页/歌单/搜索/设置等**非播放页**底部,当存在活动播放会话 + * (player_manager 有当前曲目,state != NCM_PC_STOPPED)时显示一条紧凑 mini 播放栏(与主流 + * 音乐 App 一致):封面缩略(40×40,复用 cover 缩略链)+ 歌名/歌手(截断)+ 播放/暂停钮 + * (点击 toggle)+ 细进度带;**点击栏体 → 跳转 ncm 播放页(ACT_PLAYER)**;播放页内不显示此栏。 + * 替代原先「顶栏进播放页图标」方案(本栏常驻非播放页,进播放页更直接,与主流 App 交互一致)。 + * + * 实现(零侵入页面 UI,跨页面常驻,最小侵): + * - 绘制 = SDK 绘制物注册表 CUSTOM 项(z=MINI_Z,bbox=底部 MINI_H 带)。CUSTOM 项不按 owner + * Activity 过滤(见 meow_ui_draw.c paint():仅 WIDGET 按 owner 过滤、VIEW 按 entered 过滤, + * CUSTOM 恒画)→ 跨 Activity 常驻;且只在它所在区域被失效/整帧重画时被调(区域收敛,不整屏)。 + * - 命中 = app.c app_on_tap **顶层先调 mini_bar_hit()**(返回 1 即消费,不再落页面 on_tap)—— + * 点播放/暂停钮 toggle、点栏体 push(ACT_PLAYER)。不走 meow_ui_global:宿主 test_host_stub + * 只桩了 global_render/hit 而未桩 add/remove,为双端 0 warning 可链,改走 app_on_tap 拦截。 + * - 刷新 = mini_bar_tick()(app_on_tick 每帧调):可见性/歌曲/暂停态/进度 1% 桶变化 → + * 失效整条栏带并重绘;切歌 → 复用 cover_request 拉新封面(非播放页也随切歌更新)。 + * - 绘制安全:封面 cover_get() 持锁返回,绘完 cover_put()(与播放/歌单页同口径,§18 修 UAF)。 + * + * 性能:栏带仅 ~480×64;只在该带失效时重画(区域收敛),不整屏;进度按 1% 桶驱动 + * (约 1 次/2s,不逐帧刷)。播放/进度/元数据读取全部走 player_manager 与 cover(锁内快照), + * 不新开线程、不碰页面布局。 + */ +#include "../ncm_app_internal.h" +#include +#include +#include "ncm_icons.h" + +/* ---- 几何 ---- */ +#define MINI_H 64 /* 栏带高(含底部进度带/下缘) */ +#define MINI_PAD 12 /* 左内边距 */ +#define MINI_COV 40 /* 封面缩略边长 */ +#define MINI_GAP 12 /* 封面↔文本↔按钮 间距 */ +#define MINI_BTN 32 /* 播放/暂停图标绘制边长 */ +#define MINI_HITR 22 /* 播放/暂停钮命中半径(略大于图标,好点) */ +#define MINI_Z 400 /* 栏带 z:高于页面内容(≤60)/页脚(1),不与 topbar(999,顶部) 相交 */ +#define MINI_TITLE 18 /* 歌名字号 */ +#define MINI_ART 14 /* 歌手字号 */ + +/* ---- 状态(UI 线程串行,无需锁)---- */ +static int g_mini_id; /* CUSTOM 绘制物 id(0=未注册) */ +static ncm_rect_t g_bar_r; /* 栏带矩形(绘制 bbox + 命中区) */ +static int g_last_vis, g_last_state, g_last_song; +static long g_last_bucket; /* 进度桶(0..100,1% 粒度) */ +static char g_last_id[24]; /* 上次绘制的歌曲 id(切歌判据) */ + +/* 是否显示 mini 栏:有活动播放会话(state≠STOPPED)且当前非播放页。 */ +static int mini_visible(void) +{ + if (player_manager_state() == NCM_PC_STOPPED) return 0; + if (meow_ui_activity_active() == ACT_PLAYER) return 0; + return 1; +} + +/* 当前播放曲元数据:优先播放快照(窗口无关);快照未就绪退窗口拷贝——与 player.c cur_song_meta 同口径。 */ +static int mini_cur_song_meta(ncm_song_t *out) +{ + if (player_manager_current_song(out) == 0) return 0; + int sc = player_manager_playing_song(); + if (sc >= 0 && appstate_song_copy(sc, out) == 0) return 0; + return -1; +} + +/* 圆角图四角裁掉(盖回栏底色):局部复制 player.c round_corners_bg(mini 栏独立绘制, + * 不复用跨文件 static)。 */ +static void mini_round_corners(int x, int y, int w, int h, int r, uint32_t bg) +{ + if (r > w / 2) r = w / 2; + if (r > h / 2) r = h / 2; + for (int dy = 0; dy < r; dy++) { + int inset = r - (int)sqrt((double)(r * r - (r - dy) * (r - dy))); + if (inset < 0) inset = 0; + if (inset > w / 2) inset = w / 2; + meow_ui_fill_rect(x, y + dy, inset, 1, bg); + meow_ui_fill_rect(x + w - inset, y + dy, inset, 1, bg); + meow_ui_fill_rect(x, y + h - 1 - dy, inset, 1, bg); + meow_ui_fill_rect(x + w - inset, y + h - 1 - dy, inset, 1, bg); + } +} + +/* MD3 图标 blit(播放/暂停):ncm_icons.h 32×32 单通道 alpha 最近邻放大到 size×size,居中 (cx,cy)。 */ +static void mini_draw_icon(int idx, int cx, int cy, int size, uint32_t color) +{ + const unsigned char *src = ncm_icons[idx].data; + if (size <= 0) return; + int x0 = cx - size / 2, y0 = cy - size / 2; + for (int y = 0; y < size; y++) { + int sy = (y * NCM_ICON_SIZE) / size; + if (sy >= NCM_ICON_SIZE) sy = NCM_ICON_SIZE - 1; + for (int x = 0; x < size; x++) { + int sx = (x * NCM_ICON_SIZE) / size; + if (sx >= NCM_ICON_SIZE) sx = NCM_ICON_SIZE - 1; + int a = src[sy * NCM_ICON_SIZE + sx]; + if (a > 4) meow_ui_fill_rect_alpha(x0 + x, y0 + y, 1, 1, color, a); + } + } +} + +/* 绘制整条 mini 栏。draw_cb 由绘制物注册表在「区域/整帧重画」时调用;仅 mini_visible() 才画。 */ +static void mini_draw(void *ctx) +{ + (void)ctx; + if (!mini_visible()) return; + const meow_theme *th = meow_theme_get(); + const ncm_pal_t *pa = ncm_palette(g_dark); + ncm_rect_t r = g_bar_r; + int W = r.w, H = r.h; + + /* 底(surfaceContainer,与列表卡片同色)+ 顶部 1px 分隔线 */ + meow_ui_fill_rect(r.x, r.y, W, H, th->surfaceContainer); + meow_ui_fill_rect(r.x, r.y, W, 1, th->outlineVariant); + + /* 当前曲元数据(快照优先) */ + ncm_song_t sm; + int have = (mini_cur_song_meta(&sm) == 0); + const char *nm = (have && sm.name[0]) ? sm.name : "暂无播放"; + const char *ar = (have && sm.art_name[0]) ? sm.art_name : ""; + + /* 封面缩略(复用 cover 链;cover_get 持锁返回,cover_put 配对) */ + int cx = r.x + MINI_PAD, cy = r.y + (H - MINI_COV) / 2; + ncm_fill_round(cx, cy, MINI_COV, MINI_COV, 8, pa->red_ctr); + meow_img *cov = cover_get(); + if (cov) { + meow_ui_img_cover(cx, cy, MINI_COV, cov); + mini_round_corners(cx, cy, MINI_COV, MINI_COV, 8, th->surfaceContainer); + } else { + meow_ui_text_center(cx + MINI_COV / 2, cy + (MINI_COV - meow_ui_text_height(th->font_body)) / 2, + "\u266a", th->font_body, pa->red); + } + cover_put(); + + /* 歌名/歌手(截断到播放钮左) */ + int tx = cx + MINI_COV + MINI_GAP; + int maxw = r.x + W - MINI_PAD - tx - (MINI_BTN + MINI_GAP * 2); + if (maxw < 40) maxw = 40; + int ty = r.y + (H - (MINI_TITLE + MINI_ART + 4)) / 2; + meow_ui_text(tx, ty, ncm_text_fit(nm, maxw, MINI_TITLE), MINI_TITLE, th->onSurface); + meow_ui_text(tx, ty + MINI_TITLE + 2, ncm_text_fit(ar, maxw, MINI_ART), MINI_ART, th->onSurfaceVariant); + + /* 播放/暂停钮(右侧红 icon;PAUSED/STOPPED → 播放,否则暂停) */ + int st = player_manager_state(); + int bx = r.x + W - MINI_PAD - MINI_BTN / 2 - MINI_GAP / 2; + int bcy = r.y + H / 2; + mini_draw_icon((st == NCM_PC_PAUSED || st == NCM_PC_STOPPED) ? NCM_I_PLAY : NCM_I_PAUSE, + bx, bcy, MINI_BTN, pa->red); + + /* 细进度带(底缘 3px:track surfaceVariant + fill 品牌红) */ + int64_t pos = player_manager_pos_ms(); + int64_t dur = player_manager_dur_ms(); + if (dur <= 0 && have) dur = sm.duration_ms; + int frac = dur > 0 ? (int)(pos * 1000 / dur) : 0; + if (frac < 0) frac = 0; if (frac > 1000) frac = 1000; + meow_ui_fill_rect(r.x, r.y + H - 3, W, 3, th->surfaceVariant); + meow_ui_fill_rect(r.x, r.y + H - 3, (int)((int64_t)W * frac / 1000), 3, pa->red); +} + +/* 命中:app.c app_on_tap 顶层先调。非显示态/栏带外 → 0(不消费)。点播放/暂停钮 → toggle; + * 点栏体 → push(ACT_PLAYER)(进播放页)。返回 1=消费(拦截,不再落页面 on_tap)。 */ +int mini_bar_hit(int x, int y) +{ + if (!mini_visible()) return 0; + if (y < g_bar_r.y || y >= g_bar_r.y + g_bar_r.h || + x < g_bar_r.x || x >= g_bar_r.x + g_bar_r.w) return 0; + int bx = g_bar_r.x + g_bar_r.w - MINI_PAD - MINI_BTN / 2 - MINI_GAP / 2; + int bcy = g_bar_r.y + g_bar_r.h / 2; + int dx = x - bx, dy = y - bcy; + if (dx * dx + dy * dy <= MINI_HITR * MINI_HITR) { + int st = player_manager_state(); + if (st == NCM_PC_PAUSED) player_manager_pause(0); /* 恢复 */ + else if (st != NCM_PC_STOPPED) player_manager_pause(1); /* 暂停(含 BUFFER 保守停) */ + return 1; + } + meow_view_page_push(ACT_PLAYER); + return 1; +} + +/* 每帧(app_on_tick):可见性/歌曲/暂停态/进度 1% 桶 变化 → 失效整条栏带并重绘; + * 切歌 → 复用 cover_request 拉新封面(非播放页也随切歌更新;cover_request 幂等去重,宿主 mock 内跳过网络)。 */ +void mini_bar_tick(uint64_t now) +{ + (void)now; + int vis = mini_visible(); + int st = player_manager_state(); + int sc = player_manager_playing_song(); + ncm_song_t sm; + int have = (mini_cur_song_meta(&sm) == 0); + const char *id = have ? sm.id : ""; + int64_t pos = player_manager_pos_ms(), dur = player_manager_dur_ms(); + long bucket = dur > 0 ? (long)(pos * 100 / dur) : 0; + if (bucket < 0) bucket = 0; if (bucket > 100) bucket = 100; + int id_changed = (id[0] && strcmp(id, g_last_id) != 0); + + if (vis == g_last_vis && st == g_last_state && sc == g_last_song && + bucket == g_last_bucket && !id_changed) return; + + g_last_vis = vis; g_last_state = st; g_last_song = sc; + g_last_bucket = bucket; + ncm_strlcpy(g_last_id, id, sizeof g_last_id); + + /* 切歌 → 请求当前曲封面(专辑图优先,无则歌单封面兜底) */ + if (vis && id_changed) { + if (have && sm.al_pic[0]) cover_request(sm.al_pic, sm.id); + else if (have && g_st.cover_url[0]) cover_request(g_st.cover_url, sm.id); + } + if (g_mini_id) meow_ui_invalidate(g_bar_r.x, g_bar_r.y, g_bar_r.w, g_bar_r.h); +} + +/* 登记(main 建页后调一次,host/device 通用):注册 CUSTOM 绘制物(跨 Activity 常驻)。 */ +void mini_bar_init(void) +{ + if (g_mini_id) return; + int W = meow_ui_width(), H = meow_ui_height(); + g_bar_r = NR(0, H - MINI_H, W, MINI_H); + g_last_vis = -1; g_last_state = -1; g_last_song = -1; g_last_bucket = -1; + g_last_id[0] = 0; + g_mini_id = meow_draw_custom_register(MINI_Z, g_bar_r.x, g_bar_r.y, g_bar_r.w, g_bar_r.h, + mini_draw, NULL); +} + +/* 注销(app 退出前)。 */ +void mini_bar_shutdown(void) +{ + if (g_mini_id) { meow_draw_unregister(g_mini_id); g_mini_id = 0; } +} diff --git a/patch_v2/ncm_app/build_ncm.sh b/patch_v2/ncm_app/build_ncm.sh index df050d1..4623d57 100755 --- a/patch_v2/ncm_app/build_ncm.sh +++ b/patch_v2/ncm_app/build_ncm.sh @@ -18,7 +18,7 @@ CORE="core/ncm_common.c core/ncm_json.c core/ncm_store.c core/ncm_http.c \ core/ncm_crypto.c core/ncm_req.c core/ncm_login.c core/ncm_api.c \ core/ncm_cache.c core/ncm_ctx.c core/ncm_apicache.c" APP="app/app.c app/ui/login.c app/ui/home.c app/ui/playlist.c app/ui/player.c \ - app/ui/settings.c app/ui/search.c app/ui/ncm_colors.c app/ui/chrome.c \ + app/ui/settings.c app/ui/search.c app/ui/minibar.c app/ui/ncm_colors.c app/ui/chrome.c \ app/logic/appstate.c app/logic/lyric.c app/logic/songmeta.c \ app/logic/cover.c app/logic/account.c app/play/player_manager.c app/play/audio_out.c \ app/play/ipc_media.c app/play/decoder.c app/play/stream_src.c app/play/minimp3_impl.c \ diff --git a/patch_v2/ncm_app/build_ncm_host.sh b/patch_v2/ncm_app/build_ncm_host.sh index d1c9c50..f85c0b1 100755 --- a/patch_v2/ncm_app/build_ncm_host.sh +++ b/patch_v2/ncm_app/build_ncm_host.sh @@ -30,7 +30,7 @@ $CC_HOST -O2 -c -I"$SDK_DIR" -I"$ROOT/patch_v2/meow_launcherd" "$SDK_DIR/test_ho echo "==> host app sources (exclude app.c: has main + g_st; test provides them)" APP_SRC="app/ui/login.c app/ui/home.c app/ui/playlist.c app/ui/player.c \ - app/ui/settings.c app/ui/search.c app/ui/ncm_colors.c app/ui/chrome.c \ + app/ui/settings.c app/ui/search.c app/ui/minibar.c app/ui/ncm_colors.c app/ui/chrome.c \ app/logic/appstate.c app/logic/lyric.c app/logic/songmeta.c \ app/logic/cover.c app/logic/account.c app/play/player_manager.c app/play/audio_out.c \ app/play/ipc_media.c app/play/decoder.c app/play/stream_src.c app/play/minimp3_impl.c"