feat(lib): shelf sort/section pure helpers + formatSize extraction, table tests
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import type { Format } from "../api/types";
|
||||
|
||||
export { formatSize } from "../lib/format"; // deprecated: phase-2 随阅读器清除
|
||||
|
||||
export const btn =
|
||||
"inline-flex items-center gap-1.5 rounded-lg bg-white/[0.06] px-3 py-1.5 text-sm ring-1 ring-white/10 transition-colors hover:bg-white/[0.11] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500 active:bg-white/[0.15] disabled:cursor-not-allowed disabled:opacity-50";
|
||||
export const btnPrimary =
|
||||
@@ -27,12 +29,3 @@ export const FORMAT_BADGE: Record<Format, string> = {
|
||||
export function formatBadge(fmt: Format, extra = ""): string {
|
||||
return `rounded px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide ring-1 ${FORMAT_BADGE[fmt]} ${extra}`;
|
||||
}
|
||||
|
||||
export function formatSize(bytes: number): string {
|
||||
if (bytes <= 0) return "";
|
||||
const units = ["B", "KB", "MB", "GB"];
|
||||
let i = 0;
|
||||
let n = bytes;
|
||||
for (; n >= 1024 && i < units.length - 1; i++) n /= 1024;
|
||||
return `${n >= 10 || i === 0 ? Math.round(n) : n.toFixed(1)} ${units[i]}`;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
export function formatSize(bytes: number): string {
|
||||
if (bytes <= 0) return "";
|
||||
const units = ["B", "KB", "MB", "GB"];
|
||||
let i = 0;
|
||||
let n = bytes;
|
||||
for (; n >= 1024 && i < units.length - 1; i++) n /= 1024;
|
||||
return `${n >= 10 || i === 0 ? Math.round(n) : n.toFixed(1)} ${units[i]}`;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { Book } from "../api/types";
|
||||
import { groupByDir } from "./group";
|
||||
|
||||
export type SortKey = "added" | "title" | "progress";
|
||||
export const SORT_LABEL: Record<SortKey, string> = { added: "最近入库", title: "标题", progress: "阅读进度" };
|
||||
export type GroupMode = "flat" | "dir";
|
||||
|
||||
export function sortBooks(books: Book[], key: SortKey): Book[] {
|
||||
const a = [...books];
|
||||
if (key === "title") return a.sort((x, y) => x.title.localeCompare(y.title, "zh"));
|
||||
if (key === "progress") return a.sort((x, y) => y.percent - x.percent || (x.added_at < y.added_at ? 1 : x.added_at > y.added_at ? -1 : 0));
|
||||
return a.sort((x, y) => (x.added_at < y.added_at ? 1 : x.added_at > y.added_at ? -1 : 0));
|
||||
}
|
||||
|
||||
/** 页面分组视图:flat 一段无标题;dir 沿用「根目录置顶、目录名 locale 排序」。 */
|
||||
export function sections(books: Book[], key: SortKey, mode: GroupMode): { label: string; books: Book[] }[] {
|
||||
if (mode === "flat") return [{ label: "", books: sortBooks(books, key) }];
|
||||
return groupByDir(sortBooks(books, key)).map((g) => ({ label: g.dir, books: g.books }));
|
||||
}
|
||||
Reference in New Issue
Block a user