import type { CardDefinition } from '../types';
import CreateYoutubeCardModal from './CreateYoutubeCardModal.svelte';
import YoutubeCard from './YoutubeCard.svelte';
import YoutubeCardSettings from './YoutubeCardSettings.svelte';
export const YoutubeCardDefinition = {
type: 'youtubeVideo',
contentComponent: YoutubeCard,
settingsComponent: YoutubeCardSettings,
creationModalComponent: CreateYoutubeCardModal,
createNew: (card) => {
card.cardType = 'youtubeVideo';
card.cardData = {};
card.w = 4;
card.mobileW = 8;
},
onUrlHandler: (url, item) => {
const id = matcher(url);
if (!id) return;
const posterFile = 'hqdefault';
const posterURL = `https://i.ytimg.com/vi/${id}/${posterFile}.jpg`;
item.cardData.poster = posterURL;
item.cardData.youtubeId = id;
item.cardData.href = url;
item.cardData.showInline = true;
item.w = 4;
item.mobileW = 8;
item.h = 3;
item.mobileH = 5;
return item;
},
urlHandlerPriority: 2,
canChange: (item) => Boolean(matcher(item.cardData.href)),
change: (item) => {
const href = item.cardData?.href;
const id = matcher(href);
if (!id) return;
const posterFile = 'hqdefault';
const posterURL = `https://i.ytimg.com/vi/${id}/${posterFile}.jpg`;
item.cardData.poster = posterURL;
item.cardData.youtubeId = id;
item.cardData.showInline ??= true;
return item;
},
name: 'Youtube Video',
keywords: ['video', 'yt', 'stream', 'watch'],
groups: ['Media'],
icon: ``
} as CardDefinition & { type: 'youtubeVideo' };
// Thanks to eleventy-plugin-youtube-embed
// https://github.com/gfscott/eleventy-plugin-youtube-embed/blob/main/lib/extractMatches.js
const urlPattern =
/(?=(\s*))\1(?:]*?>)??(?=(\s*))\2(?:https?:\/\/)??(?:w{3}\.)??(?:youtube\.com|youtu\.be)\/(?:watch\?v=|embed\/|shorts\/)??([A-Za-z0-9-_]{11})(?:[^\s<>]*)(?=(\s*))\4(?:<\/a>)??(?=(\s*))\5/;
/**
* Extract a YouTube ID from a URL if it matches the pattern.
* @param url URL to test
* @returns A YouTube video ID or undefined if none matched
*/
export function matcher(url: string | undefined): string | undefined {
if (!url) return;
const match = url.match(urlPattern);
return match?.[3];
}