Files
filebrowser/frontend/src/components/Shell.vue
T

129 lines
3.0 KiB
Vue
Raw Normal View History

2019-01-05 16:12:09 +00:00
<template>
2021-03-21 12:51:58 +01:00
<div
@click="focus"
class="shell"
ref="scrollable"
:class="{ ['shell--hidden']: !showShell }"
>
<div v-for="(c, index) in content" :key="index" class="shell__result">
<div class="shell__prompt">
<i class="material-icons">chevron_right</i>
</div>
2019-01-05 16:12:09 +00:00
<pre class="shell__text">{{ c.text }}</pre>
</div>
2021-03-21 12:51:58 +01:00
<div class="shell__result" :class="{ 'shell__result--hidden': !canInput }">
<div class="shell__prompt">
<i class="material-icons">chevron_right</i>
</div>
2019-01-05 16:12:09 +00:00
<pre
tabindex="0"
ref="input"
class="shell__text"
contenteditable="true"
@keydown.prevent.38="historyUp"
@keydown.prevent.40="historyDown"
2021-03-21 12:51:58 +01:00
@keypress.prevent.enter="submit"
/>
2019-01-05 16:12:09 +00:00
</div>
</div>
</template>
<script>
2021-03-21 12:51:58 +01:00
import { mapMutations, mapState, mapGetters } from "vuex";
import { commands } from "@/api";
2019-01-05 16:12:09 +00:00
export default {
2021-03-21 12:51:58 +01:00
name: "shell",
2019-01-05 16:12:09 +00:00
computed: {
2021-03-21 12:51:58 +01:00
...mapState(["user", "showShell"]),
...mapGetters(["isFiles", "isLogged"]),
2019-01-05 16:12:09 +00:00
path: function () {
if (this.isFiles) {
2021-03-21 12:51:58 +01:00
return this.$route.path;
2019-01-05 16:12:09 +00:00
}
2021-03-21 12:51:58 +01:00
return "";
},
2019-01-05 16:12:09 +00:00
},
data: () => ({
content: [],
history: [],
historyPos: 0,
2021-03-21 12:51:58 +01:00
canInput: true,
2019-01-05 16:12:09 +00:00
}),
methods: {
2021-03-21 12:51:58 +01:00
...mapMutations(["toggleShell"]),
2019-01-05 16:12:09 +00:00
scroll: function () {
2021-03-21 12:51:58 +01:00
this.$refs.scrollable.scrollTop = this.$refs.scrollable.scrollHeight;
2019-01-05 16:12:09 +00:00
},
focus: function () {
2021-03-21 12:51:58 +01:00
this.$refs.input.focus();
2019-01-05 16:12:09 +00:00
},
2021-03-21 12:51:58 +01:00
historyUp() {
2019-01-05 16:12:09 +00:00
if (this.historyPos > 0) {
2021-03-21 12:51:58 +01:00
this.$refs.input.innerText = this.history[--this.historyPos];
this.focus();
2019-01-05 16:12:09 +00:00
}
},
2021-03-21 12:51:58 +01:00
historyDown() {
2019-01-05 16:12:09 +00:00
if (this.historyPos >= 0 && this.historyPos < this.history.length - 1) {
2021-03-21 12:51:58 +01:00
this.$refs.input.innerText = this.history[++this.historyPos];
this.focus();
2019-01-05 16:12:09 +00:00
} else {
2021-03-21 12:51:58 +01:00
this.historyPos = this.history.length;
this.$refs.input.innerText = "";
2019-01-05 16:12:09 +00:00
}
},
submit: function (event) {
2021-03-21 12:51:58 +01:00
const cmd = event.target.innerText.trim();
2019-01-05 16:12:09 +00:00
2021-03-21 12:51:58 +01:00
if (cmd === "") {
return;
2019-01-05 16:12:09 +00:00
}
2021-03-21 12:51:58 +01:00
if (cmd === "clear") {
this.content = [];
event.target.innerHTML = "";
return;
2019-01-05 16:12:09 +00:00
}
2021-03-21 12:51:58 +01:00
if (cmd === "exit") {
event.target.innerHTML = "";
this.toggleShell();
return;
2019-01-05 16:12:09 +00:00
}
2021-03-21 12:51:58 +01:00
this.canInput = false;
event.target.innerHTML = "";
2019-01-05 16:12:09 +00:00
let results = {
2021-03-21 12:51:58 +01:00
text: `${cmd}\n\n`,
};
this.history.push(cmd);
this.historyPos = this.history.length;
this.content.push(results);
2019-01-05 16:12:09 +00:00
commands(
this.path,
cmd,
2021-03-21 12:51:58 +01:00
(event) => {
results.text += `${event.data}\n`;
this.scroll();
2019-01-05 16:12:09 +00:00
},
() => {
2023-07-20 23:38:53 +08:00
results.text = results.text
// eslint-disable-next-line no-control-regex
.replace(/\u001b\[[0-9;]+m/g, "") // Filter ANSI color for now
.trimEnd();
2021-03-21 12:51:58 +01:00
this.canInput = true;
this.$refs.input.focus();
this.scroll();
2019-01-05 16:12:09 +00:00
}
2021-03-21 12:51:58 +01:00
);
},
},
};
2019-01-05 16:12:09 +00:00
</script>