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