mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #44254 from nextcloud/fix/drop-service-chrome
fix(files): Adjust dropservice to work with Blink engine
This commit is contained in:
commit
92df4af12b
5 changed files with 83 additions and 14 deletions
|
|
@ -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))
|
||||
|
|
|
|||
62
cypress/e2e/files/drag-n-drop.cy.ts
Normal file
62
cypress/e2e/files/drag-n-drop.cy.ts
Normal 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')
|
||||
})
|
||||
})
|
||||
4
dist/files-main.js
vendored
4
dist/files-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-main.js.map
vendored
2
dist/files-main.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue