web/omnibox: add keyboard shortcuts support

- shift+d to paste
    - ⌘/ctrl+v to paste
    - shift+k for auto mode
    - shift+l for audio mode
    - esc to clear input

todo:
    - shortcut for "muted" mode
This commit is contained in:
dumbmoron 2024-07-03 17:42:34 +00:00
parent 9c4a4fb5a1
commit 743338ea4c
No known key found for this signature in database
2 changed files with 53 additions and 10 deletions

View file

@ -12,13 +12,16 @@
import ActionButton from "$components/buttons/ActionButton.svelte"; import ActionButton from "$components/buttons/ActionButton.svelte";
import SettingsButton from "$components/buttons/SettingsButton.svelte"; import SettingsButton from "$components/buttons/SettingsButton.svelte";
import { updateSetting } from "$lib/settings";
import type { DownloadModeOption } from "$lib/types/settings";
import IconSparkles from "$lib/icons/Sparkles.svelte"; import IconSparkles from "$lib/icons/Sparkles.svelte";
import IconMusic from "$lib/icons/Music.svelte"; import IconMusic from "$lib/icons/Music.svelte";
import IconMute from "$lib/icons/Mute.svelte"; import IconMute from "$lib/icons/Mute.svelte";
import IconClipboard from "$lib/icons/Clipboard.svelte"; import IconClipboard from "$lib/icons/Clipboard.svelte";
let link: string = ""; let link: string = "";
let linkInput: HTMLInputElement | undefined;
let isFocused = false; let isFocused = false;
let downloadButton: SvelteComponent; let downloadButton: SvelteComponent;
@ -26,10 +29,8 @@
const validLink = (link: string) => { const validLink = (link: string) => {
try { try {
return /^https:/i.test(new URL(link).protocol); return /^https:/i.test(new URL(link).protocol);
} catch { } catch {}
return false;
} }
};
const pasteClipboard = () => { const pasteClipboard = () => {
navigator.clipboard.readText().then(async (text) => { navigator.clipboard.readText().then(async (text) => {
@ -42,8 +43,47 @@
} }
}); });
}; };
const changeDownloadMode = (mode: DownloadModeOption) => {
updateSetting({ save: { downloadMode: mode }});
}
const handleKeydown = (e: KeyboardEvent) => {
if (!linkInput) {
return;
}
if (e.metaKey || e.ctrlKey || e.key === '/') {
linkInput.focus();
}
if (['Escape', 'Clear'].includes(e.key)) {
link = "";
}
if (e.target === linkInput) {
return;
}
switch (e.key) {
case 'D':
pasteClipboard();
break;
case 'K':
changeDownloadMode('auto');
break;
case 'L':
changeDownloadMode('audio');
break;
// TODO: keyboard shortcut for "muted" mode
default:
break;
}
}
</script> </script>
<svelte:window on:keydown={handleKeydown} />
<div id="omnibox"> <div id="omnibox">
<div <div
id="input-container" id="input-container"
@ -55,9 +95,10 @@
<input <input
id="link-area" id="link-area"
bind:value={link} bind:value={link}
on:input={() => (isFocused = true)} bind:this={linkInput}
on:focus={() => (isFocused = true)} on:input={() => isFocused = true}
on:blur={() => (isFocused = false)} on:focus={() => isFocused = true}
on:blur={() => isFocused = false}
spellcheck="false" spellcheck="false"
autocomplete="off" autocomplete="off"
autocapitalize="off" autocapitalize="off"
@ -67,8 +108,8 @@
data-form-type="other" data-form-type="other"
/> />
{#if link.length > 0} {#if link}
<ClearButton click={() => (link = "")} /> <ClearButton click={() => link = ""} />
{/if} {/if}
{#if validLink(link)} {#if validLink(link)}
<DownloadButton url={link} bind:this={downloadButton} /> <DownloadButton url={link} bind:this={downloadButton} />

View file

@ -50,3 +50,5 @@ export type CobaltSettings = {
save: CobaltSettingsSave, save: CobaltSettingsSave,
privacy: CobaltSettingsPrivacy, privacy: CobaltSettingsPrivacy,
}; };
export type DownloadModeOption = CobaltSettings['save']['downloadMode'];