Merge branch 'master' of https://github.com/flow-works/flowos-2.0 into parrot-dev
This commit is contained in:
commit
a7b5f61005
13 changed files with 253 additions and 134 deletions
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
# FlowOS Next
|
# FlowOS Next
|
||||||
|
|
||||||
[](https://github.com/standard/standard)
|
<img src="https://cdn.rawgit.com/standard/standard/master/badge.svg" height="50">
|
||||||
|
<a href="https://discord.gg/axUqK8CN2n"><img src="./src/assets/badge.png" height="50"></a><br/>
|
||||||
|
|
||||||
<img src="https://img.shields.io/github/stars/flow-works/flowos-2.0?style=for-the-badge" />
|
<img src="https://img.shields.io/github/stars/flow-works/flowos-2.0?style=for-the-badge" />
|
||||||
<img src="https://img.shields.io/github/issues-pr/flow-works/flowos-2.0?style=for-the-badge" />
|
<img src="https://img.shields.io/github/issues-pr/flow-works/flowos-2.0?style=for-the-badge" />
|
||||||
|
|
|
||||||
38
package-lock.json
generated
38
package-lock.json
generated
|
|
@ -12,11 +12,11 @@
|
||||||
"@ptkdev/logger": "^1.8.0",
|
"@ptkdev/logger": "^1.8.0",
|
||||||
"eruda": "^3.0.1",
|
"eruda": "^3.0.1",
|
||||||
"filer": "^1.4.1",
|
"filer": "^1.4.1",
|
||||||
"prism-code-editor": "^1.2.2",
|
"prism-code-editor": "^2.0.1",
|
||||||
"prismjs": "^1.29.0",
|
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.8.7",
|
||||||
"@types/uuid": "^9.0.5",
|
"@types/uuid": "^9.0.5",
|
||||||
"@types/web": "^0.0.117",
|
"@types/web": "^0.0.117",
|
||||||
"ts-standard": "^12.0.2",
|
"ts-standard": "^12.0.2",
|
||||||
|
|
@ -729,20 +729,18 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.8.4",
|
"version": "20.8.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz",
|
||||||
"integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==",
|
"integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.25.1"
|
"undici-types": "~5.25.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/prismjs": {
|
"node_modules/@types/prismjs": {
|
||||||
"version": "1.26.1",
|
"version": "1.26.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.2.tgz",
|
||||||
"integrity": "sha512-Q7jDsRbzcNHIQje15CS/piKhu6lMLb9jwjxSfEIi4KcFKXW23GoJMkwQiJ8VObyfx+VmUaDcJxXaWN+cTCjVog=="
|
"integrity": "sha512-/r7Cp7iUIk7gts26mHXD66geUC+2Fo26TZYjQK6Nr4LDfi6lmdRmMqM0oPwfiMhUwoBAOFe8GstKi2pf6hZvwA=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/semver": {
|
"node_modules/@types/semver": {
|
||||||
"version": "7.5.3",
|
"version": "7.5.3",
|
||||||
|
|
@ -4768,19 +4766,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prism-code-editor": {
|
"node_modules/prism-code-editor": {
|
||||||
"version": "1.2.2",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/prism-code-editor/-/prism-code-editor-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/prism-code-editor/-/prism-code-editor-2.0.1.tgz",
|
||||||
"integrity": "sha512-jmVlSNCp40BWauhzjv3GGFmXVaZkXcuVa7G/5RWV+iSPAugYfL1gQlOkXxC+E2gd/Z3/wbQIEr5RC1kyoohqlg==",
|
"integrity": "sha512-93APxLnz6ow6TU8Mw2MC16d/Xb4k2FdjfrzIqb1finFPB/X4ejQyngEF1NkHKpggrIvR33QodW638KeN/gXEfA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prismjs": "^1.26.0"
|
"@types/prismjs": "^1.26.2"
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/prismjs": {
|
|
||||||
"version": "1.29.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
|
|
||||||
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/process": {
|
"node_modules/process": {
|
||||||
|
|
@ -5807,9 +5797,7 @@
|
||||||
"version": "5.25.3",
|
"version": "5.25.3",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
|
||||||
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
|
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true,
|
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/universalify": {
|
"node_modules/universalify": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.8.7",
|
||||||
"@types/uuid": "^9.0.5",
|
"@types/uuid": "^9.0.5",
|
||||||
"@types/web": "^0.0.117",
|
"@types/web": "^0.0.117",
|
||||||
"ts-standard": "^12.0.2",
|
"ts-standard": "^12.0.2",
|
||||||
|
|
@ -26,8 +27,7 @@
|
||||||
"@ptkdev/logger": "^1.8.0",
|
"@ptkdev/logger": "^1.8.0",
|
||||||
"eruda": "^3.0.1",
|
"eruda": "^3.0.1",
|
||||||
"filer": "^1.4.1",
|
"filer": "^1.4.1",
|
||||||
"prism-code-editor": "^1.2.2",
|
"prism-code-editor": "^2.0.1",
|
||||||
"prismjs": "^1.29.0",
|
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,11 @@ import icon from '../assets/icons/editor.png'
|
||||||
import { App } from '../types.ts'
|
import { App } from '../types.ts'
|
||||||
|
|
||||||
import { fullEditor } from 'prism-code-editor/setups'
|
import { fullEditor } from 'prism-code-editor/setups'
|
||||||
import Prism from 'prism-code-editor/prism-core'
|
// this will also import markup, clike, javascript, typescript and jsx
|
||||||
import 'prismjs/components/prism-markup.js'
|
import 'prism-code-editor/grammars/tsx'
|
||||||
import 'prismjs/components/prism-clike.js'
|
import 'prism-code-editor/grammars/css-extras'
|
||||||
import 'prismjs/components/prism-javascript.js'
|
import 'prism-code-editor/grammars/markdown'
|
||||||
import 'prismjs/components/prism-typescript.js'
|
import 'prism-code-editor/grammars/python'
|
||||||
import 'prismjs/components/prism-jsx.js'
|
|
||||||
import 'prismjs/components/prism-tsx.js'
|
|
||||||
import 'prism-code-editor/languages'
|
|
||||||
import 'prism-code-editor/prism-markdown'
|
|
||||||
|
|
||||||
import { FlowWindow } from '../wm.ts'
|
import { FlowWindow } from '../wm.ts'
|
||||||
|
|
||||||
|
|
@ -18,6 +14,26 @@ interface EditorConfig {
|
||||||
path: string
|
path: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileLanguageMap: {
|
||||||
|
[key: string]: string
|
||||||
|
} = {
|
||||||
|
c: 'clike',
|
||||||
|
cpp: 'clike',
|
||||||
|
java: 'clike',
|
||||||
|
cs: 'clike',
|
||||||
|
ts: 'typescript',
|
||||||
|
js: 'javascript',
|
||||||
|
mjs: 'javascript',
|
||||||
|
cjs: 'javascript',
|
||||||
|
jsx: 'jsx',
|
||||||
|
tsx: 'tsx',
|
||||||
|
html: 'html',
|
||||||
|
md: 'markdown',
|
||||||
|
css: 'css',
|
||||||
|
xml: 'xml',
|
||||||
|
py: 'python'
|
||||||
|
}
|
||||||
|
|
||||||
export default class EditorApp implements App {
|
export default class EditorApp implements App {
|
||||||
meta = {
|
meta = {
|
||||||
name: 'Editor',
|
name: 'Editor',
|
||||||
|
|
@ -58,7 +74,7 @@ export default class EditorApp implements App {
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor" style="flex:1;"></div>
|
<div class="editor" style="flex:1;display:grid;overflow:scroll;"></div>
|
||||||
<style>
|
<style>
|
||||||
.dropdown {
|
.dropdown {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -127,74 +143,12 @@ export default class EditorApp implements App {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let language
|
const fileExtension = data.path.split('.').pop()?.toLowerCase() as string
|
||||||
|
const language = fileLanguageMap[fileExtension] ?? 'text'
|
||||||
switch (data.path.split('.').at(-1)?.toLowerCase()) {
|
|
||||||
case 'c':
|
|
||||||
case 'cs':
|
|
||||||
case 'cpp':
|
|
||||||
case 'java': {
|
|
||||||
language = 'clike'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'ts': {
|
|
||||||
language = 'typescript'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'js':
|
|
||||||
case 'mjs':
|
|
||||||
case 'cjs': {
|
|
||||||
language = 'javascript'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'jsx': {
|
|
||||||
language = 'jsx'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'tsx': {
|
|
||||||
language = 'tsx'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'html': {
|
|
||||||
language = 'html'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'md': {
|
|
||||||
language = 'md'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'css': {
|
|
||||||
language = 'css'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'xml': {
|
|
||||||
language = 'xml'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'py': {
|
|
||||||
language = 'python'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
language = 'text'
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const value = (await window.fs.promises.readFile(data.path)).toString()
|
const value = (await window.fs.promises.readFile(data.path)).toString()
|
||||||
const editor = fullEditor(
|
const editor = fullEditor(
|
||||||
Prism,
|
win.content.querySelector('.editor') as HTMLElement,
|
||||||
win.content.querySelector('.editor'),
|
|
||||||
{
|
{
|
||||||
language,
|
language,
|
||||||
theme: 'github-dark',
|
theme: 'github-dark',
|
||||||
|
|
@ -203,11 +157,11 @@ export default class EditorApp implements App {
|
||||||
)
|
)
|
||||||
|
|
||||||
const style = document.createElement('style')
|
const style = document.createElement('style')
|
||||||
style.innerHTML = `
|
style.textContent = `
|
||||||
.prism-editor {
|
.prism-code-editor {
|
||||||
border-radius: 10px 10px 0 0;
|
border-radius: 10px 10px 0 0;
|
||||||
caret-color: var(--text);
|
caret-color: var(--text);
|
||||||
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
|
font-weight: 400;
|
||||||
--editor__bg: var(--base);
|
--editor__bg: var(--base);
|
||||||
--widget__border: var(--mantle);
|
--widget__border: var(--mantle);
|
||||||
--widget__bg: var(--crust);
|
--widget__bg: var(--crust);
|
||||||
|
|
@ -225,11 +179,8 @@ export default class EditorApp implements App {
|
||||||
--editor__bg-selection-match: var(--surface-1)40;
|
--editor__bg-selection-match: var(--surface-1)40;
|
||||||
--editor__line-number: #636e7b;
|
--editor__line-number: #636e7b;
|
||||||
--editor__line-number-active: #adbac7;
|
--editor__line-number-active: #adbac7;
|
||||||
--editor__bg-scrollbar: 210, 10%, 35%;
|
|
||||||
--editor__bg-fold: #768390;
|
|
||||||
--bg-guide-indent: var(--surface-0);
|
--bg-guide-indent: var(--surface-0);
|
||||||
color-scheme: dark;
|
overflow: visible;
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
.prism-search * {
|
.prism-search * {
|
||||||
font-family: 'Satoshi', sans-serif;
|
font-family: 'Satoshi', sans-serif;
|
||||||
|
|
@ -237,11 +188,16 @@ export default class EditorApp implements App {
|
||||||
`
|
`
|
||||||
editor.scrollContainer.appendChild(style);
|
editor.scrollContainer.appendChild(style);
|
||||||
(win.content.querySelector('#find') as HTMLElement).onclick = () => {
|
(win.content.querySelector('#find') as HTMLElement).onclick = () => {
|
||||||
editor.extensions.searchWidget.open()
|
editor.extensions.searchWidget?.open()
|
||||||
}
|
}
|
||||||
(win.content.querySelector('#save') as HTMLElement).onclick = async () => {
|
(win.content.querySelector('#save') as HTMLElement).onclick = async () => {
|
||||||
await window.fs.promises.writeFile(data.path, editor.value)
|
await window.fs.promises.writeFile(data.path, editor.value)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
await window.flow.openApp('flow.files')
|
||||||
|
setTimeout(() => {
|
||||||
|
win.close()
|
||||||
|
}, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
return win
|
return win
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import icon from '../assets/icons/info.png'
|
import icon from '../assets/icons/info.png'
|
||||||
|
import badge from '../assets/badge.png'
|
||||||
import { App, PackageJSON } from '../types.ts'
|
import { App, PackageJSON } from '../types.ts'
|
||||||
import { FlowWindow } from '../wm.ts'
|
import { FlowWindow } from '../wm.ts'
|
||||||
|
|
||||||
|
|
@ -34,6 +35,7 @@ export default class SettingsApp implements App {
|
||||||
<p style="margin:0;">v${packageJSON.version}</p>
|
<p style="margin:0;">v${packageJSON.version}</p>
|
||||||
<br/>
|
<br/>
|
||||||
<p>Created by ThinLiquid, 1nspird_, proudparot2, systemless_</p>
|
<p>Created by ThinLiquid, 1nspird_, proudparot2, systemless_</p>
|
||||||
|
<img src="${badge}" height="50"><br/>
|
||||||
<a class="discord" href="https://discord.gg/flowos">Discord</a>
|
<a class="discord" href="https://discord.gg/flowos">Discord</a>
|
||||||
-
|
-
|
||||||
<a class="github" href="https://github.com/Flow-Works/FlowOS-2.0">Github</a>
|
<a class="github" href="https://github.com/Flow-Works/FlowOS-2.0">Github</a>
|
||||||
|
|
|
||||||
|
|
@ -5,26 +5,202 @@ import { FlowWindow } from '../wm.ts'
|
||||||
export default class SettingsApp implements App {
|
export default class SettingsApp implements App {
|
||||||
meta = {
|
meta = {
|
||||||
name: 'Settings',
|
name: 'Settings',
|
||||||
description: 'Modify/customize FlowOS.',
|
|
||||||
pkg: 'flow.settings',
|
pkg: 'flow.settings',
|
||||||
version: '1.0.0',
|
icon: icon,
|
||||||
icon
|
version: '1.0.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configFileLoc = '/.flow/config.json'
|
||||||
|
configFolderLoc = '/.flow/'
|
||||||
|
|
||||||
async open (): Promise<FlowWindow> {
|
async open (): Promise<FlowWindow> {
|
||||||
const win = window.wm.createWindow({
|
const fs = new (window as any).Filer.FileSystem()
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.exists(this.configFolderLoc, function (exists: any) {
|
||||||
|
if (exists === false) {
|
||||||
|
fs.mkdir(this.configFolderLoc, () => {})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e) { alert(e.message) }
|
||||||
|
try {
|
||||||
|
fs.exists(this.configFileLoc, function (exists: any) {
|
||||||
|
if (exists === false) {
|
||||||
|
fs.writeFile(this.configFileLoc, '{"clock-Type":"0", "tab-title": "Flow OS", "favicon-icon": "to-be-replaced", "proxy-type": "uv", "search-engine": "google" }', () => {})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
const win = (window as any).wm.createWindow({
|
||||||
title: this.meta.name,
|
title: this.meta.name,
|
||||||
icon: this.meta.icon,
|
icon: this.meta.icon,
|
||||||
width: 700,
|
width: 700,
|
||||||
height: 300
|
height: 300,
|
||||||
|
canResize: true
|
||||||
})
|
})
|
||||||
|
|
||||||
win.content.style.background = 'var(--base)'
|
|
||||||
win.content.style.padding = '10px'
|
win.content.style.padding = '10px'
|
||||||
win.content.innerHTML = `
|
win.content.innerHTML = `
|
||||||
<h1>Settings</h1>
|
|
||||||
<p>owo2</p>
|
<div id=>
|
||||||
|
|
||||||
|
<h1>Appereance</h1>
|
||||||
|
|
||||||
|
<p>Clock</p>
|
||||||
|
<button class="btn"> 12 Hour Clock </button>
|
||||||
|
<button class="btn"> 24 Hour Clock </button>
|
||||||
|
|
||||||
|
<p>Tab Title</p>
|
||||||
|
<input class="btn" placeholder="Enter Tab Title">
|
||||||
|
<p>Tab Icon</p>
|
||||||
|
<input class="btn" placeholder="Enter Icon URL">
|
||||||
|
<p class="error-text"> </p>
|
||||||
|
|
||||||
|
<h1>Browser Settings</h1>
|
||||||
|
|
||||||
|
<p>Proxy Type</p>
|
||||||
|
<select class="btn">
|
||||||
|
<option value="uv">Ultraviolet</option>
|
||||||
|
<option value="dy">Dynamic</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<p>Search Engine</p>
|
||||||
|
<select class="btn">
|
||||||
|
<option value="google">Google</option>
|
||||||
|
<option value="bing">Bing</option>
|
||||||
|
<option value="yahoo">Yahoo!</option>
|
||||||
|
<option value="duck">DuckDuckGo</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<p>Server</p>
|
||||||
|
<input class="btn" placeholder="Enter Server URL">
|
||||||
|
<p class="error-text"> </p>
|
||||||
|
|
||||||
|
|
||||||
|
<button disabled class="btn save"> Save </button>
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.error-text {
|
||||||
|
font-size:12px;
|
||||||
|
color:red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
background-color:#45475a;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 2px solid #11111b;
|
||||||
|
transition: 0.2s;
|
||||||
|
}
|
||||||
|
.btn:disabled {
|
||||||
|
color:rgba(205, 214, 244, 0.4);
|
||||||
|
transition: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save {
|
||||||
|
float: right;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
`
|
`
|
||||||
|
// Get current data
|
||||||
|
const data = JSON.parse(await fs.promises.readFile(this.configFileLoc))
|
||||||
|
let oldData = JSON.stringify(data)
|
||||||
|
|
||||||
|
// Handle value changes
|
||||||
|
|
||||||
|
win.content.getElementsByClassName('btn')[0].onclick = async () => {
|
||||||
|
data['clock-Type'] = '0'
|
||||||
|
win.content.getElementsByClassName('btn')[0].disabled = true
|
||||||
|
win.content.getElementsByClassName('btn')[1].disabled = false
|
||||||
|
settingsChange()
|
||||||
|
}
|
||||||
|
win.content.getElementsByClassName('btn')[1].onclick = async () => {
|
||||||
|
data['clock-Type'] = '1'
|
||||||
|
win.content.getElementsByClassName('btn')[0].disabled = false
|
||||||
|
win.content.getElementsByClassName('btn')[1].disabled = true
|
||||||
|
settingsChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
win.content.getElementsByClassName('btn')[2].addEventListener('change', () => {
|
||||||
|
data['tab-title'] = win.content.getElementsByClassName('btn')[2].value
|
||||||
|
settingsChange()
|
||||||
|
})
|
||||||
|
|
||||||
|
win.content.getElementsByClassName('btn')[6].addEventListener('change', () => {
|
||||||
|
if (isURL(win.content.getElementsByClassName('btn')[6].value) === true && win.content.getElementsByClassName('btn')[6].value !== '') {
|
||||||
|
data['flow-server'] = win.content.getElementsByClassName('btn')[6].value
|
||||||
|
win.content.getElementsByClassName('error-text')[1].textContent = ''
|
||||||
|
} else {
|
||||||
|
if (win.content.getElementsByClassName('btn')[6].value !== '') {
|
||||||
|
win.content.getElementsByClassName('error-text')[1].textContent = 'Please input a vaild URL'
|
||||||
|
} else {
|
||||||
|
win.content.getElementsByClassName('error-text')[1].textContent = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settingsChange()
|
||||||
|
})
|
||||||
|
|
||||||
|
win.content.getElementsByClassName('btn')[3].addEventListener('change', () => {
|
||||||
|
if (isURL(win.content.getElementsByClassName('btn')[3].value) === true && win.content.getElementsByClassName('btn')[4].value !== '') {
|
||||||
|
data['favicon-url'] = win.content.getElementsByClassName('btn')[3].value
|
||||||
|
win.content.getElementsByClassName('error-text')[0].textContent = ''
|
||||||
|
} else {
|
||||||
|
if (win.content.getElementsByClassName('btn')[4].value !== '') {
|
||||||
|
win.content.getElementsByClassName('error-text')[0].textContent = 'Please input a vaild URL'
|
||||||
|
} else {
|
||||||
|
win.content.getElementsByClassName('error-text')[0].textContent = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settingsChange()
|
||||||
|
})
|
||||||
|
|
||||||
|
win.content.getElementsByClassName('btn')[4].value = data['proxy-type']
|
||||||
|
win.content.getElementsByClassName('btn')[4].addEventListener('change', (event: any) => {
|
||||||
|
data['proxy-type'] = event.target.value
|
||||||
|
settingsChange()
|
||||||
|
})
|
||||||
|
|
||||||
|
win.content.getElementsByClassName('btn')[5].value = data['search-engine']
|
||||||
|
win.content.getElementsByClassName('btn')[5].addEventListener('change', (event: any) => {
|
||||||
|
data['search-engine'] = event.target.value
|
||||||
|
settingsChange()
|
||||||
|
})
|
||||||
|
|
||||||
|
// Handle saving.
|
||||||
|
|
||||||
|
win.content.getElementsByClassName('save')[0].onclick = async () => {
|
||||||
|
await fs.promises.writeFile(this.configFileLoc, JSON.stringify(data))
|
||||||
|
oldData = JSON.stringify(data)
|
||||||
|
settingsChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display unsaved changes / prevent Save button from being clicked twice.
|
||||||
|
|
||||||
|
function settingsChange (): void {
|
||||||
|
if (oldData !== JSON.stringify(data)) {
|
||||||
|
win.setTitle('Settings - Unsaved Changes')
|
||||||
|
win.content.getElementsByClassName('save')[0].disabled = false
|
||||||
|
} else {
|
||||||
|
win.setTitle('Settings')
|
||||||
|
win.content.getElementsByClassName('save')[0].disabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// URL checker
|
||||||
|
|
||||||
|
function isURL (input: string): any {
|
||||||
|
const regex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/
|
||||||
|
return input.match(regex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set values
|
||||||
|
win.content.getElementsByClassName('btn')[0].disabled = true
|
||||||
|
win.content.getElementsByClassName('btn')[1].disabled = false
|
||||||
|
if (data['clock-Type'] === '0') {
|
||||||
|
win.content.getElementsByClassName('btn')[0].disabled = false
|
||||||
|
win.content.getElementsByClassName('btn')[1].disabled = true
|
||||||
|
}
|
||||||
|
|
||||||
return win
|
return win
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
src/assets/badge.png
Normal file
BIN
src/assets/badge.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
5
src/files.d.ts
vendored
5
src/files.d.ts
vendored
|
|
@ -1,5 +0,0 @@
|
||||||
declare module '*.png' {
|
|
||||||
const image: string
|
|
||||||
export = image
|
|
||||||
}
|
|
||||||
declare module '*.json'
|
|
||||||
|
|
@ -12,6 +12,7 @@ export const run = (element: HTMLDivElement): void => {
|
||||||
element.style.alignItems = 'center'
|
element.style.alignItems = 'center'
|
||||||
element.style.gap = '5px'
|
element.style.gap = '5px'
|
||||||
element.style.flex = '1'
|
element.style.flex = '1'
|
||||||
|
|
||||||
window.addEventListener('app_opened', (e: AppOpenedEvent): void => {
|
window.addEventListener('app_opened', (e: AppOpenedEvent): void => {
|
||||||
const appIcon = document.createElement('app')
|
const appIcon = document.createElement('app')
|
||||||
const app = e.detail.app
|
const app = e.detail.app
|
||||||
|
|
@ -19,7 +20,7 @@ export const run = (element: HTMLDivElement): void => {
|
||||||
appIcon.style.background = 'var(--surface-0)'
|
appIcon.style.background = 'var(--surface-0)'
|
||||||
appIcon.style.padding = '5px 7.5px'
|
appIcon.style.padding = '5px 7.5px'
|
||||||
appIcon.style.borderRadius = '5px'
|
appIcon.style.borderRadius = '5px'
|
||||||
appIcon.innerHTML = `<img data-id="${win.id}" src="${app.meta.id as string}"/> ${app.meta.name}`
|
appIcon.innerHTML = `<img data-id="${win.id}" src="${app.meta.icon}"/> ${app.meta.name}`
|
||||||
appIcon.onclick = async () => {
|
appIcon.onclick = async () => {
|
||||||
const win = await e.detail.win
|
const win = await e.detail.win
|
||||||
win.focus()
|
win.focus()
|
||||||
|
|
@ -27,6 +28,7 @@ export const run = (element: HTMLDivElement): void => {
|
||||||
}
|
}
|
||||||
element.appendChild(appIcon)
|
element.appendChild(appIcon)
|
||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener('app_closed', (e: AppClosedEvent): void => {
|
window.addEventListener('app_closed', (e: AppClosedEvent): void => {
|
||||||
const win = e.detail.win
|
const win = e.detail.win
|
||||||
element.querySelector(`img[data-id="${win.id}"]`)?.parentElement?.remove()
|
element.querySelector(`img[data-id="${win.id}"]`)?.parentElement?.remove()
|
||||||
|
|
|
||||||
3
src/prism-code-editor.d.ts
vendored
3
src/prism-code-editor.d.ts
vendored
|
|
@ -1,3 +0,0 @@
|
||||||
declare module 'prism-code-editor';
|
|
||||||
declare module 'prism-code-editor/setups';
|
|
||||||
declare module 'prism-code-editor/prism-core';
|
|
||||||
|
|
@ -44,7 +44,6 @@ export interface FlowWindowConfig {
|
||||||
|
|
||||||
export interface App {
|
export interface App {
|
||||||
meta: {
|
meta: {
|
||||||
id: any
|
|
||||||
name: string
|
name: string
|
||||||
description: string
|
description: string
|
||||||
pkg: string
|
pkg: string
|
||||||
|
|
|
||||||
|
|
@ -88,14 +88,14 @@ export class FlowWindow {
|
||||||
this.focus()
|
this.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.canResize === undefined) config.canResize = true
|
if (config.canResize === undefined || config.canResize === null) config.canResize = true
|
||||||
|
|
||||||
this.element.style.width = `${config.width ?? 300}px`
|
this.element.style.width = `${config.width ?? 300}px`
|
||||||
this.element.style.height = `${config.height ?? 200}px`
|
this.element.style.height = `${config.height ?? 200}px`
|
||||||
|
|
||||||
this.header = document.createElement('window-header')
|
this.header = document.createElement('window-header')
|
||||||
this.header.innerHTML = `<img src="${config.icon}"></img> <div class="title">${config.title}</div><div style="flex:1;"></div><i id="min" class='bx bx-minus'></i><i id="close" class='bx bx-x'></i>`
|
this.header.innerHTML = `<img src="${config.icon}"></img> <div class="title">${config.title}</div><div style="flex:1;"></div><i id="min" class='bx bx-minus'></i><i id="close" class='bx bx-x'></i>`
|
||||||
if (!config.canResize) {
|
if (config.canResize) {
|
||||||
this.header.innerHTML = `<img src="${config.icon}"></img> <div class="title">${config.title}</div><div style="flex:1;"></div><i id="min" class='bx bx-minus'></i><i id="max" class='bx bx-checkbox'></i><i id="close" class='bx bx-x'></i>`
|
this.header.innerHTML = `<img src="${config.icon}"></img> <div class="title">${config.title}</div><div style="flex:1;"></div><i id="min" class='bx bx-minus'></i><i id="max" class='bx bx-checkbox'></i><i id="close" class='bx bx-x'></i>`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ export class FlowWindow {
|
||||||
|
|
||||||
(this.header.querySelector('#min') as HTMLElement).onclick = () => this.toggleMin()
|
(this.header.querySelector('#min') as HTMLElement).onclick = () => this.toggleMin()
|
||||||
|
|
||||||
if (!config.canResize) {
|
if (config.canResize) {
|
||||||
(this.header.querySelector('#max') as HTMLElement).onclick = () => this.toggleMax()
|
(this.header.querySelector('#max') as HTMLElement).onclick = () => this.toggleMax()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,14 @@
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"jsxFactory": "h",
|
"jsxFactory": "h",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "bundler",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"emitDeclarationOnly": true,
|
"emitDeclarationOnly": true,
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
"strictNullChecks": true
|
"strictNullChecks": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"types": ["vite/client", "node"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue