mirror of
https://github.com/ad1217/PrinterStatus
synced 2024-11-10 18:45:08 -05:00
Switch to Vite bundler, upgrade to Vue3, and split server into subfolder
This commit is contained in:
parent
20b4e5ac8b
commit
0b2919abf5
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
/.cache/
|
||||
/dist/
|
||||
/node_modules/
|
||||
node_modules/
|
||||
/src/*.js
|
||||
/config.yaml
|
||||
/server/config.yaml
|
||||
/.log/
|
||||
|
4
index.html
Normal file
4
index.html
Normal file
@ -0,0 +1,4 @@
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/index.ts"></script>
|
||||
</body>
|
16942
package-lock.json
generated
16942
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
38
package.json
38
package.json
@ -1,36 +1,20 @@
|
||||
{
|
||||
"name": "printer_status",
|
||||
"version": "0.0.0",
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
||||
"@types/express": "^4.17.8",
|
||||
"@types/express-ws": "^3.0.0",
|
||||
"@types/http-proxy": "^1.17.4",
|
||||
"@types/js-yaml": "^3.12.5",
|
||||
"@types/node": "^14.6.4",
|
||||
"@types/node-fetch": "^2.5.7",
|
||||
"@types/parcel-bundler": "^1.12.1",
|
||||
"@types/ws": "^7.2.6",
|
||||
"@vue/component-compiler-utils": "^3.2.0",
|
||||
"sass": "^1.26.10",
|
||||
"typescript": "^4.0.2",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
"@vitejs/plugin-vue": "^1.9.3",
|
||||
"sass": "^1.42.1",
|
||||
"typescript": "^4.4.3",
|
||||
"vite": "^2.6.4",
|
||||
"vue-tsc": "^0.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"express-ws": "^4.0.0",
|
||||
"http-proxy": "^1.18.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"node-gyp": "^7.1.0",
|
||||
"parcel-bundler": "^1.12.4",
|
||||
"pretty-ms": "^7.0.1",
|
||||
"ts-node": "^9.0.0",
|
||||
"vue": "^2.6.12",
|
||||
"vue-class-component": "^7.2.5",
|
||||
"vue-hot-reload-api": "^2.3.3",
|
||||
"vue-property-decorator": "^9.0.0",
|
||||
"ws": "^7.3.1"
|
||||
"vue": "^3.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "ts-node src/server.ts"
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"serve": "vite preview"
|
||||
}
|
||||
}
|
||||
|
3373
server/package-lock.json
generated
Normal file
3373
server/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
26
server/package.json
Normal file
26
server/package.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.8",
|
||||
"@types/express-ws": "^3.0.0",
|
||||
"@types/http-proxy": "^1.17.4",
|
||||
"@types/js-yaml": "^4.0.3",
|
||||
"@types/node": "^16.10.3",
|
||||
"@types/node-fetch": "^2.5.12",
|
||||
"@types/ws": "^8.2.0",
|
||||
"typescript": "^4.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"express-ws": "^5.0.2",
|
||||
"http-proxy": "^1.18.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"node-fetch": "^2.6.5",
|
||||
"node-gyp": "^8.2.0",
|
||||
"pretty-ms": "^7.0.1",
|
||||
"ts-node": "^10.3.0",
|
||||
"ws": "^8.2.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "ts-node ./server.ts"
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import * as fs from 'fs';
|
||||
import * as url from 'url';
|
||||
import * as path from 'path';
|
||||
|
||||
import * as express from 'express';
|
||||
@ -7,11 +6,10 @@ import fetch from 'node-fetch';
|
||||
import * as httpProxy from 'http-proxy';
|
||||
import * as WebSocket from 'ws';
|
||||
import * as yaml from 'js-yaml';
|
||||
import * as Bundler from 'parcel-bundler';
|
||||
import * as expressWs from 'express-ws';
|
||||
|
||||
import * as messages from './messages';
|
||||
import * as octoprint from './octoprint';
|
||||
import * as messages from '../types/messages';
|
||||
import * as octoprint from '../types/octoprint';
|
||||
|
||||
const PORT = process.env.PORT || 1234;
|
||||
|
||||
@ -58,9 +56,6 @@ app.get('/webcam/:printer', (req, res) => {
|
||||
} else res.status(404).send('Not Found: Printer not known or has no webcam.');
|
||||
});
|
||||
|
||||
let bundler = new Bundler(path.join(__dirname, 'index.html'));
|
||||
app.use(bundler.middleware());
|
||||
|
||||
app.listen(PORT);
|
||||
|
||||
class PrinterStatus {
|
9
server/tsconfig.json
Normal file
9
server/tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"strict": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true
|
||||
}
|
||||
}
|
72
src/App.vue
72
src/App.vue
@ -1,61 +1,59 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="loading" v-show="Object.keys(printers).length === 0">
|
||||
<div v-if="!hasPrinters">
|
||||
<div class="loading-spinner"></div>
|
||||
</div>
|
||||
<PrinterCard
|
||||
v-else
|
||||
v-for="(status, name) in printers"
|
||||
:key="name"
|
||||
:name="name"
|
||||
:name="name as string"
|
||||
:status="status"
|
||||
>
|
||||
</PrinterCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component, Prop } from 'vue-property-decorator';
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, Ref } from 'vue';
|
||||
|
||||
import * as messages from './messages';
|
||||
import * as octoprint from './octoprint';
|
||||
import * as messages from '../types/messages';
|
||||
import * as octoprint from '../types/octoprint';
|
||||
import PrinterCard from './PrinterCard.vue';
|
||||
|
||||
@Component({ components: { PrinterCard } })
|
||||
export default class App extends Vue {
|
||||
websocket!: WebSocket;
|
||||
printers: {
|
||||
[key: string]: octoprint.CurrentOrHistoryPayload | null;
|
||||
} = {};
|
||||
const printers: Ref<{
|
||||
[key: string]: octoprint.CurrentOrHistoryPayload | null;
|
||||
}> = ref({});
|
||||
const hasPrinters = computed(() => Object.keys(printers.value).length > 0);
|
||||
|
||||
mounted() {
|
||||
this.connectWebsocket();
|
||||
}
|
||||
let websocket!: WebSocket;
|
||||
|
||||
connectWebsocket() {
|
||||
let loc = window.location;
|
||||
const ws_uri: string =
|
||||
(loc.protocol === 'https:' ? 'wss://' : 'ws://') + loc.host + '/ws';
|
||||
this.websocket = new WebSocket(ws_uri);
|
||||
this.websocket.addEventListener('message', (ev: MessageEvent) => {
|
||||
const event: messages.ExtendedMessage = JSON.parse(ev.data as string);
|
||||
console.log(event);
|
||||
function connectWebsocket() {
|
||||
let loc = window.location;
|
||||
const ws_uri: string =
|
||||
(loc.protocol === 'https:' ? 'wss://' : 'ws://') + loc.host + '/ws';
|
||||
websocket = new WebSocket(ws_uri);
|
||||
websocket.addEventListener('message', (ev: MessageEvent) => {
|
||||
const event: messages.ExtendedMessage = JSON.parse(ev.data as string);
|
||||
console.log(event);
|
||||
|
||||
if ('init' in event) {
|
||||
this.$set(this.printers, event.printer, null);
|
||||
} else if ('current' in event) {
|
||||
this.$set(this.printers, event.printer, event.current);
|
||||
} else if ('history' in event) {
|
||||
this.$set(this.printers, event.printer, event.history);
|
||||
} else if ('remote_ws_status' in event) {
|
||||
}
|
||||
});
|
||||
if ('init' in event) {
|
||||
printers.value[event.printer] = null;
|
||||
} else if ('current' in event) {
|
||||
printers.value[event.printer] = event.current!;
|
||||
} else if ('history' in event) {
|
||||
printers.value[event.printer] = event.history!;
|
||||
} else if ('remote_ws_status' in event) {
|
||||
}
|
||||
});
|
||||
|
||||
this.websocket.addEventListener('close', () => {
|
||||
console.log('Lost connection to server reconnecting in 5 sec');
|
||||
window.setTimeout(this.connectWebsocket, 5000);
|
||||
});
|
||||
}
|
||||
websocket.addEventListener('close', () => {
|
||||
console.log('Lost connection to server reconnecting in 5 sec');
|
||||
window.setTimeout(connectWebsocket, 5000);
|
||||
});
|
||||
}
|
||||
|
||||
connectWebsocket();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<div class="card-header">{{ name || 'Unknown' }}</div>
|
||||
<img v-if="name" class="webcam" :src="'/webcam/' + name" />
|
||||
<img class="webcam" :src="'/webcam/' + name" />
|
||||
<div v-if="status">
|
||||
<div>{{ status.state.text }}</div>
|
||||
<div>Job File Name: {{ status.job.file.name || 'None' }}</div>
|
||||
@ -21,20 +21,18 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component, Prop } from 'vue-property-decorator';
|
||||
<script setup lang="ts">
|
||||
import prettyMilliseconds from 'pretty-ms';
|
||||
|
||||
import * as octoprint from './octoprint';
|
||||
import * as octoprint from '../types/octoprint';
|
||||
|
||||
@Component
|
||||
export default class PrinterCard extends Vue {
|
||||
@Prop(String) readonly name!: string;
|
||||
@Prop(Object) readonly status?: octoprint.CurrentOrHistoryPayload;
|
||||
defineProps<{
|
||||
name: string;
|
||||
status: octoprint.CurrentOrHistoryPayload | null;
|
||||
}>();
|
||||
|
||||
formatDuration(seconds: number): string {
|
||||
return prettyMilliseconds(seconds * 1000);
|
||||
}
|
||||
function formatDuration(seconds: number): string {
|
||||
return prettyMilliseconds(seconds * 1000);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="index.ts"></script>
|
||||
</body>
|
@ -1,7 +1,6 @@
|
||||
import Vue from 'vue';
|
||||
import * as Vue from 'vue';
|
||||
|
||||
import App from './App';
|
||||
import App from './App.vue';
|
||||
|
||||
let app = new Vue({
|
||||
render: (h) => h(App),
|
||||
}).$mount('#app');
|
||||
const app = Vue.createApp(App)
|
||||
.mount('#app');
|
||||
|
@ -1,8 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"target": "esnext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node"
|
||||
}
|
||||
"jsx": "preserve",
|
||||
"sourceMap": true,
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["esnext", "dom"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||
}
|
||||
|
0
src/messages.d.ts → types/messages.d.ts
vendored
0
src/messages.d.ts → types/messages.d.ts
vendored
18
vite.config.ts
Normal file
18
vite.config.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
server: {
|
||||
proxy: {
|
||||
'/ws': {
|
||||
target: "ws://localhost:1234",
|
||||
ws: true,
|
||||
},
|
||||
"/webcam": {
|
||||
target: "http://localhost:1234",
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue
Block a user