feat(editor): add upload and preview buttons
This commit is contained in:
parent
ff3367ac42
commit
7676c52deb
@ -4,6 +4,25 @@
|
|||||||
<action icon="close" :label="$t('buttons.close')" @action="close()" />
|
<action icon="close" :label="$t('buttons.close')" @action="close()" />
|
||||||
<title>{{ req.name }}</title>
|
<title>{{ req.name }}</title>
|
||||||
|
|
||||||
|
<action
|
||||||
|
v-if="headerButtons.upload"
|
||||||
|
icon="file_upload"
|
||||||
|
id="upload-button"
|
||||||
|
:label="$t('buttons.upload')"
|
||||||
|
@action="upload"
|
||||||
|
/>
|
||||||
|
<a
|
||||||
|
v-if="previewLink"
|
||||||
|
aria-label="preview"
|
||||||
|
title="Preview"
|
||||||
|
class="action"
|
||||||
|
:href="previewLink"
|
||||||
|
id="preview"
|
||||||
|
target="preview"
|
||||||
|
>
|
||||||
|
<i class="material-icons">preview</i>
|
||||||
|
<span>preview</span>
|
||||||
|
</a>
|
||||||
<action
|
<action
|
||||||
v-if="user.perm.modify"
|
v-if="user.perm.modify"
|
||||||
id="save-button"
|
id="save-button"
|
||||||
@ -16,6 +35,21 @@
|
|||||||
<breadcrumbs base="/files" noLink />
|
<breadcrumbs base="/files" noLink />
|
||||||
|
|
||||||
<form id="editor"></form>
|
<form id="editor"></form>
|
||||||
|
<input
|
||||||
|
style="display: none"
|
||||||
|
type="file"
|
||||||
|
id="upload-input"
|
||||||
|
@change="uploadInput($event)"
|
||||||
|
multiple
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
style="display: none"
|
||||||
|
type="file"
|
||||||
|
id="upload-folder-input"
|
||||||
|
@change="uploadInput($event)"
|
||||||
|
webkitdirectory
|
||||||
|
multiple
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -33,6 +67,7 @@ import "ace-builds/webpack-resolver";
|
|||||||
import HeaderBar from "@/components/header/HeaderBar";
|
import HeaderBar from "@/components/header/HeaderBar";
|
||||||
import Action from "@/components/header/Action";
|
import Action from "@/components/header/Action";
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs";
|
import Breadcrumbs from "@/components/Breadcrumbs";
|
||||||
|
import * as upload from "@/utils/upload";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "editor",
|
name: "editor",
|
||||||
@ -46,6 +81,16 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["req", "user"]),
|
...mapState(["req", "user"]),
|
||||||
|
previewLink() {
|
||||||
|
return this.$route.path
|
||||||
|
.replace(/^\/files\//, "/")
|
||||||
|
.replace(/[^/]*$/, "");
|
||||||
|
},
|
||||||
|
headerButtons() {
|
||||||
|
return {
|
||||||
|
upload: this.user.perm.create,
|
||||||
|
};
|
||||||
|
},
|
||||||
breadcrumbs() {
|
breadcrumbs() {
|
||||||
let parts = this.$route.path.split("/");
|
let parts = this.$route.path.split("/");
|
||||||
|
|
||||||
@ -78,8 +123,12 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
window.addEventListener("keydown", this.keyEvent);
|
window.addEventListener("keydown", this.keyEvent);
|
||||||
|
window.addEventListener("drop", this.drop);
|
||||||
|
window.addEventListener("paste", this.drop);
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
window.removeEventListener("paste", this.drop);
|
||||||
|
window.removeEventListener("drop", this.drop);
|
||||||
window.removeEventListener("keydown", this.keyEvent);
|
window.removeEventListener("keydown", this.keyEvent);
|
||||||
this.editor.destroy();
|
this.editor.destroy();
|
||||||
},
|
},
|
||||||
@ -104,6 +153,129 @@ export default {
|
|||||||
let uri = url.removeLastDir(this.$route.path) + "/";
|
let uri = url.removeLastDir(this.$route.path) + "/";
|
||||||
this.$router.push({ path: uri });
|
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) {
|
keyEvent(event) {
|
||||||
if (!event.ctrlKey && !event.metaKey) {
|
if (!event.ctrlKey && !event.metaKey) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user