Skip to content

Commit

Permalink
Improve root folder handling
Browse files Browse the repository at this point in the history
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
  • Loading branch information
skjnldsv committed Sep 15, 2022
1 parent 7b1173a commit 4f0425f
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 16 deletions.
59 changes: 59 additions & 0 deletions lib/components/UploadPicker.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,62 @@ describe('Destination management', () => {
})
})
})

describe('Root management', () => {
const propsData = {
root: null,
destination: '/',
}

it('Upload then changes the root', () => {
// Mount picker
cy.mount(UploadPicker, { propsData })

// Check and init aliases
cy.get('form input[type="file"]').as('input').should('exist')
cy.get('form .upload-picker__progress').as('progress').should('exist')

// Intercept single upload
cy.intercept('PUT', '/remote.php/dav/files/*/**', {
statusCode: 201,
}).as('upload')

cy.get('@input').attachFile({
// Fake file of 5 MB
fileContent: new Blob([new ArrayBuffer(5 * 1024 * 1024)]),
fileName: 'image.jpg',
mimeType: 'image/jpeg',
encoding: 'utf8',
lastModified: new Date().getTime(),
})

cy.wait('@upload').then((upload) => {
expect(upload.request.url).to.have.string('/remote.php/dav/files/user/image.jpg')
})

cy.get('@component').then(component => {
component.setRoot('dav/photos/admin/albums')
component.setDestination('/2022 Summer Vacations')
// Wait for prop propagation
expect(component.uploadManager.root).to.match(/dav\/photos\/admin\/albums$/i)
})

// Intercept single upload
cy.intercept('PUT', '/remote.php/dav/photos/admin/albums/*/*', {
statusCode: 201,
}).as('upload')

cy.get('@input').attachFile({
// Fake file of 5 MB
fileContent: new Blob([new ArrayBuffer(5 * 1024 * 1024)]),
fileName: 'image.jpg',
mimeType: 'image/jpeg',
encoding: 'utf8',
lastModified: new Date().getTime(),
})

cy.wait('@upload').then((upload) => {
expect(upload.request.url).to.have.string('/remote.php/dav/photos/admin/albums/2022%20Summer%20Vacations/image.jpg')
})
})
})
23 changes: 21 additions & 2 deletions lib/components/UploadPicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@ export default {
},
destination: {
type: String,
default: '/',
default: null,
},
root: {
type: String,
default: null,
},
context: {
type: Object,
Expand Down Expand Up @@ -197,6 +201,10 @@ export default {
this.setDestination(destination)
},
root(path) {
this.setRoot(path)
},
queue(queue, oldQueue) {
if (queue.length < oldQueue.length) {
this.$emit('uploaded', oldQueue.filter(upload => !queue.includes(upload)))
Expand All @@ -219,7 +227,13 @@ export default {
},
beforeMount() {
this.setDestination(this.destination)
if (this.destination) {
this.setDestination(this.destination)
}
if (this.root) {
this.setRoot(this.root)
}
this.setContext(this.context)
logger.debug('UploadPicker initialised')
},
Expand Down Expand Up @@ -284,6 +298,11 @@ export default {
this.uploadManager.destination = destination
},
setRoot(path) {
logger.debug(`Root path set to ${path}`)
this.uploadManager.root = path
},
setContext(context) {
logger.debug('Context changed to', context);
this.newFileMenuEntries = getNewFileMenuEntries(context)
Expand Down
2 changes: 1 addition & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Uploader } from './uploader'
import UploadPicker from './components/UploadPicker.js'
export { Status as UploaderStatus } from './uploader'
export { Status as UploadStatus } from './upload'
export { Upload, Status as UploadStatus } from './upload'

declare global {
interface Window {
Expand Down
63 changes: 50 additions & 13 deletions lib/uploader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ export enum Status {

export class Uploader {

private _userRootFolder: string
private _destinationFolder: string = '/'
// Initialized via setter in the constructor
private rootFolder!: string
private destinationFolder!: string

private _isPublic: boolean

Expand All @@ -34,39 +35,75 @@ export class Uploader {
* Initialize uploader
*
* @param {boolean} isPublic are we in public mode ?
* @param {string} rootFolder the operation root folder
* @param {string} destinationFolder the context folder to operate, relative to the root folder
*/
constructor(isPublic: boolean = false) {
constructor(
isPublic: boolean = false,
rootFolder = `dav/files/${getCurrentUser()?.uid}`,
destinationFolder = '/'
) {
this._isPublic = isPublic
this._userRootFolder = generateRemoteUrl(`dav/files/${getCurrentUser()?.uid}`)
this.root = rootFolder
this.destination = destinationFolder

logger.debug('Upload workspace initialized', {
destinationFolder: this._destinationFolder,
userRootFolder: this._userRootFolder,
destinationFolder: this.destination,
rootFolder: this.root,
isPublic,
maxChunksSize: getMaxChunksSize(),
})
}

/**
* Get the upload destination path relative to the user root folder
* Get the upload destination path relative to the root folder
*/
get destination() {
return this._destinationFolder
return this.destinationFolder
}

/**
* Set the upload destination path relative to the user root folder
* Set the upload destination path relative to the root folder
*/
set destination(path: string) {
if (typeof path !== 'string' || path === '') {
this._destinationFolder = '/'
this.destinationFolder = '/'
return
}

if (!path.startsWith('/')) {
path = `/${path}`
}
this._destinationFolder = path.replace(/\/$/, '')
this.destinationFolder = path.replace(/\/$/, '')
}

/**
* Get the root folder
*/
get root() {
return this.rootFolder
}

/**
* Set the root folder
*
* @param {string} path should be the remoteUrl path.
* This method uses the generateRemoteUrl method
*/
set root(path: string) {
if (typeof path !== 'string' || path === '') {
this.rootFolder = generateRemoteUrl(`dav/files/${getCurrentUser()?.uid}`)
return
}

if (path.startsWith('http')) {
throw new Error('The path should be a remote url string. E.g `dav/files/admin`.')
}

if (path.startsWith('/')) {
path = path.slice(1)
}
this.rootFolder = generateRemoteUrl(path)
}

/**
Expand Down Expand Up @@ -134,8 +171,8 @@ export class Uploader {
* Upload a file to the given path
*/
upload(destinationPath: string, file: File) {
const destinationFolder = this._destinationFolder === '/' ? '' : this._destinationFolder
const destinationFile = `${this._userRootFolder}${destinationFolder}/${destinationPath.replace(/^\//, '')}`
const destinationFolder = this.destinationFolder === '/' ? '' : this.destinationFolder
const destinationFile = `${this.rootFolder}${destinationFolder}/${destinationPath.replace(/^\//, '')}`

logger.debug(`Uploading ${file.name} to ${destinationFile}`)

Expand Down

0 comments on commit 4f0425f

Please sign in to comment.