From 5ac62cc1a4d9a5f50ea26d5bc1afb0fbf95da23c Mon Sep 17 00:00:00 2001 From: darkuss Date: Thu, 13 Aug 2026 05:13:32 +0200 Subject: init --- src/desktop/apps/buttons.tsx | 0 src/desktop/apps/edit.tsx | 13 +++++++ src/desktop/apps/index.tsx | 5 +++ src/desktop/apps/music.tsx | 43 +++++++++++++++++++++++ src/desktop/index.tsx | 43 +++++++++++++++++++++++ src/desktop/window.tsx | 81 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 185 insertions(+) create mode 100644 src/desktop/apps/buttons.tsx create mode 100644 src/desktop/apps/edit.tsx create mode 100644 src/desktop/apps/index.tsx create mode 100644 src/desktop/apps/music.tsx create mode 100644 src/desktop/index.tsx create mode 100644 src/desktop/window.tsx (limited to 'src/desktop') diff --git a/src/desktop/apps/buttons.tsx b/src/desktop/apps/buttons.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/desktop/apps/edit.tsx b/src/desktop/apps/edit.tsx new file mode 100644 index 0000000..00aba45 --- /dev/null +++ b/src/desktop/apps/edit.tsx @@ -0,0 +1,13 @@ +import { ComponentChildren } from "preact" + +export function Edit(props: Edit.Props) { + return +} + +namespace Edit { + export type Props = { + children?: ComponentChildren + } +} diff --git a/src/desktop/apps/index.tsx b/src/desktop/apps/index.tsx new file mode 100644 index 0000000..a2954b6 --- /dev/null +++ b/src/desktop/apps/index.tsx @@ -0,0 +1,5 @@ +import { FunctionalComponent } from "preact"; +import { Edit } from "./edit"; +import { Music } from "./music"; + +export const APP_REGISTRY: Map = new Map(); diff --git a/src/desktop/apps/music.tsx b/src/desktop/apps/music.tsx new file mode 100644 index 0000000..b5646bd --- /dev/null +++ b/src/desktop/apps/music.tsx @@ -0,0 +1,43 @@ +// type Song = { +// name: string, +// url: string, +// length: number, +// +// bc_exclusive: boolean +// } +// +// const SONGS: = [ +// [], +// [], +// [], +// [], +// [], +// [], +// [], +// [], +// [], +// [], +// [] +// ] +// +// function Song() { +// +// } + +import { useState } from "preact/hooks" + +export function Music() { + const [userApproves, setUserApproves] = useState(false); + + if (userApproves) { + return + } else { + return
+
Click here to load player from https://bandcamp.com
+ +
+ } +} + diff --git a/src/desktop/index.tsx b/src/desktop/index.tsx new file mode 100644 index 0000000..021d3a0 --- /dev/null +++ b/src/desktop/index.tsx @@ -0,0 +1,43 @@ +import { useRef } from "preact/hooks" +import { Edit } from "./apps/edit" +import { Window } from "./window" +import { Music } from "./apps/music"; + +export function Desktop() { + const ref = useRef(null); + return
+
+
+
+
+
+
+
+ + + Fine release by Sunnexo 2026 + + Tracklist: + 1. Internet Exploder + 2. Netpunk (feat. Kasane Teto) + 3. Free Download + 4. I am not a Robot + 5. Content + 6. Keygen + 7. Base64 + 8. Readme (feat. Kasane Teto) + 9. Symlink + 10. Memory + + An album about borrowing software forever. + + A clumsy robot forgets about their girlfriend's anniversary, scrambling to find something to do for the date, eventually concluding they should watch a movie. Of course the movie is in high demand, so the tickets have sold out. Ultimately they resort to piracy, and things spiral out of control... + + + + + + + +
+} diff --git a/src/desktop/window.tsx b/src/desktop/window.tsx new file mode 100644 index 0000000..b2deaec --- /dev/null +++ b/src/desktop/window.tsx @@ -0,0 +1,81 @@ +import { ComponentChildren, Ref, RefObject } from "preact"; +import { useCallback, useRef, useState } from "preact/hooks"; + +export function Window(props: Window.Props) { + const windowRef: Ref = useRef(null); + const dragTimeout: Ref> = useRef(null); + + const [x, setX] = useState(props.x ?? 0); + const [y, setY] = useState(props.y ?? 0); + + const initialOffsetX = useRef(0); + const initialOffsetY = useRef(0); + + const updatePosition = useCallback((e: MouseEvent) => { + setX(e.clientX - initialOffsetX.current) + setY(e.clientY - initialOffsetY.current) + }, []) + + const startDrag = useCallback((e: MouseEvent) => { + if (e.button === 0) { + + const BORDER_WIDTH = 1; + console.log(e); + // Naturally, I have to add the border width here, because offset* uses padding-edge for the calculations + initialOffsetX.current = e.offsetX + BORDER_WIDTH + initialOffsetY.current = e.offsetY + BORDER_WIDTH + windowRef.current?.classList.add("dragging") + + if (dragTimeout.current !== null) { + clearTimeout(dragTimeout.current); + dragTimeout.current = null; + } else { + props.desktop.current?.addEventListener("mousemove", updatePosition) + props.desktop.current?.addEventListener("mouseleave", stopDrag) + } + } + }, []); + + const stopDrag = useCallback((e: MouseEvent) => { + if (e.button === 0) { + dragTimeout.current = setTimeout(() => { + dragTimeout.current = null; + windowRef.current?.classList.remove("dragging") + props.desktop.current?.removeEventListener("mousemove", updatePosition) + props.desktop.current?.removeEventListener("mouseleave", stopDrag) + }, 50) // intrdouce a small delay where the user can still drag the window without actually pressing down lmb to prevent accidental drops + } + }, []); + + return
+
+
{props.title}
+
e.stopPropagation()}> + + + +
+
+
+ {props.children} +
+
+} + +namespace Window { + export type Props = { + title: string; + width?: string | number; + height?: string | number; + x?: string | number; + y?: string | number; + desktop: RefObject; + children: ComponentChildren + } +} -- cgit v1.2.3