[🔨] Use standard-ts codestyle
This commit is contained in:
parent
2271b5130e
commit
f935718ece
19 changed files with 3318 additions and 436 deletions
2889
package-lock.json
generated
2889
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -26,6 +26,7 @@
|
||||||
"node-polyfill-webpack-plugin": "^2.0.1",
|
"node-polyfill-webpack-plugin": "^2.0.1",
|
||||||
"source-map-loader": "^4.0.1",
|
"source-map-loader": "^4.0.1",
|
||||||
"style-loader": "^3.3.3",
|
"style-loader": "^3.3.3",
|
||||||
|
"ts-standard": "^12.0.2",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"webpack": "^5.88.2",
|
"webpack": "^5.88.2",
|
||||||
"webpack-cli": "^5.1.4",
|
"webpack-cli": "^5.1.4",
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,38 @@
|
||||||
import icon from '../assets/icons/editor.png';
|
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";
|
import Prism from 'prism-code-editor/prism-core'
|
||||||
|
|
||||||
import "prismjs/components/prism-clike.js";
|
import 'prismjs/components/prism-clike.js'
|
||||||
import "prismjs/components/prism-markup.js";
|
import 'prismjs/components/prism-markup.js'
|
||||||
import "prismjs/components/prism-javascript.js";
|
import 'prismjs/components/prism-javascript.js'
|
||||||
import "prismjs/components/prism-typescript.js";
|
import 'prismjs/components/prism-typescript.js'
|
||||||
import "prismjs/components/prism-css.js";
|
import 'prismjs/components/prism-css.js'
|
||||||
|
import { FlowWindow } from '../wm.ts'
|
||||||
|
|
||||||
interface EditorConfig {
|
interface EditorConfig {
|
||||||
path: string;
|
path: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class EditorApp implements App {
|
export default class EditorApp implements App {
|
||||||
name = 'Editor';
|
name = 'Editor'
|
||||||
pkg = 'flow.editor';
|
pkg = 'flow.editor'
|
||||||
icon = icon;
|
icon = icon
|
||||||
version = '1.0.0';
|
version = '1.0.0'
|
||||||
|
|
||||||
constructor() {}
|
async open (data?: EditorConfig): Promise<FlowWindow> {
|
||||||
|
const { default: fs } = await import('fs')
|
||||||
|
|
||||||
async open(data?: EditorConfig) {
|
const win = (window as any).wm.createWindow({
|
||||||
const { default: fs } = await import('fs');
|
|
||||||
|
|
||||||
const win = window.wm.createWindow({
|
|
||||||
title: this.name,
|
title: this.name,
|
||||||
icon: icon,
|
icon,
|
||||||
width: 500,
|
width: 500,
|
||||||
height: 400
|
height: 400
|
||||||
});
|
})
|
||||||
|
|
||||||
if (data) {
|
if (data != null) {
|
||||||
win.setTitle('Editor - ' + data.path);
|
win.setTitle('Editor - ' + data.path)
|
||||||
|
|
||||||
const value = (await fs.promises.readFile(data.path)).toString()
|
const value = (await fs.promises.readFile(data.path)).toString()
|
||||||
const editor = fullEditor(
|
const editor = fullEditor(
|
||||||
|
|
@ -41,11 +40,11 @@ export default class EditorApp implements App {
|
||||||
win.content,
|
win.content,
|
||||||
{
|
{
|
||||||
language: data.path.split('.').at(-1),
|
language: data.path.split('.').at(-1),
|
||||||
theme: "github-dark",
|
theme: 'github-dark',
|
||||||
value
|
value
|
||||||
},
|
}
|
||||||
);
|
)
|
||||||
const style = document.createElement('style');
|
const style = document.createElement('style')
|
||||||
style.innerHTML = `
|
style.innerHTML = `
|
||||||
.prism-editor {
|
.prism-editor {
|
||||||
caret-color: var(--text);
|
caret-color: var(--text);
|
||||||
|
|
@ -79,7 +78,7 @@ export default class EditorApp implements App {
|
||||||
`
|
`
|
||||||
editor.scrollContainer.appendChild(style)
|
editor.scrollContainer.appendChild(style)
|
||||||
}
|
}
|
||||||
|
|
||||||
return win;
|
return win
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,133 +1,131 @@
|
||||||
import icon from '../assets/icons/files.png';
|
import icon from '../assets/icons/files.png'
|
||||||
import { App } from "../types.ts";
|
import { App } from '../types.ts'
|
||||||
|
|
||||||
import flow from '../flow.ts';
|
import flow from '../flow.ts'
|
||||||
|
import { FlowWindow } from '../wm.ts'
|
||||||
|
|
||||||
export default class FilesApp implements App {
|
export default class FilesApp implements App {
|
||||||
name = 'Files';
|
name = 'Files'
|
||||||
pkg = 'flow.files';
|
pkg = 'flow.files'
|
||||||
icon = icon;
|
icon = icon
|
||||||
version = '1.0.0';
|
version = '1.0.0'
|
||||||
|
|
||||||
constructor() {}
|
async open (): Promise<FlowWindow> {
|
||||||
|
const { default: fs } = await import('fs')
|
||||||
|
|
||||||
async open() {
|
const win = (window as any).wm.createWindow({
|
||||||
const { default: fs } = await import('fs');
|
|
||||||
|
|
||||||
const win = window.wm.createWindow({
|
|
||||||
title: this.name,
|
title: this.name,
|
||||||
icon: icon,
|
icon,
|
||||||
width: 500,
|
width: 500,
|
||||||
height: 400
|
height: 400
|
||||||
});
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fs.mkdir('/home', () => {});
|
await fs.mkdir('/home', () => {})
|
||||||
await fs.mkdir('/home/meow', () => {});
|
await fs.mkdir('/home/meow', () => {})
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
try {
|
try {
|
||||||
await fs.writeFile('/home/owo1.txt', 'sussy', () => {});
|
await fs.writeFile('/home/owo1.txt', 'sussy', () => {})
|
||||||
await fs.writeFile('/home/owo2.html', '<body></body>', () => {});
|
await fs.writeFile('/home/owo2.html', '<body></body>', () => {})
|
||||||
await fs.writeFile('/home/owo.js', 'alert(`hi`)', () => {});
|
await fs.writeFile('/home/owo.js', 'alert(`hi`)', () => {})
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
|
win.content.style.display = 'flex'
|
||||||
|
win.content.style.flexDirection = 'column'
|
||||||
|
|
||||||
win.content.style.display = 'flex';
|
async function setDir (dir: string): Promise<void> {
|
||||||
win.content.style.flexDirection = 'column';
|
|
||||||
|
|
||||||
async function setDir(dir: string) {
|
|
||||||
await fs.readdir(dir, (e, files) => {
|
await fs.readdir(dir, (e, files) => {
|
||||||
const back = dir === '/' ? `<i class='bx bx-arrow-to-left'></i>` : `<i class='back bx bx-left-arrow-alt'></i>`;
|
const back = dir === '/' ? '<i class=\'bx bx-arrow-to-left\'></i>' : '<i class=\'back bx bx-left-arrow-alt\'></i>'
|
||||||
|
|
||||||
win.content.innerHTML = `
|
win.content.innerHTML = `
|
||||||
<div style="padding: 5px;display: flex;align-items: center;">${back}${dir}</div>
|
<div style="padding: 5px;display: flex;align-items: center;">${back}${dir}</div>
|
||||||
<div class="files" style="background: var(--base);flex: 1;border-radius: 10px;display: flex;flex-direction: column;"></div>
|
<div class="files" style="background: var(--base);flex: 1;border-radius: 10px;display: flex;flex-direction: column;"></div>
|
||||||
`;
|
`
|
||||||
|
|
||||||
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 = () => {
|
(win.content.querySelector('.back') as HTMLElement).onclick = async () => {
|
||||||
if (dir.split('/')[1] === dir.replace('/', '')) {
|
if (dir.split('/')[1] === dir.replace('/', '')) {
|
||||||
setDir('/' + dir.split('/')[0])
|
await setDir('/' + dir.split('/')[0])
|
||||||
} else {
|
} else {
|
||||||
setDir('/' + dir.split('/')[1])
|
await setDir('/' + dir.split('/')[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const file in files) {
|
for (const file of files) {
|
||||||
const separator = dir === '/' ? '' : '/';
|
const separator = dir === '/' ? '' : '/'
|
||||||
fs.stat(dir + separator + files[file], (e, fileStat) => {
|
fs.stat(dir + separator + file, (e, fileStat) => {
|
||||||
const element = document.createElement('div');
|
const element = document.createElement('div')
|
||||||
element.setAttribute('style', 'padding: 5px;border-bottom: 1px solid var(--text);display:flex;align-items:center;gap: 5px;');
|
element.setAttribute('style', 'padding: 5px;border-bottom: 1px solid var(--text);display:flex;align-items:center;gap: 5px;')
|
||||||
|
|
||||||
const genIcon = () => {
|
const genIcon = (): string => {
|
||||||
switch (files[file].split('.').at(-1)) {
|
switch (file.split('.').at(-1)) {
|
||||||
case 'js':
|
case 'js':
|
||||||
case 'mjs':
|
case 'mjs':
|
||||||
case 'cjs': {
|
case 'cjs': {
|
||||||
return `<i class='bx bxs-file-js' ></i>`
|
return '<i class=\'bx bxs-file-js\' ></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'html':
|
case 'html':
|
||||||
case 'htm': {
|
case 'htm': {
|
||||||
return `<i class='bx bxs-file-html' ></i>`
|
return '<i class=\'bx bxs-file-html\' ></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'css': {
|
case 'css': {
|
||||||
return `<i class='bx bxs-file-css' ></i>`
|
return '<i class=\'bx bxs-file-css\' ></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'json': {
|
case 'json': {
|
||||||
return `<i class='bx bxs-file-json' ></i>`
|
return '<i class=\'bx bxs-file-json\' ></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'md': {
|
case 'md': {
|
||||||
return `<i class='bx bxs-file-md' ></i>`
|
return '<i class=\'bx bxs-file-md\' ></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'txt':
|
case 'txt':
|
||||||
case 'text': {
|
case 'text': {
|
||||||
return `<i class='bx bxs-file-txt' ></i>`
|
return '<i class=\'bx bxs-file-txt\' ></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'png':
|
case 'png':
|
||||||
case 'apng': {
|
case 'apng': {
|
||||||
return `<i class='bx bxs-file-png' ></i>`
|
return '<i class=\'bx bxs-file-png\' ></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'jpg':
|
case 'jpg':
|
||||||
case 'jpeg': {
|
case 'jpeg': {
|
||||||
return `<i class='bx bxs-file-jpg' ></i>`
|
return '<i class=\'bx bxs-file-jpg\' ></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'gif': {
|
case 'gif': {
|
||||||
return `<i class='bx bxs-file-gif' ></i>`
|
return '<i class=\'bx bxs-file-gif\' ></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
return `<i class='bx bxs-file-blank' ></i>`
|
return '<i class=\'bx bxs-file-blank\' ></i>'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const icon = fileStat.isDirectory() ? `<i class='bx bx-folder'></i>` : genIcon()
|
const icon = fileStat.isDirectory() ? '<i class=\'bx bx-folder\'></i>' : genIcon()
|
||||||
|
|
||||||
element.innerHTML += `${icon} ${files[file]}`;
|
element.innerHTML += `${icon} ${file}`
|
||||||
element.onclick = () => {
|
element.onclick = async () => {
|
||||||
if (fileStat.isDirectory() === true) {
|
if (fileStat.isDirectory()) {
|
||||||
setDir(dir + separator + files[file]);
|
await setDir(dir + separator + file)
|
||||||
} else {
|
} else {
|
||||||
flow.openApp('flow.editor', { path: dir + separator + files[file] })
|
flow.openApp('flow.editor', { path: dir + separator + file })
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
win.content.querySelector('.files').appendChild(element);
|
win.content.querySelector('.files').appendChild(element)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setDir('/')
|
await setDir('/')
|
||||||
|
|
||||||
return win;
|
return win
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,21 @@
|
||||||
import icon from '../assets/icons/music.png';
|
import icon from '../assets/icons/music.png'
|
||||||
import { App } from "../types.ts";
|
import { App } from '../types.ts'
|
||||||
|
import { FlowWindow } from '../wm.ts'
|
||||||
|
|
||||||
export default class MusicApp implements App {
|
export default class MusicApp implements App {
|
||||||
name = 'Music';
|
name = 'Music'
|
||||||
pkg = 'flow.music';
|
pkg = 'flow.music'
|
||||||
icon = icon;
|
icon = icon
|
||||||
version = '1.0.0';
|
version = '1.0.0'
|
||||||
|
|
||||||
constructor() {}
|
async open (): Promise<FlowWindow> {
|
||||||
|
const win = (window as any).wm.createWindow({
|
||||||
async open() {
|
|
||||||
const win = window.wm.createWindow({
|
|
||||||
title: this.name,
|
title: this.name,
|
||||||
icon: icon
|
icon
|
||||||
});
|
})
|
||||||
|
|
||||||
win.content.innerHTML = 'hi';
|
win.content.innerHTML = 'hi'
|
||||||
|
|
||||||
return win;
|
return win
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,27 @@
|
||||||
import icon from '../assets/icons/settings.png';
|
import icon from '../assets/icons/settings.png'
|
||||||
import { App } from "../types.ts";
|
import { App } from '../types.ts'
|
||||||
|
import { FlowWindow } from '../wm.ts'
|
||||||
|
|
||||||
export default class SettingsApp implements App {
|
export default class SettingsApp implements App {
|
||||||
name = 'Settings';
|
name = 'Settings'
|
||||||
pkg = 'flow.settings';
|
pkg = 'flow.settings'
|
||||||
icon = icon;
|
icon = icon
|
||||||
version = '1.0.0';
|
version = '1.0.0'
|
||||||
|
|
||||||
constructor() {}
|
async open (): Promise<FlowWindow> {
|
||||||
|
const win = (window as any).wm.createWindow({
|
||||||
async open() {
|
|
||||||
const win = window.wm.createWindow({
|
|
||||||
title: this.name,
|
title: this.name,
|
||||||
icon: icon,
|
icon,
|
||||||
width: 700,
|
width: 700,
|
||||||
height: 300
|
height: 300
|
||||||
});
|
})
|
||||||
|
|
||||||
win.content.style.padding = '10px';
|
win.content.style.padding = '10px'
|
||||||
win.content.innerHTML = `
|
win.content.innerHTML = `
|
||||||
<h1>Settings</h1>
|
<h1>Settings</h1>
|
||||||
<p>owo2</p>
|
<p>owo2</p>
|
||||||
`;
|
`
|
||||||
|
|
||||||
return win;
|
return win
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
src/files.d.ts
vendored
8
src/files.d.ts
vendored
|
|
@ -1,4 +1,4 @@
|
||||||
declare module "*.png";
|
declare module '*.png';
|
||||||
declare module "*.svg";
|
declare module '*.svg';
|
||||||
declare module "*.jpeg";
|
declare module '*.jpeg';
|
||||||
declare module "*.jpg";
|
declare module '*.jpg';
|
||||||
|
|
|
||||||
32
src/flow.ts
32
src/flow.ts
|
|
@ -1,29 +1,29 @@
|
||||||
import { App } from './types.ts';
|
import { App } from './types.ts'
|
||||||
|
|
||||||
import SettingsApp from './apps/settings.ts';
|
import SettingsApp from './apps/settings.ts'
|
||||||
import FilesApp from './apps/files.ts';
|
import FilesApp from './apps/files.ts'
|
||||||
import MusicApp from './apps/music.ts';
|
import MusicApp from './apps/music.ts'
|
||||||
import EditorApp from './apps/editor.ts';
|
import EditorApp from './apps/editor.ts'
|
||||||
|
|
||||||
interface Flow {
|
interface Flow {
|
||||||
apps: {
|
apps: {
|
||||||
[key: string]: App
|
[key: string]: App
|
||||||
},
|
}
|
||||||
openApp: Function;
|
openApp: Function
|
||||||
}
|
}
|
||||||
|
|
||||||
const flow: Flow = {
|
const flow: Flow = {
|
||||||
apps: {
|
apps: {
|
||||||
"flow.settings": new SettingsApp(),
|
'flow.settings': new SettingsApp(),
|
||||||
"flow.music": new MusicApp(),
|
'flow.music': new MusicApp(),
|
||||||
"flow.files": new FilesApp(),
|
'flow.files': new FilesApp(),
|
||||||
"flow.editor": new EditorApp(),
|
'flow.editor': new EditorApp()
|
||||||
},
|
},
|
||||||
openApp(pkg: string, data: any) {
|
async openApp (pkg: string, data: any) {
|
||||||
const win = this.apps[pkg].open(data);
|
const win = this.apps[pkg].open(data)
|
||||||
const event = new CustomEvent('app_opened', { detail: { app: this.apps[pkg], win } });
|
const event = new CustomEvent('app_opened', { detail: { app: this.apps[pkg], win: await win } })
|
||||||
window.dispatchEvent(event);
|
window.dispatchEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default flow;
|
export default flow
|
||||||
|
|
|
||||||
15
src/index.ts
15
src/index.ts
|
|
@ -1,12 +1,7 @@
|
||||||
import './style.less';
|
import './style.less'
|
||||||
|
|
||||||
import StatusBar from './statusbar.ts';
|
import StatusBar from './statusbar.ts'
|
||||||
import WM from './wm.ts';
|
import WM from './wm.ts'
|
||||||
|
|
||||||
declare global {
|
(window as any).statusBar = new StatusBar();
|
||||||
var wm: WM;
|
(window as any).wm = new WM()
|
||||||
var statusBar: StatusBar;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.statusBar = new StatusBar();
|
|
||||||
window.wm = new WM();
|
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@ export const meta = {
|
||||||
id: 'appview'
|
id: 'appview'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const run = (element: HTMLDivElement) => {
|
export const run = (element: HTMLDivElement): void => {
|
||||||
element.style.display = 'flex';
|
element.style.display = 'flex'
|
||||||
element.style.alignItems = 'center';
|
element.style.alignItems = 'center'
|
||||||
element.style.justifyContent = 'center';
|
element.style.justifyContent = 'center'
|
||||||
element.style.aspectRatio = '1 / 1';
|
element.style.aspectRatio = '1 / 1'
|
||||||
element.innerHTML = `<i class='bx bx-rocket'></i>`;
|
element.innerHTML = '<i class=\'bx bx-rocket\'></i>'
|
||||||
|
|
||||||
element.onclick = () => {
|
element.onclick = () => {
|
||||||
window.wm.toggleLauncher();
|
(window as any).wm.toggleLauncher()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { FlowWindow } from '../wm.ts';
|
import { AppOpenedEvent, AppClosedEvent } from '../types'
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
name: 'Apps',
|
name: 'Apps',
|
||||||
|
|
@ -6,30 +6,28 @@ export const meta = {
|
||||||
id: 'apps'
|
id: 'apps'
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Status {
|
export const run = (element: HTMLDivElement): void => {
|
||||||
win: FlowWindow,
|
element.style.display = 'flex'
|
||||||
appElement: HTMLElement
|
element.style.alignItems = 'center'
|
||||||
}
|
element.style.gap = '10px'
|
||||||
|
element.style.paddingLeft = '15px'
|
||||||
|
element.style.paddingRight = '15px'
|
||||||
|
|
||||||
export const run = (element: HTMLDivElement) => {
|
window.addEventListener('app_opened', (e: AppOpenedEvent): void => {
|
||||||
element.style.display = 'flex';
|
const appIcon = document.createElement('app')
|
||||||
element.style.alignItems = 'center';
|
const app = e.detail.app
|
||||||
element.style.gap = '10px';
|
const win = e.detail.win
|
||||||
element.style.paddingLeft = '15px';
|
appIcon.innerHTML = `<img data-id="${win.id}" src="${app.icon}"/>`
|
||||||
element.style.paddingRight = '15px';
|
appIcon.onclick = async () => {
|
||||||
|
const win = await e.detail.win
|
||||||
window.addEventListener('app_opened', async (e: CustomEvent) => {
|
win.focus()
|
||||||
const app = document.createElement('app');
|
win.toggleMin()
|
||||||
app.innerHTML = `<img data-id="${(await e.detail.win).id}" src="${e.detail.app.icon}"/>`;
|
|
||||||
app.onclick = async () => {
|
|
||||||
const win = await e.detail.win;
|
|
||||||
await win.focus();
|
|
||||||
await win.toggleMin();
|
|
||||||
}
|
}
|
||||||
element.appendChild(app);
|
element.appendChild(appIcon)
|
||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener('app_closed', async (e: CustomEvent) => {
|
window.addEventListener('app_closed', (e: AppClosedEvent): void => {
|
||||||
element.querySelector(`img[data-id="${(await e.detail.win).id}"]`).parentElement.remove();
|
const win = e.detail.win
|
||||||
|
element.querySelector(`img[data-id="${win.id}"]`)?.parentElement?.remove()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ export const meta = {
|
||||||
id: 'clock'
|
id: 'clock'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const run = (element: HTMLDivElement) => {
|
export const run = (element: HTMLDivElement): void => {
|
||||||
element.style.display = 'flex';
|
element.style.display = 'flex'
|
||||||
element.style.alignItems = 'center';
|
element.style.alignItems = 'center'
|
||||||
element.innerText = '9:41 AM\n10/14/2023';
|
element.innerText = '9:41 AM\n10/14/2023'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ export const meta = {
|
||||||
id: 'switcher'
|
id: 'switcher'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const run = (element: HTMLDivElement) => {
|
export const run = (element: HTMLDivElement): void => {
|
||||||
element.style.display = 'flex';
|
element.style.display = 'flex'
|
||||||
element.style.gap = '10px';
|
element.style.gap = '10px'
|
||||||
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 = `<i class='bx bxs-dice-1'></i><i class='bx bx-dice-2'></i><i class='bx bx-dice-3'></i>`;
|
element.innerHTML = '<i class=\'bx bxs-dice-1\'></i><i class=\'bx bx-dice-2\'></i><i class=\'bx bx-dice-3\'></i>'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
src/prism-code-editor.d.ts
vendored
6
src/prism-code-editor.d.ts
vendored
|
|
@ -1,3 +1,3 @@
|
||||||
declare module "prism-code-editor";
|
declare module 'prism-code-editor';
|
||||||
declare module "prism-code-editor/setups";
|
declare module 'prism-code-editor/setups';
|
||||||
declare module "prism-code-editor/prism-core";
|
declare module 'prism-code-editor/prism-core';
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,38 @@
|
||||||
import * as clock from './modules/clock.ts';
|
import * as clock from './modules/clock.ts'
|
||||||
import * as switcher from './modules/switcher.ts';
|
import * as switcher from './modules/switcher.ts'
|
||||||
import * as appView from './modules/appView.ts';
|
import * as appView from './modules/appView.ts'
|
||||||
import * as apps from './modules/apps.ts';
|
import * as apps from './modules/apps.ts'
|
||||||
|
|
||||||
import { StatusItem } from './types';
|
import { StatusItem } from './types'
|
||||||
|
|
||||||
class StatusBar {
|
class StatusBar {
|
||||||
items: StatusItem[] = [];
|
items: StatusItem[] = []
|
||||||
element: HTMLElement;
|
element: HTMLElement
|
||||||
|
|
||||||
constructor() {
|
constructor () {
|
||||||
this.element = document.createElement('toolbar');
|
this.element = document.createElement('toolbar')
|
||||||
|
|
||||||
document.body.appendChild(this.element);
|
document.body.appendChild(this.element)
|
||||||
|
|
||||||
this.add(appView);
|
this.add(appView)
|
||||||
this.add(apps);
|
this.add(apps)
|
||||||
this.add(clock);
|
this.add(clock)
|
||||||
this.add(switcher);
|
this.add(switcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
add(item: StatusItem) {
|
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 {
|
} else {
|
||||||
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)
|
||||||
|
|
||||||
this.items.push(item);
|
this.items.push(item)
|
||||||
this.element.appendChild(element);
|
this.element.appendChild(element)
|
||||||
|
|
||||||
item.run(element);
|
item.run(element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default StatusBar;
|
export default StatusBar
|
||||||
|
|
|
||||||
37
src/types.ts
37
src/types.ts
|
|
@ -1,21 +1,34 @@
|
||||||
import { FlowWindow } from "./wm";
|
import { FlowWindow } from './wm'
|
||||||
|
|
||||||
export interface StatusItem {
|
export interface StatusItem {
|
||||||
meta: {
|
meta: {
|
||||||
name: string;
|
name: string
|
||||||
description: string;
|
description: string
|
||||||
id: string;
|
id: string
|
||||||
},
|
}
|
||||||
run: Function;
|
run: Function
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface App {
|
export interface App {
|
||||||
name: string;
|
name: string
|
||||||
pkg: string;
|
pkg: string
|
||||||
|
|
||||||
version: string;
|
version: string
|
||||||
|
|
||||||
icon: string;
|
icon: string
|
||||||
|
|
||||||
open(data: any): Promise<FlowWindow>;
|
open: (data: any) => Promise<FlowWindow>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AppOpenedEvent extends CustomEvent {
|
||||||
|
detail: {
|
||||||
|
app: App
|
||||||
|
win: FlowWindow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AppClosedEvent extends CustomEvent {
|
||||||
|
detail: {
|
||||||
|
win: FlowWindow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
312
src/wm.ts
312
src/wm.ts
|
|
@ -1,270 +1,262 @@
|
||||||
import flow from "./flow.ts";
|
import flow from './flow.ts'
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid'
|
||||||
|
|
||||||
interface FlowWindowConfig {
|
interface FlowWindowConfig {
|
||||||
title: string;
|
title: string
|
||||||
icon: string;
|
icon: string
|
||||||
|
|
||||||
width?: number;
|
width?: number
|
||||||
height?: number;
|
height?: number
|
||||||
|
|
||||||
minWidth?: number;
|
minWidth?: number
|
||||||
minHeight?: number;
|
minHeight?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
let focus = true;
|
function dragElement (element: HTMLElement, container: HTMLElement): void {
|
||||||
|
let posX = 0; let posY = 0
|
||||||
|
|
||||||
window.onfocus = () => focus = true;
|
element.querySelector('window-header')?.addEventListener('mousedown', dragMouseDown)
|
||||||
window.onblur = () => focus = false;
|
|
||||||
|
|
||||||
function dragElement(element: HTMLElement, container: HTMLElement) {
|
function dragMouseDown (e: MouseEvent): void {
|
||||||
var posX = 0, posY = 0;
|
e.preventDefault()
|
||||||
|
closeAll()
|
||||||
|
|
||||||
element.querySelector('window-header').addEventListener('mousedown', dragMouseDown);
|
posX = e.clientX
|
||||||
|
posY = e.clientY
|
||||||
|
|
||||||
function dragMouseDown(e: MouseEvent) {
|
document.onmouseup = closeDragElement
|
||||||
e.preventDefault();
|
document.onmousemove = elementDrag
|
||||||
closeAll();
|
|
||||||
|
|
||||||
posX = e.clientX;
|
|
||||||
posY = e.clientY;
|
|
||||||
|
|
||||||
document.onmouseup = closeDragElement;
|
|
||||||
document.onmousemove = elementDrag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function elementDrag(e: MouseEvent) {
|
function elementDrag (e: MouseEvent): void {
|
||||||
e.preventDefault();
|
e.preventDefault()
|
||||||
|
|
||||||
// Calculate the distance the mouse has moved
|
const dx = e.clientX - posX
|
||||||
const dx = e.clientX - posX;
|
const dy = e.clientY - posY
|
||||||
const dy = e.clientY - posY;
|
|
||||||
|
const newTop = element.offsetTop + dy
|
||||||
// Calculate the new position for the element
|
const newLeft = element.offsetLeft + dx
|
||||||
const newTop = element.offsetTop + dy;
|
|
||||||
const newLeft = element.offsetLeft + dx;
|
const containerWidth = container.offsetWidth
|
||||||
|
const containerHeight = container.offsetHeight
|
||||||
// Get the container's dimensions
|
|
||||||
const containerWidth = container.offsetWidth;
|
|
||||||
const containerHeight = container.offsetHeight;
|
|
||||||
|
|
||||||
// Ensure the element stays within the container boundaries
|
|
||||||
if (newTop >= 0 && newTop + element.offsetHeight <= containerHeight) {
|
if (newTop >= 0 && newTop + element.offsetHeight <= containerHeight) {
|
||||||
element.style.top = newTop + "px";
|
element.style.top = `${newTop}px`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newLeft >= 0 && newLeft + element.offsetWidth <= containerWidth) {
|
if (newLeft >= 0 && newLeft + element.offsetWidth <= containerWidth) {
|
||||||
element.style.left = newLeft + "px";
|
element.style.left = `${newLeft}px`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the last mouse position
|
posX = e.clientX
|
||||||
posX = e.clientX;
|
posY = e.clientY
|
||||||
posY = e.clientY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeDragElement() {
|
function closeDragElement (): void {
|
||||||
document.onmouseup = null;
|
document.onmouseup = null
|
||||||
document.onmousemove = null;
|
document.onmousemove = null
|
||||||
container.onmouseleave = null;
|
container.onmouseleave = null
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeAll () {
|
function closeAll (): void {
|
||||||
closeDragElement();
|
closeDragElement()
|
||||||
container.onmouseenter = null;
|
container.onmouseenter = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FlowWindow {
|
export class FlowWindow {
|
||||||
element: HTMLElement;
|
element: HTMLElement
|
||||||
|
|
||||||
private header: HTMLElement;
|
private readonly header: HTMLElement
|
||||||
content: HTMLElement;
|
content: HTMLElement
|
||||||
|
|
||||||
maximized: boolean;
|
maximized: boolean
|
||||||
minimized: boolean;
|
minimized: boolean
|
||||||
|
|
||||||
width: number;
|
width: number
|
||||||
height: number;
|
height: number
|
||||||
|
|
||||||
isMinimized = false;
|
isMinimized = false
|
||||||
isMaximized = false;
|
isMaximized = false
|
||||||
|
|
||||||
wm: WM;
|
wm: WM
|
||||||
|
|
||||||
id = uuid();
|
id = uuid()
|
||||||
|
|
||||||
config: FlowWindowConfig;
|
config: FlowWindowConfig
|
||||||
|
|
||||||
constructor(wm: WM, config: FlowWindowConfig) {
|
constructor (wm: WM, config: FlowWindowConfig) {
|
||||||
this.wm = wm;
|
this.wm = wm
|
||||||
this.config = config;
|
this.config = config
|
||||||
|
|
||||||
this.element = document.createElement('window');
|
this.element = document.createElement('window')
|
||||||
|
|
||||||
this.element.style.zIndex = (wm.getHighestZIndex() + 1).toString();
|
this.element.style.zIndex = (wm.getHighestZIndex() + 1).toString()
|
||||||
this.element.style.position = 'absolute';
|
this.element.style.position = 'absolute'
|
||||||
this.focus();
|
this.focus()
|
||||||
|
|
||||||
this.element.onmousedown = () => {
|
this.element.onmousedown = () => {
|
||||||
this.focus()
|
this.focus()
|
||||||
};
|
}
|
||||||
|
|
||||||
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="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>`;
|
||||||
(this.header.querySelector('#close') as HTMLElement).onclick = () => {
|
(this.header.querySelector('#close') as HTMLElement).onclick = () => {
|
||||||
this.close();
|
this.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
(this.header.querySelector('#min') as HTMLElement).onclick = () => this.toggleMin();
|
(this.header.querySelector('#min') as HTMLElement).onclick = () => this.toggleMin();
|
||||||
(this.header.querySelector('#max') as HTMLElement).onclick = () => this.toggleMax();
|
(this.header.querySelector('#max') as HTMLElement).onclick = () => this.toggleMax()
|
||||||
|
|
||||||
this.content = document.createElement('window-content');
|
this.content = document.createElement('window-content')
|
||||||
|
|
||||||
this.element.appendChild(this.header);
|
|
||||||
this.element.appendChild(this.content);
|
|
||||||
|
|
||||||
dragElement(this.element, document.querySelector('window-area'));
|
this.element.appendChild(this.header)
|
||||||
|
this.element.appendChild(this.content)
|
||||||
|
|
||||||
|
dragElement(this.element, (document.querySelector('window-area') as HTMLElement))
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleMin() {
|
toggleMin (): boolean {
|
||||||
if (this.isMinimized) {
|
if (this.isMinimized) {
|
||||||
this.element.style.pointerEvents = null;
|
this.element.style.pointerEvents = 'all'
|
||||||
this.element.style.opacity = '1';
|
this.element.style.opacity = '1'
|
||||||
} else {
|
} else {
|
||||||
this.element.style.pointerEvents = 'none';
|
this.element.style.pointerEvents = 'none'
|
||||||
this.element.style.opacity = '0';
|
this.element.style.opacity = '0'
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isMinimized = !this.isMinimized;
|
this.isMinimized = !this.isMinimized
|
||||||
|
return this.isMinimized
|
||||||
}
|
}
|
||||||
|
|
||||||
private prevTop: string;
|
private prevTop: string
|
||||||
private prevLeft: string;
|
private prevLeft: string
|
||||||
private prevWidth: string;
|
private prevWidth: string
|
||||||
private prevHeight: string;
|
private prevHeight: string
|
||||||
toggleMax() {
|
toggleMax (): boolean {
|
||||||
if (this.isMaximized) {
|
if (this.isMaximized) {
|
||||||
this.element.style.width = this.prevWidth;
|
this.element.style.width = this.prevWidth
|
||||||
this.element.style.height = this.prevHeight;
|
this.element.style.height = this.prevHeight
|
||||||
this.element.style.top = this.prevTop;
|
this.element.style.top = this.prevTop
|
||||||
this.element.style.left = this.prevLeft;
|
this.element.style.left = this.prevLeft
|
||||||
} else {
|
} else {
|
||||||
this.prevTop = this.element.style.top;
|
this.prevTop = this.element.style.top
|
||||||
this.prevLeft = this.element.style.left;
|
this.prevLeft = this.element.style.left
|
||||||
this.prevWidth = this.element.style.width;
|
this.prevWidth = this.element.style.width
|
||||||
this.prevHeight = this.element.style.height;
|
this.prevHeight = this.element.style.height
|
||||||
|
|
||||||
this.element.style.top = '0';
|
this.element.style.top = '0'
|
||||||
this.element.style.left = '0';
|
this.element.style.left = '0'
|
||||||
this.element.style.width = 'calc(100% - 2px)';
|
this.element.style.width = 'calc(100% - 2px)'
|
||||||
this.element.style.height = 'calc(100% - 3px)';
|
this.element.style.height = 'calc(100% - 3px)'
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isMaximized = !this.isMaximized;
|
this.isMaximized = !this.isMaximized
|
||||||
|
return this.isMaximized
|
||||||
}
|
}
|
||||||
|
|
||||||
focus() {
|
focus (): void {
|
||||||
if (this.element.style.zIndex !== this.wm.getHighestZIndex().toString()) {
|
if (this.element.style.zIndex !== this.wm.getHighestZIndex().toString()) {
|
||||||
this.element.style.zIndex = (this.wm.getHighestZIndex() + 1).toString();
|
this.element.style.zIndex = (this.wm.getHighestZIndex() + 1).toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close (): void {
|
||||||
this.element.remove();
|
this.element.remove()
|
||||||
const event = new CustomEvent('app_closed', { detail: { win: this } });
|
const event = new CustomEvent('app_closed', { detail: { win: this } })
|
||||||
window.dispatchEvent(event);
|
window.dispatchEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
setTitle(title: string) {
|
setTitle (title: string): void {
|
||||||
(this.header.querySelector('.title') as HTMLElement).innerText = title;
|
(this.header.querySelector('.title') as HTMLElement).innerText = title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WM {
|
class WM {
|
||||||
launcherOpen = false;
|
launcherOpen = false
|
||||||
area: HTMLElement;
|
area: HTMLElement
|
||||||
launcher: HTMLElement;
|
launcher: HTMLElement
|
||||||
windows: FlowWindow[] = [];
|
windows: FlowWindow[] = []
|
||||||
|
|
||||||
constructor() {
|
constructor () {
|
||||||
this.area = document.createElement('window-area');
|
this.area = document.createElement('window-area')
|
||||||
this.launcher = document.createElement('launcher');
|
this.launcher = document.createElement('launcher')
|
||||||
|
|
||||||
this.init();
|
this.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
getHighestZIndex() {
|
getHighestZIndex (): number {
|
||||||
const indexes = this.windows.map((win: FlowWindow) => {
|
const indexes = this.windows.map((win: FlowWindow) => {
|
||||||
if (win.element.style.zIndex === '') return;
|
return parseInt(win.element.style.zIndex)
|
||||||
return parseInt(win.element.style.zIndex);
|
})
|
||||||
}).filter(x => x !== undefined);
|
|
||||||
|
|
||||||
const max = Math.max(...indexes);
|
const max = Math.max(...indexes)
|
||||||
|
|
||||||
if (max === -Infinity) {
|
if (max === -Infinity) {
|
||||||
return 0;
|
return 0
|
||||||
} else {
|
} else {
|
||||||
return max;
|
return max
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createWindow(config: FlowWindowConfig): FlowWindow {
|
createWindow (config: FlowWindowConfig): FlowWindow {
|
||||||
const win = new FlowWindow(this, config);
|
const win = new FlowWindow(this, config)
|
||||||
this.windows.push(win);
|
this.windows.push(win)
|
||||||
this.area.appendChild(win.element);
|
this.area.appendChild(win.element)
|
||||||
return win;
|
return win
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleLauncher() {
|
toggleLauncher (): boolean {
|
||||||
if (this.launcherOpen === true) {
|
if (this.launcherOpen) {
|
||||||
this.launcher.style.opacity = '0';
|
this.launcher.style.opacity = '0'
|
||||||
this.launcher.style.backdropFilter = 'blur(0px)';
|
this.launcher.style.backdropFilter = 'blur(0px)'
|
||||||
this.launcher.style.pointerEvents = 'none';
|
this.launcher.style.pointerEvents = 'none'
|
||||||
} else {
|
} else {
|
||||||
this.launcher.style.opacity = '1';
|
this.launcher.style.opacity = '1'
|
||||||
this.launcher.style.backdropFilter = 'blur(20px)';
|
this.launcher.style.backdropFilter = 'blur(20px)'
|
||||||
this.launcher.style.pointerEvents = null;
|
this.launcher.style.pointerEvents = 'all'
|
||||||
}
|
}
|
||||||
|
|
||||||
this.launcherOpen = !this.launcherOpen;
|
this.launcherOpen = !this.launcherOpen
|
||||||
|
return this.launcherOpen
|
||||||
}
|
}
|
||||||
|
|
||||||
private async init() {
|
private init (): void {
|
||||||
this.launcher.innerHTML = `
|
this.launcher.innerHTML = `
|
||||||
<input placeholder="Search"/>
|
<input placeholder="Search"/>
|
||||||
<apps></apps>
|
<apps></apps>
|
||||||
`;
|
`
|
||||||
|
|
||||||
this.launcher.onclick = (e) => {
|
this.launcher.onclick = (e) => {
|
||||||
if(e.target !== e.currentTarget) return;
|
if (e.target !== e.currentTarget) return
|
||||||
this.toggleLauncher();
|
this.toggleLauncher()
|
||||||
}
|
}
|
||||||
|
|
||||||
(this.launcher.querySelector('apps') as HTMLElement).onclick = (e) => {
|
(this.launcher.querySelector('apps') as HTMLElement).onclick = (e) => {
|
||||||
if(e.target !== e.currentTarget) return;
|
if (e.target !== e.currentTarget) return
|
||||||
this.toggleLauncher();
|
this.toggleLauncher()
|
||||||
}
|
}
|
||||||
|
|
||||||
this.launcher.style.opacity = '0';
|
this.launcher.style.opacity = '0'
|
||||||
this.launcher.style.filter = 'blur(0px)';
|
this.launcher.style.filter = 'blur(0px)'
|
||||||
this.launcher.style.pointerEvents = 'none';
|
this.launcher.style.pointerEvents = 'none'
|
||||||
|
|
||||||
for (const pkg in flow.apps) {
|
for (const pkg in flow.apps) {
|
||||||
const app = document.createElement('app');
|
const app = document.createElement('app')
|
||||||
app.onclick = () => {
|
app.onclick = () => {
|
||||||
flow.openApp(pkg);
|
flow.openApp(pkg)
|
||||||
this.toggleLauncher();
|
this.toggleLauncher()
|
||||||
}
|
}
|
||||||
app.innerHTML = `<img src="${flow.apps[pkg].icon}"><div>${flow.apps[pkg].name}</div>`
|
app.innerHTML = `<img src="${flow.apps[pkg].icon}"><div>${flow.apps[pkg].name}</div>`
|
||||||
this.launcher.querySelector('apps').appendChild(app);
|
this.launcher.querySelector('apps')?.appendChild(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
document.body.appendChild(this.area);
|
document.body.appendChild(this.area)
|
||||||
document.body.appendChild(this.launcher);
|
document.body.appendChild(this.launcher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default WM;
|
export default WM
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"emitDeclarationOnly": true,
|
"emitDeclarationOnly": true,
|
||||||
"allowImportingTsExtensions": true
|
"allowImportingTsExtensions": true,
|
||||||
|
"strictNullChecks": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||||
const { FilerWebpackPlugin } = require('filer/webpack');
|
const { FilerWebpackPlugin } = require('filer/webpack')
|
||||||
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
|
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack')
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
flow: './src/index.ts',
|
flow: './src/index.ts'
|
||||||
},
|
},
|
||||||
devtool: 'inline-source-map',
|
devtool: 'inline-source-map',
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
|
|
@ -16,24 +16,24 @@ module.exports = {
|
||||||
{
|
{
|
||||||
test: /\.less$/i,
|
test: /\.less$/i,
|
||||||
use: [
|
use: [
|
||||||
"style-loader",
|
'style-loader',
|
||||||
"css-loader",
|
'css-loader',
|
||||||
"less-loader",
|
'less-loader'
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.css$/i,
|
test: /\.css$/i,
|
||||||
use: [
|
use: [
|
||||||
"style-loader",
|
'style-loader',
|
||||||
"css-loader",
|
'css-loader'
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(png|jpe?g|gif)$/i,
|
test: /\.(png|jpe?g|gif)$/i,
|
||||||
loader: 'file-loader',
|
loader: 'file-loader',
|
||||||
options: {
|
options: {
|
||||||
outputPath: 'images',
|
outputPath: 'images'
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.ts$/,
|
test: /\.ts$/,
|
||||||
|
|
@ -42,33 +42,33 @@ module.exports = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.js$/,
|
test: /\.js$/,
|
||||||
use: ["source-map-loader"],
|
use: ['source-map-loader'],
|
||||||
enforce: "pre"
|
enforce: 'pre'
|
||||||
},
|
}
|
||||||
|
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.tsx', '.ts', '.js'],
|
extensions: ['.tsx', '.ts', '.js']
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: '[name].bundle.js',
|
filename: '[name].bundle.js',
|
||||||
path: path.resolve(__dirname, 'dist'),
|
path: path.resolve(__dirname, 'dist'),
|
||||||
clean: true,
|
clean: true
|
||||||
},
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
static: {
|
static: {
|
||||||
directory: path.join(__dirname, 'dist'),
|
directory: path.join(__dirname, 'dist')
|
||||||
},
|
},
|
||||||
compress: true,
|
compress: true,
|
||||||
port: 9000,
|
port: 9000
|
||||||
},
|
},
|
||||||
plugins: [new HtmlWebpackPlugin(), new FilerWebpackPlugin(),
|
plugins: [new HtmlWebpackPlugin(), new FilerWebpackPlugin(),
|
||||||
new NodePolyfillPlugin({
|
new NodePolyfillPlugin({
|
||||||
excludeAliases: ['console']
|
excludeAliases: ['console']
|
||||||
}),
|
}),
|
||||||
new webpack.optimize.MinChunkSizePlugin({
|
new webpack.optimize.MinChunkSizePlugin({
|
||||||
minChunkSize: 50000,
|
minChunkSize: 50000
|
||||||
}),
|
}),
|
||||||
new webpack.optimize.SplitChunksPlugin({
|
new webpack.optimize.SplitChunksPlugin({
|
||||||
minSize: 45000,
|
minSize: 45000,
|
||||||
|
|
@ -87,15 +87,15 @@ module.exports = {
|
||||||
cacheGroups: {
|
cacheGroups: {
|
||||||
commons: {
|
commons: {
|
||||||
test: /[\\/]node_modules[\\/]/,
|
test: /[\\/]node_modules[\\/]/,
|
||||||
name: "vendor",
|
name: 'vendor',
|
||||||
chunks: "initial",
|
chunks: 'initial',
|
||||||
reuseExistingChunk: true,
|
reuseExistingChunk: true
|
||||||
},
|
},
|
||||||
default: {
|
default: {
|
||||||
minChunks: 2,
|
minChunks: 2,
|
||||||
reuseExistingChunk: true,
|
reuseExistingChunk: true
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue