Skip to content

Commit 365aef6

Browse files
Rebase&refactor
1 parent 61658b3 commit 365aef6

File tree

15 files changed

+299
-789
lines changed

15 files changed

+299
-789
lines changed

packages/web-app-files/package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
"description": "ownCloud web files",
55
"license": "AGPL-3.0",
66
"dependencies": {
7-
"copy-to-clipboard": "^3.3.1",
8-
"vue2-dropzone": "^3.6.0"
7+
"@uppy/core": "^2.1.4",
8+
"@uppy/drop-target": "^1.1.1",
9+
"@uppy/status-bar": "^2.1.2",
10+
"@uppy/tus": "^2.1.2",
11+
"@uppy/xhr-upload": "^2.0.7",
12+
"copy-to-clipboard": "^3.3.1"
913
}
1014
}

packages/web-app-files/src/App.vue

+1-6
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
</template>
2323
<script>
2424
import Mixins from './mixins'
25-
import { mapActions, mapGetters, mapState } from 'vuex'
25+
import { mapActions, mapState } from 'vuex'
2626
import SideBar from './components/SideBar/SideBar.vue'
2727
2828
export default {
@@ -31,7 +31,6 @@ export default {
3131
},
3232
mixins: [Mixins],
3333
computed: {
34-
...mapGetters('Files', ['dropzone']),
3534
...mapState('Files/sidebar', { sidebarClosed: 'closed' }),
3635
3736
showSidebar() {
@@ -104,8 +103,4 @@ main {
104103
grid-area: main;
105104
z-index: 0;
106105
}
107-
108-
#files-upload-progress {
109-
grid-area: upload;
110-
}
111106
</style>

packages/web-app-files/src/components/AppBar/CreateAndUpload.vue

+135-31
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,10 @@
7070
<translate>New folder</translate>
7171
</oc-button>
7272
</template>
73-
<file-drop
74-
v-if="!uploadOrFileCreationBlocked"
75-
:root-path="currentPath"
76-
:path="currentPath"
77-
:headers="headers"
78-
@success="onFileSuccess"
79-
@error="onFileError"
80-
@progress="onFileProgress"
81-
/>
73+
<!-- PoC since the components don't get recognized on
74+
initial page rendering as (hidden) OcDrop elements -->
75+
<folder-upload />
76+
<file-upload />
8277
<oc-button
8378
id="upload-menu-btn"
8479
key="upload-menu-btn-enabled"
@@ -99,23 +94,10 @@
9994
>
10095
<oc-list id="upload-list">
10196
<li>
102-
<folder-upload
103-
:root-path="currentPath"
104-
:path="currentPath"
105-
:headers="headers"
106-
@success="onFileSuccess"
107-
@error="onFileError"
108-
@progress="onFileProgress"
109-
/>
97+
<folder-upload />
11098
</li>
11199
<li>
112-
<file-upload
113-
:path="currentPath"
114-
:headers="headers"
115-
@success="onFileSuccess"
116-
@error="onFileError"
117-
@progress="onFileProgress"
118-
/>
100+
<file-upload />
119101
</li>
120102
</oc-list>
121103
</oc-drop>
@@ -125,26 +107,29 @@
125107
<script>
126108
import { mapActions, mapGetters, mapState, mapMutations } from 'vuex'
127109
import pathUtil from 'path'
110+
import Uppy from '@uppy/core'
111+
import Tus from '@uppy/tus'
112+
import XHRUpload from '@uppy/xhr-upload'
113+
import StatusBar from '@uppy/status-bar'
114+
import DropTarget from '@uppy/drop-target'
128115
129-
import Mixins from '../../mixins'
130116
import MixinFileActions, { EDITOR_MODE_CREATE } from '../../mixins/fileActions'
131117
import { buildResource, buildWebDavFilesPath, buildWebDavSpacesPath } from '../../helpers/resources'
132118
import { isLocationPublicActive, isLocationSpacesActive } from '../../router'
133119
import { useActiveLocation } from '../../composables'
134120
135121
import { DavProperties, DavProperty } from 'web-pkg/src/constants'
136122
137-
import FileDrop from './Upload/FileDrop.vue'
123+
// TODO: Simplify to one UploadButton component and fill from here
138124
import FileUpload from './Upload/FileUpload.vue'
139125
import FolderUpload from './Upload/FolderUpload.vue'
140126
141127
export default {
142128
components: {
143-
FileDrop,
144129
FileUpload,
145130
FolderUpload
146131
},
147-
mixins: [Mixins, MixinFileActions],
132+
mixins: [MixinFileActions],
148133
setup() {
149134
return {
150135
isPersonalLocation: useActiveLocation(isLocationSpacesActive, 'files-spaces-personal-home'),
@@ -256,17 +241,136 @@ export default {
256241
)
257242
}
258243
},
244+
mounted() {
245+
const chunkSize = this.configuration.uploadChunkSize
246+
// if (this.currentFolder.isChunkedUploadSupported) {
247+
// let chunkSize = this.configuration.uploadChunkSize
248+
// if (this.capabilities.files.tus_support.max_chunk_size > 0) {
249+
// if (
250+
// chunkSize === null ||
251+
// chunkSize === 0 ||
252+
// chunkSize > this.capabilities.files.tus_support.max_chunk_size
253+
// ) {
254+
// chunkSize = this.capabilities.files.tus_support.max_chunk_size
255+
// }
256+
// }
257+
// }
258+
259+
const client = this.$client
260+
// might make sense to initialize an Uppy instance in the runtime?
261+
// todo: set debug to false
262+
const uppy = new Uppy({ debug: true, autoProceed: true })
263+
const uploadPath = client.files.getFileUrl(this.currentPath)
264+
const headers = client.helpers.buildHeaders()
265+
266+
if (this.capabilities.files.tus_support) {
267+
delete headers['OCS-APIREQUEST']
268+
uppy.use(Tus, {
269+
endpoint: uploadPath,
270+
headers: headers,
271+
chunkSize: chunkSize || Infinity,
272+
removeFingerprintOnSuccess: true,
273+
overridePatchMethod: !!this.capabilities.files.tus_support.http_method_override,
274+
retryDelays: [0, 3000, 5000, 10000, 20000]
275+
})
276+
} else {
277+
uppy.use(XHRUpload, {
278+
endpoint: uploadPath,
279+
method: 'put',
280+
headers: headers
281+
})
282+
}
283+
284+
// upload button handling (files & folders separately)
285+
// doesn't recognize elements yet since they're tippy children
286+
const uploadInputTarget = document.querySelectorAll('.upload-input-target')
287+
288+
uploadInputTarget.forEach((item) => {
289+
item.addEventListener('change', (event) => {
290+
const files = Array.from(event.target.files)
291+
292+
files.forEach((file) => {
293+
try {
294+
console.log('file', file)
295+
uppy.addFile({
296+
source: 'file input',
297+
name: file.name,
298+
type: file.type,
299+
data: file
300+
})
301+
} catch (err) {
302+
if (err.isRestriction) {
303+
// handle restrictions
304+
console.log('Restriction error:', err)
305+
} else {
306+
// handle other errors
307+
console.error(err)
308+
}
309+
}
310+
})
311+
})
312+
})
313+
314+
// upload via drag&drop handling
315+
uppy.use(DropTarget, {
316+
target: '#files-view'
317+
})
318+
319+
uppy.on('upload-error', (file, error, response) => {
320+
console.log('error with file:', file.id)
321+
console.log('error message:', error)
322+
this.onFileError(error.toString())
323+
})
324+
325+
uppy.on('file-removed', () => {
326+
uploadInputTarget.forEach((item) => {
327+
item.value = ''
328+
})
329+
})
330+
331+
uppy.on('complete', (result) => {
332+
result.successful.forEach((file) => {
333+
this.onFileSuccess(file.data)
334+
})
335+
uploadInputTarget.forEach((item) => {
336+
item.value = ''
337+
})
338+
339+
console.log('successful files:', result.successful)
340+
console.log('failed files:', result.failed)
341+
})
342+
343+
uppy.use(StatusBar, {
344+
id: 'StatusBar',
345+
target: '#files-app-bar',
346+
hideAfterFinish: true,
347+
showProgressDetails: true,
348+
hideUploadButton: false,
349+
hideRetryButton: false,
350+
hidePauseResumeButton: false,
351+
hideCancelButton: false,
352+
doneButtonHandler: null,
353+
locale: {
354+
// TODO: Uppy&l10n research
355+
}
356+
})
357+
},
358+
359+
beforeDestroy() {
360+
// maybe bad that we close uppy this early,
361+
// eventually on rerender even?
362+
this.uppy.close()
363+
},
259364
methods: {
260365
...mapActions('Files', [
261366
'loadPreview',
262367
'updateFileProgress',
263-
'removeFilesFromTrashbin',
264-
'loadIndicators'
368+
'loadIndicators',
369+
'setFileSelection'
265370
]),
266371
...mapActions(['openFile', 'showMessage', 'createModal', 'setModalInputErrorMessage']),
267372
...mapMutations('Files', [
268373
'UPSERT_RESOURCE',
269-
'SET_HIDDEN_FILES_VISIBILITY',
270374
'REMOVE_FILE',
271375
'REMOVE_FILE_FROM_SEARCHED',
272376
'SET_FILE_SELECTION',

packages/web-app-files/src/components/AppBar/Upload/FileDrop.vue

-129
This file was deleted.

0 commit comments

Comments
 (0)