updated frontend
|
@ -50,6 +50,7 @@ func setDefaults() Settings {
|
|||
AdminUsername: "admin",
|
||||
AdminPassword: "admin",
|
||||
Server: Server{
|
||||
EnableThumbnails: true,
|
||||
EnableExec: false,
|
||||
IndexingInterval: 5,
|
||||
Port: 8080,
|
||||
|
|
Before Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 843 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 190 KiB |
Before Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 4.9 KiB |
|
@ -1,27 +1,12 @@
|
|||
<template>
|
||||
<div id="search" @click="open" v-bind:class="{ active, ongoing }">
|
||||
<div id="input">
|
||||
<button
|
||||
v-if="active"
|
||||
class="action"
|
||||
@click="close"
|
||||
:aria-label="$t('buttons.close')"
|
||||
:title="$t('buttons.close')"
|
||||
>
|
||||
<button v-if="active" class="action" @click="close" :aria-label="$t('buttons.close')" :title="$t('buttons.close')">
|
||||
<i class="material-icons">close</i>
|
||||
</button>
|
||||
<i v-else class="material-icons">search</i>
|
||||
<input
|
||||
class="main-input"
|
||||
type="text"
|
||||
@keyup.exact="keyup"
|
||||
@input="submit"
|
||||
ref="input"
|
||||
:autofocus="active"
|
||||
v-model.trim="value"
|
||||
:aria-label="$t('search.search')"
|
||||
:placeholder="$t('search.search')"
|
||||
/>
|
||||
<input class="main-input" type="text" @keyup.exact="keyup" @input="submit" ref="input" :autofocus="active"
|
||||
v-model.trim="value" :aria-label="$t('search.search')" :placeholder="$t('search.search')" />
|
||||
</div>
|
||||
<div v-if="isMobile && active" id="result" :class="{ hidden: !active }" ref="result">
|
||||
<div id="result-list">
|
||||
|
@ -29,12 +14,7 @@
|
|||
Search Context: {{ getContext(this.$route.path) }}
|
||||
</div>
|
||||
<ul v-show="results.length > 0">
|
||||
<li
|
||||
v-for="(s, k) in results"
|
||||
:key="k"
|
||||
@click.stop.prevent="navigateTo(s.url)"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
<li v-for="(s, k) in results" :key="k" @click.stop.prevent="navigateTo(s.url)" style="cursor: pointer">
|
||||
<router-link to="#" event="">
|
||||
<i v-if="s.dir" class="material-icons folder-icons"> folder </i>
|
||||
<i v-else-if="s.audio" class="material-icons audio-icons"> volume_up </i>
|
||||
|
@ -57,26 +37,15 @@
|
|||
</div>
|
||||
</div>
|
||||
<template v-if="isEmpty">
|
||||
<button
|
||||
class="mobile-boxes"
|
||||
v-if="value.length === 0 && !showBoxes"
|
||||
@click="resetSearchFilters()"
|
||||
>
|
||||
<button class="mobile-boxes" v-if="value.length === 0 && !showBoxes" @click="resetSearchFilters()">
|
||||
Reset filters
|
||||
</button>
|
||||
<template v-if="value.length === 0 && showBoxes">
|
||||
<div class="boxes">
|
||||
<h3>{{ $t("search.types") }}</h3>
|
||||
<div>
|
||||
<div
|
||||
class="mobile-boxes"
|
||||
tabindex="0"
|
||||
v-for="(v, k) in boxes"
|
||||
:key="k"
|
||||
role="button"
|
||||
@click="addToTypes('type:' + k)"
|
||||
:aria-label="v.label"
|
||||
>
|
||||
<div class="mobile-boxes" tabindex="0" v-for="(v, k) in boxes" :key="k" role="button"
|
||||
@click="addToTypes('type:' + k)" :aria-label="v.label">
|
||||
<i class="material-icons">{{ v.icon }}</i>
|
||||
<p>{{ v.label }}</p>
|
||||
</div>
|
||||
|
@ -121,52 +90,26 @@
|
|||
</p>
|
||||
</div>
|
||||
<template>
|
||||
<ButtonGroup
|
||||
:buttons="folderSelect"
|
||||
@button-clicked="addToTypes"
|
||||
@remove-button-clicked="removeFromTypes"
|
||||
@disableAll="folderSelectClicked()"
|
||||
@enableAll="resetButtonGroups()"
|
||||
/>
|
||||
<ButtonGroup
|
||||
:buttons="typeSelect"
|
||||
@button-clicked="addToTypes"
|
||||
@remove-button-clicked="removeFromTypes"
|
||||
:isDisabled="isTypeSelectDisabled"
|
||||
/>
|
||||
<ButtonGroup :buttons="folderSelect" @button-clicked="addToTypes" @remove-button-clicked="removeFromTypes"
|
||||
@disableAll="folderSelectClicked()" @enableAll="resetButtonGroups()" />
|
||||
<ButtonGroup :buttons="typeSelect" @button-clicked="addToTypes" @remove-button-clicked="removeFromTypes"
|
||||
:isDisabled="isTypeSelectDisabled" />
|
||||
<div class="sizeConstraints">
|
||||
<div class="sizeInputWrapper">
|
||||
<p>Smaller Than:</p>
|
||||
<input
|
||||
|
||||
class="sizeInput"
|
||||
v-model="smallerThan"
|
||||
type="number"
|
||||
min="0"
|
||||
placeholder="number"
|
||||
/>
|
||||
<input class="sizeInput" v-model="smallerThan" type="number" min="0" placeholder="number" />
|
||||
<p>MB</p>
|
||||
</div>
|
||||
<div class="sizeInputWrapper">
|
||||
<p>Larger Than:</p>
|
||||
<input
|
||||
class="sizeInput"
|
||||
v-model="largerThan"
|
||||
type="number"
|
||||
placeholder="number"
|
||||
/>
|
||||
<input class="sizeInput" v-model="largerThan" type="number" placeholder="number" />
|
||||
<p>MB</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<ul v-show="results.length > 0">
|
||||
<li
|
||||
v-for="(s, k) in results"
|
||||
:key="k"
|
||||
@click.stop.prevent="navigateTo(s.url)"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
<li v-for="(s, k) in results" :key="k" @click.stop.prevent="navigateTo(s.url)" style="cursor: pointer">
|
||||
<router-link to="#" event="">
|
||||
<i v-if="s.dir" class="material-icons folder-icons"> folder </i>
|
||||
<i v-else-if="s.audio" class="material-icons audio-icons"> volume_up </i>
|
||||
|
@ -189,42 +132,56 @@
|
|||
.main-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.searchContext {
|
||||
width: 100%;
|
||||
padding: 0.5em 1em;
|
||||
background: var(--blue);
|
||||
color: white;
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
border-left: 1px solid gray;
|
||||
border-right: 1px solid gray;
|
||||
}
|
||||
|
||||
#result-desktop #result-list {
|
||||
-webkit-transition: width 0.3s ease 0s;
|
||||
transition: width 0.3s ease 0s;
|
||||
max-width: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
border-color: gray;
|
||||
overflow: auto;
|
||||
width: 30em;
|
||||
padding-top: 0em;
|
||||
border-color: #a7a7a7;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 1em;
|
||||
border-top: none;
|
||||
border-top-width: initial;
|
||||
border-top-style: none;
|
||||
border-top-color: initial;
|
||||
border-top-left-radius: 0px;
|
||||
border-top-right-radius: 0px;
|
||||
background: white;
|
||||
max-height: 80vh;
|
||||
left: 50%;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
-webkit-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
-webkit-box-shadow: 0px 2em 50px 10px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0px 2em 50px 10px rgba(0, 0, 0, 0.3);
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
#result-desktop {
|
||||
animation: SlideDown 0.5s forwards;
|
||||
border-radius: 1em;
|
||||
|
||||
}
|
||||
|
||||
#search.active #result-desktop ul li a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: .3em 0;
|
||||
margin-right: .3em;
|
||||
}
|
||||
|
||||
#result-list.active {
|
||||
width: 65em !important;
|
||||
max-width: 85vw !important;
|
||||
|
@ -236,11 +193,13 @@
|
|||
transform: translateY(-3em);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Search */
|
||||
#search {
|
||||
flex-basis: auto;
|
||||
|
@ -283,8 +242,10 @@
|
|||
|
||||
/* Hiding scrollbar for IE, Edge and Firefox */
|
||||
#result-list {
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none;
|
||||
/* Firefox */
|
||||
-ms-overflow-style: none;
|
||||
/* IE and Edge */
|
||||
}
|
||||
|
||||
.text-container {
|
||||
|
@ -316,7 +277,7 @@ body.rtl #search #result {
|
|||
direction: ltr;
|
||||
}
|
||||
|
||||
#search #result > div > *:first-child {
|
||||
#search #result>div>*:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
|
@ -326,7 +287,7 @@ body.rtl #search #result {
|
|||
}
|
||||
|
||||
/* Search Results */
|
||||
body.rtl #search #result ul > * {
|
||||
body.rtl #search #result ul>* {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
|
@ -352,12 +313,13 @@ body.rtl #search #result ul > * {
|
|||
#search.ongoing #renew {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#search.active #input {
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
border-bottom-left-radius: 1px;
|
||||
background-color: lightgray;
|
||||
border-color: gray;
|
||||
border-bottom-style: none;
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
border-bottom-right-radius: 1px;
|
||||
}
|
||||
|
||||
/* Search Input Placeholder */
|
||||
|
@ -406,10 +368,6 @@ body.rtl #search .boxes h3 {
|
|||
font-size: 3.5em;
|
||||
}
|
||||
|
||||
#result-desktop {
|
||||
animation: SlideDown 0.5s forwards;
|
||||
}
|
||||
|
||||
.mobile-boxes {
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
|
@ -420,6 +378,7 @@ body.rtl #search .boxes h3 {
|
|||
border-radius: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Hiding scrollbar for Chrome, Safari and Opera */
|
||||
.mobile-boxes::-webkit-scrollbar {
|
||||
display: none;
|
||||
|
@ -427,9 +386,12 @@ body.rtl #search .boxes h3 {
|
|||
|
||||
/* Hiding scrollbar for IE, Edge and Firefox */
|
||||
.mobile-boxes {
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none;
|
||||
/* Firefox */
|
||||
-ms-overflow-style: none;
|
||||
/* IE and Edge */
|
||||
}
|
||||
|
||||
.helpText {
|
||||
padding: 1em;
|
||||
}
|
||||
|
@ -455,17 +417,17 @@ body.rtl #search .boxes h3 {
|
|||
|
||||
.sizeInputWrapper {
|
||||
border-radius: 1em;
|
||||
margin-left: 0.5em;
|
||||
margin-right: 0.5em;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
background-color: rgb(245, 245, 245);
|
||||
padding: 0.25em;
|
||||
height: 3em;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
border: 1px solid #ccc
|
||||
margin-left: 0.5em;
|
||||
margin-right: 0.5em;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
background-color: rgb(245, 245, 245);
|
||||
padding: 0.25em;
|
||||
height: 3em;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
border: 1px solid #ccc
|
||||
}
|
||||
|
||||
.helpButton {
|
||||
|
@ -545,7 +507,7 @@ export default {
|
|||
setTimeout(() => {
|
||||
resultList.classList.add("active");
|
||||
}, 100);
|
||||
|
||||
|
||||
},
|
||||
show(val, old) {
|
||||
this.active = val === "search";
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<i class="material-icons">note_add</i>
|
||||
<span>{{ $t("sidebar.newFile") }}</span>
|
||||
</button>
|
||||
<button id="upload-button" @click="upload($event)" class="action" :aria-label="$t('sidebar.upload')" >
|
||||
<button id="upload-button" @click="upload($event)" class="action" >
|
||||
<i class="material-icons">file_upload</i>
|
||||
<span>Upload file</span>
|
||||
</button>
|
||||
|
|
|
@ -126,8 +126,13 @@ main {
|
|||
padding-top: 4em;
|
||||
overflow: scroll;
|
||||
top: 0;
|
||||
height: 100vh;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
main > div {
|
||||
height: calc(100% - 3em);
|
||||
}
|
||||
|
||||
.breadcrumbs {
|
||||
|
|
|
@ -53,11 +53,6 @@ header .action span {
|
|||
display: none;
|
||||
}
|
||||
|
||||
header>div div {
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Icon Colors */
|
||||
.folder-icons {
|
||||
color: var(--icon-blue);
|
||||
|
|
|
@ -280,15 +280,11 @@ main .spinner .bounce2 {
|
|||
#editor-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fafafa;
|
||||
position: fixed;
|
||||
padding-top: 4em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: none;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 9999;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#editor-container #editor {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<header-bar v-if="showHeader" showMenu showLogo />
|
||||
|
||||
<h2 class="message">
|
||||
<i class="material-icons">{{ info.icon }}</i>
|
||||
<span>{{ $t(info.message) }}</span>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<header-bar v-if="error || req.type == null" showMenu showLogo />
|
||||
|
||||
<breadcrumbs base="/files" />
|
||||
|
||||
<errors v-if="error" :errorCode="error.status" />
|
||||
|
@ -91,8 +89,12 @@ export default {
|
|||
}
|
||||
this.$store.commit("updateRequest", {});
|
||||
},
|
||||
currentView(newView) {
|
||||
// Commit the new value to the store
|
||||
this.setCurrentValue(this.newValue);
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(["setLoading"]),
|
||||
...mapMutations(["setLoading","setCurrentView"]),
|
||||
async fetchData() {
|
||||
// Reset view information.
|
||||
this.$store.commit("setReload", false);
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
<div v-if="progress" class="progress">
|
||||
<div v-bind:style="{ width: this.progress + '%' }"></div>
|
||||
</div>
|
||||
<editorBar v-if="getCurrentView === 'editor'"></editorBar>
|
||||
<listingBar v-else-if="getCurrentView === 'listing'"></listingBar>
|
||||
<previewBar v-else-if="getCurrentView === 'preview'"></previewBar>
|
||||
<defaultBar v-if="currentView === 'listing'"></defaultBar>
|
||||
<editorBar v-else-if="currentView === 'editor'"></editorBar>
|
||||
<editorBar v-else-if="currentView === 'share'"></editorBar>
|
||||
<editorBar v-else-if="currentView === 'dashboard'"></editorBar>
|
||||
<editorBar v-else-if="currentView === 'error'"></editorBar>
|
||||
<defaultBar v-else></defaultBar>
|
||||
<sidebar></sidebar>
|
||||
<main>
|
||||
|
@ -17,9 +19,9 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import editorBar from "./files/Editor.vue"
|
||||
import editorBar from "./files/EditorBar.vue"
|
||||
import defaultBar from "./files/Default.vue"
|
||||
import listingBar from"./files/Listing.vue"
|
||||
import listingBar from "./files/Listing.vue"
|
||||
import previewBar from "./files/Preview.vue"
|
||||
import Prompts from "@/components/prompts/Prompts";
|
||||
import Action from "@/components/header/Action";
|
||||
|
@ -27,7 +29,6 @@ import { mapState, mapGetters } from "vuex";
|
|||
import Sidebar from "@/components/Sidebar.vue";
|
||||
import UploadFiles from "../components/prompts/UploadFiles";
|
||||
import { enableExec } from "@/utils/constants";
|
||||
|
||||
export default {
|
||||
name: "layout",
|
||||
components: {
|
||||
|
@ -49,18 +50,28 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["isLogged", "progress"]),
|
||||
...mapState(["req", "user", "currentView"]),
|
||||
|
||||
...mapGetters(["isLogged", "progress", "isListing"]),
|
||||
...mapState(["req", "user", "state"]),
|
||||
|
||||
isExecEnabled: () => enableExec,
|
||||
getCurrentView() {
|
||||
return this.currentView;
|
||||
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";
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
getCurrentView: function () {
|
||||
console.log(this.currentView)
|
||||
},
|
||||
$route: function () {
|
||||
this.$store.commit("resetSelected");
|
||||
this.$store.commit("multiple", false);
|
||||
|
@ -70,7 +81,7 @@ export default {
|
|||
methods: {
|
||||
getTitle() {
|
||||
let title = "Title"
|
||||
if (this.$route.path.startsWith('/settings/')){
|
||||
if (this.$route.path.startsWith('/settings/')) {
|
||||
title = "Settings"
|
||||
}
|
||||
return title
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<template>
|
||||
<div class="dashboard">
|
||||
<header-bar showMenu showLogo />
|
||||
|
||||
<div id="nav">
|
||||
<div class="wrapper">
|
||||
<ul>
|
||||
|
@ -52,15 +50,10 @@
|
|||
<script>
|
||||
import { mapState } from "vuex";
|
||||
|
||||
import HeaderBar from "@/components/header/HeaderBar";
|
||||
|
||||
export default {
|
||||
name: "settings",
|
||||
components: {
|
||||
HeaderBar,
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user", "loading"]),
|
||||
...mapState(["user", "loading","req"]),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,30 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<header-bar showMenu showLogo>
|
||||
<title />
|
||||
|
||||
<action
|
||||
v-if="selectedCount"
|
||||
icon="file_download"
|
||||
:label="$t('buttons.download')"
|
||||
@action="download"
|
||||
:counter="selectedCount"
|
||||
/>
|
||||
<button
|
||||
v-if="isSingleFile()"
|
||||
class="action copy-clipboard"
|
||||
:data-clipboard-text="linkSelected()"
|
||||
:aria-label="$t('buttons.copyDownloadLinkToClipboard')"
|
||||
:title="$t('buttons.copyDownloadLinkToClipboard')"
|
||||
>
|
||||
<i class="material-icons">content_paste</i>
|
||||
</button>
|
||||
<action
|
||||
icon="check_circle"
|
||||
:label="$t('buttons.selectMultiple')"
|
||||
@action="toggleMultipleSelection"
|
||||
/>
|
||||
</header-bar>
|
||||
|
||||
<breadcrumbs :base="'/share/' + hash" />
|
||||
|
||||
|
|
|
@ -1,20 +1,5 @@
|
|||
<template>
|
||||
<div id="editor-container">
|
||||
<header-bar>
|
||||
<action icon="close" :label="$t('buttons.close')" @action="close()" />
|
||||
<title>{{ req.name }}</title>
|
||||
|
||||
<action
|
||||
v-if="user.perm.modify"
|
||||
id="save-button"
|
||||
icon="save"
|
||||
:label="$t('buttons.save')"
|
||||
@action="save()"
|
||||
/>
|
||||
</header-bar>
|
||||
|
||||
<breadcrumbs base="/files" noLink />
|
||||
|
||||
<div id="editor-container">
|
||||
<form id="editor"></form>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -45,7 +30,7 @@ export default {
|
|||
return {};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["req", "user"]),
|
||||
...mapState(["req", "user","currentView"]),
|
||||
breadcrumbs() {
|
||||
let parts = this.$route.path.split("/");
|
||||
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
<template>
|
||||
<header-bar>
|
||||
<action icon="close" :label="$t('buttons.close')" @action="close()" />
|
||||
<title class="topTitle">{{ req.name }}</title>
|
||||
|
||||
<action v-if="user.perm.modify" id="save-button" icon="save" :label="$t('buttons.save')"
|
||||
@action="save()" />
|
||||
</header-bar>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.flexbar {
|
||||
display: flex;
|
||||
flex-direction: block;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.topTitle {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
import { files as api } from "@/api";
|
||||
import { theme } from "@/utils/constants";
|
||||
import buttons from "@/utils/buttons";
|
||||
import url from "@/utils/url";
|
||||
|
||||
import ace from "ace-builds/src-min-noconflict/ace.js";
|
||||
import modelist from "ace-builds/src-min-noconflict/ext-modelist.js";
|
||||
import "ace-builds/webpack-resolver";
|
||||
|
||||
import HeaderBar from "@/components/header/HeaderBar";
|
||||
import Action from "@/components/header/Action";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs";
|
||||
|
||||
export default {
|
||||
name: "editor",
|
||||
components: {
|
||||
HeaderBar,
|
||||
Action,
|
||||
Breadcrumbs,
|
||||
},
|
||||
data: function () {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["req", "user", "currentView"]),
|
||||
breadcrumbs() {
|
||||
let parts = this.$route.path.split("/");
|
||||
|
||||
if (parts[0] === "") {
|
||||
parts.shift();
|
||||
}
|
||||
|
||||
if (parts[parts.length - 1] === "") {
|
||||
parts.pop();
|
||||
}
|
||||
|
||||
let breadcrumbs = [];
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]) });
|
||||
}
|
||||
|
||||
breadcrumbs.shift();
|
||||
|
||||
if (breadcrumbs.length > 3) {
|
||||
while (breadcrumbs.length !== 4) {
|
||||
breadcrumbs.shift();
|
||||
}
|
||||
|
||||
breadcrumbs[0].name = "...";
|
||||
}
|
||||
|
||||
return breadcrumbs;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
window.addEventListener("keydown", this.keyEvent);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener("keydown", this.keyEvent);
|
||||
this.editor.destroy();
|
||||
},
|
||||
mounted: function () {
|
||||
const fileContent = this.req.content || "";
|
||||
|
||||
this.editor = ace.edit("editor", {
|
||||
value: fileContent,
|
||||
showPrintMargin: false,
|
||||
readOnly: this.req.type === "textImmutable",
|
||||
theme: "ace/theme/chrome",
|
||||
mode: modelist.getModeForPath(this.req.name).mode,
|
||||
wrap: true,
|
||||
});
|
||||
|
||||
if (theme == "dark") {
|
||||
this.editor.setTheme("ace/theme/twilight");
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
let uri = url.removeLastDir(this.$route.path) + "/";
|
||||
this.$router.push({ path: uri });
|
||||
},
|
||||
keyEvent(event) {
|
||||
if (!event.ctrlKey && !event.metaKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (String.fromCharCode(event.which).toLowerCase() !== "s") {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
this.save();
|
||||
},
|
||||
async save() {
|
||||
const button = "save";
|
||||
buttons.loading("save");
|
||||
|
||||
try {
|
||||
await api.put(this.$route.path, this.editor.getValue());
|
||||
buttons.success(button);
|
||||
} catch (e) {
|
||||
buttons.done(button);
|
||||
this.$showError(e);
|
||||
}
|
||||
},
|
||||
close() {
|
||||
if (this.isSettings) { // Use this.isSettings to access the computed property
|
||||
this.$router.push({ path: "/files/" }, () => { });
|
||||
this.$store.commit("closeHovers");
|
||||
return;
|
||||
}
|
||||
this.$store.commit("updateRequest", {});
|
||||
let uri = url.removeLastDir(this.$route.path) + "/";
|
||||
this.$router.push({ path: uri });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -4,48 +4,6 @@
|
|||
@mousemove="toggleNavigation"
|
||||
@touchstart="toggleNavigation"
|
||||
>
|
||||
<header-bar>
|
||||
<action icon="close" :label="$t('buttons.close')" @action="close()" />
|
||||
<title>{{ name }}</title>
|
||||
<action
|
||||
:disabled="loading"
|
||||
v-if="isResizeEnabled && req.type === 'image'"
|
||||
:icon="fullSize ? 'photo_size_select_large' : 'hd'"
|
||||
@action="toggleSize"
|
||||
/>
|
||||
|
||||
<template #actions>
|
||||
<action
|
||||
:disabled="loading"
|
||||
v-if="user.perm.rename"
|
||||
icon="mode_edit"
|
||||
:label="$t('buttons.rename')"
|
||||
show="rename"
|
||||
/>
|
||||
<action
|
||||
:disabled="loading"
|
||||
v-if="user.perm.delete"
|
||||
icon="delete"
|
||||
:label="$t('buttons.delete')"
|
||||
@action="deleteFile"
|
||||
id="delete-button"
|
||||
/>
|
||||
<action
|
||||
:disabled="loading"
|
||||
v-if="user.perm.download"
|
||||
icon="file_download"
|
||||
:label="$t('buttons.download')"
|
||||
@action="download"
|
||||
/>
|
||||
<action
|
||||
:disabled="loading"
|
||||
icon="info"
|
||||
:label="$t('buttons.info')"
|
||||
show="info"
|
||||
/>
|
||||
</template>
|
||||
</header-bar>
|
||||
|
||||
<div class="loading delayed" v-if="loading">
|
||||
<div class="spinner">
|
||||
<div class="bounce1"></div>
|
||||
|
|