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/desktop/file.tsx | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 src/desktop/file.tsx

(limited to 'src/desktop/file.tsx')

diff --git a/src/desktop/file.tsx b/src/desktop/file.tsx
new file mode 100644
index 0000000..a3aa01b
--- /dev/null
+++ b/src/desktop/file.tsx
@@ -0,0 +1,62 @@
+import { APP_REGISTRY } from "$/apps";
+import { Ref } from "preact";
+import { useCallback, useRef, useState } from "preact/hooks";
+import { getTaskId, taskManager } from ".";
+import { signal } from "@preact/signals";
+import { SourceTypes, VirtualFile } from "$/apps/source";
+
+export function File({ file }: { file: VirtualFile }) {
+    const [focused, setFocused] = useState(false);
+    const buttonRef: Ref<HTMLButtonElement> = useRef(null);
+    
+    const handleBlur = useCallback((e: PointerEvent) => {
+        if (!buttonRef.current!.contains(e.target! as Node)) {
+            setFocused(false);
+            document.removeEventListener("click", handleBlur)
+        }
+    }, [])
+
+    const handleFocus = useCallback(() => {
+        setFocused(true);
+
+        document.addEventListener("click", handleBlur)
+    }, [])
+
+    const handleDoubleClick = useCallback(() => {
+        let app = APP_REGISTRY[file.type as SourceTypes];
+        if (app === undefined) {
+            console.error(`couldn't find app for file of type "${file.type}"`)
+            return
+        }
+
+        setFocused(false);
+        taskManager.add({
+            app,
+            source: signal(file),
+            window: {
+                minimized: signal(false),
+                maximized: signal(false),
+                height: file.height,
+                width: file.width,
+                z: signal(taskManager.tasks.value.value.length)
+            },
+            title: signal(undefined),
+            id: getTaskId(),
+            contentReady: signal(false),
+            sizingFinished: signal(false)
+        })
+    }, [])
+
+    return <button ref={buttonRef} class={focused ? "focused" : undefined} onClick={handleFocus}  onDblClick={handleDoubleClick}>
+        <div class="icon">
+            <img src={`/assets/${file.type}.png`}/>
+        </div>
+        {/* for some reason firefox can select the name div if i don't add tabindex=-1
+          * as a side effect of doing that, click events don't go to the button 
+          * See:
+          *     https://html.spec.whatwg.org/multipage/interaction.html#click-focusable
+          *     https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
+          */}
+        <div class="name" tabindex={-1} onClick={handleFocus}><div>{file.name}</div></div>
+    </button>
+}
-- 
cgit v1.2.3

