From 8f32fd58cafe677c07d9ed9fff84f6e255156d37 Mon Sep 17 00:00:00 2001
From: darkuss <darkussdelta@gmail.com>
Date: Sat, 22 Aug 2026 01:58:37 +0200
Subject: holy shit i'm finally done

---
 src/apps/image.tsx | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 src/apps/image.tsx

(limited to 'src/apps/image.tsx')

diff --git a/src/apps/image.tsx b/src/apps/image.tsx
new file mode 100644
index 0000000..12623c3
--- /dev/null
+++ b/src/apps/image.tsx
@@ -0,0 +1,61 @@
+import { effect, Signal, useSignalEffect } from "@preact/signals"
+import { Address } from "$/apps/source";
+import { memo, Ref, useRef } from "preact/compat";
+
+const filenameRegex = /.*\/(.*)$/;
+
+export const Image = memo(function Image({ source, title, contentReady, sizingFinished }: Image.Props) {
+    useSignalEffect(() => {
+        const filename = decodeURIComponent(source.value.link.pathname.match(filenameRegex)?.[1] ?? source.value.link.toString());
+        title.value = `${filename} - picview`;
+    })
+
+    const imgRef: Ref<HTMLImageElement> = useRef(null);
+
+    return <img style={{ "image-rendering": (source.value.pixelated ? "crisp-edges" : undefined) }} src={source.value.link.toString()} ref={img => {
+        imgRef.current = img
+        const id = setInterval(() => {
+            if (img && img.naturalWidth) {
+                clearInterval(id)
+                contentReady.value = true
+                const vw = Math.max(document.documentElement.clientWidth, window.innerWidth)
+                const vh = Math.max(document.documentElement.clientHeight, window.innerHeight)
+
+                const maxImageSize = Math.min(vw, vh) * 0.4;
+                const smallestImageAxis = Math.min(img.naturalHeight, img.naturalWidth);
+                
+                const aspectRatio = img.naturalWidth / img.naturalHeight
+                if (smallestImageAxis > maxImageSize) {
+                    if (img.naturalWidth > img.naturalHeight) {
+                        img.style.height = `${maxImageSize / aspectRatio}px`
+                        img.style.width = `${maxImageSize}px`
+                    } else {
+                        img.style.height = `${maxImageSize}px`
+                        img.style.width = `${maxImageSize * aspectRatio}px`
+                    }
+
+                    effect(() => {
+                        if (sizingFinished.value) {
+                            img!.style.setProperty("height", null)
+                            img!.style.setProperty("width", null)
+                        }
+                    })
+                }
+            }
+        }, 50)
+
+        return () => {
+            clearInterval(id)
+            imgRef.current = null
+        }
+    }}/>
+})
+
+namespace Image {
+    export type Props = {
+        source: Signal<Address>,
+        title: Signal<string | undefined>,
+        contentReady: Signal<boolean>,
+        sizingFinished: Signal<boolean>
+    }
+}
-- 
cgit v1.2.3

