mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-21 22:15:40 +00:00
606a150e01
* feat(settings): clock format setting (Auto / 24h / 12h) Reported on the Psysonic Discord — the Queue side panel's ETA label and the sleep-timer preview both render via `formatClockTime`, which just calls `toLocaleTimeString` and so follows the user's system locale. On en-US that means AM/PM, with no in-app way out. Add a tri-state **Clock Format** setting under **Settings → System → App Behavior**: * `auto` (default) — keep the existing locale-driven behaviour, so bestehende installs are unaffected on first launch. * `24h` — force 24-hour wall-clock output everywhere `formatClockTime` is used. * `12h` — force AM/PM output. Wired through `authStore` (`clockFormat`, `setClockFormat`), exposed via `CustomSelect` in `SystemTab`, and threaded into the two consumers (`QueueHeader`, `PlaybackDelayModal`) so they re-render on change. `formatClockTime` itself stays a pure helper — it accepts the setting as an optional second argument and maps it to `hour12`. Locale coverage: all nine bundled locales (en, de, es, fr, nl, nb, ru, zh, ro) get the four new settings strings. Pin tests added for the `setClockFormat` setter and the `hour12` mapping in `formatClockTime`. * docs(changelog): clock format setting + contributors (PR #742)
33 lines
1.4 KiB
TypeScript
33 lines
1.4 KiB
TypeScript
/**
|
|
* `formatClockTime` is a thin wrapper around `Date.toLocaleTimeString` whose
|
|
* only knob is `hour12`, mapped from the user's `ClockFormat` setting. The
|
|
* exact `HH:MM` output is locale-dependent and not asserted here — these
|
|
* tests pin only the `hour12` mapping, which is what the setting controls.
|
|
*/
|
|
import { describe, expect, it } from 'vitest';
|
|
import { formatClockTime } from './formatClockTime';
|
|
|
|
const SAMPLE_TS = Date.UTC(2026, 0, 1, 19, 17, 0); // 19:17 UTC, deterministic
|
|
|
|
describe('formatClockTime — clockFormat mapping', () => {
|
|
it('forces 24-hour output when clockFormat === "24h" (no AM/PM marker)', () => {
|
|
const out = formatClockTime(SAMPLE_TS, '24h');
|
|
expect(out).not.toMatch(/AM|PM/i);
|
|
});
|
|
|
|
it('forces 12-hour output when clockFormat === "12h" (renders an AM/PM marker)', () => {
|
|
const out = formatClockTime(SAMPLE_TS, '12h');
|
|
expect(out).toMatch(/AM|PM/i);
|
|
});
|
|
|
|
it('falls through to the locale default when clockFormat === "auto"', () => {
|
|
// We do not assert AM/PM either way here — `'auto'` deliberately defers to
|
|
// the JS engine's locale. The contract is just "do not force `hour12`".
|
|
expect(() => formatClockTime(SAMPLE_TS, 'auto')).not.toThrow();
|
|
});
|
|
|
|
it('falls through to the locale default when clockFormat is omitted', () => {
|
|
expect(() => formatClockTime(SAMPLE_TS)).not.toThrow();
|
|
});
|
|
});
|