improvements to the sleep timer
This commit is contained in:
@@ -5,24 +5,32 @@
|
||||
sleepTimerActive,
|
||||
} from "$lib/stores/sleepTimer";
|
||||
import { currentQueueItem } from "$lib/stores/queue";
|
||||
import ScrollPicker from "$lib/components/common/ScrollPicker.svelte";
|
||||
|
||||
interface Props {
|
||||
isOpen?: boolean;
|
||||
onClose?: () => void;
|
||||
mediaType?: string; // Override queue-based detection (e.g. for video player)
|
||||
}
|
||||
|
||||
let { isOpen = false, onClose }: Props = $props();
|
||||
let { isOpen = false, onClose, mediaType }: Props = $props();
|
||||
|
||||
const timePickerItems = [
|
||||
{ value: 15, label: "15 min" },
|
||||
{ value: 30, label: "30 min" },
|
||||
{ value: 45, label: "45 min" },
|
||||
{ value: 60, label: "60 min" },
|
||||
];
|
||||
|
||||
let selectedMinutes = $state(30);
|
||||
|
||||
const timePresets = [15, 30, 45, 60];
|
||||
const episodePresets = [1, 2, 3];
|
||||
|
||||
const isEpisode = $derived($currentQueueItem?.type === "Episode");
|
||||
const isVideo = $derived(
|
||||
$currentQueueItem?.type === "Episode" || $currentQueueItem?.type === "Movie"
|
||||
);
|
||||
const effectiveType = $derived(mediaType ?? $currentQueueItem?.type);
|
||||
const isEpisode = $derived(effectiveType === "Episode");
|
||||
|
||||
function handleTimePreset(minutes: number) {
|
||||
sleepTimer.setTimeTimer(minutes);
|
||||
function handleSetTimer() {
|
||||
sleepTimer.setTimeTimer(selectedMinutes);
|
||||
onClose?.();
|
||||
}
|
||||
|
||||
@@ -62,7 +70,7 @@
|
||||
}
|
||||
|
||||
function getEndOfTrackLabel(): string {
|
||||
const type = $currentQueueItem?.type;
|
||||
const type = effectiveType;
|
||||
if (type === "Episode") return "End of current episode";
|
||||
if (type === "Movie") return "End of current film";
|
||||
return "End of current track";
|
||||
@@ -73,7 +81,7 @@
|
||||
<div
|
||||
class="fixed inset-0 bg-black/60 z-[60] flex items-end sm:items-center justify-center p-0 sm:p-4"
|
||||
onclick={handleBackdropClick}
|
||||
onkeydown={(e) => { if (e.key === 'Escape') handleBackdropClick(); }}
|
||||
onkeydown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="sleep-timer-title"
|
||||
@@ -144,19 +152,23 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Time presets -->
|
||||
<!-- Time roller -->
|
||||
<div class="mb-6">
|
||||
<h3 class="text-sm font-medium text-gray-400 mb-3">Stop after time</h3>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
{#each timePresets as minutes}
|
||||
<button
|
||||
onclick={() => handleTimePreset(minutes)}
|
||||
class="p-4 rounded-lg border border-gray-800 hover:border-[var(--color-jellyfin)]/50 hover:bg-[var(--color-jellyfin)]/5 transition-all text-center"
|
||||
>
|
||||
<span class="text-lg font-medium text-white">{minutes}</span>
|
||||
<span class="text-sm text-gray-400 ml-1">min</span>
|
||||
</button>
|
||||
{/each}
|
||||
<div class="flex flex-col items-center gap-3">
|
||||
<ScrollPicker
|
||||
items={timePickerItems}
|
||||
selectedValue={selectedMinutes}
|
||||
visibleCount={3}
|
||||
itemHeight={56}
|
||||
onSelect={(val) => { selectedMinutes = val as number; }}
|
||||
/>
|
||||
<button
|
||||
onclick={handleSetTimer}
|
||||
class="w-full py-3 rounded-lg bg-[var(--color-jellyfin)] text-white font-semibold hover:opacity-90 transition-opacity"
|
||||
>
|
||||
Set {selectedMinutes} min timer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user