web/Omnibox: add extraction of links from page hash and query

This commit is contained in:
wukko 2024-07-15 14:21:51 +06:00
parent f9dc8096bc
commit 25cfa3e443
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2

View file

@ -1,8 +1,13 @@
<script lang="ts"> <script lang="ts">
import { page } from "$app/stores";
import { goto } from "$app/navigation";
import { SvelteComponent, tick } from "svelte"; import { SvelteComponent, tick } from "svelte";
import { t } from "$lib/i18n/translations"; import { t } from "$lib/i18n/translations";
import { updateSetting } from "$lib/state/settings";
import type { DownloadModeOption } from "$lib/types/settings";
import IconLink from "@tabler/icons-svelte/IconLink.svelte"; import IconLink from "@tabler/icons-svelte/IconLink.svelte";
import ClearButton from "$components/save/buttons/ClearButton.svelte"; import ClearButton from "$components/save/buttons/ClearButton.svelte";
@ -12,12 +17,9 @@
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/state/settings";
import type { DownloadModeOption } from "$lib/types/settings";
import IconSparkles from "$lib/icons/Sparkles.svelte";
import IconMusic from "$lib/icons/Music.svelte";
import IconMute from "$lib/icons/Mute.svelte"; import IconMute from "$lib/icons/Mute.svelte";
import IconMusic from "$lib/icons/Music.svelte";
import IconSparkles from "$lib/icons/Sparkles.svelte";
import IconClipboard from "$lib/icons/Clipboard.svelte"; import IconClipboard from "$lib/icons/Clipboard.svelte";
let link: string = ""; let link: string = "";
@ -30,6 +32,20 @@
try { try {
return /^https:/i.test(new URL(link).protocol); return /^https:/i.test(new URL(link).protocol);
} catch {} } catch {}
};
$: linkFromHash = $page.url.hash.replace("#", "") || "";
$: linkFromQuery = $page.url.searchParams.get("u") || "";
$: if (linkFromHash || linkFromQuery) {
if (validLink(linkFromHash)) {
link = linkFromHash;
} else if (validLink(linkFromQuery)) {
link = linkFromQuery;
}
// clear hash and query to prevent bookmarking unwanted links
goto("/", { replaceState: true });
} }
const pasteClipboard = () => { const pasteClipboard = () => {
@ -46,14 +62,14 @@
const changeDownloadMode = (mode: DownloadModeOption) => { const changeDownloadMode = (mode: DownloadModeOption) => {
updateSetting({ save: { downloadMode: mode } }); updateSetting({ save: { downloadMode: mode } });
} };
const handleKeydown = (e: KeyboardEvent) => { const handleKeydown = (e: KeyboardEvent) => {
if (!linkInput) { if (!linkInput) {
return; return;
} }
if (e.metaKey || e.ctrlKey || e.key === '/') { if (e.metaKey || e.ctrlKey || e.key === "/") {
linkInput.focus(); linkInput.focus();
} }
@ -61,7 +77,7 @@
downloadButton.download(link); downloadButton.download(link);
} }
if (['Escape', 'Clear'].includes(e.key)) { if (["Escape", "Clear"].includes(e.key)) {
link = ""; link = "";
} }
@ -70,22 +86,22 @@
} }
switch (e.key) { switch (e.key) {
case 'D': case "D":
pasteClipboard(); pasteClipboard();
break; break;
case 'J': case "J":
changeDownloadMode('auto'); changeDownloadMode("auto");
break; break;
case 'K': case "K":
changeDownloadMode('audio'); changeDownloadMode("audio");
break; break;
case 'L': case "L":
changeDownloadMode('mute'); changeDownloadMode("mute");
break; break;
default: default:
break; break;
} }
} };
</script> </script>
<svelte:window on:keydown={handleKeydown} /> <svelte:window on:keydown={handleKeydown} />
@ -102,9 +118,9 @@
id="link-area" id="link-area"
bind:value={link} bind:value={link}
bind:this={linkInput} bind:this={linkInput}
on:input={() => isFocused = true} on:input={() => (isFocused = true)}
on:focus={() => isFocused = true} on:focus={() => (isFocused = true)}
on:blur={() => isFocused = false} on:blur={() => (isFocused = false)}
spellcheck="false" spellcheck="false"
autocomplete="off" autocomplete="off"
autocapitalize="off" autocapitalize="off"
@ -115,7 +131,7 @@
/> />
{#if link} {#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} />
@ -124,16 +140,32 @@
<div id="action-container"> <div id="action-container">
<Switcher> <Switcher>
<SettingsButton settingContext="save" settingId="downloadMode" settingValue="auto"> <SettingsButton
<IconSparkles /> {$t("save.auto")} settingContext="save"
settingId="downloadMode"
settingValue="auto"
>
<IconSparkles />
{$t("save.auto")}
</SettingsButton> </SettingsButton>
<SettingsButton settingContext="save" settingId="downloadMode" settingValue="audio"> <SettingsButton
<IconMusic /> {$t("save.audio")} settingContext="save"
settingId="downloadMode"
settingValue="audio"
>
<IconMusic />
{$t("save.audio")}
</SettingsButton> </SettingsButton>
<SettingsButton settingContext="save" settingId="downloadMode" settingValue="mute"> <SettingsButton
<IconMute /> {$t("save.mute")} settingContext="save"
settingId="downloadMode"
settingValue="mute"
>
<IconMute />
{$t("save.mute")}
</SettingsButton> </SettingsButton>
</Switcher> </Switcher>
<ActionButton id="paste" click={pasteClipboard}> <ActionButton id="paste" click={pasteClipboard}>
<IconClipboard /> <IconClipboard />
<span id="paste-desktop-text">{$t("save.paste")}</span> <span id="paste-desktop-text">{$t("save.paste")}</span>
@ -237,7 +269,7 @@
} }
#action-container :global(.button) { #action-container :global(.button) {
width: 100% width: 100%;
} }
#paste-mobile-text { #paste-mobile-text {