diff --git a/src/index.ts b/src/index.ts index 24f0676..312bb1c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ import './style.less' +import Preloader from './preloader' import StatusBar from './statusbar' import WM from './wm' @@ -7,16 +8,13 @@ import * as fs from 'fs' declare global { interface Window { + preloader: Preloader statusBar: StatusBar wm: WM fs: typeof fs } } -window.statusBar = new StatusBar() -window.wm = new WM() -window.fs = new (window as any).Filer.FileSystem() - const params = new URLSearchParams(window.location.search) async function enableDebug (): Promise { @@ -28,3 +26,19 @@ async function enableDebug (): Promise { if (params.get('debug') !== null && params.get('debug') !== undefined) { enableDebug().catch(e => console.error(e)) } + +window.preloader = new Preloader() +window.statusBar = new StatusBar() +window.wm = new WM(); + +(async function () { + window.preloader.setPending('filesystem') + window.fs = new (window as any).Filer.FileSystem() + await window.preloader.setDone('filesystem') + + await window.statusBar.init() + await window.wm.init() + + window.preloader.setStatus('') + window.preloader.finish() +})().catch(e => console.error) diff --git a/src/preloader.ts b/src/preloader.ts new file mode 100644 index 0000000..200a246 --- /dev/null +++ b/src/preloader.ts @@ -0,0 +1,39 @@ +import flowIcon from './assets/flow.png' + +class Preloader { + element: HTMLElement + + constructor () { + this.element = document.createElement('preloader') + + this.element.innerHTML = ` + +
+
+ ` + + document.body.appendChild(this.element) + } + + setStatus (value: string): void { + (this.element.querySelector('.status') as HTMLElement).innerText = value + } + + setPending (value: string): void { + (this.element.querySelector('.done') as HTMLElement).innerHTML += `
${value}
` + } + + async setDone (value: string): Promise { + const icon = this.element.querySelector('.done')?.querySelector(`.${value.split(' ').join('-')}`)?.querySelector('.icon') + icon?.classList.remove('bx-minus') + icon?.classList.add('bx-check') + await new Promise(resolve => setTimeout(resolve, 300)) + } + + finish (): void { + this.element.style.opacity = '0' + this.element.style.pointerEvents = 'none' + } +} + +export default Preloader diff --git a/src/statusbar.ts b/src/statusbar.ts index 5111cfc..6f6ed86 100644 --- a/src/statusbar.ts +++ b/src/statusbar.ts @@ -1,31 +1,27 @@ -import * as clock from './modules/clock.ts' -import * as switcher from './modules/switcher.ts' -import * as appView from './modules/appLauncher.ts' -import * as apps from './modules/apps.ts' -import * as weather from './modules/weather.ts' -import * as battery from './modules/battery.ts' import { StatusItem } from './types' class StatusBar { - items: StatusItem[] = [] + pluginList: string[] = [ + './modules/appLauncher.ts', + './modules/apps.ts', + './modules/weather.ts', + './modules/clock.ts', + './modules/switcher.ts', + './modules/battery.ts' + ] + + plugins: StatusItem[] = [] element: HTMLElement constructor () { this.element = document.createElement('toolbar') document.body.appendChild(this.element) - - this.add(appView) - this.add(apps) - this.add(weather) - this.add(clock) - this.add(switcher) - this.add(battery) } add (item: StatusItem): void { - if (this.items.some(x => x.meta.id === item.meta.id)) { + if (this.plugins.some(x => x.meta.id === item.meta.id)) { console.error(`Unable to register tool; ${item.meta.id} is already registered.`) return } @@ -33,11 +29,25 @@ class StatusBar { const element = document.createElement('div') element.setAttribute('data-toolbar-id', item.meta.id) - this.items.push(item) + this.plugins.push(item) this.element.appendChild(element) item.run(element) } + + async init (): Promise { + window.preloader.setPending('plugins') + window.preloader.setStatus('importing default plugins...') + + for (const pluginPath of this.pluginList) { + const plugin = await import(pluginPath) + + window.preloader.setStatus(`importing default plugins\n${pluginPath}`) + this.add(plugin) + } + + await window.preloader.setDone('plugins') + } } export default StatusBar diff --git a/src/style.less b/src/style.less index 9efce8c..1f5a4e3 100644 --- a/src/style.less +++ b/src/style.less @@ -185,3 +185,28 @@ launcher { } } } + +preloader { + position: absolute; + z-index: 999999999999999999; + top: 0; + left: 0; + background: var(--crust); + width: 100vw; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + transition: opacity 1s; + + .status, .done { + text-align: center; + } + + .done div { + display: flex; + align-items: center; + gap: 2px; + } +} \ No newline at end of file diff --git a/src/wm.ts b/src/wm.ts index d7da6a4..0fc83f3 100644 --- a/src/wm.ts +++ b/src/wm.ts @@ -173,9 +173,6 @@ class WM { constructor () { this.windowArea = document.createElement('window-area') - this.launcher = document.createElement('launcher') - - this.init() } getHighestZIndex (): number { @@ -210,7 +207,11 @@ class WM { return this.isLauncherOpen } - private init (): void { + async init (): Promise { + window.preloader.setPending('window manager') + window.preloader.setStatus('creating app launcher...') + this.launcher = document.createElement('launcher') + this.launcher.innerHTML = ` @@ -230,7 +231,10 @@ class WM { this.launcher.style.filter = 'blur(0px)' this.launcher.style.pointerEvents = 'none' + window.preloader.setStatus('adding apps to app launcher...') + for (const pkg in flow.apps) { + window.preloader.setStatus(`adding apps to app launcher\n${flow.apps[pkg].name}`) const app = document.createElement('app') app.onclick = () => { flow.openApp(pkg) @@ -242,6 +246,8 @@ class WM { document.body.appendChild(this.windowArea) document.body.appendChild(this.launcher) + + await window.preloader.setDone('window manager') } } diff --git a/tsconfig.json b/tsconfig.json index 8b317be..a2d9131 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "outDir": "./dist/", "sourceMap": true, "noImplicitAny": true, - "module": "CommonJS", + "module": "ES2022", "target": "ESNext", "jsx": "react", "jsxFactory": "h",