Merge pull request #44254 from nextcloud/fix/drop-service-chrome

fix(files): Adjust dropservice to work with Blink engine
pull/44275/head
Ferdinand Thiessen 2 months ago committed by GitHub
commit 92df4af12b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -22,6 +22,7 @@
-->
<template>
<div v-show="dragover"
data-cy-files-drag-drop-area
class="files-list__drag-drop-notice"
@drop="onDrop">
<div class="files-list__drag-drop-notice-wrapper">

@ -36,21 +36,27 @@ export const handleDrop = async (data: DataTransfer): Promise<Upload[]> => {
// TODO: Maybe handle `getAsFileSystemHandle()` in the future
const uploads = [] as Upload[]
for (const item of data.items) {
if (item.kind !== 'file') {
logger.debug('Skipping dropped item', { kind: item.kind, type: item.type })
continue
}
// MDN recommends to try both, as it might be renamed in the future
const entry = (item as unknown as { getAsEntry?: () => FileSystemEntry|undefined})?.getAsEntry?.() ?? item.webkitGetAsEntry()
// we need to cache the entries to prevent Blink engine bug that clears the list (`data.items`) after first access props of one of the entries
const entries = [...data.items]
.filter((item) => {
if (item.kind !== 'file') {
logger.debug('Skipping dropped item', { kind: item.kind, type: item.type })
return false
}
return true
})
.map((item) => {
// MDN recommends to try both, as it might be renamed in the future
return (item as unknown as { getAsEntry?: () => FileSystemEntry|undefined})?.getAsEntry?.() ?? item.webkitGetAsEntry() ?? item
})
for (const entry of entries) {
// Handle browser issues if Filesystem API is not available. Fallback to File API
if (entry === null) {
if (entry instanceof DataTransferItem) {
logger.debug('Could not get FilesystemEntry of item, falling back to file')
const file = item.getAsFile()
const file = entry.getAsFile()
if (file === null) {
logger.warn('Could not process DataTransferItem', { type: item.type, kind: item.kind })
logger.warn('Could not process DataTransferItem', { type: entry.type, kind: entry.kind })
showError(t('files', 'One of the dropped files could not be processed'))
} else {
uploads.push(await handleFileUpload(file))

@ -0,0 +1,62 @@
import { getRowForFile } from './FilesUtils.ts'
describe('files: Drag and Drop', { testIsolation: true }, () => {
beforeEach(() => {
cy.createRandomUser().then((user) => {
cy.login(user)
})
cy.visit('/apps/files')
})
it('can drop a file', () => {
const dataTransfer = new DataTransfer()
dataTransfer.items.add(new File([], 'single-file.txt'))
cy.intercept('PUT', /\/remote.php\/dav\/files\//).as('uploadFile')
cy.get('[data-cy-files-drag-drop-area]').should('not.be.visible')
// Trigger the drop notice
cy.get('main.app-content').trigger('dragover', { dataTransfer })
cy.get('[data-cy-files-drag-drop-area]').should('be.visible')
// Upload drop a file
cy.get('[data-cy-files-drag-drop-area]').selectFile({
fileName: 'single-file.txt',
contents: ['hello '.repeat(1024)],
}, { action: 'drag-drop' })
cy.wait('@uploadFile')
getRowForFile('single-file.txt').should('be.visible')
getRowForFile('single-file.txt').find('[data-cy-files-list-row-size]').should('contain', '6 KB')
})
it('can drop multiple files', () => {
const dataTransfer = new DataTransfer()
dataTransfer.items.add(new File([], 'first.txt'))
dataTransfer.items.add(new File([], 'second.txt'))
cy.intercept('PUT', /\/remote.php\/dav\/files\//).as('uploadFile')
// Trigger the drop notice
cy.get('main.app-content').trigger('dragover', { dataTransfer })
cy.get('[data-cy-files-drag-drop-area]').should('be.visible')
// Upload drop a file
cy.get('[data-cy-files-drag-drop-area]').selectFile([
{
fileName: 'first.txt',
contents: ['Hello'],
},
{
fileName: 'second.txt',
contents: ['World'],
},
], { action: 'drag-drop' })
cy.wait('@uploadFile')
getRowForFile('first.txt').should('be.visible')
getRowForFile('second.txt').should('be.visible')
})
})

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save