You've already forked filebrowser
mirror of
https://github.com/filebrowser/filebrowser.git
synced 2025-11-26 14:25:26 +08:00
feat: migrate to vue 3 (#2689)
--------- Co-authored-by: Joep <jcbuhre@gmail.com> Co-authored-by: Omar Hussein <omarmohammad1951@gmail.com> Co-authored-by: Oleg Lobanov <oleg@lobanov.me>
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
<header-bar v-if="error || req.type == null" showMenu showLogo />
|
||||
<header-bar
|
||||
v-if="error || fileStore.req?.type === null"
|
||||
showMenu
|
||||
showLogo
|
||||
/>
|
||||
|
||||
<breadcrumbs base="/files" />
|
||||
<listing />
|
||||
<errors v-if="error" :errorCode="error.status" />
|
||||
<component v-else-if="currentView" :is="currentView"></component>
|
||||
<div v-else-if="currentView !== null">
|
||||
@@ -13,140 +16,151 @@
|
||||
<div class="bounce2"></div>
|
||||
<div class="bounce3"></div>
|
||||
</div>
|
||||
<span>{{ $t("files.loading") }}</span>
|
||||
<span>{{ t("files.loading") }}</span>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
computed,
|
||||
defineAsyncComponent,
|
||||
onBeforeUnmount,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
ref,
|
||||
watch,
|
||||
} from "vue";
|
||||
import { files as api } from "@/api";
|
||||
import { mapState, mapMutations } from "vuex";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useFileStore } from "@/stores/file";
|
||||
import { useLayoutStore } from "@/stores/layout";
|
||||
import { useUploadStore } from "@/stores/upload";
|
||||
|
||||
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";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRoute } from "vue-router";
|
||||
import FileListing from "@/views/files/FileListing.vue";
|
||||
import { StatusError } from "@/api/utils";
|
||||
const Editor = defineAsyncComponent(() => import("@/views/files/Editor.vue"));
|
||||
const Preview = defineAsyncComponent(() => import("@/views/files/Preview.vue"));
|
||||
|
||||
function clean(path) {
|
||||
const layoutStore = useLayoutStore();
|
||||
const fileStore = useFileStore();
|
||||
const uploadStore = useUploadStore();
|
||||
|
||||
const { reload } = storeToRefs(fileStore);
|
||||
const { error: uploadError } = storeToRefs(uploadStore);
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const { t } = useI18n({});
|
||||
|
||||
const clean = (path: string) => {
|
||||
return path.endsWith("/") ? path.slice(0, -1) : path;
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
name: "files",
|
||||
components: {
|
||||
HeaderBar,
|
||||
Breadcrumbs,
|
||||
Errors,
|
||||
Preview,
|
||||
Listing,
|
||||
Editor: () => import("@/views/files/Editor.vue"),
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
error: null,
|
||||
width: window.innerWidth,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["req", "reload", "loading"]),
|
||||
currentView() {
|
||||
if (this.req.type == undefined || this.req.isDir) {
|
||||
return null;
|
||||
} else if (
|
||||
this.req.type === "text" ||
|
||||
this.req.type === "textImmutable"
|
||||
) {
|
||||
return "editor";
|
||||
} else {
|
||||
return "preview";
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.fetchData();
|
||||
},
|
||||
watch: {
|
||||
$route: function (to, from) {
|
||||
if (from.path.endsWith("/")) {
|
||||
if (to.path.endsWith("/")) {
|
||||
window.sessionStorage.setItem("listFrozen", "false");
|
||||
this.fetchData();
|
||||
return;
|
||||
} else {
|
||||
window.sessionStorage.setItem("listFrozen", "true");
|
||||
this.fetchData();
|
||||
return;
|
||||
}
|
||||
} else if (to.path.endsWith("/")) {
|
||||
this.$store.commit("updateRequest", {});
|
||||
this.fetchData();
|
||||
return;
|
||||
} else {
|
||||
this.fetchData();
|
||||
return;
|
||||
}
|
||||
},
|
||||
reload: function (value) {
|
||||
if (value === true) {
|
||||
this.fetchData();
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener("keydown", this.keyEvent);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener("keydown", this.keyEvent);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.$store.state.showShell) {
|
||||
this.$store.commit("toggleShell");
|
||||
const error = ref<StatusError | null>(null);
|
||||
|
||||
const currentView = computed(() => {
|
||||
if (fileStore.req?.type === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (fileStore.req.isDir) {
|
||||
return FileListing;
|
||||
} else if (
|
||||
fileStore.req.type === "text" ||
|
||||
fileStore.req.type === "textImmutable"
|
||||
) {
|
||||
return Editor;
|
||||
} else {
|
||||
return Preview;
|
||||
}
|
||||
});
|
||||
|
||||
// Define hooks
|
||||
onMounted(() => {
|
||||
fetchData();
|
||||
fileStore.isFiles = true;
|
||||
window.addEventListener("keydown", keyEvent);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener("keydown", keyEvent);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
fileStore.isFiles = false;
|
||||
if (layoutStore.showShell) {
|
||||
layoutStore.toggleShell();
|
||||
}
|
||||
fileStore.updateRequest(null);
|
||||
});
|
||||
|
||||
watch(route, (to, from) => {
|
||||
if (from.path.endsWith("/")) {
|
||||
window.sessionStorage.setItem(
|
||||
"listFrozen",
|
||||
(!to.path.endsWith("/")).toString()
|
||||
);
|
||||
} else if (to.path.endsWith("/")) {
|
||||
fileStore.updateRequest(null);
|
||||
}
|
||||
fetchData();
|
||||
});
|
||||
watch(reload, (newValue) => {
|
||||
newValue && fetchData();
|
||||
});
|
||||
watch(uploadError, (newValue) => {
|
||||
newValue && layoutStore.showError();
|
||||
});
|
||||
|
||||
// Define functions
|
||||
|
||||
const fetchData = async () => {
|
||||
// Reset view information.
|
||||
fileStore.reload = false;
|
||||
fileStore.selected = [];
|
||||
fileStore.multiple = false;
|
||||
layoutStore.closeHovers();
|
||||
|
||||
// Set loading to true and reset the error.
|
||||
if (
|
||||
window.sessionStorage.getItem("listFrozen") !== "true" &&
|
||||
window.sessionStorage.getItem("modified") !== "true"
|
||||
) {
|
||||
layoutStore.loading = true;
|
||||
}
|
||||
error.value = null;
|
||||
|
||||
let url = route.path;
|
||||
if (url === "") url = "/";
|
||||
if (url[0] !== "/") url = "/" + url;
|
||||
try {
|
||||
const res = await api.fetch(url);
|
||||
|
||||
if (clean(res.path) !== clean(`/${[...route.params.path].join("/")}`)) {
|
||||
throw new Error("Data Mismatch!");
|
||||
}
|
||||
this.$store.commit("updateRequest", {});
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(["setLoading"]),
|
||||
async fetchData() {
|
||||
// Reset view information.
|
||||
this.$store.commit("setReload", false);
|
||||
this.$store.commit("resetSelected");
|
||||
this.$store.commit("multiple", false);
|
||||
this.$store.commit("closeHovers");
|
||||
|
||||
// Set loading to true and reset the error.
|
||||
if (window.sessionStorage.getItem("listFrozen") !=="true" && window.sessionStorage.getItem("modified") !=="true"){
|
||||
this.setLoading(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.pathMatch}`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$store.commit("updateRequest", res);
|
||||
document.title = `${res.name} - ${document.title}`;
|
||||
} catch (e) {
|
||||
this.error = e;
|
||||
} finally {
|
||||
this.setLoading(false);
|
||||
}
|
||||
},
|
||||
keyEvent(event) {
|
||||
// F1!
|
||||
if (event.keyCode === 112) {
|
||||
event.preventDefault();
|
||||
this.$store.commit("showHover", "help");
|
||||
}
|
||||
},
|
||||
},
|
||||
fileStore.updateRequest(res);
|
||||
document.title = `${res.name} - ${document.title}`;
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
error.value = err;
|
||||
}
|
||||
} finally {
|
||||
layoutStore.loading = false;
|
||||
}
|
||||
};
|
||||
const keyEvent = (event: KeyboardEvent) => {
|
||||
if (event.key === "F1") {
|
||||
event.preventDefault();
|
||||
layoutStore.showHover("help");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user