your personal website on atproto - mirror blento.app
at remove-extra-buttons 83 lines 2.7 kB view raw
1import type { CardDefinition } from '../types'; 2import CreateYoutubeCardModal from './CreateYoutubeCardModal.svelte'; 3import YoutubeCard from './YoutubeCard.svelte'; 4import YoutubeCardSettings from './YoutubeCardSettings.svelte'; 5 6export const YoutubeCardDefinition = { 7 type: 'youtubeVideo', 8 contentComponent: YoutubeCard, 9 settingsComponent: YoutubeCardSettings, 10 creationModalComponent: CreateYoutubeCardModal, 11 createNew: (card) => { 12 card.cardType = 'youtubeVideo'; 13 card.cardData = {}; 14 card.w = 4; 15 card.mobileW = 8; 16 }, 17 18 onUrlHandler: (url, item) => { 19 const id = matcher(url); 20 if (!id) return; 21 22 const posterFile = 'hqdefault'; 23 const posterURL = `https://i.ytimg.com/vi/${id}/${posterFile}.jpg`; 24 25 item.cardData.poster = posterURL; 26 item.cardData.youtubeId = id; 27 item.cardData.href = url; 28 item.cardData.showInline = true; 29 30 item.w = 4; 31 item.mobileW = 8; 32 item.h = 3; 33 item.mobileH = 5; 34 35 return item; 36 }, 37 urlHandlerPriority: 2, 38 39 canChange: (item) => Boolean(matcher(item.cardData.href)), 40 41 change: (item) => { 42 const href = item.cardData?.href; 43 44 const id = matcher(href); 45 if (!id) return; 46 47 const posterFile = 'hqdefault'; 48 const posterURL = `https://i.ytimg.com/vi/${id}/${posterFile}.jpg`; 49 50 item.cardData.poster = posterURL; 51 item.cardData.youtubeId = id; 52 item.cardData.showInline ??= true; 53 54 return item; 55 }, 56 name: 'Youtube Video', 57 58 groups: ['Media'], 59 60 icon: `<svg xmlns="http://www.w3.org/2000/svg" class="h-3" viewBox="0 0 256 180" 61 ><path 62 fill="currentColor" 63 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" 64 /><path fill="currentColor" class="invert" d="m102.421 128.06l66.328-38.418l-66.328-38.418z" /></svg 65 >` 66} as CardDefinition & { type: 'youtubeVideo' }; 67 68// Thanks to eleventy-plugin-youtube-embed 69// https://github.com/gfscott/eleventy-plugin-youtube-embed/blob/main/lib/extractMatches.js 70const urlPattern = 71 /(?=(\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/; 72 73/** 74 * Extract a YouTube ID from a URL if it matches the pattern. 75 * @param url URL to test 76 * @returns A YouTube video ID or undefined if none matched 77 */ 78export function matcher(url: string | undefined): string | undefined { 79 if (!url) return; 80 81 const match = url.match(urlPattern); 82 return match?.[3]; 83}