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