Skip to content

Commit

Permalink
Merge pull request #9552 from owncloud/upload-preparation-time
Browse files Browse the repository at this point in the history
perf: upload preparation time
  • Loading branch information
JammingBen authored Sep 6, 2023
2 parents 838f89c + fa9ccdb commit f4e8ddb
Show file tree
Hide file tree
Showing 4 changed files with 279 additions and 56 deletions.
101 changes: 45 additions & 56 deletions packages/web-app-files/src/HandleUpload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export interface HandleUploadOptions {
* 5. start upload
*/
export class HandleUpload extends BasePlugin {
id: string
type: string
uppy: Uppy

clientService: ClientService
hasSpaces: Ref<boolean>
language: Language
Expand All @@ -54,8 +58,10 @@ export class HandleUpload extends BasePlugin {

constructor(uppy: Uppy, opts: HandleUploadOptions) {
super(uppy, opts)
;(this as any).id = opts.id || 'HandleUpload'
;(this as any).type = 'modifier'
this.id = opts.id || 'HandleUpload'
this.type = 'modifier'
this.uppy = uppy

this.clientService = opts.clientService
this.hasSpaces = opts.hasSpaces
this.language = opts.language
Expand All @@ -71,10 +77,6 @@ export class HandleUpload extends BasePlugin {
this.handleUpload = this.handleUpload.bind(this)
}

get _uppy(): Uppy {
return (this as any).uppy
}

get currentFolder(): Resource {
return this.store.getters['Files/currentFolder']
}
Expand All @@ -89,57 +91,53 @@ export class HandleUpload extends BasePlugin {

removeFilesFromUpload(filesToUpload: UppyResource[]) {
for (const file of filesToUpload) {
this._uppy.removeFile(file.id)
this.uppy.removeFile(file.id)
}
}

/**
* Sets the endpoint url for a given file.
*/
setEndpointUrl(fileId: string, endpoint: string) {
if (this._uppy.getPlugin('Tus')) {
this._uppy.setFileState(fileId, { tus: { endpoint } })
return
}
this._uppy.setFileState(fileId, { xhrUpload: { endpoint } })
getUploadPluginName() {
return this.uppy.getPlugin('Tus') ? 'tus' : 'xhrUpload'
}

/**
* Converts the input files type UppyResources and updates the uppy upload queue
*/
prepareFiles(files: UppyFile[]): UppyResource[] {
const filesToUpload = []
const filesToUpload: Record<string, UppyResource> = {}

if (!this.currentFolder && unref(this.route)?.params?.token) {
// public file drop
const publicLinkToken = unref(this.route).params.token
let endpoint = this.clientService.owncloudSdk.publicFiles.getFileUrl(publicLinkToken) + '/'
for (const file of files) {
if (!this._uppy.getPlugin('Tus')) {
if (!this.uppy.getPlugin('Tus')) {
endpoint = urlJoin(endpoint, encodeURIComponent(file.name))
}
this.setEndpointUrl(file.id, endpoint)
this._uppy.setFileMeta(file.id, {

file[this.getUploadPluginName()] = { endpoint }
file.meta = {
...file.meta,
tusEndpoint: endpoint,
uploadId: uuid.v4()
})
}

filesToUpload.push(this._uppy.getFile(file.id))
filesToUpload[file.id] = file as unknown as UppyResource
}
return filesToUpload
this.uppy.setState({ files: { ...this.uppy.getState().files, ...filesToUpload } })
return Object.values(filesToUpload)
}
const { id: currentFolderId, path: currentFolderPath } = this.currentFolder

const { name, params, query } = unref(this.route)
const topLevelFolderIds = {}
const topLevelFolderIds: Record<string, string> = {}

for (const file of files) {
const relativeFilePath = file.meta.relativePath as string
// Directory without filename
const directory =
!relativeFilePath || dirname(relativeFilePath) === '.' ? '' : dirname(relativeFilePath)

let topLevelFolderId
let topLevelFolderId: string
if (relativeFilePath) {
const topLevelDirectory = relativeFilePath.split('/').filter(Boolean)[0]
if (!topLevelFolderIds[topLevelDirectory]) {
Expand All @@ -153,12 +151,13 @@ export class HandleUpload extends BasePlugin {
})

let endpoint = urlJoin(webDavUrl, directory.split('/').map(encodeURIComponent).join('/'))
if (!this._uppy.getPlugin('Tus')) {
if (!this.uppy.getPlugin('Tus')) {
endpoint = urlJoin(endpoint, encodeURIComponent(file.name))
}

this.setEndpointUrl(file.id, endpoint)
this._uppy.setFileMeta(file.id, {
file[this.getUploadPluginName()] = { endpoint }
file.meta = {
...file.meta,
// file data
name: file.name,
mtime: (file.data as any).lastModified / 1000,
Expand All @@ -179,19 +178,20 @@ export class HandleUpload extends BasePlugin {
routeName: name as string,
routeDriveAliasAndItem: (params as any)?.driveAliasAndItem || '',
routeShareId: (query as any)?.shareId || ''
})
}

filesToUpload.push(this._uppy.getFile(file.id))
filesToUpload[file.id] = file as unknown as UppyResource
}

return filesToUpload
this.uppy.setState({ files: { ...this.uppy.getState().files, ...filesToUpload } })
return Object.values(filesToUpload)
}

checkQuotaExceeded(filesToUpload: UppyResource[]): boolean {
let quotaExceeded = false

const uploadSizeSpaceMapping = filesToUpload.reduce((acc, uppyResource) => {
let targetUploadSpace
let targetUploadSpace: SpaceResource

if (uppyResource.meta.routeName === locationPublicLink.name) {
return acc
Expand Down Expand Up @@ -338,14 +338,14 @@ export class HandleUpload extends BasePlugin {
}
}

let filesToRemove = []
let filesToRemove: string[] = []
if (failedFolders.length) {
// remove file of folders that could not be created
// remove files of folders that could not be created
filesToRemove = filesToUpload
.filter((f) => failedFolders.some((r) => f.meta.relativeFolder.startsWith(r)))
.map(({ id }) => id)
for (const fileId of filesToRemove) {
this._uppy.removeFile(fileId)
this.uppy.removeFile(fileId)
}
}

Expand All @@ -370,37 +370,26 @@ export class HandleUpload extends BasePlugin {

// name conflict handling
if (this.conflictHandlingEnabled) {
const confictHandler = new ResourceConflict(this.store, this.language)
const conflicts = confictHandler.getConflicts(filesToUpload)
const conflictHandler = new ResourceConflict(this.store, this.language)
const conflicts = conflictHandler.getConflicts(filesToUpload)
if (conflicts.length) {
const dashboard = document.getElementsByClassName('uppy-Dashboard')
if (dashboard.length) {
;(dashboard[0] as HTMLElement).style.display = 'none'
}

const result = await confictHandler.displayOverwriteDialog(filesToUpload, conflicts)
const result = await conflictHandler.displayOverwriteDialog(filesToUpload, conflicts)
if (result.length === 0) {
this.removeFilesFromUpload(filesToUpload)
return this.uppyService.clearInputs()
}

for (const file of filesToUpload) {
const conflictResult = result.find(({ id }) => id === file.id)
if (!conflictResult) {
this._uppy.removeFile(file.id)
continue
}
this._uppy.setFileMeta(file.id, conflictResult.meta)
this._uppy.setFileState(file.id, { name: conflictResult.name })
this.setEndpointUrl(
file.id,
!!this._uppy.getPlugin('Tus')
? conflictResult.meta.tusEndpoint
: conflictResult.xhrUpload.endpoint
)
}

filesToUpload = result
const conflictMap = result.reduce<Record<string, UppyResource>>((acc, file) => {
acc[file.id] = file
return acc
}, {})
this.uppy.setState({ files: { ...this.uppy.getState().files, ...conflictMap } })
}
}

Expand All @@ -419,10 +408,10 @@ export class HandleUpload extends BasePlugin {
}

install() {
this._uppy.on('files-added', this.handleUpload)
this.uppy.on('files-added', this.handleUpload)
}

uninstall() {
this._uppy.off('files-added', this.handleUpload)
this.uppy.off('files-added', this.handleUpload)
}
}
6 changes: 6 additions & 0 deletions packages/web-app-files/src/helpers/resource/actions/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ export class ResourceConflict extends ConflictDialog {
`/${encodeURIComponent(newFolderName)}`
)
}
if (file.tus?.endpoint) {
file.tus.endpoint = file.tus.endpoint.replace(
new RegExp(`/${encodeURIComponent(folder)}`),
`/${encodeURIComponent(newFolderName)}`
)
}
}
}
return files
Expand Down
Loading

0 comments on commit f4e8ddb

Please sign in to comment.