* feat: add YouTube video embed support for TipTap editor - Paste YouTube URLs to auto-embed videos with metadata - Edit video title and URL through dropdown menu - Convert embed back to plain URL link - Fetch video titles automatically via YouTube oEmbed API * fix: - reverted NewCardForm CSS properties back to max-h-48. - Added boolean prop to TipTap Edtior for YouTube embed. - Disabled YouTube embed feature for NewCardForm Editor * chore: lint * chore: translations * chore: update translations --------- Co-authored-by: Henry <henry_ball@hotmail.co.uk>
62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
export function extractVideoId(url: string): string | null {
|
|
if (!url) return null;
|
|
url = url.trim();
|
|
|
|
// youtube.com/watch?v=VIDEO_ID
|
|
const watchMatch = /(?:youtube\.com\/watch\?v=)([a-zA-Z0-9_-]{11})/.exec(url);
|
|
if (watchMatch) return watchMatch[1] ?? null;
|
|
|
|
// youtu.be/VIDEO_ID
|
|
const shortMatch = /(?:youtu\.be\/)([a-zA-Z0-9_-]{11})/.exec(url);
|
|
if (shortMatch) return shortMatch[1] ?? null;
|
|
|
|
// youtube.com/embed/VIDEO_ID
|
|
const embedMatch = /(?:youtube\.com\/embed\/)([a-zA-Z0-9_-]{11})/.exec(url);
|
|
if (embedMatch) return embedMatch[1] ?? null;
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Check if a URL is a valid YouTube link
|
|
*/
|
|
export function isYouTubeUrl(url: string): boolean {
|
|
if (!url) return false;
|
|
const videoId = extractVideoId(url);
|
|
return videoId !== null;
|
|
}
|
|
|
|
/**
|
|
* Fetch YouTube video metadata using oEmbed API
|
|
* Returns title, author, thumbnail URL, etc.
|
|
* No API key required
|
|
*/
|
|
export async function fetchYouTubeMetadata(url: string): Promise<{
|
|
title: string;
|
|
author_name: string;
|
|
thumbnail_url: string;
|
|
} | null> {
|
|
try {
|
|
const oembedUrl = `https://www.youtube.com/oembed?url=${encodeURIComponent(url)}&format=json`;
|
|
const response = await fetch(oembedUrl);
|
|
|
|
if (!response.ok) {
|
|
return null;
|
|
}
|
|
|
|
const data = (await response.json()) as {
|
|
title: string;
|
|
author_name: string;
|
|
thumbnail_url: string;
|
|
};
|
|
return {
|
|
title: data.title || "YouTube Video",
|
|
author_name: data.author_name || "",
|
|
thumbnail_url: data.thumbnail_url || "",
|
|
};
|
|
} catch (error) {
|
|
console.error("Failed to fetch YouTube metadata:", error);
|
|
return null;
|
|
}
|
|
}
|