From e527cfe67f579b7f5d88bc50ed903caecf585731 Mon Sep 17 00:00:00 2001 From: cucadmuh <49571317+cucadmuh@users.noreply.github.com> Date: Mon, 8 Jun 2026 01:02:29 +0300 Subject: [PATCH] fix(fullscreen): respect Settings clock format on wall clock (#1025) * fix(fullscreen): respect Settings clock format on wall clock The fullscreen player corner clock always used the browser locale default (12-hour). Route it through formatClockTime and authStore.clockFormat so 24-hour matches queue ETA and sleep-timer preview. * docs(changelog): fullscreen clock format fix (PR #1025) --- CHANGELOG.md | 8 +++++ .../fullscreenPlayer/FsClock.test.tsx | 31 +++++++++++++++++++ src/components/fullscreenPlayer/FsClock.tsx | 21 ++++++++----- 3 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 src/components/fullscreenPlayer/FsClock.test.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 835747a7..87c3a019 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -153,6 +153,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +### Fullscreen player — corner clock follows Clock format setting + +**By [@cucadmuh](https://github.com/cucadmuh), reported by zunoz on Discord, PR [#1025](https://github.com/Psychotoxical/psysonic/pull/1025)** + +* The wall clock in the fullscreen player now honours **Settings → System → Clock format** (24-hour vs 12-hour), matching the queue ETA and sleep-timer preview instead of always showing AM/PM. + + + ## [1.47.0] > **🙏 Thank you to our amazing Discord community.** This release would not have been possible without your tireless support, quality checks, bug reports and all-round collaboration. Every report, every repro and every bit of feedback shaped what shipped here — thank you. Come join us: [discord.gg/AMnDRErm4u](https://discord.gg/AMnDRErm4u) diff --git a/src/components/fullscreenPlayer/FsClock.test.tsx b/src/components/fullscreenPlayer/FsClock.test.tsx new file mode 100644 index 00000000..4c63ba1b --- /dev/null +++ b/src/components/fullscreenPlayer/FsClock.test.tsx @@ -0,0 +1,31 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { screen } from '@testing-library/react'; +import { renderWithProviders } from '../../test/helpers/renderWithProviders'; +import { resetAuthStore } from '../../test/helpers/storeReset'; +import { useAuthStore } from '../../store/authStore'; +import { FsClock } from './FsClock'; + +describe('FsClock', () => { + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date(2026, 0, 1, 21, 59, 0)); + resetAuthStore(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it('uses the 24-hour clock format from Settings → System', () => { + useAuthStore.setState({ clockFormat: '24h' }); + renderWithProviders(); + expect(screen.getByText('21:59')).toBeInTheDocument(); + expect(screen.queryByText(/AM|PM/i)).toBeNull(); + }); + + it('uses the 12-hour clock format when selected', () => { + useAuthStore.setState({ clockFormat: '12h' }); + renderWithProviders(); + expect(screen.getByText('09:59 PM')).toBeInTheDocument(); + }); +}); diff --git a/src/components/fullscreenPlayer/FsClock.tsx b/src/components/fullscreenPlayer/FsClock.tsx index 5c3d3e4c..190dce64 100644 --- a/src/components/fullscreenPlayer/FsClock.tsx +++ b/src/components/fullscreenPlayer/FsClock.tsx @@ -1,8 +1,7 @@ import { memo, useEffect, useState } from 'react'; - -function formatClock(): string { - return new Date().toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' }); -} +import { useTranslation } from 'react-i18next'; +import { useAuthStore } from '../../store/authStore'; +import { formatClockTime } from '../../utils/format/formatClockTime'; /** * Standalone wall-clock for the fullscreen player. Owns its own state so the @@ -10,11 +9,19 @@ function formatClock(): string { * the minute rollover) and pauses while the window/tab is hidden. */ export const FsClock = memo(function FsClock() { - const [time, setTime] = useState(formatClock); + const clockFormat = useAuthStore(s => s.clockFormat); + const { i18n } = useTranslation(); + + const formatNow = () => formatClockTime(Date.now(), clockFormat, i18n.language); + const [time, setTime] = useState(formatNow); + + useEffect(() => { + setTime(formatNow()); + }, [clockFormat, i18n.language]); useEffect(() => { let id: number | undefined; - const tick = () => setTime(formatClock()); + const tick = () => setTime(formatClockTime(Date.now(), clockFormat, i18n.language)); const sync = () => { if (document.hidden) { if (id !== undefined) { clearInterval(id); id = undefined; } @@ -29,7 +36,7 @@ export const FsClock = memo(function FsClock() { if (id !== undefined) clearInterval(id); document.removeEventListener('visibilitychange', sync); }; - }, []); + }, [clockFormat, i18n.language]); return {time}; });