chore: share view logic responsability
parent
d8306559fd
commit
edb9e85efd
|
@ -58,7 +58,7 @@ export async function put (url, content = '') {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function download (format, ...files) {
|
export function download (format, ...files) {
|
||||||
let url = store.getters['isSharing'] ? `${baseURL}/api/public/dl/${store.state.hash}` : `${baseURL}/api/raw`
|
let url = `${baseURL}/api/raw`
|
||||||
|
|
||||||
if (files.length === 1) {
|
if (files.length === 1) {
|
||||||
url += removePrefix(files[0]) + '?'
|
url += removePrefix(files[0]) + '?'
|
||||||
|
@ -74,15 +74,13 @@ export function download (format, ...files) {
|
||||||
url += `/?files=${arg}&`
|
url += `/?files=${arg}&`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format !== null) {
|
if (format) {
|
||||||
url += `algo=${format}&`
|
url += `algo=${format}&`
|
||||||
}
|
}
|
||||||
if (store.state.jwt !== ''){
|
|
||||||
|
if (store.state.jwt){
|
||||||
url += `auth=${store.state.jwt}&`
|
url += `auth=${store.state.jwt}&`
|
||||||
}
|
}
|
||||||
if (store.state.token !== ''){
|
|
||||||
url += `token=${store.state.token}`
|
|
||||||
}
|
|
||||||
|
|
||||||
window.open(url)
|
window.open(url)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import * as files from './files'
|
||||||
import * as share from './share'
|
import * as share from './share'
|
||||||
import * as users from './users'
|
import * as users from './users'
|
||||||
import * as settings from './settings'
|
import * as settings from './settings'
|
||||||
|
import * as pub from './pub'
|
||||||
import search from './search'
|
import search from './search'
|
||||||
import commands from './commands'
|
import commands from './commands'
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ export {
|
||||||
share,
|
share,
|
||||||
users,
|
users,
|
||||||
settings,
|
settings,
|
||||||
|
pub,
|
||||||
commands,
|
commands,
|
||||||
search
|
search
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { fetchJSON, removePrefix } from './utils'
|
||||||
|
import { baseURL } from '@/utils/constants'
|
||||||
|
|
||||||
|
export async function fetch(hash, password = "") {
|
||||||
|
return fetchJSON(`/api/public/share/${hash}`, {
|
||||||
|
headers: {'X-SHARE-PASSWORD': password},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function download(format, hash, token, ...files) {
|
||||||
|
let url = `${baseURL}/api/public/dl/${hash}`
|
||||||
|
|
||||||
|
const prefix = `/share/${hash}`
|
||||||
|
if (files.length === 1) {
|
||||||
|
url += removePrefix(files[0], prefix) + '?'
|
||||||
|
} else {
|
||||||
|
let arg = ''
|
||||||
|
|
||||||
|
for (let file of files) {
|
||||||
|
arg += removePrefix(file, prefix) + ','
|
||||||
|
}
|
||||||
|
|
||||||
|
arg = arg.substring(0, arg.length - 1)
|
||||||
|
arg = encodeURIComponent(arg)
|
||||||
|
url += `/?files=${arg}&`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format) {
|
||||||
|
url += `algo=${format}&`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
url += `token=${token}&`
|
||||||
|
}
|
||||||
|
|
||||||
|
window.open(url)
|
||||||
|
}
|
|
@ -4,12 +4,6 @@ export async function list() {
|
||||||
return fetchJSON('/api/shares')
|
return fetchJSON('/api/shares')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getHash(hash, password = "") {
|
|
||||||
return fetchJSON(`/api/public/share/${hash}`, {
|
|
||||||
headers: {'X-SHARE-PASSWORD': password},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function get(url) {
|
export async function get(url) {
|
||||||
url = removePrefix(url)
|
url = removePrefix(url)
|
||||||
return fetchJSON(`/api/share${url}`)
|
return fetchJSON(`/api/share${url}`)
|
||||||
|
|
|
@ -33,11 +33,11 @@ export async function fetchJSON (url, opts) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removePrefix (url) {
|
export function removePrefix (url, prefix) {
|
||||||
if (url.startsWith('/files')) {
|
if (url.startsWith('/files')) {
|
||||||
url = url.slice(6)
|
url = url.slice(6)
|
||||||
} else if (store.getters['isSharing']) {
|
} else if (prefix) {
|
||||||
url = url.slice(7 + store.state.hash.length)
|
url = url.replace(prefix, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url === '') url = '/'
|
if (url === '') url = '/'
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
:aria-label="name"
|
:aria-label="name"
|
||||||
:aria-selected="isSelected">
|
:aria-selected="isSelected">
|
||||||
<div>
|
<div>
|
||||||
<img v-if="type==='image' && isThumbsEnabled && !isSharing" v-lazy="thumbnailUrl">
|
<img v-if="readOnly == undefined && type==='image' && isThumbsEnabled" v-lazy="thumbnailUrl">
|
||||||
<i v-else class="material-icons">{{ icon }}</i>
|
<i v-else class="material-icons">{{ icon }}</i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -45,13 +45,12 @@ export default {
|
||||||
touches: 0
|
touches: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: ['name', 'isDir', 'url', 'type', 'size', 'modified', 'index'],
|
props: ['name', 'isDir', 'url', 'type', 'size', 'modified', 'index', 'readOnly'],
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['user', 'selected', 'req', 'jwt']),
|
...mapState(['user', 'selected', 'req', 'jwt']),
|
||||||
...mapGetters(['selectedCount', 'isSharing']),
|
...mapGetters(['selectedCount']),
|
||||||
singleClick () {
|
singleClick () {
|
||||||
if (this.isSharing) return false
|
return this.readOnly == undefined && this.user.singleClick
|
||||||
return this.user.singleClick
|
|
||||||
},
|
},
|
||||||
isSelected () {
|
isSelected () {
|
||||||
return (this.selected.indexOf(this.index) !== -1)
|
return (this.selected.indexOf(this.index) !== -1)
|
||||||
|
@ -64,10 +63,10 @@ export default {
|
||||||
return 'insert_drive_file'
|
return 'insert_drive_file'
|
||||||
},
|
},
|
||||||
isDraggable () {
|
isDraggable () {
|
||||||
return !this.isSharing && this.user.perm.rename
|
return this.readOnly == undefined && this.user.perm.rename
|
||||||
},
|
},
|
||||||
canDrop () {
|
canDrop () {
|
||||||
if (!this.isDir || this.isSharing) return false
|
if (!this.isDir || this.readOnly == undefined) return false
|
||||||
|
|
||||||
for (let i of this.selected) {
|
for (let i of this.selected) {
|
||||||
if (this.req.items[i].url === this.url) {
|
if (this.req.items[i].url === this.url) {
|
||||||
|
|
|
@ -7,43 +7,29 @@
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<p>{{ $t('prompts.downloadMessage') }}</p>
|
<p>{{ $t('prompts.downloadMessage') }}</p>
|
||||||
|
|
||||||
<button class="button button--block" @click="download('zip')" v-focus>zip</button>
|
<button v-for="(ext, format) in formats" :key="format" class="button button--block" @click="showConfirm(format)" v-focus>{{ ext }}</button>
|
||||||
<button class="button button--block" @click="download('tar')" v-focus>tar</button>
|
|
||||||
<button class="button button--block" @click="download('targz')" v-focus>tar.gz</button>
|
|
||||||
<button class="button button--block" @click="download('tarbz2')" v-focus>tar.bz2</button>
|
|
||||||
<button class="button button--block" @click="download('tarxz')" v-focus>tar.xz</button>
|
|
||||||
<button class="button button--block" @click="download('tarlz4')" v-focus>tar.lz4</button>
|
|
||||||
<button class="button button--block" @click="download('tarsz')" v-focus>tar.sz</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapGetters, mapState} from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import { files as api } from '@/api'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'download',
|
name: 'download',
|
||||||
computed: {
|
data: function () {
|
||||||
...mapState(['selected', 'req']),
|
return {
|
||||||
...mapGetters(['selectedCount'])
|
formats: {
|
||||||
|
zip: 'zip',
|
||||||
|
tar: 'tar',
|
||||||
|
targz: 'tar.gz',
|
||||||
|
tarbz2: 'tar.bz2',
|
||||||
|
tarxz: 'tar.xz',
|
||||||
|
tarlz4: 'tar.lz4',
|
||||||
|
tarsz: 'tar.sz'
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
computed: mapState(['showConfirm'])
|
||||||
download: function (format) {
|
|
||||||
if (this.selectedCount === 0) {
|
|
||||||
api.download(format, this.$route.path)
|
|
||||||
} else {
|
|
||||||
let files = []
|
|
||||||
|
|
||||||
for (let i of this.selected) {
|
|
||||||
files.push(this.req.items[i].url)
|
|
||||||
}
|
|
||||||
|
|
||||||
api.download(format, ...files)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$store.commit('closeHovers')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,7 +2,6 @@ const getters = {
|
||||||
isLogged: state => state.user !== null,
|
isLogged: state => state.user !== null,
|
||||||
isFiles: state => !state.loading && state.route.name === 'Files',
|
isFiles: state => !state.loading && state.route.name === 'Files',
|
||||||
isListing: (state, getters) => getters.isFiles && state.req.isDir,
|
isListing: (state, getters) => getters.isFiles && state.req.isDir,
|
||||||
isSharing: state => !state.loading && state.route.name === 'Share',
|
|
||||||
selectedCount: state => state.selected.length,
|
selectedCount: state => state.selected.length,
|
||||||
progress : state => {
|
progress : state => {
|
||||||
if (state.upload.progress.length == 0) {
|
if (state.upload.progress.length == 0) {
|
||||||
|
|
|
@ -22,10 +22,7 @@ const state = {
|
||||||
multiple: false,
|
multiple: false,
|
||||||
show: null,
|
show: null,
|
||||||
showShell: false,
|
showShell: false,
|
||||||
showMessage: null,
|
showConfirm: null
|
||||||
showConfirm: null,
|
|
||||||
hash: '',
|
|
||||||
token: ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
|
|
|
@ -4,7 +4,7 @@ import moment from 'moment'
|
||||||
const mutations = {
|
const mutations = {
|
||||||
closeHovers: state => {
|
closeHovers: state => {
|
||||||
state.show = null
|
state.show = null
|
||||||
state.showMessage = null
|
state.showConfirm = null
|
||||||
},
|
},
|
||||||
toggleShell: (state) => {
|
toggleShell: (state) => {
|
||||||
state.showShell = !state.showShell
|
state.showShell = !state.showShell
|
||||||
|
@ -16,16 +16,13 @@ const mutations = {
|
||||||
}
|
}
|
||||||
|
|
||||||
state.show = value.prompt
|
state.show = value.prompt
|
||||||
state.showMessage = value.message
|
|
||||||
state.showConfirm = value.confirm
|
state.showConfirm = value.confirm
|
||||||
},
|
},
|
||||||
showError: (state, value) => {
|
showError: (state) => {
|
||||||
state.show = 'error'
|
state.show = 'error'
|
||||||
state.showMessage = value
|
|
||||||
},
|
},
|
||||||
showSuccess: (state, value) => {
|
showSuccess: (state) => {
|
||||||
state.show = 'success'
|
state.show = 'success'
|
||||||
state.showMessage = value
|
|
||||||
},
|
},
|
||||||
setLoading: (state, value) => { state.loading = value },
|
setLoading: (state, value) => { state.loading = value },
|
||||||
setReload: (state, value) => { state.reload = value },
|
setReload: (state, value) => { state.reload = value },
|
||||||
|
@ -46,12 +43,8 @@ const mutations = {
|
||||||
state.user = value
|
state.user = value
|
||||||
},
|
},
|
||||||
setJWT: (state, value) => (state.jwt = value),
|
setJWT: (state, value) => (state.jwt = value),
|
||||||
setToken: (state, value ) => (state.token = value),
|
|
||||||
multiple: (state, value) => (state.multiple = value),
|
multiple: (state, value) => (state.multiple = value),
|
||||||
addSelected: (state, value) => (state.selected.push(value)),
|
addSelected: (state, value) => (state.selected.push(value)),
|
||||||
addPlugin: (state, value) => {
|
|
||||||
state.plugins.push(value)
|
|
||||||
},
|
|
||||||
removeSelected: (state, value) => {
|
removeSelected: (state, value) => {
|
||||||
let i = state.selected.indexOf(value)
|
let i = state.selected.indexOf(value)
|
||||||
if (i === -1) return
|
if (i === -1) return
|
||||||
|
@ -84,8 +77,7 @@ const mutations = {
|
||||||
resetClipboard: (state) => {
|
resetClipboard: (state) => {
|
||||||
state.clipboard.key = ''
|
state.clipboard.key = ''
|
||||||
state.clipboard.items = []
|
state.clipboard.items = []
|
||||||
},
|
}
|
||||||
setHash: (state, value) => (state.hash = value),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default mutations
|
export default mutations
|
||||||
|
|
|
@ -47,7 +47,8 @@
|
||||||
v-bind:url="item.url"
|
v-bind:url="item.url"
|
||||||
v-bind:modified="item.modified"
|
v-bind:modified="item.modified"
|
||||||
v-bind:type="item.type"
|
v-bind:type="item.type"
|
||||||
v-bind:size="item.size">
|
v-bind:size="item.size"
|
||||||
|
readOnly>
|
||||||
</item>
|
</item>
|
||||||
<div v-if="req.items.length > showLimit" class="item">
|
<div v-if="req.items.length > showLimit" class="item">
|
||||||
<div>
|
<div>
|
||||||
|
@ -97,7 +98,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {mapState, mapMutations, mapGetters} from 'vuex';
|
import {mapState, mapMutations, mapGetters} from 'vuex';
|
||||||
import { files, share as api } from '@/api'
|
import { pub as api } from '@/api'
|
||||||
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'
|
||||||
|
@ -124,14 +125,16 @@ export default {
|
||||||
path: '',
|
path: '',
|
||||||
showLimit: 500,
|
showLimit: 500,
|
||||||
password: '',
|
password: '',
|
||||||
attemptedPasswordLogin: false
|
attemptedPasswordLogin: false,
|
||||||
|
hash: null,
|
||||||
|
token: null
|
||||||
}),
|
}),
|
||||||
watch: {
|
watch: {
|
||||||
'$route': 'fetchData'
|
'$route': 'fetchData'
|
||||||
},
|
},
|
||||||
created: async function () {
|
created: async function () {
|
||||||
const hash = this.$route.params.pathMatch.split('/')[0]
|
const hash = this.$route.params.pathMatch.split('/')[0]
|
||||||
this.setHash(hash)
|
this.hash = hash
|
||||||
await this.fetchData()
|
await this.fetchData()
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
@ -141,7 +144,7 @@ export default {
|
||||||
window.removeEventListener('keydown', this.keyEvent)
|
window.removeEventListener('keydown', this.keyEvent)
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(['hash', 'req', 'loading', 'multiple', 'selected']),
|
...mapState(['req', 'loading', 'multiple', 'selected']),
|
||||||
...mapGetters(['selectedCount', 'selectedCount']),
|
...mapGetters(['selectedCount', 'selectedCount']),
|
||||||
icon: function () {
|
icon: function () {
|
||||||
if (this.req.isDir) return 'folder'
|
if (this.req.isDir) return 'folder'
|
||||||
|
@ -175,7 +178,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations([ 'setHash', 'resetSelected', 'updateRequest', 'setLoading' ]),
|
...mapMutations([ 'resetSelected', 'updateRequest', 'setLoading' ]),
|
||||||
base64: function (name) {
|
base64: function (name) {
|
||||||
return window.btoa(unescape(encodeURIComponent(name)))
|
return window.btoa(unescape(encodeURIComponent(name)))
|
||||||
},
|
},
|
||||||
|
@ -194,12 +197,11 @@ export default {
|
||||||
if (this.password !== ''){
|
if (this.password !== ''){
|
||||||
this.attemptedPasswordLogin = true
|
this.attemptedPasswordLogin = true
|
||||||
}
|
}
|
||||||
let file = await api.getHash(encodeURIComponent(this.$route.params.pathMatch), this.password)
|
let file = await api.fetch(encodeURIComponent(this.$route.params.pathMatch), this.password)
|
||||||
this.path = file.path
|
this.path = file.path
|
||||||
if (this.path.endsWith('/')) this.path = this.path.slice(0, -1)
|
if (this.path.endsWith('/')) this.path = this.path.slice(0, -1)
|
||||||
|
|
||||||
this.token = file.token || ''
|
this.token = file.token || ''
|
||||||
this.$store.commit('setToken', this.token)
|
|
||||||
if (file.isDir) file.items = file.items.map((item, index) => {
|
if (file.isDir) file.items = file.items.map((item, index) => {
|
||||||
item.index = index
|
item.index = index
|
||||||
item.url = `/share/${this.hash}${this.path}/${encodeURIComponent(item.name)}`
|
item.url = `/share/${this.hash}${this.path}/${encodeURIComponent(item.name)}`
|
||||||
|
@ -226,11 +228,24 @@ export default {
|
||||||
},
|
},
|
||||||
download () {
|
download () {
|
||||||
if (this.selectedCount === 1 && !this.req.items[this.selected[0]].isDir) {
|
if (this.selectedCount === 1 && !this.req.items[this.selected[0]].isDir) {
|
||||||
files.download(null, this.req.items[this.selected[0]].url)
|
api.download(null, this.hash, this.token, this.req.items[this.selected[0]].url)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$store.commit('showHover', 'download')
|
this.$store.commit('showHover', {
|
||||||
|
prompt: 'download',
|
||||||
|
confirm: (format) => {
|
||||||
|
this.$store.commit('closeHovers')
|
||||||
|
|
||||||
|
let files = []
|
||||||
|
|
||||||
|
for (let i of this.selected) {
|
||||||
|
files.push(this.req.items[i].url)
|
||||||
|
}
|
||||||
|
|
||||||
|
api.download(format, this.hash, this.token, ...files)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,8 @@ export default {
|
||||||
'selected',
|
'selected',
|
||||||
'user',
|
'user',
|
||||||
'show',
|
'show',
|
||||||
'multiple'
|
'multiple',
|
||||||
|
'selected'
|
||||||
]),
|
]),
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
'selectedCount'
|
'selectedCount'
|
||||||
|
@ -580,7 +581,20 @@ export default {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$store.commit('showHover', 'download')
|
this.$store.commit('showHover', {
|
||||||
|
prompt: 'download',
|
||||||
|
confirm: (format) => {
|
||||||
|
this.$store.commit('closeHovers')
|
||||||
|
|
||||||
|
let files = []
|
||||||
|
|
||||||
|
for (let i of this.selected) {
|
||||||
|
files.push(this.req.items[i].url)
|
||||||
|
}
|
||||||
|
|
||||||
|
api.download(format, ...files)
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
switchView: async function () {
|
switchView: async function () {
|
||||||
this.$store.commit('closeHovers')
|
this.$store.commit('closeHovers')
|
||||||
|
|
Loading…
Reference in New Issue