2
0
mirror of https://github.com/ad1217/PrinterStatus synced 2024-11-21 15:03:48 -05:00

Switch to Vite bundler, upgrade to Vue3, and split server into subfolder

This commit is contained in:
Adam Goldsmith 2021-10-11 21:28:12 -04:00
parent 20b4e5ac8b
commit 0b2919abf5
16 changed files with 5607 additions and 14937 deletions

5
.gitignore vendored
View File

@ -1,5 +1,6 @@
/.cache/
/dist/
/node_modules/
node_modules/
/src/*.js
/config.yaml
/server/config.yaml
/.log/

4
index.html Normal file
View File

@ -0,0 +1,4 @@
<body>
<div id="app"></div>
<script type="module" src="/src/index.ts"></script>
</body>

16978
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

26
server/package.json Normal file
View 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"
}
}

View File

@ -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
View File

@ -0,0 +1,9 @@
{
"compilerOptions": {
"target": "es5",
"strict": true,
"module": "commonjs",
"moduleResolution": "node",
"experimentalDecorators": true
}
}

View File

@ -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: {
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() {
function 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) => {
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);
printers.value[event.printer] = null;
} else if ('current' in event) {
this.$set(this.printers, event.printer, event.current);
printers.value[event.printer] = event.current!;
} else if ('history' in event) {
this.$set(this.printers, event.printer, event.history);
printers.value[event.printer] = event.history!;
} else if ('remote_ws_status' in event) {
}
});
this.websocket.addEventListener('close', () => {
websocket.addEventListener('close', () => {
console.log('Lost connection to server reconnecting in 5 sec');
window.setTimeout(this.connectWebsocket, 5000);
window.setTimeout(connectWebsocket, 5000);
});
}
}
connectWebsocket();
</script>
<style>

View File

@ -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 {
function formatDuration(seconds: number): string {
return prettyMilliseconds(seconds * 1000);
}
}
</script>

View File

@ -1,4 +0,0 @@
<body>
<div id="app"></div>
<script src="index.ts"></script>
</body>

View File

@ -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');

View File

@ -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"]
}

18
vite.config.ts Normal file
View 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",
}
}
}
})