Files
feishin/src/renderer/store/sleep-timer.store.ts
T
York cc8cb4f4f1 Add sleep timer to player bar (#1671)
* feat: add sleep timer to player bar

- Add sleep timer button in player bar right controls
- Preset options: End of song, 5/10/15/30/45 min, 1 hr, 2 hrs
- Custom timer with HH:MM:SS input fields
- Timer only counts down while music is playing
- Timer pauses playback when it expires
- End-of-song mode pauses at the next track change
- Uses theme-aware styling (--theme-colors-surface)
- Add sleepTimer/sleepTimerOff icons (LuTimer/LuTimerOff)
- Add i18n strings for sleep timer UI

---------

Co-authored-by: York <york@BonecharMac.local>
Co-authored-by: jeffvli <jeffvictorli@gmail.com>
2026-02-10 21:19:37 -08:00

70 lines
1.9 KiB
TypeScript

import { useShallow } from 'zustand/react/shallow';
import { createWithEqualityFn } from 'zustand/traditional';
export type SleepTimerMode = 'endOfSong' | 'timed';
interface SleepTimerActions {
cancelTimer: () => void;
setRemaining: (remaining: number) => void;
startEndOfSongTimer: () => void;
startTimedTimer: (durationSeconds: number) => void;
}
interface SleepTimerState {
/** Whether the timer is currently active */
active: boolean;
/** The mode of the timer */
mode: SleepTimerMode;
/** Remaining seconds (only ticks while playing) */
remaining: number;
}
export const useSleepTimerStore = createWithEqualityFn<SleepTimerActions & SleepTimerState>()(
(set) => ({
active: false,
cancelTimer: () => {
set({
active: false,
mode: 'timed',
remaining: 0,
});
},
mode: 'timed',
remaining: 0,
setRemaining: (remaining: number) => {
set({ remaining });
},
startEndOfSongTimer: () => {
set({
active: true,
mode: 'endOfSong',
remaining: 0,
});
},
startTimedTimer: (durationSeconds: number) => {
set({
active: true,
mode: 'timed',
remaining: durationSeconds,
});
},
}),
);
// Selectors
export const useSleepTimerActive = () => useSleepTimerStore((s) => s.active);
export const useSleepTimerMode = () => useSleepTimerStore((s) => s.mode);
export const useSleepTimerRemaining = () => useSleepTimerStore((s) => s.remaining);
export const useSleepTimerActions = () =>
useSleepTimerStore(
useShallow((s) => ({
cancelTimer: s.cancelTimer,
setRemaining: s.setRemaining,
startEndOfSongTimer: s.startEndOfSongTimer,
startTimedTimer: s.startTimedTimer,
})),
);