Files
scrypted/plugins/core/ui/src/components/ConsoleCard.vue
2021-09-15 19:05:42 -07:00

68 lines
1.6 KiB
Vue

<template>
<v-card raised>
<v-toolbar dark color="blue">
Console
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-btn @click="copy" v-on="on" text
><v-icon small> far fa-copy</v-icon>
</v-btn>
</template>
<span>Copy</span>
</v-tooltip>
</v-toolbar>
<div ref="terminal"></div>
</v-card>
</template>
<script>
import { Terminal } from "xterm";
import { FitAddon } from "xterm-addon-fit";
import eio from "engine.io-client";
import { sleep } from "../common/sleep";
export default {
props: ["deviceId"],
socket: null,
buffer: [],
methods: {
reconnect(term) {
this.buffer = [];
const endpointPath = `/endpoint/@scrypted/core`;
const options = {
path: `${endpointPath}/engine.io/console/${this.deviceId}`,
};
const rootLocation = `${window.location.protocol}//${window.location.host}`;
this.socket = eio(rootLocation, options);
this.socket.on("message", (data) => {
this.buffer.push(Buffer.from(data));
term.write(new Uint8Array(data));
});
this.socket.on("close", async () => {
await sleep(1000);
this.reconnect(term);
});
},
copy() {
this.$copyText(Buffer.concat(this.buffer).toString());
},
},
mounted() {
const term = new Terminal({
convertEol: true,
disableStdin: true,
scrollback: 10000,
});
const fitAddon = new FitAddon();
term.loadAddon(fitAddon);
term.open(this.$refs.terminal);
fitAddon.fit();
this.reconnect(term);
},
destroyed() {
this.socket?.close();
},
};
</script>