filebrowser/frontend/src/views/Files.vue
2023-08-30 18:06:34 +02:00

152 lines
3.5 KiB
Vue

<template>
<div>
<header-bar v-if="error || req.type == null" showMenu showLogo />
<breadcrumbs base="/files" />
<errors v-if="error" :errorCode="error.status" />
<component v-else-if="currentView" :is="currentView"></component>
<div v-else>
<h2 class="message delayed">
<div class="spinner">
<div class="bounce1"></div>
<div class="bounce2"></div>
<div class="bounce3"></div>
</div>
<span>{{ $t("files.loading") }}</span>
</h2>
</div>
</div>
</template>
<script>
import { defineAsyncComponent } from "vue";
import { files as api } from "@/api";
import { mapState, mapActions, mapWritableState } from "pinia";
import { useFileStore } from "@/stores/file";
import { useLayoutStore } from "@/stores/layout";
import HeaderBar from "@/components/header/HeaderBar.vue";
import Breadcrumbs from "@/components/Breadcrumbs.vue";
import Errors from "@/views/Errors.vue";
import Preview from "@/views/files/Preview.vue";
import Listing from "@/views/files/Listing.vue";
function clean(path) {
return path.endsWith("/") ? path.slice(0, -1) : path;
}
export default {
name: "files",
components: {
HeaderBar,
Breadcrumbs,
Errors,
Preview,
Listing,
Editor: defineAsyncComponent(() => import("@/views/files/Editor.vue")),
},
data: function () {
return {
error: null,
width: window.innerWidth,
};
},
computed: {
...mapWritableState(useFileStore, [
"req",
"reload",
"selected",
"multiple",
"isFiles",
]),
...mapState(useLayoutStore, ["show", "showShell"]),
...mapWritableState(useLayoutStore, ["loading"]),
currentView() {
if (this.req.type == undefined) {
return null;
}
if (this.req.isDir) {
return "listing";
} else if (
this.req.type === "text" ||
this.req.type === "textImmutable"
) {
return "editor";
} else {
return "preview";
}
},
},
created() {
this.fetchData();
},
watch: {
$route: "fetchData",
reload: function (value) {
if (value === true) {
this.fetchData();
}
},
},
mounted() {
this.isFiles = true;
window.addEventListener("keydown", this.keyEvent);
},
beforeUnmount() {
window.removeEventListener("keydown", this.keyEvent);
},
unmounted() {
this.isFiles = false;
if (this.showShell) {
this.toggleShell();
}
this.updateRequest({});
},
methods: {
...mapActions(useLayoutStore, ["toggleShell", "showHover", "closeHovers"]),
...mapActions(useFileStore, ["updateRequest"]),
async fetchData() {
// Reset view information.
this.reload = false;
this.selected = [];
this.multiple = false;
this.closeHovers();
// Set loading to true and reset the error.
this.loading = true;
this.error = null;
let url = this.$route.path;
if (url === "") url = "/";
if (url[0] !== "/") url = "/" + url;
try {
const res = await api.fetch(url);
if (
clean(res.path) !==
clean(`/${[...this.$route.params.path].join("/")}`)
) {
throw new Error("Data Mismatch!");
}
this.updateRequest(res);
document.title = `${res.name} - ${document.title}`;
} catch (e) {
this.error = e;
} finally {
this.loading = false;
}
},
keyEvent(event) {
if (event.key === "F1") {
event.preventDefault();
this.showHover("help");
}
},
},
};
</script>