mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 14:35:41 +00:00
refactor(player): E.36 — extract schedule-pause/resume factory (#600)
Four scheduled-timer actions extracted into `createScheduleActions` (`src/store/scheduleActions.ts`): - `schedulePauseIn` / `scheduleResumeIn` — clamp the delay to ≥ 500 ms, store absolute target + start timestamps (for the countdown UI), and arm a single-shot timer. - `clearScheduledPause` / `clearScheduledResume` — cancel the timer and blank the timestamps. Pure code-move. playerStore.ts: 1030 → 991 LOC (−39, first sub-1000 state since Phase E started).
This commit is contained in:
committed by
GitHub
parent
1e2c651196
commit
55b2b12fa5
@@ -45,10 +45,6 @@ import {
|
|||||||
} from './loudnessGainCache';
|
} from './loudnessGainCache';
|
||||||
import {
|
import {
|
||||||
clearAllPlaybackScheduleTimers,
|
clearAllPlaybackScheduleTimers,
|
||||||
clearScheduledPauseTimers,
|
|
||||||
clearScheduledResumeTimers,
|
|
||||||
schedulePauseTimer,
|
|
||||||
scheduleResumeTimer,
|
|
||||||
} from './scheduleTimers';
|
} from './scheduleTimers';
|
||||||
import { invokeAudioUpdateReplayGainDeduped } from './normalizationIpcDedupe';
|
import { invokeAudioUpdateReplayGainDeduped } from './normalizationIpcDedupe';
|
||||||
import { touchHotCacheOnPlayback } from './hotCacheTouch';
|
import { touchHotCacheOnPlayback } from './hotCacheTouch';
|
||||||
@@ -154,6 +150,7 @@ export type { PlayerState, Track };
|
|||||||
import { createLastfmActions } from './lastfmActions';
|
import { createLastfmActions } from './lastfmActions';
|
||||||
import { createMiscActions } from './miscActions';
|
import { createMiscActions } from './miscActions';
|
||||||
import { createQueueMutationActions } from './queueMutationActions';
|
import { createQueueMutationActions } from './queueMutationActions';
|
||||||
|
import { createScheduleActions } from './scheduleActions';
|
||||||
import { createTransportLightActions } from './transportLightActions';
|
import { createTransportLightActions } from './transportLightActions';
|
||||||
import { createUiStateActions } from './uiStateActions';
|
import { createUiStateActions } from './uiStateActions';
|
||||||
import { createUndoRedoActions } from './undoRedoActions';
|
import { createUndoRedoActions } from './undoRedoActions';
|
||||||
@@ -211,6 +208,7 @@ export const usePlayerStore = create<PlayerState>()(
|
|||||||
...createTransportLightActions(set, get),
|
...createTransportLightActions(set, get),
|
||||||
...createUndoRedoActions(set, get),
|
...createUndoRedoActions(set, get),
|
||||||
...createMiscActions(set, get),
|
...createMiscActions(set, get),
|
||||||
|
...createScheduleActions(set, get),
|
||||||
|
|
||||||
// ── playTrack ────────────────────────────────────────────────────────────
|
// ── playTrack ────────────────────────────────────────────────────────────
|
||||||
playTrack: (track, queue, manual = true, _orbitConfirmed = false, targetQueueIndex) => {
|
playTrack: (track, queue, manual = true, _orbitConfirmed = false, targetQueueIndex) => {
|
||||||
@@ -658,43 +656,6 @@ export const usePlayerStore = create<PlayerState>()(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clearScheduledPause: () => {
|
|
||||||
clearScheduledPauseTimers();
|
|
||||||
set({ scheduledPauseAtMs: null, scheduledPauseStartMs: null });
|
|
||||||
},
|
|
||||||
|
|
||||||
clearScheduledResume: () => {
|
|
||||||
clearScheduledResumeTimers();
|
|
||||||
set({ scheduledResumeAtMs: null, scheduledResumeStartMs: null });
|
|
||||||
},
|
|
||||||
|
|
||||||
schedulePauseIn: (seconds) => {
|
|
||||||
const s = get();
|
|
||||||
if (!s.isPlaying) return;
|
|
||||||
const delayMs = Math.max(500, Math.round(Number(seconds) * 1000));
|
|
||||||
const startedAt = Date.now();
|
|
||||||
const at = startedAt + delayMs;
|
|
||||||
set({ scheduledPauseAtMs: at, scheduledPauseStartMs: startedAt });
|
|
||||||
schedulePauseTimer(delayMs, () => {
|
|
||||||
set({ scheduledPauseAtMs: null, scheduledPauseStartMs: null });
|
|
||||||
get().pause();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
scheduleResumeIn: (seconds) => {
|
|
||||||
const s = get();
|
|
||||||
if (s.isPlaying) return;
|
|
||||||
if (!s.currentTrack && !s.currentRadio) return;
|
|
||||||
const delayMs = Math.max(500, Math.round(Number(seconds) * 1000));
|
|
||||||
const startedAt = Date.now();
|
|
||||||
const at = startedAt + delayMs;
|
|
||||||
set({ scheduledResumeAtMs: at, scheduledResumeStartMs: startedAt });
|
|
||||||
scheduleResumeTimer(delayMs, () => {
|
|
||||||
set({ scheduledResumeAtMs: null, scheduledResumeStartMs: null });
|
|
||||||
get().resume();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// ── next / previous ──────────────────────────────────────────────────────
|
// ── next / previous ──────────────────────────────────────────────────────
|
||||||
next: (manual = true) => {
|
next: (manual = true) => {
|
||||||
const { queue, queueIndex, repeatMode, currentTrack } = get();
|
const { queue, queueIndex, repeatMode, currentTrack } = get();
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import type { PlayerState } from './playerStoreTypes';
|
||||||
|
import {
|
||||||
|
clearScheduledPauseTimers,
|
||||||
|
clearScheduledResumeTimers,
|
||||||
|
schedulePauseTimer,
|
||||||
|
scheduleResumeTimer,
|
||||||
|
} from './scheduleTimers';
|
||||||
|
|
||||||
|
type SetState = (
|
||||||
|
partial: Partial<PlayerState> | ((state: PlayerState) => Partial<PlayerState>),
|
||||||
|
) => void;
|
||||||
|
type GetState = () => PlayerState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User-facing scheduled-pause / scheduled-resume actions. Each setter
|
||||||
|
* clamps the delay to ≥ 500 ms, stores the absolute target + start
|
||||||
|
* timestamps in the store (so countdown UI can render a progress arc),
|
||||||
|
* and arms a single-shot timer in `scheduleTimers.ts`. The matching
|
||||||
|
* `clearScheduled*` actions cancel the timer and blank the timestamps.
|
||||||
|
*/
|
||||||
|
export function createScheduleActions(set: SetState, get: GetState): Pick<
|
||||||
|
PlayerState,
|
||||||
|
'clearScheduledPause' | 'clearScheduledResume' | 'schedulePauseIn' | 'scheduleResumeIn'
|
||||||
|
> {
|
||||||
|
return {
|
||||||
|
clearScheduledPause: () => {
|
||||||
|
clearScheduledPauseTimers();
|
||||||
|
set({ scheduledPauseAtMs: null, scheduledPauseStartMs: null });
|
||||||
|
},
|
||||||
|
|
||||||
|
clearScheduledResume: () => {
|
||||||
|
clearScheduledResumeTimers();
|
||||||
|
set({ scheduledResumeAtMs: null, scheduledResumeStartMs: null });
|
||||||
|
},
|
||||||
|
|
||||||
|
schedulePauseIn: (seconds) => {
|
||||||
|
const s = get();
|
||||||
|
if (!s.isPlaying) return;
|
||||||
|
const delayMs = Math.max(500, Math.round(Number(seconds) * 1000));
|
||||||
|
const startedAt = Date.now();
|
||||||
|
const at = startedAt + delayMs;
|
||||||
|
set({ scheduledPauseAtMs: at, scheduledPauseStartMs: startedAt });
|
||||||
|
schedulePauseTimer(delayMs, () => {
|
||||||
|
set({ scheduledPauseAtMs: null, scheduledPauseStartMs: null });
|
||||||
|
get().pause();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
scheduleResumeIn: (seconds) => {
|
||||||
|
const s = get();
|
||||||
|
if (s.isPlaying) return;
|
||||||
|
if (!s.currentTrack && !s.currentRadio) return;
|
||||||
|
const delayMs = Math.max(500, Math.round(Number(seconds) * 1000));
|
||||||
|
const startedAt = Date.now();
|
||||||
|
const at = startedAt + delayMs;
|
||||||
|
set({ scheduledResumeAtMs: at, scheduledResumeStartMs: startedAt });
|
||||||
|
scheduleResumeTimer(delayMs, () => {
|
||||||
|
set({ scheduledResumeAtMs: null, scheduledResumeStartMs: null });
|
||||||
|
get().resume();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user