diff --git a/src/components/json.tsx b/src/components/json.tsx
--- a/src/components/json.tsx
+++ b/src/components/json.tsx
@@ -7,6 +7,8 @@ createSignal,
ErrorBoundary,
For,
on,
+ onCleanup,
+ onMount,
Show,
useContext,
} from "solid-js";
@@ -260,47 +262,70 @@ pds() &&
!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
--- 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 @@ }
const VideoPlayer = (props: VideoPlayerProps) => {
let video!: HTMLVideoElement;
+ let objectUrl: string | undefined;
onMount(async () => {
// thanks bf <3
@@ -17,8 +18,12 @@ `https://${pds()}/xrpc/com.atproto.sync.getBlob?did=${props.did}&cid=${props.cid}`,
);
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 (