allow download multiple shares

This commit is contained in:
Weidi Deng 2020-12-11 10:41:07 +08:00
parent 338c546f2f
commit 72ca1f4b48
6 changed files with 96 additions and 9 deletions

View File

@ -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 {

View File

@ -245,6 +245,7 @@
},
"download": {
"downloadFile": "Download File",
"downloadFolder": "Download Folder"
"downloadFolder": "Download Folder",
"downloadSelected": "Download Selected"
}
}

View File

@ -242,6 +242,7 @@
},
"download": {
"downloadFile": "下载文件",
"downloadFolder": "下载文件夹"
"downloadFolder": "下载文件夹",
"downloadSelected": "下载已选"
}
}

View File

@ -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}`})
}
}
}

View File

@ -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
}

View File

@ -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)