summaryrefslogtreecommitdiff
path: root/src/desktop/index.tsx
blob: 25b31e18b3a0cdbcccd20e1e3889b3897892234f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { useRef } from "preact/hooks"
import { Window } from "./window"
import { FILE_REGISTRY } from "./files";
import { Source } from "$/apps/source";
import { App } from "$/apps";
import { createModel, Signal, signal } from "@preact/signals";
import { MutableValue } from "$/util";
import { File } from "./file";
import { StartMenu } from "./start";

export type Task = {
    app: App,
    source: Signal<Source>,
    window: {
        minimized: Signal<boolean>,
        maximized: Signal<boolean>
        width?: string | number;
        height?: string | number;
        position?: {
            x?: string | number;
            y?: string | number;
        },
        z: Signal<number>;
    }
    title: Signal<string | undefined>,
    id: number;
    contentReady: Signal<boolean>,
    sizingFinished: Signal<boolean>
}

const TaskManagerModel = createModel(() => {
    const tasks: Signal<MutableValue<Task[]>> = signal(new MutableValue([]))

    return {
        tasks,
        close(currentTask: Task) {
            tasks.value = tasks.value.deriveNew(self => {
                const idx = self.findIndex(task => {
                    return currentTask === task
                })
                self.splice(idx, 1);
                return self
            })
        },
        focusWindow(currentTask: Task) {
            const t = tasks.value.value;
            const currentTaskZ = currentTask.window.z.value;

            for (const task of t) {
                if (task === currentTask) {
                    task.window.z.value = t.length - 1
                } else if (task.window.z.value > currentTaskZ) {
                    task.window.z.value = task.window.z.value - 1
                }
            }
        },
        add(task: Task) {
            tasks.value = tasks.value.deriveNew(self => {
                self.push(task)
                return self
            })
        }
    }
})
export const taskManager = new TaskManagerModel();

let taskCounter = 0;
export function getTaskId(): number {
    return taskCounter++;
}

export function Desktop() {
    const ref = useRef(null);

    return <div id="desktop" ref={ref}>
        <div class="icon_list">
            { FILE_REGISTRY.map(file => <File file={file} />)}
        </div>
        { taskManager.tasks.value.value.map(task => {
            const App = task.app;
            return <Window
                key={task.id}
                task={task}
                desktop={ref}
                onFocus={taskManager.focusWindow}
                onClose={taskManager.close}
            >
                <App
                    title={task.title}
                    source={task.source}
                    contentReady={task.contentReady}
                    sizingFinished={task.sizingFinished}
                />
            </Window>
        })}
        <StartMenu />
        <img id="netpunk" src="/assets/netpunk.png" />
    </div>
}