feat: add some keyboard controls
This commit is contained in:
parent
1dfc0dc01e
commit
c5f7b1797b
@ -20,6 +20,7 @@
|
||||
</Link>
|
||||
{#if link.id === 'search' && $page.route.id === '/'}
|
||||
<input
|
||||
id="search-input"
|
||||
class="input rounded-none"
|
||||
bind:value={$searchText}
|
||||
on:input={(ev) => search(ev.currentTarget.value)}
|
||||
|
@ -72,18 +72,8 @@
|
||||
currentTime = ev.seekTime;
|
||||
}
|
||||
});
|
||||
mediaSession.setActionHandler('seekbackward', () => {
|
||||
currentTime -= 5;
|
||||
if (currentTime < 0) {
|
||||
currentTime = 0;
|
||||
}
|
||||
});
|
||||
mediaSession.setActionHandler('seekforward', () => {
|
||||
currentTime += 5;
|
||||
if (currentTime > duration) {
|
||||
currentTime = duration;
|
||||
}
|
||||
});
|
||||
mediaSession.setActionHandler('seekbackward', () => (currentTime -= 5));
|
||||
mediaSession.setActionHandler('seekforward', () => (currentTime += 5));
|
||||
}}
|
||||
on:timeupdate={(_) => {
|
||||
navigator.mediaSession.setPositionState({ position: currentTime, duration });
|
||||
|
@ -2,7 +2,7 @@
|
||||
import IconRepeat from '~icons/mdi/repeat';
|
||||
import IconRepeatOff from '~icons/mdi/repeat-off';
|
||||
import IconRepeatOnce from '~icons/mdi/repeat-once';
|
||||
import { loop } from '../stores';
|
||||
import { changeLoop, loop } from '../stores';
|
||||
import { LoopKind } from '../types';
|
||||
|
||||
function getIcon(kind: LoopKind) {
|
||||
@ -16,20 +16,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function changeLoop() {
|
||||
switch ($loop) {
|
||||
case LoopKind.Always:
|
||||
loop.set(LoopKind.Off);
|
||||
break;
|
||||
case LoopKind.Off:
|
||||
loop.set(LoopKind.Once);
|
||||
break;
|
||||
case LoopKind.Once:
|
||||
loop.set(LoopKind.Always);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function loopKindToString(kind: LoopKind) {
|
||||
switch (kind) {
|
||||
case LoopKind.Off:
|
||||
|
@ -8,7 +8,10 @@
|
||||
import { AppShell, Toast, toastStore } from '@skeletonlabs/skeleton';
|
||||
import {
|
||||
address,
|
||||
changeLoop,
|
||||
currentTrack,
|
||||
getAudioElement,
|
||||
muted,
|
||||
paused,
|
||||
queuePosition,
|
||||
token,
|
||||
@ -81,10 +84,37 @@
|
||||
<svelte:window
|
||||
on:keydown={(event) => {
|
||||
const tagName = document.activeElement?.tagName ?? '';
|
||||
if (tagName !== 'INPUT' && event.code === 'Space') {
|
||||
const actions = new Map([
|
||||
['Space', () => ($paused = !$paused)],
|
||||
['KeyL', changeLoop],
|
||||
['KeyM', () => ($muted = !$muted)],
|
||||
['KeyS', () => document.getElementById('search-input')?.focus()],
|
||||
[
|
||||
'ArrowLeft',
|
||||
() => {
|
||||
const audio = getAudioElement();
|
||||
if (audio !== null) {
|
||||
audio.currentTime -= 5;
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'ArrowRight',
|
||||
() => {
|
||||
const audio = getAudioElement();
|
||||
if (audio !== null) {
|
||||
audio.currentTime += 5;
|
||||
}
|
||||
}
|
||||
]
|
||||
]);
|
||||
if (tagName !== 'INPUT' && actions.has(event.code)) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
paused.set(!$paused);
|
||||
const action = actions.get(event.code) ?? null;
|
||||
if (action !== null) {
|
||||
action();
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
@ -87,6 +87,20 @@ export const volume = writable<number>(1.0);
|
||||
export const muted = writable<boolean>(false);
|
||||
export const loop = writable<LoopKind>(LoopKind.Off);
|
||||
|
||||
export function changeLoop() {
|
||||
switch (get(loop)) {
|
||||
case LoopKind.Always:
|
||||
loop.set(LoopKind.Off);
|
||||
break;
|
||||
case LoopKind.Off:
|
||||
loop.set(LoopKind.Once);
|
||||
break;
|
||||
case LoopKind.Once:
|
||||
loop.set(LoopKind.Always);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export const searchText = writable<string>("");
|
||||
|
||||
export function search(q: string) {
|
||||
|
Loading…
Reference in New Issue
Block a user