From 7b2611129a739767f2eac6367d4333c9c7284820 Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Sat, 1 Nov 2025 21:54:50 +0100 Subject: [PATCH] feat: add youtube button for video id extraction --- src/utils/youtube.ts | 39 +++++++++++++++++++++++++++++++ src/views/FleetingNotes.vue | 46 +++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/utils/youtube.ts diff --git a/src/utils/youtube.ts b/src/utils/youtube.ts new file mode 100644 index 0000000..8208612 --- /dev/null +++ b/src/utils/youtube.ts @@ -0,0 +1,39 @@ +export const extractYouTubeId = (input: string) => { + if (!input) { + return null + } + + let url: URL + + try { + url = new URL(input) + } catch { + return input.trim() + } + + const host = url.hostname.toLowerCase() + const pathSegments = url.pathname.split("/").filter(Boolean) + + if (host.includes("youtu.be")) { + return pathSegments[0] ?? null + } + + if (!host.includes("youtube.com")) { + return null + } + + const vParam = url.searchParams.get("v") + + if (vParam) { + return vParam + } + + if ( + pathSegments.length >= 2 && + ["embed", "shorts", "live", "watch"].includes(pathSegments[0]) + ) { + return pathSegments[1] + } + + return null +} diff --git a/src/views/FleetingNotes.vue b/src/views/FleetingNotes.vue index f88cf97..dfac4a5 100644 --- a/src/views/FleetingNotes.vue +++ b/src/views/FleetingNotes.vue @@ -9,6 +9,8 @@ import { prepareNoteCache } from "@/modules/note/cache/prepareNoteCache" import EditNote from "@/modules/note/components/EditNote.vue" import { useFolderNotes } from "@/modules/note/hooks/useFolderNotes" import { encodeUTF8ToBase64 } from "@/utils/decodeBase64ToUTF8" +import { confirmMessage, errorMessage } from "@/utils/notif" +import { extractYouTubeId } from "@/utils/youtube" const FLEETING_NOTES_FOLDER = ["inbox", "_inbox"] @@ -25,6 +27,47 @@ const initialContent = `` const newContent = ref(initialContent) const { mode, toggleMode } = useEditionMode() +const handleYouTube = async () => { + if (typeof navigator === "undefined" || !navigator.clipboard?.readText) { + errorMessage("Clipboard access is not available.") + return + } + + let clipboardText: string + + try { + clipboardText = (await navigator.clipboard.readText()).trim() + } catch (err) { + console.warn(err) + + errorMessage("Unable to read from the clipboard.") + return + } + + debugger + + if (!clipboardText) { + errorMessage("Clipboard is empty.") + return + } + + const videoId = extractYouTubeId(clipboardText) + + if (!videoId) { + errorMessage("The clipboard does not contain a valid YouTube link or id.") + return + } + + const snippet = `@[youtube](${videoId})` + try { + await navigator.clipboard.writeText(snippet) + } catch { + errorMessage("Unable to paste to the clipboard.") + } + + confirmMessage("YouTube video embed added to the note.") +} + const { createFile } = useGitHubContent({ repo: repo.value, user: user.value, @@ -74,6 +117,9 @@ watch(mode, async (newMode) => { new fleeting note +
+ +