web/Omnibox: improve pasting links from clipboard

- `text/uri-list` type is now accepted (such as clipboard data from bluesky)
- http links are now allowed (such as those from rednote)
- rednote share link is properly extracted
This commit is contained in:
wukko 2025-01-20 21:26:55 +06:00
parent 73f458a999
commit 39752b2c5f
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2
2 changed files with 31 additions and 11 deletions

View file

@ -11,6 +11,7 @@
import dialogs from "$lib/state/dialogs"; import dialogs from "$lib/state/dialogs";
import { link } from "$lib/state/omnibox"; import { link } from "$lib/state/omnibox";
import { updateSetting } from "$lib/state/settings"; import { updateSetting } from "$lib/state/settings";
import { pasteLinkFromClipboard } from "$lib/clipboard";
import { turnstileEnabled, turnstileSolved } from "$lib/state/turnstile"; import { turnstileEnabled, turnstileSolved } from "$lib/state/turnstile";
import type { Optional } from "$lib/types/generic"; import type { Optional } from "$lib/types/generic";
@ -41,7 +42,7 @@
const validLink = (url: string) => { const validLink = (url: string) => {
try { try {
return /^https:/i.test(new URL(url).protocol); return /^https?\:/i.test(new URL(url).protocol);
} catch {} } catch {}
}; };
@ -59,22 +60,24 @@
goto("/", { replaceState: true }); goto("/", { replaceState: true });
} }
const pasteClipboard = () => { const pasteClipboard = async () => {
if ($dialogs.length > 0 || isDisabled || isLoading) { if ($dialogs.length > 0 || isDisabled || isLoading) {
return; return;
} }
navigator.clipboard.readText().then(async (text: string) => { const pastedData = await pasteLinkFromClipboard();
let matchLink = text.match(/https:\/\/[^\s]+/g); if (!pastedData) return;
if (matchLink) {
$link = matchLink[0]; const linkMatch = pastedData.match(/https?\:\/\/[^\s]+/g);
if (linkMatch) {
$link = linkMatch[0].split('')[0];
if (!isBotCheckOngoing) { if (!isBotCheckOngoing) {
await tick(); // wait for button to render await tick(); // wait for button to render
downloadButton.download($link); downloadButton.download($link);
} }
} }
});
}; };
const changeDownloadMode = (mode: DownloadModeOption) => { const changeDownloadMode = (mode: DownloadModeOption) => {

17
web/src/lib/clipboard.ts Normal file
View file

@ -0,0 +1,17 @@
const allowedLinkTypes = new Set(["text/plain", "text/uri-list"]);
export const pasteLinkFromClipboard = async () => {
const clipboard = await navigator.clipboard.read();
if (clipboard?.length) {
const clipboardItem = clipboard[0];
for (const type of clipboardItem.types) {
if (allowedLinkTypes.has(type)) {
const blob = await clipboardItem.getType(type);
const blobText = await blob.text();
return blobText;
}
}
}
}