fix(reader): M27 r3 评审整改 — cap 边界截断/默认副题不变/提示两行且 6s 消失/版本号
对应评审 P2-1、P3-7、P3-1、P3-2、P3-10、P3-9: - P2-1:scan_dir 在目录边界遇 cap 时探测子树(count_books_under)再置 truncated; 同目录内超限逻辑不变。新增两条断言:cap 卡边界 → truncated=1;恰好装满且后续为空目录 → 不误报 - P3-7:shelf_book 拆 sub(默认副题,与 base 逐字一致)/sub_folder(folder 模式前置子路径); list 按模式选,宫格始终用 base;断言 format 副题逐字等于 base - P3-1:超量+超深合并提示拆两行绘制(610 起,不再被 480px 右缘切掉) - P3-2:提示 6s 到期自动消失(app.c 书架前台时调 shelf_on_tick) - P3-10:app.json version 0.1.1 / version_code 2 - P3-9:shelf_scan_bench.c 头部注明 /proc/uptime 10ms 分辨率、只适合真机
This commit is contained in:
1 parent
63ead3ec1e
commit
e0a82a3d47
8 files changed
+129
-44
No files matched your search
@@ -71,13 +71,14 @@ typedef struct scan_ctx {
|
||||
shelf_ts_fn ts_fn;
|
||||
} scan_ctx;
|
||||
|
||||
/* 已超过深度上限的目录:只数其中还能识别的书籍文件,不出书(不静默跳过)。
|
||||
* 自身再留 8 层硬上限,防符号链接/异常深目录把计数也拖死。 */
|
||||
static void count_books_under(scan_ctx *c, const char *dir, int depth)
|
||||
/* 统计 dir 子树里还能识别的书籍文件数(只数不收集)。自身留 8 层硬上限,
|
||||
* 防符号链接/异常深目录把计数也拖死。返回书籍文件数。 */
|
||||
static int count_books_under(const char *dir, int depth)
|
||||
{
|
||||
if (depth > SHELF_SCAN_MAX_DEPTH + 8) return;
|
||||
if (depth > SHELF_SCAN_MAX_DEPTH + 8) return 0;
|
||||
int n = 0;
|
||||
DIR *dp = opendir(dir);
|
||||
if (!dp) return;
|
||||
if (!dp) return 0;
|
||||
struct dirent *de;
|
||||
while ((de = readdir(dp))) {
|
||||
if (de->d_name[0] == '.') continue;
|
||||
@@ -85,10 +86,11 @@ static void count_books_under(scan_ctx *c, const char *dir, int depth)
|
||||
if (snprintf(path, sizeof path, "%s/%s", dir, de->d_name) >= (int)sizeof path) continue;
|
||||
struct stat st;
|
||||
if (stat(path, &st) != 0) continue;
|
||||
if (S_ISDIR(st.st_mode)) { count_books_under(c, path, depth + 1); continue; }
|
||||
if (shelf_fmt_from_ext(de->d_name) >= 0) c->depth_skipped++;
|
||||
if (S_ISDIR(st.st_mode)) { n += count_books_under(path, depth + 1); continue; }
|
||||
if (shelf_fmt_from_ext(de->d_name) >= 0) n++;
|
||||
}
|
||||
closedir(dp);
|
||||
return n;
|
||||
}
|
||||
|
||||
/* 递归收集。rel = 相对 root 的完整目录路径(root 自身为 ""),
|
||||
@@ -108,7 +110,14 @@ static void scan_dir(scan_ctx *c, const char *dir, int depth, const char *rel, c
|
||||
if (stat(path, &st) != 0) continue;
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (depth + 1 > SHELF_SCAN_MAX_DEPTH) {
|
||||
count_books_under(c, path, depth + 1); /* 超深:计数→可见提示 */
|
||||
c->depth_skipped += count_books_under(path, depth + 1); /* 超深:计数→可见提示 */
|
||||
continue;
|
||||
}
|
||||
if (c->n >= c->cap) {
|
||||
/* 上限卡在目录边界:探一下这个子树是否真有书,有书才算被截断。
|
||||
* 只探空目录不置位,避免“正好装满且后面全是空目录”误报。 */
|
||||
if (!c->truncated && count_books_under(path, depth + 1) > 0) c->truncated = 1;
|
||||
if (c->truncated) break; /* 已确认丢书,后面的目录/文件不必再跑 */
|
||||
continue;
|
||||
}
|
||||
char subrel[SHELF_GROUP_MAX * 16];
|
||||
@@ -132,17 +141,18 @@ static void scan_dir(scan_ctx *c, const char *dir, int depth, const char *rel, c
|
||||
b->ts = c->ts_fn ? c->ts_fn(b->path) : 0;
|
||||
char sz[24];
|
||||
shelf_fmt_size(sz, sizeof sz, b->size);
|
||||
/* 副题:第一级之后的子路径(分类/作品)· 格式 · 大小 [· 读] */
|
||||
/* 默认副题:与 M27 前逐字一致(format 模式/宫格都用它)。 */
|
||||
snprintf(b->sub, sizeof b->sub, "%s · %s%s", shelf_fmt_name(f), sz,
|
||||
b->ts ? " · 读" : "");
|
||||
/* folder 副题:第一级之后的子路径(分类/作品)前置,其余同默认副题。 */
|
||||
const char *rest = strchr(rel, '/');
|
||||
if (rest) rest++;
|
||||
if (rest && rest[0]) {
|
||||
char pre[100];
|
||||
shelf_copy_utf8(pre, (int)sizeof pre, rest);
|
||||
snprintf(b->sub, sizeof b->sub, "%s · %s · %s%s", pre, shelf_fmt_name(f), sz,
|
||||
b->ts ? " · 读" : "");
|
||||
snprintf(b->sub_folder, sizeof b->sub_folder, "%s · %s", pre, b->sub);
|
||||
} else {
|
||||
snprintf(b->sub, sizeof b->sub, "%s · %s%s", shelf_fmt_name(f), sz,
|
||||
b->ts ? " · 读" : "");
|
||||
snprintf(b->sub_folder, sizeof b->sub_folder, "%s", b->sub);
|
||||
}
|
||||
c->n++;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user