Bluesky app fork with some witchin' additions 馃挮
at main 115 lines 3.0 kB view raw
1// eslint-disable-next-line @typescript-eslint/no-unused-vars 2interface Window { 3 bluesky: { 4 scan: (element?: Pick<Element, 'querySelectorAll'>) => void 5 } 6 BSKY_DEV_EMBED_URL?: string 7} 8 9/** 10 * Allow url to be overwritten during development 11 */ 12const IS_DEV = 13 window.location.protocol === 'file:' || 14 window.location.hostname === 'localhost' 15const EMBED_URL = 16 IS_DEV && window.BSKY_DEV_EMBED_URL 17 ? window.BSKY_DEV_EMBED_URL 18 : 'https://embed.bsky.app' 19 20window.bluesky = window.bluesky || { 21 scan, 22} 23 24/** 25 * Listen for messages from the Bluesky embed iframe and adjust the height of 26 * the iframe accordingly. 27 */ 28window.addEventListener('message', event => { 29 if (event.origin !== EMBED_URL) { 30 return 31 } 32 33 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment 34 const id = (event.data as {id: string}).id 35 if (!id) { 36 return 37 } 38 39 const embed = document.querySelector<HTMLIFrameElement>( 40 `[data-bluesky-id="${id}"]`, 41 ) 42 43 if (!embed) { 44 return 45 } 46 47 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment 48 const height = (event.data as {height: number}).height 49 if (height) { 50 embed.style.height = `${height}px` 51 } 52}) 53 54/** 55 * Scan the document for all elements with the data-bluesky-aturi attribute, 56 * and initialize them as Bluesky embeds. 57 * 58 * @param element Only scan this specific element @default document @optional 59 * @returns 60 */ 61function scan(node = document) { 62 const embeds = node.querySelectorAll<HTMLIFrameElement>('[data-bluesky-uri]') 63 64 for (let i = 0; i < embeds.length; i++) { 65 const id = String(Math.random()).slice(2) 66 67 const embed = embeds[i] 68 const aturi = embed.getAttribute('data-bluesky-uri') 69 70 if (!aturi) { 71 continue 72 } 73 74 const ref_url = location.origin + location.pathname 75 76 const searchParams = new URLSearchParams() 77 searchParams.set('id', id) 78 if (ref_url.startsWith('http')) { 79 searchParams.set('ref_url', encodeURIComponent(ref_url)) 80 } 81 if (embed.dataset.blueskyEmbedColorMode) { 82 searchParams.set('colorMode', embed.dataset.blueskyEmbedColorMode) 83 } 84 85 const iframe = document.createElement('iframe') 86 iframe.setAttribute('data-bluesky-id', id) 87 iframe.src = `${EMBED_URL}/embed/${aturi.slice( 88 'at://'.length, 89 )}?${searchParams.toString()}` 90 iframe.width = '100%' 91 iframe.style.border = 'none' 92 iframe.style.display = 'block' 93 iframe.style.flexGrow = '1' 94 iframe.frameBorder = '0' 95 iframe.scrolling = 'no' 96 97 const container = document.createElement('div') 98 container.style.maxWidth = '600px' 99 container.style.width = '100%' 100 container.style.marginTop = '10px' 101 container.style.marginBottom = '10px' 102 container.style.display = 'flex' 103 container.className = 'bluesky-embed' 104 105 container.appendChild(iframe) 106 107 embed.replaceWith(container) 108 } 109} 110 111if (['interactive', 'complete'].indexOf(document.readyState) !== -1) { 112 scan() 113} else { 114 document.addEventListener('DOMContentLoaded', () => scan()) 115}