diff --git a/src/components/json.tsx b/src/components/json.tsx index 998f10e..516ef65 100644 --- a/src/components/json.tsx +++ b/src/components/json.tsx @@ -7,6 +7,8 @@ import { ErrorBoundary, For, on, + onCleanup, + onMount, Show, useContext, } from "solid-js"; @@ -260,47 +262,70 @@ const JSONObject = (props: { data: { [x: string]: JSONType } }) => { !ctx.hideBlobs && (blob.mimeType.startsWith("image/") || blob.mimeType === "video/mp4"); - const MediaDisplay = () => ( -
- - - - setMediaLoaded(true)} - /> - - - Failed to load video}> - { + const [imageObjectUrl, setImageObjectUrl] = createSignal(); + + onMount(() => { + if (blob.mimeType.startsWith("image/")) { + const fetchImage = async () => { + const res = await fetch( + `https://${pds()}/xrpc/com.atproto.sync.getBlob?did=${ctx.repo}&cid=${blob.ref.$link}`, + ); + if (!res.ok) throw new Error(res.statusText); + const blobData = await res.blob(); + const url = URL.createObjectURL(blobData); + setImageObjectUrl(url); + }; + fetchImage().catch((err) => console.error("Failed to load image:", err)); + } + }); + + onCleanup(() => { + if (imageObjectUrl()) URL.revokeObjectURL(imageObjectUrl()!); + }); + + return ( +
+ + + + setMediaLoaded(true)} /> - + + + Failed to load video}> + setMediaLoaded(true)} + /> + + + + + - + - - - - - -
- ); +
+
+ ); + }; if (blob.$type === "blob") { return ( diff --git a/src/components/video-player.tsx b/src/components/video-player.tsx index 5366bea..f36f147 100644 --- a/src/components/video-player.tsx +++ b/src/components/video-player.tsx @@ -1,4 +1,4 @@ -import { onMount } from "solid-js"; +import { onCleanup, onMount } from "solid-js"; import { pds } from "./navbar"; export interface VideoPlayerProps { @@ -9,6 +9,7 @@ export interface VideoPlayerProps { const VideoPlayer = (props: VideoPlayerProps) => { let video!: HTMLVideoElement; + let objectUrl: string | undefined; onMount(async () => { // thanks bf <3 @@ -17,8 +18,12 @@ const VideoPlayer = (props: VideoPlayerProps) => { ); if (!res.ok) throw new Error(res.statusText); const blob = await res.blob(); - const url = URL.createObjectURL(blob); - if (video) video.src = url; + objectUrl = URL.createObjectURL(blob); + if (video) video.src = objectUrl; + }); + + onCleanup(() => { + if (objectUrl) URL.revokeObjectURL(objectUrl); }); return (