your personal website on atproto - mirror blento.app
at card-command-bar 81 lines 2.6 kB view raw
1import type { CardDefinition } from '../types'; 2import YoutubeCard from './YoutubeCard.svelte'; 3import YoutubeCardSettings from './YoutubeCardSettings.svelte'; 4 5export const YoutubeCardDefinition = { 6 type: 'youtubeVideo', 7 contentComponent: YoutubeCard, 8 settingsComponent: YoutubeCardSettings, 9 createNew: (card) => { 10 card.cardType = 'youtubeVideo'; 11 card.cardData = {}; 12 card.w = 4; 13 card.mobileW = 8; 14 }, 15 16 onUrlHandler: (url, item) => { 17 const id = matcher(url); 18 if (!id) return; 19 20 const posterFile = 'hqdefault'; 21 const posterURL = `https://i.ytimg.com/vi/${id}/${posterFile}.jpg`; 22 23 item.cardData.poster = posterURL; 24 item.cardData.youtubeId = id; 25 item.cardData.href = url; 26 item.cardData.showInline = true; 27 28 item.w = 4; 29 item.mobileW = 8; 30 item.h = 3; 31 item.mobileH = 5; 32 33 return item; 34 }, 35 urlHandlerPriority: 2, 36 37 canChange: (item) => Boolean(matcher(item.cardData.href)), 38 39 change: (item) => { 40 const href = item.cardData?.href; 41 42 const id = matcher(href); 43 if (!id) return; 44 45 const posterFile = 'hqdefault'; 46 const posterURL = `https://i.ytimg.com/vi/${id}/${posterFile}.jpg`; 47 48 item.cardData.poster = posterURL; 49 item.cardData.youtubeId = id; 50 item.cardData.showInline ??= true; 51 52 return item; 53 }, 54 name: 'Youtube Video', 55 56 groups: ['Media'], 57 58 icon: `<svg xmlns="http://www.w3.org/2000/svg" class="h-3" viewBox="0 0 256 180" 59 ><path 60 fill="currentColor" 61 d="M250.346 28.075A32.18 32.18 0 0 0 227.69 5.418C207.824 0 127.87 0 127.87 0S47.912.164 28.046 5.582A32.18 32.18 0 0 0 5.39 28.24c-6.009 35.298-8.34 89.084.165 122.97a32.18 32.18 0 0 0 22.656 22.657c19.866 5.418 99.822 5.418 99.822 5.418s79.955 0 99.82-5.418a32.18 32.18 0 0 0 22.657-22.657c6.338-35.348 8.291-89.1-.164-123.134" 62 /><path fill="currentColor" class="invert" d="m102.421 128.06l66.328-38.418l-66.328-38.418z" /></svg 63 >` 64} as CardDefinition & { type: 'youtubeVideo' }; 65 66// Thanks to eleventy-plugin-youtube-embed 67// https://github.com/gfscott/eleventy-plugin-youtube-embed/blob/main/lib/extractMatches.js 68const urlPattern = 69 /(?=(\s*))\1(?:<a [^>]*?>)??(?=(\s*))\2(?:https?:\/\/)??(?:w{3}\.)??(?:youtube\.com|youtu\.be)\/(?:watch\?v=|embed\/|shorts\/)??([A-Za-z0-9-_]{11})(?:[^\s<>]*)(?=(\s*))\4(?:<\/a>)??(?=(\s*))\5/; 70 71/** 72 * Extract a YouTube ID from a URL if it matches the pattern. 73 * @param url URL to test 74 * @returns A YouTube video ID or undefined if none matched 75 */ 76export function matcher(url: string | undefined): string | undefined { 77 if (!url) return; 78 79 const match = url.match(urlPattern); 80 return match?.[3]; 81}