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>
}
|