From 8af40d28a72beebdbb6f934fb86fb886ffdfdcf5 Mon Sep 17 00:00:00 2001 From: liwei Date: Sat, 6 Jun 2020 18:55:01 +0800 Subject: [PATCH 1/3] feat:Support compress image view --- frontend/src/components/files/ListingItem.vue | 178 +++++++++--------- frontend/src/components/files/Preview.vue | 163 +++++++++------- frontend/src/css/listing.css | 40 ++-- go.mod | 1 + go.sum | 2 + http/http.go | 1 + http/preview.go | 126 +++++++++++++ 7 files changed, 346 insertions(+), 165 deletions(-) create mode 100644 http/preview.go diff --git a/frontend/src/components/files/ListingItem.vue b/frontend/src/components/files/ListingItem.vue index 8c70d54d..96aa9dad 100644 --- a/frontend/src/components/files/ListingItem.vue +++ b/frontend/src/components/files/ListingItem.vue @@ -1,19 +1,23 @@ diff --git a/frontend/src/components/files/Preview.vue b/frontend/src/components/files/Preview.vue index 75190daa..c96fc7bb 100644 --- a/frontend/src/components/files/Preview.vue +++ b/frontend/src/components/files/Preview.vue @@ -1,7 +1,13 @@ diff --git a/frontend/src/css/listing.css b/frontend/src/css/listing.css index 48c78f10..a97fd6b8 100644 --- a/frontend/src/css/listing.css +++ b/frontend/src/css/listing.css @@ -1,6 +1,6 @@ #listing h2 { margin: 0 0 0 0.5em; - font-size: .9em; + font-size: 0.9em; color: rgba(0, 0, 0, 0.38); font-weight: 500; } @@ -10,7 +10,7 @@ overflow: hidden; } -#listing>div { +#listing > div { display: flex; flex-wrap: wrap; justify-content: flex-start; @@ -22,7 +22,7 @@ display: flex; flex-wrap: nowrap; color: #6f6f6f; - transition: .1s ease background, .1s ease opacity; + transition: 0.1s ease background, 0.1s ease opacity; align-items: center; cursor: pointer; } @@ -52,6 +52,13 @@ vertical-align: bottom; } +#listing .item img { + width: 4em; + height: 4em; + margin-right: 0.1em; + vertical-align: bottom; +} + .message { text-align: center; font-size: 2em; @@ -64,7 +71,7 @@ .message i { font-size: 2.5em; - margin-bottom: .2em; + margin-bottom: 0.2em; display: block; } @@ -75,14 +82,14 @@ #listing.mosaic .item { width: calc(33% - 1em); - margin: .5em; + margin: 0.5em; padding: 0.5em; border-radius: 0.2em; - box-shadow: 0 1px 3px rgba(0, 0, 0, .06), 0 1px 2px rgba(0, 0, 0, .12); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.12); } #listing.mosaic .item:hover { - box-shadow: 0 1px 3px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .24) !important; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24) !important; } #listing.mosaic .header { @@ -116,7 +123,7 @@ display: none; } -#listing .item[aria-selected=true] { +#listing .item[aria-selected="true"] { background: var(--blue) !important; color: #fff !important; } @@ -129,6 +136,11 @@ font-size: 2em; } +#listing.list .item div:first-of-type img { + width: 2em; + height: 2em; +} + #listing.list .item div:last-of-type { width: calc(100% - 3em); display: flex; @@ -151,19 +163,19 @@ #listing.list .header i { font-size: 1.5em; vertical-align: middle; - margin-left: .2em; + margin-left: 0.2em; } #listing.list .item.header { display: flex !important; background: #fafafa; z-index: 999; - padding: .85em; + padding: 0.85em; border: 0; border-bottom: 1px solid rgba(0, 0, 0, 0.1); } -#listing.list .item.header>div:first-child { +#listing.list .item.header > div:first-child { width: 0; } @@ -175,7 +187,7 @@ color: inherit; } -#listing.list .item.header>div:first-child { +#listing.list .item.header > div:first-child { width: 0; } @@ -193,7 +205,7 @@ #listing.list .header i { opacity: 0; - transition: .1s ease all; + transition: 0.1s ease all; } #listing.list .header p:hover i, @@ -215,7 +227,7 @@ height: 4em; padding: 0.5em 0.5em 0.5em 1em; justify-content: space-between; - transition: .2s ease bottom; + transition: 0.2s ease bottom; } #listing #multiple-selection.active { diff --git a/go.mod b/go.mod index 043493cc..522ac272 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/maruel/natural v0.0.0-20180416170133-dbcb3e2e8cf1 github.com/mholt/archiver v3.1.1+incompatible github.com/mitchellh/go-homedir v1.1.0 + github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/nwaples/rardecode v1.0.0 // indirect github.com/pelletier/go-toml v1.6.0 github.com/pierrec/lz4 v0.0.0-20190131084431-473cd7ce01a1 // indirect diff --git a/go.sum b/go.sum index 271709a8..c86002a4 100644 --- a/go.sum +++ b/go.sum @@ -141,6 +141,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= +github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMBOs= diff --git a/http/http.go b/http/http.go index 20828f44..fc8d5929 100644 --- a/http/http.go +++ b/http/http.go @@ -59,6 +59,7 @@ func NewHandler(store *storage.Storage, server *settings.Server) (http.Handler, api.Handle("/settings", monkey(settingsPutHandler, "")).Methods("PUT") api.PathPrefix("/raw").Handler(monkey(rawHandler, "/api/raw")).Methods("GET") + api.PathPrefix("/compress").Handler(monkey(compressHandler, "/api/compress")).Methods("GET") api.PathPrefix("/command").Handler(monkey(commandsHandler, "/api/command")).Methods("GET") api.PathPrefix("/search").Handler(monkey(searchHandler, "/api/search")).Methods("GET") diff --git a/http/preview.go b/http/preview.go new file mode 100644 index 00000000..05666703 --- /dev/null +++ b/http/preview.go @@ -0,0 +1,126 @@ +package http + +import ( + "bytes" + "errors" + "fmt" + "github.com/filebrowser/filebrowser/v2/files" + "github.com/nfnt/resize" + "image" + "image/gif" + "image/jpeg" + "image/png" + "io" + "mime" + "net/http" + "net/url" +) + +var compressHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { + if !d.user.Perm.Download { + return http.StatusAccepted, nil + } + + file, err := files.NewFileInfo(files.FileOptions{ + Fs: d.user.Fs, + Path: r.URL.Path, + Modify: d.user.Perm.Modify, + Expand: true, + Checker: d, + }) + if err != nil { + return errToStatus(err), err + } + + if file.IsDir || file.Type != "image" { + return http.StatusNotFound, nil + } + + return compressFileHandler(w, r, file) +}) + +func compressFileHandler(w http.ResponseWriter, r *http.Request, file *files.FileInfo) (int, error) { + fd, err := file.Fs.Open(file.Path) + if err != nil { + return http.StatusInternalServerError, err + } + defer fd.Close() + + if r.URL.Query().Get("inline") == "true" { + w.Header().Set("Content-Disposition", "inline") + } else { + // As per RFC6266 section 4.3 + w.Header().Set("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(file.Name)) + } + + buf, err := compressImageHandler(file, fd) + if err != nil { + return errToStatus(err), err + } + w.Header().Add("Content-Length", fmt.Sprintf("%d", buf.Len())) + w.Header().Add("Content-Type", mime.TypeByExtension(file.Extension)) + io.Copy(w, buf) + return 0, nil +} + +func compressImageHandler(file *files.FileInfo, fd io.Reader) (*bytes.Buffer, error) { + var ( + buf *bytes.Buffer + m image.Image + err error + ) + + switch file.Extension { + case ".jpg", ".jpeg": + buf, m, err = compressImage(jpeg.Decode, fd) + if err != nil { + return nil, err + } + err = jpeg.Encode(buf, m, nil) + break + case ".png": + buf, m, err = compressImage(png.Decode, fd) + if err != nil { + return nil, err + } + err = png.Encode(buf, m) + break + case ".gif": + buf, m, err = compressImage(gif.Decode, fd) + if err != nil { + return nil, err + } + err = gif.Encode(buf, m, nil) + break + default: + return nil, errors.New("extension is not supported") + } + if err != nil { + return nil, err + } + return buf, nil +} + +const maxSize = 1080 + +func compressImage(decode func(r io.Reader) (image.Image, error), fd io.Reader) (*bytes.Buffer, image.Image, error) { + img, err := decode(fd) + if err != nil { + return nil, nil, err + } + buf := bytes.NewBuffer([]byte{}) + width := img.Bounds().Dx() + height := img.Bounds().Dy() + if width > maxSize && width > height { + width = maxSize + height = 0 + } else if height > maxSize && height > width { + width = 0 + height = maxSize + } else { + width = 0 + height = 0 + } + m := resize.Resize(uint(width), uint(height), img, resize.Lanczos3) + return buf, m, nil +} From 558a56bad54a273c94db6de98a4193f782d6cd6a Mon Sep 17 00:00:00 2001 From: liwei Date: Sat, 6 Jun 2020 19:40:38 +0800 Subject: [PATCH 2/3] fix: image compress --- frontend/src/components/files/Preview.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/files/Preview.vue b/frontend/src/components/files/Preview.vue index c96fc7bb..714c34fe 100644 --- a/frontend/src/components/files/Preview.vue +++ b/frontend/src/components/files/Preview.vue @@ -105,7 +105,7 @@ export default { return `${baseURL}/api/raw${this.req.path}?auth=${this.jwt}`; }, compress() { - if (this.type === 'image') { + if (this.req.type === 'image') { return `${baseURL}/api/compress${this.req.path}?auth=${this.jwt}`; } else { return `${baseURL}/api/raw${this.req.path}?auth=${this.jwt}`; From 60711fa74baf10c0df25543a208aa41e1933104a Mon Sep 17 00:00:00 2001 From: liwei Date: Sat, 6 Jun 2020 21:19:53 +0800 Subject: [PATCH 3/3] refactor: eslint config --- frontend/.eslintrc.js | 198 ++++++++++++++++++ frontend/src/components/files/Listing.vue | 182 ++++++++-------- frontend/src/components/files/ListingItem.vue | 132 ++++++------ frontend/src/components/files/Preview.vue | 116 +++++----- frontend/vue.config.js | 2 +- 5 files changed, 421 insertions(+), 209 deletions(-) create mode 100644 frontend/.eslintrc.js diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js new file mode 100644 index 00000000..c9775054 --- /dev/null +++ b/frontend/.eslintrc.js @@ -0,0 +1,198 @@ +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module' + }, + env: { + browser: true, + node: true, + es6: true, + }, + extends: ['plugin:vue/recommended', 'eslint:recommended'], + + // add your custom rules here + //it is base on https://github.com/vuejs/eslint-config-vue + rules: { + "vue/max-attributes-per-line": [2, { + "singleline": 10, + "multiline": { + "max": 1, + "allowFirstLine": false + } + }], + "vue/singleline-html-element-content-newline": "off", + "vue/multiline-html-element-content-newline":"off", + "vue/name-property-casing": ["error", "PascalCase"], + "vue/no-v-html": "off", + 'accessor-pairs': 2, + 'arrow-spacing': [2, { + 'before': true, + 'after': true + }], + 'block-spacing': [2, 'always'], + 'brace-style': [2, '1tbs', { + 'allowSingleLine': true + }], + 'camelcase': [0, { + 'properties': 'always' + }], + 'comma-dangle': [2, 'never'], + 'comma-spacing': [2, { + 'before': false, + 'after': true + }], + 'comma-style': [2, 'last'], + 'constructor-super': 2, + 'curly': [2, 'multi-line'], + 'dot-location': [2, 'property'], + 'eol-last': 2, + 'eqeqeq': ["error", "always", {"null": "ignore"}], + 'generator-star-spacing': [2, { + 'before': true, + 'after': true + }], + 'handle-callback-err': [2, '^(err|error)$'], + 'indent': [2, 2, { + 'SwitchCase': 1 + }], + 'jsx-quotes': [2, 'prefer-single'], + 'key-spacing': [2, { + 'beforeColon': false, + 'afterColon': true + }], + 'keyword-spacing': [2, { + 'before': true, + 'after': true + }], + 'new-cap': [2, { + 'newIsCap': true, + 'capIsNew': false + }], + 'new-parens': 2, + 'no-array-constructor': 2, + 'no-caller': 2, + 'no-console': 'off', + 'no-class-assign': 2, + 'no-cond-assign': 2, + 'no-const-assign': 2, + 'no-control-regex': 0, + 'no-delete-var': 2, + 'no-dupe-args': 2, + 'no-dupe-class-members': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-empty-pattern': 2, + 'no-eval': 2, + 'no-ex-assign': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-boolean-cast': 2, + 'no-extra-parens': [2, 'functions'], + 'no-fallthrough': 2, + 'no-floating-decimal': 2, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-inner-declarations': [2, 'functions'], + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 2, + 'no-iterator': 2, + 'no-label-var': 2, + 'no-labels': [2, { + 'allowLoop': false, + 'allowSwitch': false + }], + 'no-lone-blocks': 2, + 'no-mixed-spaces-and-tabs': 2, + 'no-multi-spaces': 2, + 'no-multi-str': 2, + 'no-multiple-empty-lines': [2, { + 'max': 1 + }], + 'no-native-reassign': 2, + 'no-negated-in-lhs': 2, + 'no-new-object': 2, + 'no-new-require': 2, + 'no-new-symbol': 2, + 'no-new-wrappers': 2, + 'no-obj-calls': 2, + 'no-octal': 2, + 'no-octal-escape': 2, + 'no-path-concat': 2, + 'no-proto': 2, + 'no-redeclare': 2, + 'no-regex-spaces': 2, + 'no-return-assign': [2, 'except-parens'], + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow-restricted-names': 2, + 'no-spaced-func': 2, + 'no-sparse-arrays': 2, + 'no-this-before-super': 2, + 'no-throw-literal': 2, + 'no-trailing-spaces': 2, + 'no-undef': 2, + 'no-undef-init': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': [2, { + 'defaultAssignment': false + }], + 'no-unreachable': 2, + 'no-unsafe-finally': 2, + 'no-unused-vars': [2, { + 'vars': 'all', + 'args': 'none' + }], + 'no-useless-call': 2, + 'no-useless-computed-key': 2, + 'no-useless-constructor': 2, + 'no-useless-escape': 0, + 'no-whitespace-before-property': 2, + 'no-with': 2, + 'one-var': [2, { + 'initialized': 'never' + }], + 'operator-linebreak': [2, 'after', { + 'overrides': { + '?': 'before', + ':': 'before' + } + }], + 'padded-blocks': [2, 'never'], + 'quotes': [2, 'single', { + 'avoidEscape': true, + 'allowTemplateLiterals': true + }], + 'semi': [2, 'never'], + 'semi-spacing': [2, { + 'before': false, + 'after': true + }], + 'space-before-blocks': [2, 'always'], + 'space-before-function-paren': [2, 'never'], + 'space-in-parens': [2, 'never'], + 'space-infix-ops': 2, + 'space-unary-ops': [2, { + 'words': true, + 'nonwords': false + }], + 'spaced-comment': [2, 'always', { + 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] + }], + 'template-curly-spacing': [2, 'never'], + 'use-isnan': 2, + 'valid-typeof': 2, + 'wrap-iife': [2, 'any'], + 'yield-star-spacing': [2, 'both'], + 'yoda': [2, 'never'], + 'prefer-const': 2, + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'object-curly-spacing': [2, 'always', { + objectsInObjects: false + }], + 'array-bracket-spacing': [2, 'never'] + } +} diff --git a/frontend/src/components/files/Listing.vue b/frontend/src/components/files/Listing.vue index a227cced..44cfd31e 100644 --- a/frontend/src/components/files/Listing.vue +++ b/frontend/src/components/files/Listing.vue @@ -4,41 +4,53 @@ sentiment_dissatisfied {{ $t('files.lonely') }} - + -
+ @dragend="dragEnd" + >
-
+
-

+ :aria-label="$t('files.sortByName')" + @click="sort('name')" + > {{ $t('files.name') }} {{ nameIcon }}

-

+ :aria-label="$t('files.sortBySize')" + @click="sort('size')" + > {{ $t('files.size') }} {{ sizeIcon }}

-

+ :aria-label="$t('files.sortByLastModified')" + @click="sort('modified')" + > {{ $t('files.lastModified') }} {{ modifiedIcon }}

@@ -48,37 +60,39 @@

{{ $t('files.folders') }}

- - + :index="item.index" + :name="item.name" + :is-dir="item.isDir" + :url="item.url" + :modified="item.modified" + :type="item.type" + :size="item.size" + />

{{ $t('files.files') }}

- - + :index="item.index" + :name="item.name" + :is-dir="item.isDir" + :url="item.url" + :modified="item.modified" + :type="item.type" + :size="item.size" + />
- + -
-

{{ $t('files.multipleSelectionEnabled') }}

-
+
+

{{ $t('files.multipleSelectionEnabled') }}

+
clear
@@ -94,28 +108,28 @@ import buttons from '@/utils/buttons' import url from '@/utils/url' export default { - name: 'listing', + name: 'Listing', components: { Item }, - data: function () { + data: function() { return { show: 50 } }, computed: { ...mapState(['req', 'selected', 'user']), - nameSorted () { + nameSorted() { return (this.req.sorting.by === 'name') }, - sizeSorted () { + sizeSorted() { return (this.req.sorting.by === 'size') }, - modifiedSorted () { + modifiedSorted() { return (this.req.sorting.by === 'modified') }, - ascOrdered () { + ascOrdered() { return this.req.sorting.asc }, - items () { + items() { const dirs = [] const files = [] @@ -129,31 +143,31 @@ export default { return { dirs, files } }, - dirs () { + dirs() { return this.items.dirs.slice(0, this.show) }, - files () { + files() { let show = this.show - this.items.dirs.length if (show < 0) show = 0 return this.items.files.slice(0, show) }, - nameIcon () { + nameIcon() { if (this.nameSorted && !this.ascOrdered) { return 'arrow_upward' } return 'arrow_downward' }, - sizeIcon () { + sizeIcon() { if (this.sizeSorted && this.ascOrdered) { return 'arrow_downward' } return 'arrow_upward' }, - modifiedIcon () { + modifiedIcon() { if (this.modifiedSorted && this.ascOrdered) { return 'arrow_downward' } @@ -161,7 +175,7 @@ export default { return 'arrow_upward' } }, - mounted: function () { + mounted: function() { // Check the columns size for the first time. this.resizeEvent() @@ -172,7 +186,7 @@ export default { document.addEventListener('dragover', this.preventDefault) document.addEventListener('drop', this.drop) }, - beforeDestroy () { + beforeDestroy() { // Remove event listeners before destroying this page. window.removeEventListener('keydown', this.keyEvent) window.removeEventListener('resize', this.resizeEvent) @@ -181,16 +195,16 @@ export default { document.removeEventListener('drop', this.drop) }, methods: { - ...mapMutations([ 'updateUser' ]), - base64: function (name) { + ...mapMutations(['updateUser']), + base64: function(name) { return window.btoa(unescape(encodeURIComponent(name))) }, - keyEvent (event) { + keyEvent(event) { if (!event.ctrlKey && !event.metaKey) { return } - let key = String.fromCharCode(event.which).toLowerCase() + const key = String.fromCharCode(event.which).toLowerCase() switch (key) { case 'f': @@ -206,25 +220,25 @@ export default { break } }, - preventDefault (event) { + preventDefault(event) { // Wrapper around prevent default. event.preventDefault() }, - copyCut (event, key) { + copyCut(event, key) { if (event.target.tagName.toLowerCase() === 'input') { return } - let items = [] + const items = [] - for (let i of this.selected) { + for (const i of this.selected) { items.push({ from: this.req.items[i].url, name: encodeURIComponent(this.req.items[i].name) }) } - if (items.length == 0) { + if (items.length === 0) { return } @@ -233,14 +247,14 @@ export default { items: items }) }, - paste (event) { + paste(event) { if (event.target.tagName.toLowerCase() === 'input') { return } - let items = [] + const items = [] - for (let item of this.$store.state.clipboard.items) { + for (const item of this.$store.state.clipboard.items) { const from = item.from.endsWith('/') ? item.from.slice(0, -1) : item.from const to = this.$route.path + item.name items.push({ from, to }) @@ -261,36 +275,36 @@ export default { this.$store.commit('setReload', true) }).catch(this.$showError) }, - resizeEvent () { + resizeEvent() { // Update the columns size based on the window width. let columns = Math.floor(document.querySelector('main').offsetWidth / 300) - let items = css(['#listing.mosaic .item', '.mosaic#listing .item']) + const items = css(['#listing.mosaic .item', '.mosaic#listing .item']) if (columns === 0) columns = 1 items.style.width = `calc(${100 / columns}% - 1em)` }, - scrollEvent () { + scrollEvent() { if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) { this.show += 50 } }, - dragEnter () { + dragEnter() { // When the user starts dragging an item, put every // file on the listing with 50% opacity. - let items = document.getElementsByClassName('item') + const items = document.getElementsByClassName('item') Array.from(items).forEach(file => { file.style.opacity = 0.5 }) }, - dragEnd () { + dragEnd() { this.resetOpacity() }, - drop: function (event) { + drop: function(event) { event.preventDefault() this.resetOpacity() - let dt = event.dataTransfer - let files = dt.files + const dt = event.dataTransfer + const files = dt.files let el = event.target if (files.length <= 0) return @@ -318,14 +332,14 @@ export default { this.checkConflict(files, this.req.items, base) }, - checkConflict (files, items, base) { + checkConflict(files, items, base) { if (typeof items === 'undefined' || items === null) { items = [] } let conflict = false for (let i = 0; i < files.length; i++) { - let res = items.findIndex(function hasConflict (element) { + const res = items.findIndex(function hasConflict(element) { return (element.name === this) }, files[i].name) @@ -349,22 +363,22 @@ export default { } }) }, - uploadInput (event) { + uploadInput(event) { this.checkConflict(event.currentTarget.files, this.req.items, '') }, - resetOpacity () { - let items = document.getElementsByClassName('item') + resetOpacity() { + const items = document.getElementsByClassName('item') Array.from(items).forEach(file => { file.style.opacity = 1 }) }, - handleFiles (files, base, overwrite = false) { + handleFiles(files, base, overwrite = false) { buttons.loading('upload') - let promises = [] - let progress = new Array(files.length).fill(0) + const promises = [] + const progress = new Array(files.length).fill(0) - let onupload = (id) => (event) => { + const onupload = (id) => (event) => { progress[id] = (event.loaded / event.total) * 100 let sum = 0 @@ -376,12 +390,12 @@ export default { } for (let i = 0; i < files.length; i++) { - let file = files[i] - let filenameEncoded = url.encodeRFC5987ValueChars(file.name) + const file = files[i] + const filenameEncoded = url.encodeRFC5987ValueChars(file.name) promises.push(api.post(this.$route.path + base + filenameEncoded, file, overwrite, onupload(i))) } - let finish = () => { + const finish = () => { buttons.success('upload') this.$store.commit('setProgress', 0) } @@ -398,7 +412,7 @@ export default { return false }, - async sort (by) { + async sort(by) { let asc = false if (by === 'name') { @@ -416,7 +430,7 @@ export default { } try { - await users.update({ id: this.user.id, sorting: { by, asc } }, ['sorting']) + await users.update({ id: this.user.id, sorting: { by, asc }}, ['sorting']) } catch (e) { this.$showError(e) } diff --git a/frontend/src/components/files/ListingItem.vue b/frontend/src/components/files/ListingItem.vue index 96aa9dad..b47bef8d 100644 --- a/frontend/src/components/files/ListingItem.vue +++ b/frontend/src/components/files/ListingItem.vue @@ -4,18 +4,18 @@ role="button" tabindex="0" draggable="true" + :data-dir="isDir" + :aria-label="name" + :aria-selected="isSelected" @dragstart="dragStart" @dragover="dragOver" @drop="drop" @click="click" @dblclick="open" @touchstart="touchstart" - :data-dir="isDir" - :aria-label="name" - :aria-selected="isSelected" >
- + {{ icon }}
@@ -34,146 +34,146 @@ diff --git a/frontend/src/components/files/Preview.vue b/frontend/src/components/files/Preview.vue index 714c34fe..aed90522 100644 --- a/frontend/src/components/files/Preview.vue +++ b/frontend/src/components/files/Preview.vue @@ -2,57 +2,57 @@
- - - - + + + +
- - + +