feat: file copy, move and paste conflict checking

This commit is contained in:
Ramires Viana
2020-07-15 15:12:13 +00:00
parent 9a2ebbabe2
commit eed9da1471
8 changed files with 138 additions and 51 deletions

View File

@@ -261,23 +261,43 @@ export default {
for (let item of this.$store.state.clipboard.items) {
const from = item.from.endsWith('/') ? item.from.slice(0, -1) : item.from
const to = this.$route.path + item.name
items.push({ from, to })
items.push({ from, to, name: item.name })
}
if (items.length === 0) {
return
}
if (this.$store.state.clipboard.key === 'x') {
api.move(items).then(() => {
let action = (overwrite) => {
api.copy(items, overwrite).then(() => {
this.$store.commit('setReload', true)
}).catch(this.$showError)
}
if (this.$store.state.clipboard.key === 'x') {
action = (overwrite) => {
api.move(items, overwrite).then(() => {
this.$store.commit('setReload', true)
}).catch(this.$showError)
}
}
let conflict = upload.checkConflict(items, this.req.items)
if (conflict) {
this.$store.commit('showHover', {
prompt: 'replace',
confirm: (event) => {
event.preventDefault()
this.$store.commit('closeHovers')
action(true)
}
})
return
}
api.copy(items).then(() => {
this.$store.commit('setReload', true)
}).catch(this.$showError)
action(false)
},
resizeEvent () {
// Update the columns size based on the window width.

View File

@@ -36,6 +36,7 @@ import { mapMutations, mapGetters, mapState } from 'vuex'
import filesize from 'filesize'
import moment from 'moment'
import { files as api } from '@/api'
import * as upload from '@/utils/upload'
export default {
name: 'item',
@@ -110,26 +111,55 @@ export default {
el.style.opacity = 1
},
drop: function (event) {
drop: async function (event) {
if (!this.canDrop) return
event.preventDefault()
if (this.selectedCount === 0) return
let el = event.target
for (let i = 0; i < 5; i++) {
if (el !== null && !el.classList.contains('item')) {
el = el.parentElement
}
}
let items = []
for (let i of this.selected) {
items.push({
from: this.req.items[i].url,
to: this.url + this.req.items[i].name
to: this.url + this.req.items[i].name,
name: this.req.items[i].name
})
}
let base = el.querySelector('.name').innerHTML + '/'
let path = this.$route.path + base
let baseItems = (await api.fetch(path)).items
let action = (overwrite) => {
api.move(items, overwrite).then(() => {
this.$store.commit('setReload', true)
}).catch(this.$showError)
}
api.move(items)
.then(() => {
this.$store.commit('setReload', true)
let conflict = upload.checkConflict(items, baseItems)
if (conflict) {
this.$store.commit('showHover', {
prompt: 'replace',
confirm: (event) => {
event.preventDefault()
this.$store.commit('closeHovers')
action(true)
}
})
.catch(this.$showError)
return
}
action(false)
},
click: function (event) {
if (this.selectedCount !== 0) event.preventDefault()

View File

@@ -28,6 +28,7 @@ import { mapState } from 'vuex'
import FileList from './FileList'
import { files as api } from '@/api'
import buttons from '@/utils/buttons'
import * as upload from '@/utils/upload'
export default {
name: 'copy',
@@ -42,25 +43,46 @@ export default {
methods: {
copy: async function (event) {
event.preventDefault()
buttons.loading('copy')
let items = []
// Create a new promise for each file.
for (let item of this.selected) {
items.push({
from: this.req.items[item].url,
to: this.dest + encodeURIComponent(this.req.items[item].name)
to: this.dest + encodeURIComponent(this.req.items[item].name),
name: this.req.items[item].name
})
}
try {
await api.copy(items)
buttons.success('copy')
this.$router.push({ path: this.dest })
} catch (e) {
buttons.done('copy')
this.$showError(e)
let action = async (overwrite) => {
buttons.loading('copy')
await api.copy(items, overwrite).then(() => {
buttons.success('copy')
this.$router.push({ path: this.dest })
}).catch((e) => {
buttons.done('copy')
this.$showError(e)
})
}
let dstItems = (await api.fetch(this.dest)).items
let conflict = upload.checkConflict(items, dstItems)
if (conflict) {
this.$store.commit('showHover', {
prompt: 'replace',
confirm: (event) => {
event.preventDefault()
this.$store.commit('closeHovers')
action(true)
}
})
return
}
action(false)
}
}
}

View File

@@ -41,19 +41,7 @@ export default {
}
},
mounted () {
// If we're showing this on a listing,
// we can use the current request object
// to fill the move options.
if (this.req.kind === 'listing') {
this.fillOptions(this.req)
return
}
// Otherwise, we must be on a preview or editor
// so we fetch the data from the previous directory.
files.fetch(url.removeLastDir(this.$route.path))
.then(this.fillOptions)
.catch(this.$showError)
this.fillOptions(this.req)
},
methods: {
fillOptions (req) {

View File

@@ -27,6 +27,7 @@ import { mapState } from 'vuex'
import FileList from './FileList'
import { files as api } from '@/api'
import buttons from '@/utils/buttons'
import * as upload from '@/utils/upload'
export default {
name: 'move',
@@ -41,26 +42,45 @@ export default {
methods: {
move: async function (event) {
event.preventDefault()
buttons.loading('move')
let items = []
for (let item of this.selected) {
items.push({
from: this.req.items[item].url,
to: this.dest + encodeURIComponent(this.req.items[item].name)
to: this.dest + encodeURIComponent(this.req.items[item].name),
name: this.req.items[item].name
})
}
try {
api.move(items)
buttons.success('move')
this.$router.push({ path: this.dest })
} catch (e) {
buttons.done('move')
this.$showError(e)
let action = async (overwrite) => {
buttons.loading('move')
await api.move(items, overwrite).then(() => {
buttons.success('move')
this.$router.push({ path: this.dest })
}).catch((e) => {
buttons.done('move')
this.$showError(e)
})
}
event.preventDefault()
let dstItems = (await api.fetch(this.dest)).items
let conflict = upload.checkConflict(items, dstItems)
if (conflict) {
this.$store.commit('showHover', {
prompt: 'replace',
confirm: (event) => {
event.preventDefault()
this.$store.commit('closeHovers')
action(true)
}
})
return
}
action(false)
}
}
}