This commit is contained in:
RisingGlitch 2023-10-17 17:48:34 -07:00
commit df8209bf2c
12 changed files with 88 additions and 63 deletions

2
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,2 @@
# These are supported funding model platforms
ko_fi: flowworks

View file

@ -13,20 +13,20 @@
[![build](https://github.com/Flow-Works/FlowOS-2.0/actions/workflows/build.yml/badge.svg)](https://github.com/Flow-Works/FlowOS-2.0/actions/workflows/build.yml) [![build](https://github.com/Flow-Works/FlowOS-2.0/actions/workflows/build.yml/badge.svg)](https://github.com/Flow-Works/FlowOS-2.0/actions/workflows/build.yml)
<br> <br>
<i>The future of Flow OS</i> <i>The future of FlowOS</i>
<br> <br>
<a href="https://docs.flow-works.me"><strong>Read the docs »</strong></a> <a href="https://docs.flow-works.me"><strong>Read the docs »</strong></a>
<br> <br>
</div> </div>
## What is Flow OS? ## What is FlowOS?
Flow OS is a web OS proxy made for the Titanium Network 2023 Proxathon. It's extremly customizable with an API to make your own apps, themes, and modules. FlowOS is a web OS proxy made for the Titanium Network 2023 Proxathon. It's extremly customizable with an API to make your own apps, themes, and modules.
## Getting Started ## Getting Started
To run Flow OS on your local machine, you need Node.js 16 or above. To run FlowOS on your local machine, you need Node.js 16 or above.
1. Clone the repository 1. Clone the repository
```bash ```bash
@ -44,7 +44,7 @@ npm run serve
## Made with ## Made with
Flow OS is made with the following software: FlowOS is made with the following software:
* [Filer](https://github.com/filerjs/filer) * [Filer](https://github.com/filerjs/filer)
* [Prism Code Editor](https://github.com/FIameCaster/prism-code-editor) * [Prism Code Editor](https://github.com/FIameCaster/prism-code-editor)
* [Vite](https://vitejs.dev) * [Vite](https://vitejs.dev)

View file

@ -1,12 +1,13 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Flow OS</title> <title>Flow OS</title>
</head> <link rel="shortcut icon" href="./src/assets/flow.png" type="image/png">
<body> </head>
<body>
<script src="https://unpkg.com/filer"></script> <script src="https://unpkg.com/filer"></script>
<script src="./src/index.ts" type="module"></script> <script src="./src/index.ts" type="module"></script>
</body> </body>
</html> </html>

6
package-lock.json generated
View file

@ -10,6 +10,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ptkdev/logger": "^1.8.0", "@ptkdev/logger": "^1.8.0",
"eruda": "^3.0.1",
"filer": "^1.4.1", "filer": "^1.4.1",
"prism-code-editor": "^1.2.2", "prism-code-editor": "^1.2.2",
"prismjs": "^1.29.0", "prismjs": "^1.29.0",
@ -1846,6 +1847,11 @@
"is-arrayish": "^0.2.1" "is-arrayish": "^0.2.1"
} }
}, },
"node_modules/eruda": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/eruda/-/eruda-3.0.1.tgz",
"integrity": "sha512-6q1Xdwga4JTr1mKSW4mzuWSSbmXgqpm/8Wa1QGFGfCWRjC0bCQjbS4u06M1te1moucIS3hBLlbSTPWYH2W0qbQ=="
},
"node_modules/es-abstract": { "node_modules/es-abstract": {
"version": "1.22.2", "version": "1.22.2",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz",

View file

@ -7,7 +7,7 @@
"test": "ts-standard", "test": "ts-standard",
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
"serve": "vite serve" "preview": "vite preview"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
@ -21,6 +21,7 @@
}, },
"dependencies": { "dependencies": {
"@ptkdev/logger": "^1.8.0", "@ptkdev/logger": "^1.8.0",
"eruda": "^3.0.1",
"filer": "^1.4.1", "filer": "^1.4.1",
"prism-code-editor": "^1.2.2", "prism-code-editor": "^1.2.2",
"prismjs": "^1.29.0", "prismjs": "^1.29.0",

View file

@ -35,7 +35,7 @@ export default class EditorApp implements App {
}) })
if (data != null) { if (data != null) {
win.setTitle('Editor - ' + data.path) win.setTitle(`Editor - ${data.path}`)
win.content.style.display = 'flex' win.content.style.display = 'flex'
win.content.style.flexDirection = 'column' win.content.style.flexDirection = 'column'
@ -100,34 +100,30 @@ export default class EditorApp implements App {
const fileBtn = win.content.querySelector('#file-open') const fileBtn = win.content.querySelector('#file-open')
const editBtn = win.content.querySelector('#edit-open') const editBtn = win.content.querySelector('#edit-open')
const toggleDropdown = function (id: string): void { const toggleDropdown = (id: string): void => {
const el = win.content.querySelector(`#${id}`) const el = win.content.querySelector(`#${id}`)
el?.classList.toggle('show') el?.classList.toggle('show')
} }
fileBtn?.addEventListener('click', function (e) { fileBtn?.addEventListener('click', (e) => {
e.stopPropagation() e.stopPropagation()
toggleDropdown('file') toggleDropdown('file')
}) })
editBtn?.addEventListener('click', function (e) { editBtn?.addEventListener('click', (e) => {
e.stopPropagation() e.stopPropagation()
toggleDropdown('edit') toggleDropdown('edit')
}) })
win.content.addEventListener('click', function () { win.content.addEventListener('click', () => {
const file = win.content.querySelector('#file') const file = (win.content.querySelector('#file') as HTMLElement)
const edit = win.content.querySelector('#edit') const edit = (win.content.querySelector('#edit') as HTMLElement)
if (file !== null) {
if (file.classList.contains('show')) { if (file.classList.contains('show')) {
toggleDropdown('file') toggleDropdown('file')
} }
}
if (edit !== null) {
if (edit.classList.contains('show')) { if (edit.classList.contains('show')) {
toggleDropdown('edit') toggleDropdown('edit')
} }
}
}) })
const value = (await window.fs.promises.readFile(data.path)).toString() const value = (await window.fs.promises.readFile(data.path)).toString()

View file

@ -40,22 +40,22 @@ export default class FilesApp implements App {
if (back !== '<i class=\'bx bx-arrow-to-left\'></i>') { if (back !== '<i class=\'bx bx-arrow-to-left\'></i>') {
(win.content.querySelector('.back') as HTMLElement).onclick = async () => { (win.content.querySelector('.back') as HTMLElement).onclick = async () => {
if (dir.split('/')[1] === dir.replace('/', '')) { if (dir.split('/')[1] === dir.replace('/', '')) {
await setDir('/' + dir.split('/')[0]) await setDir(`/${dir.split('/')[0]}`)
} else { } else {
await setDir('/' + dir.split('/')[1]) await setDir(`/${dir.split('/')[1]}`)
} }
} }
} }
(win.content.querySelector('.file') as HTMLElement).onclick = async () => { (win.content.querySelector('.file') as HTMLElement).onclick = async () => {
const title: string = prompt('Enter file name') ?? 'new-file.txt' const title: string = prompt('Enter file name') ?? 'new-file.txt'
await window.fs.promises.open(dir + '/' + title, 'w') await window.fs.promises.open(`${dir}/${title}`, 'w')
await setDir(dir) await setDir(dir)
} }
(win.content.querySelector('.folder') as HTMLElement).onclick = async () => { (win.content.querySelector('.folder') as HTMLElement).onclick = async () => {
const title: string = prompt('Enter folder name') ?? 'new-folder' const title: string = prompt('Enter folder name') ?? 'new-folder'
await window.fs.promises.mkdir(dir + '/' + title) await window.fs.promises.mkdir(`${dir}/${title}`)
await setDir(dir) await setDir(dir)
} }

View file

@ -1,7 +1,7 @@
import './style.less' import './style.less'
import StatusBar from './statusbar.ts' import StatusBar from './statusbar'
import WM from './wm.ts' import WM from './wm'
import * as fs from 'fs' import * as fs from 'fs'
@ -16,3 +16,15 @@ declare global {
window.statusBar = new StatusBar() window.statusBar = new StatusBar()
window.wm = new WM() window.wm = new WM()
window.fs = new (window as any).Filer.FileSystem() window.fs = new (window as any).Filer.FileSystem()
const params = new URLSearchParams(window.location.search)
async function enableDebug (): Promise<void> {
const { default: eruda } = await import('eruda')
eruda.init()
return await Promise.resolve()
}
if (params.get('debug') !== null && params.get('debug') !== undefined) {
enableDebug().catch(e => console.error(e))
}

View file

@ -9,5 +9,5 @@ export const run = (element: HTMLDivElement): void => {
element.style.alignItems = 'center' element.style.alignItems = 'center'
element.style.paddingLeft = '15px' element.style.paddingLeft = '15px'
element.style.paddingRight = '15px' element.style.paddingRight = '15px'
element.innerHTML = '100%' element.innerHTML = '🔋 100%'
} }

View file

@ -27,7 +27,9 @@ class StatusBar {
add (item: StatusItem): void { add (item: StatusItem): void {
if (this.items.some(x => x.meta.id === item.meta.id)) { if (this.items.some(x => x.meta.id === item.meta.id)) {
console.error(`Unable to register tool; ${item.meta.id} is already registered.`) console.error(`Unable to register tool; ${item.meta.id} is already registered.`)
} else { return
}
const element = document.createElement('div') const element = document.createElement('div')
element.setAttribute('data-toolbar-id', item.meta.id) element.setAttribute('data-toolbar-id', item.meta.id)
@ -36,7 +38,6 @@ class StatusBar {
item.run(element) item.run(element)
} }
}
} }
export default StatusBar export default StatusBar

View file

@ -11,7 +11,12 @@
--crust: #11111b; --crust: #11111b;
} }
body, html { .bx-category {
color: #181926;
}
body,
html {
background-color: var(--crust); background-color: var(--crust);
width: 100vw; width: 100vw;
@ -25,7 +30,6 @@ body, html {
overflow: hidden; overflow: hidden;
} }
*::-webkit-scrollbar { *::-webkit-scrollbar {
display: none; display: none;
} }
@ -34,7 +38,7 @@ body, html {
-ms-overflow-style: none; -ms-overflow-style: none;
scrollbar-width: none; scrollbar-width: none;
font-family: 'Satoshi', sans-serif; font-family: "Satoshi", sans-serif;
font-weight: 600; font-weight: 600;
color: var(--text); color: var(--text);
@ -50,12 +54,17 @@ toolbar {
margin: 0 0 0 0; margin: 0 0 0 0;
justify-content: center; justify-content: center;
div[data-toolbar-id="appview"] {
background: rgb(150, 181, 246);
background: linear-gradient(45deg, rgba(150, 181, 246, 1) 0%, rgba(150, 181, 246, 1) 12%, rgba(77, 129, 236, 1) 100%);
color: black;
}
& > div { & > div {
background: var(--base); background: var(--base);
padding: 5px; padding: 5px;
border-radius: 5px; border-radius: 5px;
box-shadow: 0 10px 10px rgba(0, 0, 0, 0.1), 0 0px 10px rgba(0, 0, 0, 0.1); box-shadow: 0 10px 10px rgba(0, 0, 0, 0.1), 0 0px 10px rgba(0, 0, 0, 0.1);
height: 40px!important; height: 40px !important;
display: flex; display: flex;
app { app {
@ -81,7 +90,6 @@ window-area {
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
window { window {
background: var(--base); background: var(--base);
display: flex; display: flex;
@ -91,7 +99,7 @@ window-area {
overflow: hidden; overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.2); border: 1px solid rgba(255, 255, 255, 0.2);
background: var(--crust); background: var(--crust);
transition: .2s opacity, .2s width, .2s height; transition: 0.2s opacity, 0.2s width, 0.2s height;
window-header { window-header {
height: 20px; height: 20px;
@ -129,10 +137,12 @@ launcher {
top: 0; top: 0;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
z-index: 99999999999999999999999; z-index: 99999999999999999999999;
width: 100vw; width: calc(100vw + 20px);
height: calc(100vh + 20px); height: calc(100vh + 20px);
gap: 20px; gap: 20px;
transition: .2s opacity, .2s backdrop-filter; transition: 0.2s opacity, 0.2s backdrop-filter;
margin: 0;
left: 0;
apps { apps {
max-height: 70vh; max-height: 70vh;
@ -167,7 +177,7 @@ launcher {
width: 300px; width: 300px;
max-width: 100vw; max-width: 100vw;
text-align: center; text-align: center;
transition: border .2s; transition: border 0.2s;
&:focus { &:focus {
outline: none; outline: none;

View file

@ -192,11 +192,7 @@ class WM {
const max = Math.max(...indexes) const max = Math.max(...indexes)
if (max === -Infinity) { return max === -Infinity ? 0 : max
return 0
} else {
return max
}
} }
createWindow (config: FlowWindowConfig): FlowWindow { createWindow (config: FlowWindowConfig): FlowWindow {