diff --git a/frontend/src/views/files/Editor.vue b/frontend/src/views/files/Editor.vue
index 3dbabc74..6ee0db48 100644
--- a/frontend/src/views/files/Editor.vue
+++ b/frontend/src/views/files/Editor.vue
@@ -4,6 +4,25 @@
{{ req.name }}
+
+
+ preview
+ preview
+
+
+
@@ -33,6 +67,7 @@ import "ace-builds/webpack-resolver";
import HeaderBar from "@/components/header/HeaderBar";
import Action from "@/components/header/Action";
import Breadcrumbs from "@/components/Breadcrumbs";
+import * as upload from "@/utils/upload";
export default {
name: "editor",
@@ -46,6 +81,16 @@ export default {
},
computed: {
...mapState(["req", "user"]),
+ previewLink() {
+ return this.$route.path
+ .replace(/^\/files\//, "/")
+ .replace(/[^/]*$/, "");
+ },
+ headerButtons() {
+ return {
+ upload: this.user.perm.create,
+ };
+ },
breadcrumbs() {
let parts = this.$route.path.split("/");
@@ -78,8 +123,12 @@ export default {
},
created() {
window.addEventListener("keydown", this.keyEvent);
+ window.addEventListener("drop", this.drop);
+ window.addEventListener("paste", this.drop);
},
beforeDestroy() {
+ window.removeEventListener("paste", this.drop);
+ window.removeEventListener("drop", this.drop);
window.removeEventListener("keydown", this.keyEvent);
this.editor.destroy();
},
@@ -104,6 +153,129 @@ export default {
let uri = url.removeLastDir(this.$route.path) + "/";
this.$router.push({ path: uri });
},
+ dragEnter() {
+ this.dragCounter++;
+
+ // When the user starts dragging an item, put every
+ // file on the listing with 50% opacity.
+ let items = document.getElementsByClassName("item");
+
+ Array.from(items).forEach((file) => {
+ file.style.opacity = 0.5;
+ });
+ },
+ dragLeave() {
+ this.dragCounter--;
+
+ if (this.dragCounter == 0) {
+ this.resetOpacity();
+ }
+ },
+ drop: async function (event) {
+ event.preventDefault();
+ this.dragCounter = 0;
+ this.resetOpacity();
+
+ let dt = event.dataTransfer ?? event.clipboardData;
+ let el = event.target;
+
+ if (dt.files.length <= 0) return;
+
+ for (let i = 0; i < 5; i++) {
+ if (el !== null && !el.classList.contains("item")) {
+ el = el.parentElement;
+ }
+ }
+
+ let files = await upload.scanFiles(dt);
+ let items = this.req.items;
+ let path = this.$route.path.replace(/\/[^/]*$/, "/");
+
+ if (
+ el !== null &&
+ el.classList.contains("item") &&
+ el.dataset.dir === "true"
+ ) {
+ // Get url from ListingItem instance
+ path = el.__vue__.url;
+
+ try {
+ items = (await api.fetch(path)).items;
+ } catch (error) {
+ this.$showError(error);
+ }
+ }
+
+ let conflict = upload.checkConflict(files, items);
+
+ if (conflict) {
+ this.$store.commit("showHover", {
+ prompt: "replace",
+ confirm: (event) => {
+ event.preventDefault();
+ this.$store.commit("closeHovers");
+ upload.handleFiles(files, path, true);
+ },
+ });
+
+ return;
+ }
+
+ upload.handleFiles(files, path);
+ const alt = files[0].name;
+ const link = files[0].name;
+ this.editor.insert(``);
+ },
+ uploadInput(event) {
+ this.$store.commit("closeHovers");
+
+ let files = event.currentTarget.files;
+ let folder_upload =
+ files[0].webkitRelativePath !== undefined &&
+ files[0].webkitRelativePath !== "";
+
+ if (folder_upload) {
+ for (let i = 0; i < files.length; i++) {
+ let file = files[i];
+ files[i].fullPath = file.webkitRelativePath;
+ }
+ }
+
+ let path = this.$route.path.replace(/\/[^/]*$/, "/");
+ let conflict = upload.checkConflict(files, this.req.items);
+
+ if (conflict) {
+ this.$store.commit("showHover", {
+ prompt: "replace",
+ confirm: (event) => {
+ event.preventDefault();
+ this.$store.commit("closeHovers");
+ upload.handleFiles(files, path, true);
+ },
+ });
+
+ return;
+ }
+
+ upload.handleFiles(files, path);
+ },
+ resetOpacity() {
+ let items = document.getElementsByClassName("item");
+
+ Array.from(items).forEach((file) => {
+ file.style.opacity = 1;
+ });
+ },
+ upload: function () {
+ if (
+ typeof window.DataTransferItem !== "undefined" &&
+ typeof DataTransferItem.prototype.webkitGetAsEntry !== "undefined"
+ ) {
+ this.$store.commit("showHover", "upload");
+ } else {
+ document.getElementById("upload-input").click();
+ }
+ },
keyEvent(event) {
if (!event.ctrlKey && !event.metaKey) {
return;