diff --git a/src/lib/format-utils.ts b/src/lib/format-utils.ts index 2d47e81..64acb3c 100644 --- a/src/lib/format-utils.ts +++ b/src/lib/format-utils.ts @@ -168,8 +168,10 @@ export function formatResetCountdown(iso?: string, opts?: FormatResetCountdownOp if (opts?.compactRounded) { if (days > 0) return `${days}d`; - if (hours > 0) return `${hours}h`; - return `${minutes}m`; + const halfHours = Math.ceil(diffMinutes / 30); + const h = Math.floor(halfHours / 2); + if (h > 0) return halfHours % 2 === 1 ? `${h}.5h` : `${h}h`; + return `0.5h`; } if (days > 0) return `${days}d ${hours}h`; diff --git a/tests/format.test.ts b/tests/format.test.ts index 5db8404..6e22997 100644 --- a/tests/format.test.ts +++ b/tests/format.test.ts @@ -149,7 +149,7 @@ describe("formatQuotaRows", () => { }); // We don't assert exact time math; just that some countdown marker appears. - expect(out).toMatch(/(\d+[dhms]|reset)/); + expect(out).toMatch(/([\d.]+[dhms]|reset)/); }); it("does not show reset countdown when quota is fully available", () => { @@ -184,7 +184,7 @@ describe("formatQuotaRows", () => { ], }); - expect(out).toContain("2h"); + expect(out).toContain("2.5h"); expect(out).not.toContain("2h 14m"); }); @@ -207,7 +207,7 @@ describe("formatQuotaRows", () => { ], }); - expect(out).toContain("14m"); + expect(out).toContain("0.5h"); expect(out).not.toContain("0h 14m"); }); diff --git a/tests/tui-sidebar-format.test.ts b/tests/tui-sidebar-format.test.ts index 0cc0e96..f3843f6 100644 --- a/tests/tui-sidebar-format.test.ts +++ b/tests/tui-sidebar-format.test.ts @@ -253,7 +253,7 @@ describe("buildSidebarQuotaPanelLines", () => { }, }); - expect(lines.join("\n")).toContain("2h"); + expect(lines.join("\n")).toContain("2.5h"); expect(lines.join("\n")).not.toContain("2h 14m"); });