diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-04-13 03:58:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-13 03:58:40 +0100 |
commit | 4b3ec5573241b9c71504dfd0bd5f181cbde19a49 (patch) | |
tree | 698c2463b389cdf6e14536610e8f96f200ddaaa3 /bskyembed/snippet/embed.ts | |
parent | 8e29b1f63309ef9ac2da21f62e03b66d477244e9 (diff) | |
download | voidsky-4b3ec5573241b9c71504dfd0bd5f181cbde19a49.tar.zst |
[Embeds] Embed subdomain landing page (#3501)
* add build output to web build * simplify post-build step by copying everything at once * make script that converts placeholder -> iframe * dynamically resize iframe based on inner content Requires the iframe content to `postMessage` its height back up to the parent * add lang to embed * svg explicit height -> viewBox * add build output to web build * simplify post-build step by copying everything at once * attempt to fix go embed issue * rm changes to bskyweb * remove another bskyweb change * embed landing page * Drop xl breakpoint, too far down * Remove pointer enter behavior * Avoid button width jump * Escape HTML --------- Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
Diffstat (limited to 'bskyembed/snippet/embed.ts')
-rw-r--r-- | bskyembed/snippet/embed.ts | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/bskyembed/snippet/embed.ts b/bskyembed/snippet/embed.ts new file mode 100644 index 000000000..f2b9b442e --- /dev/null +++ b/bskyembed/snippet/embed.ts @@ -0,0 +1,90 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +interface Window { + bluesky: { + scan: (element?: Pick<Element, 'querySelectorAll'>) => void + } +} + +const EMBED_URL = 'https://embed.bsky.app' + +window.bluesky = window.bluesky || { + scan, +} + +/** + * Listen for messages from the Bluesky embed iframe and adjust the height of + * the iframe accordingly. + */ +window.addEventListener('message', event => { + if (event.origin !== EMBED_URL) { + return + } + + const id = (event.data as {id: string}).id + if (!id) { + return + } + + const embed = document.querySelector<HTMLIFrameElement>( + `[data-bluesky-id="${id}"]`, + ) + + if (!embed) { + return + } + + const height = (event.data as {height: number}).height + if (height) { + embed.style.height = `${height}px` + } +}) + +/** + * Scan the document for all elements with the data-bluesky-aturi attribute, + * and initialize them as Bluesky embeds. + * + * @param element Only scan this specific element @default document @optional + * @returns + */ +function scan(node = document) { + const embeds = node.querySelectorAll('[data-bluesky-uri]') + + for (let i = 0; i < embeds.length; i++) { + const id = String(Math.random()).slice(2) + + const embed = embeds[i] + const aturi = embed.getAttribute('data-bluesky-uri') + + if (!aturi) { + continue + } + + const iframe = document.createElement('iframe') + iframe.setAttribute('data-bluesky-id', id) + iframe.src = `${EMBED_URL}/embed/${aturi.slice('at://'.length)}?id=${id}` + iframe.width = '100%' + iframe.style.border = 'none' + iframe.style.display = 'block' + iframe.style.flexGrow = '1' + iframe.frameBorder = '0' + iframe.scrolling = 'no' + + const container = document.createElement('div') + container.style.maxWidth = '600px' + container.style.width = '100%' + container.style.marginTop = '10px' + container.style.marginBottom = '10px' + container.style.display = 'flex' + container.className = 'bluesky-embed' + + container.appendChild(iframe) + + embed.replaceWith(container) + } +} + +if (['interactive', 'complete'].indexOf(document.readyState) !== -1) { + scan() +} else { + document.addEventListener('DOMContentLoaded', () => scan()) +} |