OpenDTU-old/webapp/src/views/ConsoleInfoView.vue
2024-07-05 21:57:53 +02:00

168 lines
5.6 KiB
Vue

<template>
<BasePage :title="$t('console.Console')" :isLoading="dataLoading">
<CardElement :text="$t('console.VirtualDebugConsole')" textVariant="text-bg-primary">
<div class="row g-3 align-items-center">
<div class="col">
<div class="form-check form-switch">
<input
class="form-check-input"
type="checkbox"
role="switch"
id="autoScroll"
v-model="isAutoScroll"
/>
<label class="form-check-label" for="autoScroll">
{{ $t('console.EnableAutoScroll') }}
</label>
</div>
</div>
<div class="col text-end">
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary" :onClick="clearConsole">
{{ $t('console.ClearConsole') }}
</button>
<button type="button" class="btn btn-secondary" :onClick="copyConsole">
{{ $t('console.CopyToClipboard') }}
</button>
</div>
</div>
</div>
<textarea id="console" class="form-control" rows="24" v-model="consoleBuffer" readonly></textarea>
</CardElement>
</BasePage>
</template>
<script lang="ts">
import BasePage from '@/components/BasePage.vue';
import CardElement from '@/components/CardElement.vue';
import { authUrl } from '@/utils/authentication';
import { defineComponent } from 'vue';
export default defineComponent({
components: {
BasePage,
CardElement,
},
data() {
return {
socket: {} as WebSocket,
heartInterval: 0,
dataLoading: true,
consoleBuffer: '',
isAutoScroll: true,
endWithNewline: false,
};
},
created() {
this.initSocket();
this.dataLoading = false;
},
unmounted() {
this.closeSocket();
},
watch: {
consoleBuffer() {
if (this.isAutoScroll) {
const textarea = this.$el.querySelector('#console');
setTimeout(() => {
textarea.scrollTop = textarea.scrollHeight;
}, 0);
}
},
},
methods: {
initSocket() {
console.log('Starting connection to WebSocket Server');
const { protocol, host } = location;
const authString = authUrl();
const webSocketUrl = `${protocol === 'https:' ? 'wss' : 'ws'}://${authString}${host}/console`;
this.closeSocket();
this.socket = new WebSocket(webSocketUrl);
this.socket.onmessage = (event) => {
console.log(event);
let outstr = new String(event.data);
let removedNewline = false;
if (outstr.endsWith('\n')) {
outstr = outstr.substring(0, outstr.length - 1);
removedNewline = true;
}
this.consoleBuffer +=
(this.endWithNewline ? this.getOutDate() : '') + outstr.replaceAll('\n', '\n' + this.getOutDate());
this.endWithNewline = removedNewline;
this.heartCheck(); // Reset heartbeat detection
};
this.socket.onopen = function (event) {
console.log(event);
console.log('Successfully connected to the echo websocket server...');
};
// Listen to window events , When the window closes , Take the initiative to disconnect websocket Connect
window.onbeforeunload = () => {
this.closeSocket();
};
},
// Send heartbeat packets regularly * 59s Send a heartbeat
heartCheck() {
this.heartInterval && clearTimeout(this.heartInterval);
this.heartInterval = setInterval(() => {
if (this.socket.readyState === 1) {
// Connection status
this.socket.send('ping');
} else {
this.initSocket(); // Breakpoint reconnection 5 Time
}
}, 5 * 1000);
},
/** To break off websocket Connect */
closeSocket() {
try {
this.socket.close();
} catch {
// continue regardless of error
}
this.heartInterval && clearTimeout(this.heartInterval);
},
getOutDate(): string {
const u = new Date();
return (
('0' + u.getHours()).slice(-2) +
':' +
('0' + u.getMinutes()).slice(-2) +
':' +
('0' + u.getSeconds()).slice(-2) +
'.' +
(u.getMilliseconds() / 1000).toFixed(3).slice(2, 5) +
' > '
);
},
clearConsole() {
this.consoleBuffer = '';
},
copyConsole() {
const input = document.createElement('textarea');
input.innerHTML = this.consoleBuffer;
document.body.appendChild(input);
input.select();
document.execCommand('copy');
document.body.removeChild(input);
},
},
});
</script>
<style>
#console {
background-color: #0c0c0c;
color: #cccccc;
padding: 8px;
font-family: courier new;
font-size: 0.875em;
}
</style>