refactor: eslint config
This commit is contained in:
parent
558a56bad5
commit
60711fa74b
198
frontend/.eslintrc.js
Normal file
198
frontend/.eslintrc.js
Normal file
@ -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']
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,41 +4,53 @@
|
|||||||
<i class="material-icons">sentiment_dissatisfied</i>
|
<i class="material-icons">sentiment_dissatisfied</i>
|
||||||
<span>{{ $t('files.lonely') }}</span>
|
<span>{{ $t('files.lonely') }}</span>
|
||||||
</h2>
|
</h2>
|
||||||
<input style="display:none" type="file" id="upload-input" @change="uploadInput($event)" multiple>
|
<input id="upload-input" style="display:none" type="file" multiple @change="uploadInput($event)">
|
||||||
</div>
|
</div>
|
||||||
<div v-else id="listing"
|
<div
|
||||||
|
v-else
|
||||||
|
id="listing"
|
||||||
:class="user.viewMode"
|
:class="user.viewMode"
|
||||||
@dragenter="dragEnter"
|
@dragenter="dragEnter"
|
||||||
@dragend="dragEnd">
|
@dragend="dragEnd"
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<div class="item header">
|
<div class="item header">
|
||||||
<div></div>
|
<div />
|
||||||
<div>
|
<div>
|
||||||
<p :class="{ active: nameSorted }" class="name"
|
<p
|
||||||
|
:class="{ active: nameSorted }"
|
||||||
|
class="name"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@click="sort('name')"
|
|
||||||
:title="$t('files.sortByName')"
|
:title="$t('files.sortByName')"
|
||||||
:aria-label="$t('files.sortByName')">
|
:aria-label="$t('files.sortByName')"
|
||||||
|
@click="sort('name')"
|
||||||
|
>
|
||||||
<span>{{ $t('files.name') }}</span>
|
<span>{{ $t('files.name') }}</span>
|
||||||
<i class="material-icons">{{ nameIcon }}</i>
|
<i class="material-icons">{{ nameIcon }}</i>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p :class="{ active: sizeSorted }" class="size"
|
<p
|
||||||
|
:class="{ active: sizeSorted }"
|
||||||
|
class="size"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@click="sort('size')"
|
|
||||||
:title="$t('files.sortBySize')"
|
:title="$t('files.sortBySize')"
|
||||||
:aria-label="$t('files.sortBySize')">
|
:aria-label="$t('files.sortBySize')"
|
||||||
|
@click="sort('size')"
|
||||||
|
>
|
||||||
<span>{{ $t('files.size') }}</span>
|
<span>{{ $t('files.size') }}</span>
|
||||||
<i class="material-icons">{{ sizeIcon }}</i>
|
<i class="material-icons">{{ sizeIcon }}</i>
|
||||||
</p>
|
</p>
|
||||||
<p :class="{ active: modifiedSorted }" class="modified"
|
<p
|
||||||
|
:class="{ active: modifiedSorted }"
|
||||||
|
class="modified"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@click="sort('modified')"
|
|
||||||
:title="$t('files.sortByLastModified')"
|
:title="$t('files.sortByLastModified')"
|
||||||
:aria-label="$t('files.sortByLastModified')">
|
:aria-label="$t('files.sortByLastModified')"
|
||||||
|
@click="sort('modified')"
|
||||||
|
>
|
||||||
<span>{{ $t('files.lastModified') }}</span>
|
<span>{{ $t('files.lastModified') }}</span>
|
||||||
<i class="material-icons">{{ modifiedIcon }}</i>
|
<i class="material-icons">{{ modifiedIcon }}</i>
|
||||||
</p>
|
</p>
|
||||||
@ -48,37 +60,39 @@
|
|||||||
|
|
||||||
<h2 v-if="req.numDirs > 0">{{ $t('files.folders') }}</h2>
|
<h2 v-if="req.numDirs > 0">{{ $t('files.folders') }}</h2>
|
||||||
<div v-if="req.numDirs > 0">
|
<div v-if="req.numDirs > 0">
|
||||||
<item v-for="(item) in dirs"
|
<item
|
||||||
|
v-for="(item) in dirs"
|
||||||
:key="base64(item.name)"
|
:key="base64(item.name)"
|
||||||
v-bind:index="item.index"
|
:index="item.index"
|
||||||
v-bind:name="item.name"
|
:name="item.name"
|
||||||
v-bind:isDir="item.isDir"
|
:is-dir="item.isDir"
|
||||||
v-bind:url="item.url"
|
:url="item.url"
|
||||||
v-bind:modified="item.modified"
|
:modified="item.modified"
|
||||||
v-bind:type="item.type"
|
:type="item.type"
|
||||||
v-bind:size="item.size">
|
:size="item.size"
|
||||||
</item>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 v-if="req.numFiles > 0">{{ $t('files.files') }}</h2>
|
<h2 v-if="req.numFiles > 0">{{ $t('files.files') }}</h2>
|
||||||
<div v-if="req.numFiles > 0">
|
<div v-if="req.numFiles > 0">
|
||||||
<item v-for="(item) in files"
|
<item
|
||||||
|
v-for="(item) in files"
|
||||||
:key="base64(item.name)"
|
:key="base64(item.name)"
|
||||||
v-bind:index="item.index"
|
:index="item.index"
|
||||||
v-bind:name="item.name"
|
:name="item.name"
|
||||||
v-bind:isDir="item.isDir"
|
:is-dir="item.isDir"
|
||||||
v-bind:url="item.url"
|
:url="item.url"
|
||||||
v-bind:modified="item.modified"
|
:modified="item.modified"
|
||||||
v-bind:type="item.type"
|
:type="item.type"
|
||||||
v-bind:size="item.size">
|
:size="item.size"
|
||||||
</item>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input style="display:none" type="file" id="upload-input" @change="uploadInput($event)" multiple>
|
<input id="upload-input" style="display:none" type="file" multiple @change="uploadInput($event)">
|
||||||
|
|
||||||
<div :class="{ active: $store.state.multiple }" id="multiple-selection">
|
<div id="multiple-selection" :class="{ active: $store.state.multiple }">
|
||||||
<p>{{ $t('files.multipleSelectionEnabled') }}</p>
|
<p>{{ $t('files.multipleSelectionEnabled') }}</p>
|
||||||
<div @click="$store.commit('multiple', false)" tabindex="0" role="button" :title="$t('files.clear')" :aria-label="$t('files.clear')" class="action">
|
<div tabindex="0" role="button" :title="$t('files.clear')" :aria-label="$t('files.clear')" class="action" @click="$store.commit('multiple', false)">
|
||||||
<i class="material-icons">clear</i>
|
<i class="material-icons">clear</i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -94,7 +108,7 @@ import buttons from '@/utils/buttons'
|
|||||||
import url from '@/utils/url'
|
import url from '@/utils/url'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'listing',
|
name: 'Listing',
|
||||||
components: { Item },
|
components: { Item },
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
@ -190,7 +204,7 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let key = String.fromCharCode(event.which).toLowerCase()
|
const key = String.fromCharCode(event.which).toLowerCase()
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'f':
|
case 'f':
|
||||||
@ -215,16 +229,16 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let items = []
|
const items = []
|
||||||
|
|
||||||
for (let i of this.selected) {
|
for (const i of this.selected) {
|
||||||
items.push({
|
items.push({
|
||||||
from: this.req.items[i].url,
|
from: this.req.items[i].url,
|
||||||
name: encodeURIComponent(this.req.items[i].name)
|
name: encodeURIComponent(this.req.items[i].name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items.length == 0) {
|
if (items.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,9 +252,9 @@ export default {
|
|||||||
return
|
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 from = item.from.endsWith('/') ? item.from.slice(0, -1) : item.from
|
||||||
const to = this.$route.path + item.name
|
const to = this.$route.path + item.name
|
||||||
items.push({ from, to })
|
items.push({ from, to })
|
||||||
@ -264,7 +278,7 @@ export default {
|
|||||||
resizeEvent() {
|
resizeEvent() {
|
||||||
// Update the columns size based on the window width.
|
// Update the columns size based on the window width.
|
||||||
let columns = Math.floor(document.querySelector('main').offsetWidth / 300)
|
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
|
if (columns === 0) columns = 1
|
||||||
items.style.width = `calc(${100 / columns}% - 1em)`
|
items.style.width = `calc(${100 / columns}% - 1em)`
|
||||||
},
|
},
|
||||||
@ -276,7 +290,7 @@ export default {
|
|||||||
dragEnter() {
|
dragEnter() {
|
||||||
// When the user starts dragging an item, put every
|
// When the user starts dragging an item, put every
|
||||||
// file on the listing with 50% opacity.
|
// file on the listing with 50% opacity.
|
||||||
let items = document.getElementsByClassName('item')
|
const items = document.getElementsByClassName('item')
|
||||||
|
|
||||||
Array.from(items).forEach(file => {
|
Array.from(items).forEach(file => {
|
||||||
file.style.opacity = 0.5
|
file.style.opacity = 0.5
|
||||||
@ -289,8 +303,8 @@ export default {
|
|||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
this.resetOpacity()
|
this.resetOpacity()
|
||||||
|
|
||||||
let dt = event.dataTransfer
|
const dt = event.dataTransfer
|
||||||
let files = dt.files
|
const files = dt.files
|
||||||
let el = event.target
|
let el = event.target
|
||||||
|
|
||||||
if (files.length <= 0) return
|
if (files.length <= 0) return
|
||||||
@ -325,7 +339,7 @@ export default {
|
|||||||
|
|
||||||
let conflict = false
|
let conflict = false
|
||||||
for (let i = 0; i < files.length; i++) {
|
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)
|
return (element.name === this)
|
||||||
}, files[i].name)
|
}, files[i].name)
|
||||||
|
|
||||||
@ -353,7 +367,7 @@ export default {
|
|||||||
this.checkConflict(event.currentTarget.files, this.req.items, '')
|
this.checkConflict(event.currentTarget.files, this.req.items, '')
|
||||||
},
|
},
|
||||||
resetOpacity() {
|
resetOpacity() {
|
||||||
let items = document.getElementsByClassName('item')
|
const items = document.getElementsByClassName('item')
|
||||||
|
|
||||||
Array.from(items).forEach(file => {
|
Array.from(items).forEach(file => {
|
||||||
file.style.opacity = 1
|
file.style.opacity = 1
|
||||||
@ -361,10 +375,10 @@ export default {
|
|||||||
},
|
},
|
||||||
handleFiles(files, base, overwrite = false) {
|
handleFiles(files, base, overwrite = false) {
|
||||||
buttons.loading('upload')
|
buttons.loading('upload')
|
||||||
let promises = []
|
const promises = []
|
||||||
let progress = new Array(files.length).fill(0)
|
const progress = new Array(files.length).fill(0)
|
||||||
|
|
||||||
let onupload = (id) => (event) => {
|
const onupload = (id) => (event) => {
|
||||||
progress[id] = (event.loaded / event.total) * 100
|
progress[id] = (event.loaded / event.total) * 100
|
||||||
|
|
||||||
let sum = 0
|
let sum = 0
|
||||||
@ -376,12 +390,12 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
let file = files[i]
|
const file = files[i]
|
||||||
let filenameEncoded = url.encodeRFC5987ValueChars(file.name)
|
const filenameEncoded = url.encodeRFC5987ValueChars(file.name)
|
||||||
promises.push(api.post(this.$route.path + base + filenameEncoded, file, overwrite, onupload(i)))
|
promises.push(api.post(this.$route.path + base + filenameEncoded, file, overwrite, onupload(i)))
|
||||||
}
|
}
|
||||||
|
|
||||||
let finish = () => {
|
const finish = () => {
|
||||||
buttons.success('upload')
|
buttons.success('upload')
|
||||||
this.$store.commit('setProgress', 0)
|
this.$store.commit('setProgress', 0)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,18 +4,18 @@
|
|||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
draggable="true"
|
draggable="true"
|
||||||
|
:data-dir="isDir"
|
||||||
|
:aria-label="name"
|
||||||
|
:aria-selected="isSelected"
|
||||||
@dragstart="dragStart"
|
@dragstart="dragStart"
|
||||||
@dragover="dragOver"
|
@dragover="dragOver"
|
||||||
@drop="drop"
|
@drop="drop"
|
||||||
@click="click"
|
@click="click"
|
||||||
@dblclick="open"
|
@dblclick="open"
|
||||||
@touchstart="touchstart"
|
@touchstart="touchstart"
|
||||||
:data-dir="isDir"
|
|
||||||
:aria-label="name"
|
|
||||||
:aria-selected="isSelected"
|
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<img v-if="type==='image'" :src="compressUrl" />
|
<img v-if="type==='image'" :src="compressUrl">
|
||||||
<i v-else class="material-icons">{{ icon }}</i>
|
<i v-else class="material-icons">{{ icon }}</i>
|
||||||
<!-- <i class="material-icons">{{ icon }}</i> -->
|
<!-- <i class="material-icons">{{ icon }}</i> -->
|
||||||
</div>
|
</div>
|
||||||
@ -34,146 +34,146 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapMutations, mapGetters, mapState } from "vuex";
|
import { mapMutations, mapGetters, mapState } from 'vuex'
|
||||||
import { baseURL } from "@/utils/constants";
|
import { baseURL } from '@/utils/constants'
|
||||||
import filesize from "filesize";
|
import filesize from 'filesize'
|
||||||
import moment from "moment";
|
import moment from 'moment'
|
||||||
import { files as api } from "@/api";
|
import { files as api } from '@/api'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "item",
|
name: 'Item',
|
||||||
|
props: ['name', 'isDir', 'url', 'type', 'size', 'modified', 'index'],
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
touches: 0
|
touches: 0
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
props: ["name", "isDir", "url", "type", "size", "modified", "index"],
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["selected", "req", "jwt"]),
|
...mapState(['selected', 'req', 'jwt']),
|
||||||
...mapGetters(["selectedCount"]),
|
...mapGetters(['selectedCount']),
|
||||||
isSelected() {
|
isSelected() {
|
||||||
return this.selected.indexOf(this.index) !== -1;
|
return this.selected.indexOf(this.index) !== -1
|
||||||
},
|
},
|
||||||
icon() {
|
icon() {
|
||||||
if (this.isDir) return "folder";
|
if (this.isDir) return 'folder'
|
||||||
if (this.type === "image") return "insert_photo";
|
if (this.type === 'image') return 'insert_photo'
|
||||||
if (this.type === "audio") return "volume_up";
|
if (this.type === 'audio') return 'volume_up'
|
||||||
if (this.type === "video") return "movie";
|
if (this.type === 'video') return 'movie'
|
||||||
return "insert_drive_file";
|
return 'insert_drive_file'
|
||||||
},
|
},
|
||||||
canDrop() {
|
canDrop() {
|
||||||
if (!this.isDir) return false;
|
if (!this.isDir) return false
|
||||||
|
|
||||||
for (let i of this.selected) {
|
for (const i of this.selected) {
|
||||||
if (this.req.items[i].url === this.url) {
|
if (this.req.items[i].url === this.url) {
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true
|
||||||
},
|
},
|
||||||
compressUrl() {
|
compressUrl() {
|
||||||
const path = this.url.replace(/^\/files\//, "");
|
const path = this.url.replace(/^\/files\//, '')
|
||||||
return `${baseURL}/api/compress/${path}?auth=${this.jwt}&inline=true`;
|
return `${baseURL}/api/compress/${path}?auth=${this.jwt}&inline=true`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations(["addSelected", "removeSelected", "resetSelected"]),
|
...mapMutations(['addSelected', 'removeSelected', 'resetSelected']),
|
||||||
humanSize: function() {
|
humanSize: function() {
|
||||||
return filesize(this.size);
|
return filesize(this.size)
|
||||||
},
|
},
|
||||||
humanTime: function() {
|
humanTime: function() {
|
||||||
return moment(this.modified).fromNow();
|
return moment(this.modified).fromNow()
|
||||||
},
|
},
|
||||||
dragStart: function() {
|
dragStart: function() {
|
||||||
if (this.selectedCount === 0) {
|
if (this.selectedCount === 0) {
|
||||||
this.addSelected(this.index);
|
this.addSelected(this.index)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.isSelected) {
|
if (!this.isSelected) {
|
||||||
this.resetSelected();
|
this.resetSelected()
|
||||||
this.addSelected(this.index);
|
this.addSelected(this.index)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dragOver: function(event) {
|
dragOver: function(event) {
|
||||||
if (!this.canDrop) return;
|
if (!this.canDrop) return
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault()
|
||||||
let el = event.target;
|
let el = event.target
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
if (!el.classList.contains("item")) {
|
if (!el.classList.contains('item')) {
|
||||||
el = el.parentElement;
|
el = el.parentElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
el.style.opacity = 1;
|
el.style.opacity = 1
|
||||||
},
|
},
|
||||||
drop: function(event) {
|
drop: function(event) {
|
||||||
if (!this.canDrop) return;
|
if (!this.canDrop) return
|
||||||
event.preventDefault();
|
event.preventDefault()
|
||||||
|
|
||||||
if (this.selectedCount === 0) return;
|
if (this.selectedCount === 0) return
|
||||||
|
|
||||||
let items = [];
|
const items = []
|
||||||
|
|
||||||
for (let i of this.selected) {
|
for (const i of this.selected) {
|
||||||
items.push({
|
items.push({
|
||||||
from: this.req.items[i].url,
|
from: this.req.items[i].url,
|
||||||
to: this.url + this.req.items[i].name
|
to: this.url + this.req.items[i].name
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
api
|
api
|
||||||
.move(items)
|
.move(items)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$store.commit("setReload", true);
|
this.$store.commit('setReload', true)
|
||||||
})
|
})
|
||||||
.catch(this.$showError);
|
.catch(this.$showError)
|
||||||
},
|
},
|
||||||
click: function(event) {
|
click: function(event) {
|
||||||
if (this.selectedCount !== 0) event.preventDefault();
|
if (this.selectedCount !== 0) event.preventDefault()
|
||||||
if (this.$store.state.selected.indexOf(this.index) !== -1) {
|
if (this.$store.state.selected.indexOf(this.index) !== -1) {
|
||||||
this.removeSelected(this.index);
|
this.removeSelected(this.index)
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.shiftKey) {
|
if (event.shiftKey) {
|
||||||
let fi = 0;
|
let fi = 0
|
||||||
let la = 0;
|
let la = 0
|
||||||
|
|
||||||
if (this.index > this.selected[0]) {
|
if (this.index > this.selected[0]) {
|
||||||
fi = this.selected[0] + 1;
|
fi = this.selected[0] + 1
|
||||||
la = this.index;
|
la = this.index
|
||||||
} else {
|
} else {
|
||||||
fi = this.index;
|
fi = this.index
|
||||||
la = this.selected[0] - 1;
|
la = this.selected[0] - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; fi <= la; fi++) {
|
for (; fi <= la; fi++) {
|
||||||
this.addSelected(fi);
|
this.addSelected(fi)
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!event.ctrlKey && !this.$store.state.multiple) this.resetSelected();
|
if (!event.ctrlKey && !this.$store.state.multiple) this.resetSelected()
|
||||||
this.addSelected(this.index);
|
this.addSelected(this.index)
|
||||||
},
|
},
|
||||||
touchstart() {
|
touchstart() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.touches = 0;
|
this.touches = 0
|
||||||
}, 300);
|
}, 300)
|
||||||
|
|
||||||
this.touches++;
|
this.touches++
|
||||||
if (this.touches > 1) {
|
if (this.touches > 1) {
|
||||||
this.open();
|
this.open()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
open: function() {
|
open: function() {
|
||||||
this.$router.push({ path: this.url });
|
this.$router.push({ path: this.url })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,57 +2,57 @@
|
|||||||
<div id="previewer">
|
<div id="previewer">
|
||||||
<div class="bar">
|
<div class="bar">
|
||||||
<button
|
<button
|
||||||
@click="back"
|
id="close"
|
||||||
class="action"
|
class="action"
|
||||||
:title="$t('files.closePreview')"
|
:title="$t('files.closePreview')"
|
||||||
:aria-label="$t('files.closePreview')"
|
:aria-label="$t('files.closePreview')"
|
||||||
id="close"
|
@click="back"
|
||||||
>
|
>
|
||||||
<i class="material-icons">close</i>
|
<i class="material-icons">close</i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<rename-button v-if="user.perm.rename"></rename-button>
|
<rename-button v-if="user.perm.rename" />
|
||||||
<delete-button v-if="user.perm.delete"></delete-button>
|
<delete-button v-if="user.perm.delete" />
|
||||||
<download-button v-if="user.perm.download"></download-button>
|
<download-button v-if="user.perm.download" />
|
||||||
<info-button></info-button>
|
<info-button />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="action"
|
|
||||||
@click="prev"
|
|
||||||
v-show="hasPrevious"
|
v-show="hasPrevious"
|
||||||
|
class="action"
|
||||||
:aria-label="$t('buttons.previous')"
|
:aria-label="$t('buttons.previous')"
|
||||||
:title="$t('buttons.previous')"
|
:title="$t('buttons.previous')"
|
||||||
|
@click="prev"
|
||||||
>
|
>
|
||||||
<i class="material-icons">chevron_left</i>
|
<i class="material-icons">chevron_left</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="action"
|
|
||||||
@click="next"
|
|
||||||
v-show="hasNext"
|
v-show="hasNext"
|
||||||
|
class="action"
|
||||||
:aria-label="$t('buttons.next')"
|
:aria-label="$t('buttons.next')"
|
||||||
:title="$t('buttons.next')"
|
:title="$t('buttons.next')"
|
||||||
|
@click="next"
|
||||||
>
|
>
|
||||||
<i class="material-icons">chevron_right</i>
|
<i class="material-icons">chevron_right</i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="preview">
|
<div class="preview">
|
||||||
<ExtendedImage v-if="req.type == 'image'" :src="raw"></ExtendedImage>
|
<ExtendedImage v-if="req.type == 'image'" :src="raw" />
|
||||||
<audio v-else-if="req.type == 'audio'" :src="raw" autoplay controls></audio>
|
<audio v-else-if="req.type == 'audio'" :src="raw" autoplay controls />
|
||||||
<video v-else-if="req.type == 'video'" :src="raw" autoplay controls>
|
<video v-else-if="req.type == 'video'" :src="raw" autoplay controls>
|
||||||
<track
|
<track
|
||||||
kind="captions"
|
|
||||||
v-for="(sub, index) in subtitles"
|
v-for="(sub, index) in subtitles"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
kind="captions"
|
||||||
:src="sub"
|
:src="sub"
|
||||||
:label="'Subtitle ' + index"
|
:label="'Subtitle ' + index"
|
||||||
:default="index === 0"
|
:default="index === 0"
|
||||||
/>Sorry, your browser doesn't support embedded videos,
|
>Sorry, your browser doesn't support embedded videos,
|
||||||
but don't worry, you can
|
but don't worry, you can
|
||||||
<a :href="download">download it</a>
|
<a :href="download">download it</a>
|
||||||
and watch it with your favorite video player!
|
and watch it with your favorite video player!
|
||||||
</video>
|
</video>
|
||||||
<object v-else-if="req.extension == '.pdf'" class="pdf" :data="raw"></object>
|
<object v-else-if="req.extension == '.pdf'" class="pdf" :data="raw" />
|
||||||
<a v-else-if="req.type == 'blob'" :href="download">
|
<a v-else-if="req.type == 'blob'" :href="download">
|
||||||
<h2 class="message">
|
<h2 class="message">
|
||||||
{{ $t('buttons.download') }}
|
{{ $t('buttons.download') }}
|
||||||
@ -64,20 +64,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from "vuex";
|
import { mapState } from 'vuex'
|
||||||
import url from "@/utils/url";
|
import url from '@/utils/url'
|
||||||
import { baseURL } from "@/utils/constants";
|
import { baseURL } from '@/utils/constants'
|
||||||
import { files as api } from "@/api";
|
import { files as api } from '@/api'
|
||||||
import InfoButton from "@/components/buttons/Info";
|
import InfoButton from '@/components/buttons/Info'
|
||||||
import DeleteButton from "@/components/buttons/Delete";
|
import DeleteButton from '@/components/buttons/Delete'
|
||||||
import RenameButton from "@/components/buttons/Rename";
|
import RenameButton from '@/components/buttons/Rename'
|
||||||
import DownloadButton from "@/components/buttons/Download";
|
import DownloadButton from '@/components/buttons/Download'
|
||||||
import ExtendedImage from "./ExtendedImage";
|
import ExtendedImage from './ExtendedImage'
|
||||||
|
|
||||||
const mediaTypes = ["image", "video", "audio", "blob"];
|
const mediaTypes = ['image', 'video', 'audio', 'blob']
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "preview",
|
name: 'Preview',
|
||||||
components: {
|
components: {
|
||||||
InfoButton,
|
InfoButton,
|
||||||
DeleteButton,
|
DeleteButton,
|
||||||
@ -87,103 +87,103 @@ export default {
|
|||||||
},
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
previousLink: "",
|
previousLink: '',
|
||||||
nextLink: "",
|
nextLink: '',
|
||||||
listing: null,
|
listing: null,
|
||||||
subtitles: []
|
subtitles: []
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["req", "user", "oldReq", "jwt"]),
|
...mapState(['req', 'user', 'oldReq', 'jwt']),
|
||||||
hasPrevious() {
|
hasPrevious() {
|
||||||
return this.previousLink !== "";
|
return this.previousLink !== ''
|
||||||
},
|
},
|
||||||
hasNext() {
|
hasNext() {
|
||||||
return this.nextLink !== "";
|
return this.nextLink !== ''
|
||||||
},
|
},
|
||||||
download() {
|
download() {
|
||||||
return `${baseURL}/api/raw${this.req.path}?auth=${this.jwt}`;
|
return `${baseURL}/api/raw${this.req.path}?auth=${this.jwt}`
|
||||||
},
|
},
|
||||||
compress() {
|
compress() {
|
||||||
if (this.req.type === 'image') {
|
if (this.req.type === 'image') {
|
||||||
return `${baseURL}/api/compress${this.req.path}?auth=${this.jwt}`;
|
return `${baseURL}/api/compress${this.req.path}?auth=${this.jwt}`
|
||||||
} else {
|
} else {
|
||||||
return `${baseURL}/api/raw${this.req.path}?auth=${this.jwt}`;
|
return `${baseURL}/api/raw${this.req.path}?auth=${this.jwt}`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
raw() {
|
raw() {
|
||||||
return `${this.compress}&inline=true`;
|
return `${this.compress}&inline=true`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
window.addEventListener("keyup", this.key);
|
window.addEventListener('keyup', this.key)
|
||||||
|
|
||||||
if (this.req.subtitles) {
|
if (this.req.subtitles) {
|
||||||
this.subtitles = this.req.subtitles.map(
|
this.subtitles = this.req.subtitles.map(
|
||||||
sub => `${baseURL}/api/raw${sub}?auth=${this.jwt}&inline=true`
|
sub => `${baseURL}/api/raw${sub}?auth=${this.jwt}&inline=true`
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.oldReq.items) {
|
if (this.oldReq.items) {
|
||||||
this.updateLinks(this.oldReq.items);
|
this.updateLinks(this.oldReq.items)
|
||||||
} else {
|
} else {
|
||||||
const path = url.removeLastDir(this.$route.path);
|
const path = url.removeLastDir(this.$route.path)
|
||||||
const res = await api.fetch(path);
|
const res = await api.fetch(path)
|
||||||
this.updateLinks(res.items);
|
this.updateLinks(res.items)
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$showError(e);
|
this.$showError(e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
window.removeEventListener("keyup", this.key);
|
window.removeEventListener('keyup', this.key)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
back() {
|
back() {
|
||||||
let uri = url.removeLastDir(this.$route.path) + "/";
|
const uri = url.removeLastDir(this.$route.path) + '/'
|
||||||
this.$router.push({ path: uri });
|
this.$router.push({ path: uri })
|
||||||
},
|
},
|
||||||
prev() {
|
prev() {
|
||||||
this.$router.push({ path: this.previousLink });
|
this.$router.push({ path: this.previousLink })
|
||||||
},
|
},
|
||||||
next() {
|
next() {
|
||||||
this.$router.push({ path: this.nextLink });
|
this.$router.push({ path: this.nextLink })
|
||||||
},
|
},
|
||||||
key(event) {
|
key(event) {
|
||||||
event.preventDefault();
|
event.preventDefault()
|
||||||
|
|
||||||
if (event.which === 13 || event.which === 39) {
|
if (event.which === 13 || event.which === 39) {
|
||||||
// right arrow
|
// right arrow
|
||||||
if (this.hasNext) this.next();
|
if (this.hasNext) this.next()
|
||||||
} else if (event.which === 37) {
|
} else if (event.which === 37) {
|
||||||
// left arrow
|
// left arrow
|
||||||
if (this.hasPrevious) this.prev();
|
if (this.hasPrevious) this.prev()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateLinks(items) {
|
updateLinks(items) {
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
if (items[i].name !== this.req.name) {
|
if (items[i].name !== this.req.name) {
|
||||||
continue;
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let j = i - 1; j >= 0; j--) {
|
for (let j = i - 1; j >= 0; j--) {
|
||||||
if (mediaTypes.includes(items[j].type)) {
|
if (mediaTypes.includes(items[j].type)) {
|
||||||
this.previousLink = items[j].url;
|
this.previousLink = items[j].url
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let j = i + 1; j < items.length; j++) {
|
for (let j = i + 1; j < items.length; j++) {
|
||||||
if (mediaTypes.includes(items[j].type)) {
|
if (mediaTypes.includes(items[j].type)) {
|
||||||
this.nextLink = items[j].url;
|
this.nextLink = items[j].url
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user