Add kumos.
This commit is contained in:
parent
8a2c269d26
commit
964bd2e808
18 changed files with 427 additions and 23 deletions
29
static/kumos/apps.mjs
Normal file
29
static/kumos/apps.mjs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { Application, Window, promoteWindow, registerApplication, getScreenRoot, getApplications } from "./kernel.mjs";
|
||||
|
||||
const app = new Application('apps', (p) => {
|
||||
const w = new Window();
|
||||
w.setTitle("App list");
|
||||
w.content.style.padding = "1rem";
|
||||
|
||||
const list = document.createElement("ul");
|
||||
getApplications().forEach(app => {
|
||||
const item = document.createElement("li");
|
||||
const link = document.createElement("a");
|
||||
link.innerText = app.name;
|
||||
link.addEventListener('click', () => app.fn());
|
||||
item.appendChild(link);
|
||||
list.appendChild(item);
|
||||
})
|
||||
|
||||
w.content.appendChild(list);
|
||||
|
||||
w.close.addEventListener('click', () => {
|
||||
p.detach();
|
||||
w.destroy();
|
||||
});
|
||||
|
||||
getScreenRoot().appendChild(w.window);
|
||||
promoteWindow(w);
|
||||
})
|
||||
|
||||
registerApplication(app);
|
||||
32
static/kumos/browser.mjs
Normal file
32
static/kumos/browser.mjs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import { Application, Window, promoteWindow, registerApplication, getScreenRoot } from "./kernel.mjs";
|
||||
|
||||
const app = new Application('browser', (p) => {
|
||||
const w = new Window();
|
||||
w.setTitle("Web browser");
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.src = "https://adrianvic.github.io";
|
||||
iframe.style.height = "100%";
|
||||
const searchBar = document.createElement("div");
|
||||
searchBar.style.display = "flex";
|
||||
const search = document.createElement("input");
|
||||
search.style.width = "100%";
|
||||
const searchButton = document.createElement("button");
|
||||
searchBar.appendChild(search);
|
||||
searchBar.appendChild(searchButton);
|
||||
search.type = "text";
|
||||
iframe.addEventListener('load', () => search.value = iframe.src);
|
||||
searchButton.innerText = "go";
|
||||
searchButton.addEventListener('click', () => iframe.src = search.value);
|
||||
w.content.appendChild(searchBar);
|
||||
w.content.appendChild(iframe);
|
||||
|
||||
getScreenRoot().appendChild(w.window);
|
||||
promoteWindow(w);
|
||||
|
||||
w.close.addEventListener('click', () => {
|
||||
p.detach();
|
||||
w.destroy();
|
||||
})
|
||||
})
|
||||
|
||||
registerApplication(app);
|
||||
38
static/kumos/guestbook.mjs
Normal file
38
static/kumos/guestbook.mjs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { Application, Window, promoteWindow, registerApplication, getScreenRoot, getProcList } from "./kernel.mjs";
|
||||
import { notify } from "./shell.mjs";
|
||||
|
||||
function draw(p) {
|
||||
const w = new Window();
|
||||
w.setTitle("Guestbook");
|
||||
w.content.innerHTML = `
|
||||
<script src="https://iframe.chat/scripts/main.min.js"></script>
|
||||
<iframe class="windowContent" src="https://iframe.chat/embed?chat=17048300" id="chattable"></iframe>
|
||||
<script>chattable.initialize({ theme: "moderno" });</script>
|
||||
`
|
||||
|
||||
getScreenRoot().appendChild(w.window);
|
||||
promoteWindow(w);
|
||||
|
||||
w.close.addEventListener('click', () => {
|
||||
p.detach();
|
||||
w.destroy();
|
||||
})
|
||||
}
|
||||
|
||||
function main(p) {
|
||||
let running = false;
|
||||
getProcList().forEach(proc => {
|
||||
if (proc.name == 'guestbook' && proc != p) {
|
||||
notify("Guestbook", "Guestbook is already running!")
|
||||
p.detach();
|
||||
running = true;
|
||||
}
|
||||
})
|
||||
|
||||
if (!running) {
|
||||
draw(p);
|
||||
}
|
||||
}
|
||||
|
||||
const app = new Application('guestbook', main);
|
||||
registerApplication(app);
|
||||
125
static/kumos/kernel.mjs
Normal file
125
static/kumos/kernel.mjs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
const language = "en";
|
||||
const procList = [];
|
||||
|
||||
export class Process {
|
||||
constructor(app) {
|
||||
this.pid = procList.length == 0 ? 0 : procList[procList.length - 1].pid + 1;
|
||||
this.name = app.name;
|
||||
procList.push(this);
|
||||
app.fn(this);
|
||||
}
|
||||
|
||||
detach() {
|
||||
procList.splice(procList.indexOf(this), 1);
|
||||
}
|
||||
}
|
||||
|
||||
export class Application {
|
||||
constructor(name, fn) {
|
||||
this.fn = fn;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
export class Window {
|
||||
constructor() {
|
||||
// Window
|
||||
const w = document.createElement("div");
|
||||
w.classList.add("window");
|
||||
this.window = w;
|
||||
|
||||
// Header
|
||||
const h = document.createElement("div");
|
||||
h.classList.add("windowHeader");
|
||||
this.header = h;
|
||||
|
||||
// Title
|
||||
const title = document.createElement("p");
|
||||
title.classList.add("windowHeaderTitle");
|
||||
this.title = title;
|
||||
|
||||
// Close button
|
||||
const close = document.createElement("button");
|
||||
close.innerText = "close";
|
||||
close.classList.add("windowHeaderButton");
|
||||
close.classList.add("windowHeaderButtonClose");
|
||||
this.close = close;
|
||||
|
||||
// Content
|
||||
const c = document.createElement("div");
|
||||
c.classList.add("windowContent");
|
||||
this.content = c;
|
||||
|
||||
// Building
|
||||
h.appendChild(title);
|
||||
h.appendChild(close);
|
||||
w.appendChild(h);
|
||||
w.appendChild(c);
|
||||
}
|
||||
|
||||
setTitle(title) {
|
||||
this.title.innerText = title;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.window.remove();
|
||||
}
|
||||
}
|
||||
|
||||
export function promoteWindow(window) {
|
||||
const header = window.header;
|
||||
const elmnt = window.window;
|
||||
|
||||
header.style.cursor = 'move';
|
||||
|
||||
header.onmousedown = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
let pos3 = e.clientX;
|
||||
let pos4 = e.clientY;
|
||||
|
||||
const startTop = elmnt.offsetTop;
|
||||
const startLeft = elmnt.offsetLeft;
|
||||
|
||||
document.onmouseup = closeDragElement;
|
||||
document.onmousemove = elementDrag;
|
||||
|
||||
function elementDrag(e) {
|
||||
e.preventDefault();
|
||||
const pos1 = pos3 - e.clientX;
|
||||
const pos2 = pos4 - e.clientY;
|
||||
pos3 = e.clientX;
|
||||
pos4 = e.clientY;
|
||||
|
||||
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
|
||||
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
|
||||
}
|
||||
|
||||
function closeDragElement() {
|
||||
document.onmouseup = null;
|
||||
document.onmousemove = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getScreenRoot() {
|
||||
return document.querySelector('body');
|
||||
}
|
||||
|
||||
const applications = [];
|
||||
|
||||
export function getApplications() {
|
||||
return applications;
|
||||
}
|
||||
|
||||
export function registerApplication(application) {
|
||||
applications.push(application);
|
||||
}
|
||||
|
||||
export function getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
export function getProcList() {
|
||||
return procList;
|
||||
}
|
||||
36
static/kumos/shell.mjs
Normal file
36
static/kumos/shell.mjs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { getScreenRoot, getApplications, Process } from "./kernel.mjs";
|
||||
import { showNotification } from "../scripts/notification.js";
|
||||
|
||||
export function notify(title, text, time) {
|
||||
showNotification(title, text, time);
|
||||
}
|
||||
|
||||
function runApp(name) {
|
||||
let launched = false;
|
||||
getApplications().forEach(app => {
|
||||
if (app.name == name) {
|
||||
new Process(app);
|
||||
launched = true;
|
||||
}
|
||||
})
|
||||
if (!launched) alert("Not found.");
|
||||
}
|
||||
|
||||
function createShell() {
|
||||
const bar = document.createElement('div');
|
||||
bar.classList.add("kumosBar");
|
||||
|
||||
const run = document.createElement('input');
|
||||
const runButton = document.createElement('button');
|
||||
run.type = "text";
|
||||
runButton.innerText = "Run";
|
||||
runButton.id = "kumosBarRunButton"
|
||||
runButton.addEventListener('click', () => runApp(run.value));
|
||||
bar.appendChild(run);
|
||||
bar.appendChild(runButton);
|
||||
|
||||
getScreenRoot().appendChild(bar);
|
||||
}
|
||||
|
||||
createShell();
|
||||
showNotification("KumOS Shell", "Welcome to KumOS, everything is work-in-progress! Try running apps to see available packages.", 10000);
|
||||
34
static/kumos/taskmanager.mjs
Normal file
34
static/kumos/taskmanager.mjs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { Application, Window, promoteWindow, registerApplication, getScreenRoot, getProcList } from "./kernel.mjs";
|
||||
|
||||
const app = new Application('task', (p) => {
|
||||
function update() {
|
||||
w.content.innerHTML = ``;
|
||||
const list = document.createElement("ul");
|
||||
getProcList().forEach(proc => {
|
||||
const item = document.createElement("li");
|
||||
const link = document.createElement("a");
|
||||
link.innerText = `${proc.pid} -> ${proc.name}`;
|
||||
item.appendChild(link);
|
||||
list.appendChild(item);
|
||||
})
|
||||
|
||||
w.content.appendChild(list);
|
||||
}
|
||||
|
||||
const w = new Window();
|
||||
w.setTitle("Task Manager");
|
||||
w.content.style.padding = "1rem";
|
||||
|
||||
const task = setInterval(update, 100);
|
||||
|
||||
w.close.addEventListener('click', () => {
|
||||
clearInterval(task);
|
||||
p.detach();
|
||||
w.destroy();
|
||||
});
|
||||
|
||||
getScreenRoot().appendChild(w.window);
|
||||
promoteWindow(w);
|
||||
})
|
||||
|
||||
registerApplication(app);
|
||||
Loading…
Reference in a new issue