2
0
mirror of https://github.com/ad1217/PrinterStatus synced 2024-09-21 13:49:04 -04:00

Add card footer with last updated time as string

This commit is contained in:
Adam Goldsmith 2021-11-03 16:01:24 -04:00
parent de43fdd642
commit 007e08d269
2 changed files with 29 additions and 5 deletions

View File

@ -18,8 +18,8 @@
justify-content-center justify-content-center
" "
> >
<div class="col" v-for="({ name, status }, slug) in printers" :key="slug"> <div class="col" v-for="(printer, slug) in printers" :key="slug">
<PrinterCard :slug="slug as string" :name="name" :status="status"> <PrinterCard :slug="slug as string" v-bind="printer" :now="now">
</PrinterCard> </PrinterCard>
</div> </div>
</div> </div>
@ -36,11 +36,15 @@ import PrinterCard from './PrinterCard.vue';
const printers: Ref<{ const printers: Ref<{
[key: string]: { [key: string]: {
name?: string; name?: string;
lastUpdate: Date;
status: octoprint.CurrentOrHistoryPayload | null; status: octoprint.CurrentOrHistoryPayload | null;
}; };
}> = ref({}); }> = ref({});
const hasPrinters = computed(() => Object.keys(printers.value).length > 0); const hasPrinters = computed(() => Object.keys(printers.value).length > 0);
let now: Ref<Date> = ref(new Date());
setInterval(() => (now.value = new Date()), 1000);
let websocket!: WebSocket; let websocket!: WebSocket;
function connectWebsocket() { function connectWebsocket() {
@ -53,9 +57,10 @@ function connectWebsocket() {
console.log(event); console.log(event);
if (!(event.printer in printers.value)) { if (!(event.printer in printers.value)) {
printers.value[event.printer] = { status: null }; printers.value[event.printer] = { status: null, lastUpdate: new Date() };
} }
printers.value[event.printer].name = event.name; printers.value[event.printer].name = event.name;
printers.value[event.printer].lastUpdate = new Date();
if ('init' in event) { if ('init' in event) {
printers.value[event.printer].status = null; printers.value[event.printer].status = null;

View File

@ -2,7 +2,7 @@
<div class="card"> <div class="card">
<h3 class="card-header">{{ name || 'Unknown' }}</h3> <h3 class="card-header">{{ name || 'Unknown' }}</h3>
<img class="card-img webcam" :src="'/webcam/' + slug" /> <img class="card-img webcam" :src="'/webcam/' + slug" />
<div v-if="status"> <div class="card-body" v-if="status">
<div>{{ status.state.text }}</div> <div>{{ status.state.text }}</div>
<div>Job File Name: {{ status.job.file.name || 'None' }}</div> <div>Job File Name: {{ status.job.file.name || 'None' }}</div>
<div v-if="status.progress.completion"> <div v-if="status.progress.completion">
@ -18,21 +18,40 @@
</div> </div>
<div>User: {{ status.job.user || '-' }}</div> <div>User: {{ status.job.user || '-' }}</div>
</div> </div>
<div class="card-footer">Last updated {{ lastUpdateString }}</div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue';
import prettyMilliseconds from 'pretty-ms'; import prettyMilliseconds from 'pretty-ms';
import * as octoprint from '../types/octoprint'; import * as octoprint from '../types/octoprint';
defineProps<{ const props = defineProps<{
slug: string; slug: string;
name?: string; name?: string;
lastUpdate: Date;
now: Date;
status: octoprint.CurrentOrHistoryPayload | null; status: octoprint.CurrentOrHistoryPayload | null;
}>(); }>();
function formatDuration(seconds: number): string { function formatDuration(seconds: number): string {
return prettyMilliseconds(seconds * 1000); return prettyMilliseconds(seconds * 1000);
} }
const lastUpdateString = computed(() => {
if (props.status !== null) {
const elapsed = props.now.getTime() - props.lastUpdate.getTime();
if (elapsed < 10_000) {
return 'seconds ago';
} else if (elapsed < 60_000) {
return 'less than a minute ago';
} else {
return (
prettyMilliseconds(elapsed, { compact: true, verbose: true }) + ' ago'
);
}
}
});
</script> </script>