allow download multiple shares
This commit is contained in:
parent
338c546f2f
commit
72ca1f4b48
@ -49,11 +49,17 @@
|
||||
}
|
||||
|
||||
.share__box__items #listing.list .item {
|
||||
cursor: auto;
|
||||
cursor: pointer;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
-webkit-user-select:none;
|
||||
-khtml-user-select:none;
|
||||
-moz-user-select:none;
|
||||
-ms-user-select:none;
|
||||
-o-user-select:none;
|
||||
user-select:none;
|
||||
}
|
||||
|
||||
.share__box__items #listing.list .item .name {
|
||||
|
||||
@ -245,6 +245,7 @@
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder"
|
||||
"downloadFolder": "Download Folder",
|
||||
"downloadSelected": "Download Selected"
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,6 +242,7 @@
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "下载文件",
|
||||
"downloadFolder": "下载文件夹"
|
||||
"downloadFolder": "下载文件夹",
|
||||
"downloadSelected": "下载已选"
|
||||
}
|
||||
}
|
||||
@ -13,7 +13,7 @@
|
||||
<div class="share">
|
||||
<div class="share__box share__box__info">
|
||||
<div class="share__box__header">
|
||||
{{ file.isDir ? $t('download.downloadFolder') : $t('download.downloadFile') }}
|
||||
{{ file.isDir ? multiple ? $t('download.downloadSelected') : $t('download.downloadFolder') : $t('download.downloadFile') }}
|
||||
</div>
|
||||
<div class="share__box__element share__box__center share__box__icon">
|
||||
<i class="material-icons">{{ file.isDir ? 'folder' : 'insert_drive_file'}}</i>
|
||||
@ -39,12 +39,16 @@
|
||||
{{ $t('files.files') }}
|
||||
</div>
|
||||
<div id="listing" class="list">
|
||||
<div class="item" v-for="(item) in file.items.slice(0, this.showLimit)" :key="base64(item.name)">
|
||||
<div class="item" v-for="(item) in file.items.slice(0, this.showLimit)" :key="base64(item.name)"
|
||||
:aria-selected="selected.includes(item.name)"
|
||||
@click="click(item.name)"
|
||||
@dblclick="dbclick(item.name)"
|
||||
>
|
||||
<div>
|
||||
<router-link :to="'/share/' + hash + item.name + '/'"><i class="material-icons">{{ item.isDir ? 'folder' : (item.type==='image') ? 'insert_photo' : 'insert_drive_file' }}</i></router-link>
|
||||
<i class="material-icons">{{ item.isDir ? 'folder' : (item.type==='image') ? 'insert_photo' : 'insert_drive_file' }}</i>
|
||||
</div>
|
||||
<div>
|
||||
<router-link :to="'/share/' + hash + item.name + '/'"><p class="name">{{ item.name }}</p></router-link>
|
||||
<p class="name">{{ item.name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="file.items.length > showLimit" class="item">
|
||||
@ -74,7 +78,9 @@ export default {
|
||||
loaded: false,
|
||||
notFound: false,
|
||||
file: null,
|
||||
showLimit: 500
|
||||
showLimit: 500,
|
||||
selected: [],
|
||||
firstSelected: -1
|
||||
}),
|
||||
watch: {
|
||||
'$route': 'fetchData'
|
||||
@ -83,6 +89,9 @@ export default {
|
||||
this.fetchData()
|
||||
},
|
||||
computed: {
|
||||
multiple: function () {
|
||||
return this.selected.length > 0
|
||||
},
|
||||
hash: function () {
|
||||
if (this.$route.params.pathMatch[this.$route.params.pathMatch.length - 1] !== '/') return this.$route.params.pathMatch + '/'
|
||||
return this.$route.params.pathMatch
|
||||
@ -91,7 +100,12 @@ export default {
|
||||
return this.$route.params.pathMatch.split('/')[0] + '/'
|
||||
},
|
||||
link: function () {
|
||||
return `${baseURL}/api/public/dl/${this.hash}${encodeURI(this.file.name)}`
|
||||
if (!this.multiple) return `${baseURL}/api/public/dl/${this.hash}${encodeURI(this.file.name)}`
|
||||
let files = []
|
||||
for (let s of this.selected) {
|
||||
files.push('/' + encodeURI(s) + '/')
|
||||
}
|
||||
return `${baseURL}/api/public/raw/${this.hash}?files=${encodeURIComponent(files.join(','))}`
|
||||
},
|
||||
fullLink: function () {
|
||||
return window.location.origin + this.link
|
||||
@ -146,12 +160,67 @@ export default {
|
||||
return window.btoa(unescape(encodeURIComponent(name)))
|
||||
},
|
||||
fetchData: async function () {
|
||||
this.loaded = false
|
||||
this.notFound = false
|
||||
this.selected = []
|
||||
this.firstSelected = -1
|
||||
try {
|
||||
this.file = await api.getHash(this.hash)
|
||||
this.loaded = true
|
||||
} catch (e) {
|
||||
this.notFound = true
|
||||
}
|
||||
},
|
||||
addSelected: function(name) {
|
||||
this.selected.push(name)
|
||||
},
|
||||
removeSelected: function (name) {
|
||||
let i = this.selected.indexOf(name)
|
||||
if (i === -1) return
|
||||
this.selected.splice(i, 1)
|
||||
if (i === 0 && this.multiple) {
|
||||
this.firstSelected = this.file.items.indexOf(this.file.items.filter(item => item.name === this.selected[0])[0])
|
||||
}
|
||||
},
|
||||
resetSelected: function () {
|
||||
this.selected = []
|
||||
this.firstSelected = -1
|
||||
},
|
||||
click: function (name) {
|
||||
if (this.multiple) event.preventDefault()
|
||||
if (this.selected.indexOf(name) !== -1) {
|
||||
this.removeSelected(name)
|
||||
return
|
||||
}
|
||||
|
||||
let index = this.file.items.indexOf(this.file.items.filter(item => item.name === name)[0])
|
||||
if (event.shiftKey && this.multiple) {
|
||||
let fi = 0
|
||||
let la = 0
|
||||
|
||||
if (index > this.firstSelected) {
|
||||
fi = this.firstSelected + 1
|
||||
la = index
|
||||
} else {
|
||||
fi = index
|
||||
la = this.firstSelected - 1
|
||||
}
|
||||
|
||||
for (; fi <= la; fi++) {
|
||||
if (this.selected.indexOf(this.file.items[fi].name) === -1) {
|
||||
this.addSelected(this.file.items[fi].name)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (!event.ctrlKey && !this.multiple) this.resetSelected()
|
||||
if (this.firstSelected === -1) this.firstSelected = index
|
||||
this.addSelected(name)
|
||||
},
|
||||
dbclick: function (name) {
|
||||
this.$router.push({path: `/share/${this.hash}${name}`})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ func NewHandler(imgSvc ImgService, fileCache FileCache, store *storage.Storage,
|
||||
public := api.PathPrefix("/public").Subrouter()
|
||||
public.PathPrefix("/dl").Handler(monkey(publicDlHandler, "/api/public/dl/")).Methods("GET")
|
||||
public.PathPrefix("/share").Handler(monkey(publicShareHandler, "/api/public/share/")).Methods("GET")
|
||||
public.PathPrefix("/raw").Handler(monkey(publicRawHandler, "/api/public/raw/")).Methods("GET")
|
||||
|
||||
return stripPrefix(server.BaseURL, r), nil
|
||||
}
|
||||
|
||||
@ -74,3 +74,12 @@ var publicDlHandler = withHashFile(func(w http.ResponseWriter, r *http.Request,
|
||||
|
||||
return rawDirHandler(w, r, d, file)
|
||||
}, true)
|
||||
|
||||
var publicRawHandler = withHashFile(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||
file := d.raw.(*files.FileInfo)
|
||||
if !file.IsDir {
|
||||
return rawFileHandler(w, r, file)
|
||||
}
|
||||
|
||||
return rawDirHandler(w, r, d, file)
|
||||
}, false)
|
||||
Loading…
Reference in New Issue
Block a user