diff --git a/fileutils/file.go b/fileutils/file.go
index 1b1e6403..00549584 100644
--- a/fileutils/file.go
+++ b/fileutils/file.go
@@ -2,6 +2,7 @@ package fileutils
import (
"io"
+ "os"
"path/filepath"
"github.com/spf13/afero"
@@ -25,7 +26,7 @@ func CopyFile(fs afero.Fs, source, dest string) error {
}
// Create the destination file.
- dst, err := fs.Create(dest)
+ dst, err := fs.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
if err != nil {
return err
}
diff --git a/frontend/public/themes/dark.css b/frontend/public/themes/dark.css
index 978b4f0f..1ee5f1ac 100644
--- a/frontend/public/themes/dark.css
+++ b/frontend/public/themes/dark.css
@@ -1,7 +1,7 @@
:root {
- --background: #121212;
- --surfacePrimary: #171819;
- --surfaceSecondary: #212528;
+ --background: #141D24;
+ --surfacePrimary: #20292F;
+ --surfaceSecondary: #3A4147;
--divider: rgba(255, 255, 255, 0.12);
--icon: #ffffff;
--textPrimary: rgba(255, 255, 255, 0.87);
@@ -16,7 +16,7 @@ body {
#loading {
background: var(--background);
}
-#loading .spinner div {
+#loading .spinner div, #previewer .loading .spinner div {
background: var(--icon);
}
@@ -30,25 +30,34 @@ header {
#search #input {
background: var(--surfaceSecondary);
+ border-color: var(--surfacePrimary);
}
-#search.active #input,
-#search.active .boxes {
+#search #input input::placeholder {
+ color: var(--textSecondary);
+}
+#search.active #input {
background: var(--surfacePrimary);
}
#search.active input {
color: var(--textPrimary);
}
-#search.active #result {
+#search #result {
background: var(--background);
color: var(--textPrimary);
}
-#search.active .boxes h3 {
+#search .boxes {
+ background: var(--surfaceSecondary);
+}
+#search .boxes h3 {
color: var(--textPrimary);
}
.action {
color: var(--textPrimary) !important;
}
+.action:hover {
+ background-color: rgba(255, 255, 255, .1);
+}
.action i {
color: var(--icon) !important;
}
@@ -93,6 +102,10 @@ nav > div {
background: var(--background);
}
+.message {
+ color: var(--textPrimary);
+}
+
.card {
background: var(--surfacePrimary);
color: var(--textPrimary);
@@ -106,9 +119,23 @@ nav > div {
.dashboard p label {
color: var(--textPrimary);
}
+.card#share ul li input,
+.card#share ul li select,
.input {
background: var(--surfaceSecondary);
color: var(--textPrimary);
+ border: 1px solid rgba(255, 255, 255, 0.05);
+}
+.input:hover,
+.input:focus {
+ border-color: rgba(255, 255, 255, 0.15);
+}
+.input--red {
+ background: #73302D;
+}
+
+.input--green {
+ background: #147A41;
}
.dashboard #nav li,
@@ -119,10 +146,27 @@ nav > div {
color: var(--textPrimary);
}
+table th {
+ color: var(--textSecondary);
+}
+
+.file-list li:hover {
+ background: var(--surfaceSecondary);
+}
+.file-list li:before {
+ color: var(--textSecondary);
+}
+.file-list li[aria-selected=true]:before {
+ color: var(--icon);
+}
+
.shell {
background: var(--surfacePrimary);
color: var(--textPrimary);
}
+.shell__result {
+ border-top: 1px solid var(--divider);
+}
#editor-container {
background: var(--background);
@@ -146,3 +190,11 @@ nav > div {
background: var(--surfaceSecondary) !important;
}
}
+
+.share__box, .share__box__download {
+ background: var(--surfaceSecondary) !important;
+ color: var(--textPrimary);
+}
+.share__box__download {
+ border-bottom-color: var(--divider);
+}
\ No newline at end of file
diff --git a/frontend/src/api/files.js b/frontend/src/api/files.js
index 602090c1..5942e71a 100644
--- a/frontend/src/api/files.js
+++ b/frontend/src/api/files.js
@@ -94,9 +94,6 @@ export async function post (url, content = '', overwrite = false, onupload) {
request.upload.onprogress = onupload
}
- // Send a message to user before closing the tab during file upload
- window.onbeforeunload = () => "Files are being uploaded."
-
request.onload = () => {
if (request.status === 200) {
resolve(request.responseText)
@@ -112,29 +109,28 @@ export async function post (url, content = '', overwrite = false, onupload) {
}
request.send(content)
- // Upload is done no more message before closing the tab
- }).finally(() => { window.onbeforeunload = null })
+ })
}
-function moveCopy (items, copy = false) {
+function moveCopy (items, copy = false, overwrite = false, rename = false) {
let promises = []
for (let item of items) {
const from = removePrefix(item.from)
const to = encodeURIComponent(removePrefix(item.to))
- const url = `${from}?action=${copy ? 'copy' : 'rename'}&destination=${to}`
+ const url = `${from}?action=${copy ? 'copy' : 'rename'}&destination=${to}&override=${overwrite}&rename=${rename}`
promises.push(resourceAction(url, 'PATCH'))
}
return Promise.all(promises)
}
-export function move (items) {
- return moveCopy(items)
+export function move (items, overwrite = false, rename = false) {
+ return moveCopy(items, false, overwrite, rename)
}
-export function copy (items) {
- return moveCopy(items, true)
+export function copy (items, overwrite = false, rename = false) {
+ return moveCopy(items, true, overwrite, rename)
}
export async function checksum (url, algo) {
diff --git a/frontend/src/components/files/ExtendedImage.vue b/frontend/src/components/files/ExtendedImage.vue
index 2fa0f35e..aeb27981 100644
--- a/frontend/src/components/files/ExtendedImage.vue
+++ b/frontend/src/components/files/ExtendedImage.vue
@@ -10,10 +10,12 @@
@mouseup="mouseUp"
@wheel="wheelMove"
>
-
+
diff --git a/frontend/src/css/_buttons.css b/frontend/src/css/_buttons.css
index 79dab790..087c6286 100644
--- a/frontend/src/css/_buttons.css
+++ b/frontend/src/css/_buttons.css
@@ -25,8 +25,8 @@
background: var(--red);
}
-.button--red:hover {
- background: var(--dark-red);
+.button--blue {
+ background: var(--blue);
}
.button--flat {
diff --git a/frontend/src/css/styles.css b/frontend/src/css/styles.css
index 2da1d242..8d486c0d 100644
--- a/frontend/src/css/styles.css
+++ b/frontend/src/css/styles.css
@@ -125,8 +125,13 @@
height: 3.7em;
}
-#previewer .action:first-of-type {
+#previewer .bar .title {
margin-right: auto;
+ padding: 0 1em;
+ line-height: 2.7em;
+ overflow: hidden;
+ word-break: break-word;
+ color: #fff;
}
#previewer .action i {
@@ -219,6 +224,11 @@
font-size: 1.2em;
}
+#previewer .loading {
+ height: 100%;
+ width: 100%;
+}
+
#editor-container #editor {
height: calc(100vh - 8.2em);
}
diff --git a/frontend/src/store/index.js b/frontend/src/store/index.js
index 3662d3a6..40b56df4 100644
--- a/frontend/src/store/index.js
+++ b/frontend/src/store/index.js
@@ -23,7 +23,8 @@ const state = {
show: null,
showShell: false,
showMessage: null,
- showConfirm: null
+ showConfirm: null,
+ previewMode: false
}
export default new Vuex.Store({
diff --git a/frontend/src/store/modules/upload.js b/frontend/src/store/modules/upload.js
index 738edaf9..6552dd01 100644
--- a/frontend/src/store/modules/upload.js
+++ b/frontend/src/store/modules/upload.js
@@ -37,6 +37,11 @@ const mutations = {
}
}
+const beforeUnload = (event) => {
+ event.preventDefault()
+ event.returnValue = ''
+}
+
const actions = {
upload: (context, item) => {
let uploadsCount = Object.keys(context.state.uploads).length;
@@ -45,6 +50,7 @@ const actions = {
let isUploadsEmpty = uploadsCount == 0
if (isQueueEmpty && isUploadsEmpty) {
+ window.addEventListener('beforeunload', beforeUnload)
buttons.loading('upload')
}
@@ -67,6 +73,7 @@ const actions = {
let canProcess = isBellowLimit && !isQueueEmpty
if (isFinished) {
+ window.removeEventListener('beforeunload', beforeUnload)
buttons.success('upload')
context.commit('reset')
context.commit('setReload', true, { root: true })
diff --git a/frontend/src/store/mutations.js b/frontend/src/store/mutations.js
index 579edbec..46aad6e6 100644
--- a/frontend/src/store/mutations.js
+++ b/frontend/src/store/mutations.js
@@ -78,10 +78,14 @@ const mutations = {
updateClipboard: (state, value) => {
state.clipboard.key = value.key
state.clipboard.items = value.items
+ state.clipboard.path = value.path
},
resetClipboard: (state) => {
state.clipboard.key = ''
state.clipboard.items = []
+ },
+ setPreviewMode(state, value) {
+ state.previewMode = value
}
}
diff --git a/frontend/src/utils/upload.js b/frontend/src/utils/upload.js
index 61e6a8e7..54b5669e 100644
--- a/frontend/src/utils/upload.js
+++ b/frontend/src/utils/upload.js
@@ -6,10 +6,7 @@ export function checkConflict(files, items) {
items = []
}
- let folder_upload = false
- if (files[0].fullPath !== undefined) {
- folder_upload = true
- }
+ let folder_upload = files[0].fullPath !== undefined
let conflict = false
for (let i = 0; i < files.length; i++) {
@@ -69,7 +66,7 @@ export function scanFiles(dt) {
const dir = {
isDir: true,
size: 0,
- path: `${directory}${entry.name}`
+ fullPath: `${directory}${entry.name}`
}
contents.push(dir)
@@ -112,7 +109,7 @@ export function handleFiles(files, path, overwrite = false) {
if (file.isDir) {
itemPath = path
- let folders = file.path.split("/")
+ let folders = file.fullPath.split("/")
for (let i = 0; i < folders.length; i++) {
let folder = folders[i]
diff --git a/frontend/src/views/Files.vue b/frontend/src/views/Files.vue
index af54a91c..c0e03bfc 100644
--- a/frontend/src/views/Files.vue
+++ b/frontend/src/views/Files.vue
@@ -10,14 +10,15 @@