summaryrefslogtreecommitdiff
path: root/src/apps/image.tsx
diff options
context:
space:
mode:
authordarkuss <darkussdelta@gmail.com>2026-08-22 01:58:37 +0200
committerdarkuss <darkussdelta@gmail.com>2026-08-22 01:58:37 +0200
commit8f32fd58cafe677c07d9ed9fff84f6e255156d37 (patch)
treea5de06ffb2c0a8b878c8a563ec8cee692efc98ac /src/apps/image.tsx
parent5ac62cc1a4d9a5f50ea26d5bc1afb0fbf95da23c (diff)
holy shit i'm finally done
Diffstat (limited to 'src/apps/image.tsx')
-rw-r--r--src/apps/image.tsx61
1 files changed, 61 insertions, 0 deletions
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>
+ }
+}