Leaflet Blog in Deno Fresh
1"use client";
2
3import { useEffect, useId, useState } from "preact/hooks";
4
5const EMBED_URL = "https://embed.bsky.app";
6
7export function BlueskyPostEmbed({ uri }: { uri: string }) {
8 const id = useId();
9 const [height, setHeight] = useState(0);
10
11 useEffect(() => {
12 const abortController = new AbortController();
13 const { signal } = abortController;
14 globalThis.addEventListener(
15 "message",
16 (event) => {
17 if (event.origin !== EMBED_URL) {
18 return;
19 }
20
21 const iframeId = (event.data as { id: string }).id;
22 if (id !== iframeId) {
23 return;
24 }
25
26 const internalHeight = (event.data as { height: number }).height;
27 if (internalHeight && typeof internalHeight === "number") {
28 setHeight(internalHeight);
29 }
30 },
31 { signal },
32 );
33
34 return () => {
35 abortController.abort();
36 };
37 }, [id]);
38
39 const ref_url = "https://" + "knotbin.com/post/" + uri.split("/").pop();
40
41 const searchParams = new URLSearchParams();
42 searchParams.set("id", id);
43 searchParams.set("ref_url", encodeURIComponent(ref_url));
44
45 return (
46 <div
47 className="mt-6 flex max-w-[600px] w-full bluesky-embed"
48 data-uri={uri}
49 >
50 <iframe
51 className="w-full block border-none grow"
52 style={{ height }}
53 data-bluesky-uri={uri}
54 src={`${EMBED_URL}/embed/${uri.slice("at://".length)}?${searchParams.toString()}`}
55 width="100%"
56 frameBorder="0"
57 scrolling="no"
58 />
59 </div>
60 );
61}