Add combined model selector and refactor working indicator

This commit is contained in:
Mohamed Boudra
2026-03-19 08:55:40 +07:00
parent 22c27dd583
commit f0ba64f23b
14 changed files with 690 additions and 127 deletions
@@ -0,0 +1,33 @@
import { describe, expect, it } from "vitest";
import {
getWorkingIndicatorDotStrength,
WORKING_INDICATOR_OFFSETS,
} from "./working-indicator";
describe("getWorkingIndicatorDotStrength", () => {
it("returns a stable triangular pulse over one cycle", () => {
expect(getWorkingIndicatorDotStrength(0, 0)).toBe(0);
expect(getWorkingIndicatorDotStrength(0.125, 0)).toBe(0.25);
expect(getWorkingIndicatorDotStrength(0.25, 0)).toBe(0.5);
expect(getWorkingIndicatorDotStrength(0.5, 0)).toBe(1);
expect(getWorkingIndicatorDotStrength(0.75, 0)).toBe(0.5);
expect(getWorkingIndicatorDotStrength(1, 0)).toBe(0);
});
it("keeps the dots phase-shifted instead of identical", () => {
const strengths = WORKING_INDICATOR_OFFSETS.map((offset) =>
getWorkingIndicatorDotStrength(0, offset)
);
expect(strengths).toEqual([0, 0.26666666666666666, 0.5333333333333333]);
});
it("wraps progress cleanly across loop boundaries", () => {
expect(getWorkingIndicatorDotStrength(1.1, 0)).toBeCloseTo(
getWorkingIndicatorDotStrength(0.1, 0)
);
expect(getWorkingIndicatorDotStrength(-0.1, 0)).toBeCloseTo(
getWorkingIndicatorDotStrength(0.9, 0)
);
});
});
@@ -0,0 +1,22 @@
export const WORKING_INDICATOR_CYCLE_MS = 1200;
export const WORKING_INDICATOR_OFFSETS = [
0,
160 / WORKING_INDICATOR_CYCLE_MS,
320 / WORKING_INDICATOR_CYCLE_MS,
] as const;
function normalizePhase(value: number): number {
const wrapped = value % 1;
return wrapped < 0 ? wrapped + 1 : wrapped;
}
export function getWorkingIndicatorDotStrength(
progress: number,
offset: number
): number {
const phase = normalizePhase(progress + offset);
if (phase <= 0.5) {
return phase * 2;
}
return (1 - phase) * 2;
}