mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
refactor(editor): split openFileOrFiles into openSingleFileWith and openFilesWith (#12523)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved file selection dialogs for attachments, imports, and uploads, allowing for more consistent and streamlined file picking across the app. - **Bug Fixes** - Resolved inconsistencies when selecting single or multiple files, ensuring a smoother user experience during file import and upload. - **Refactor** - Unified and simplified file selection logic throughout the app for better reliability and maintainability. - Standardized import functions to uniformly handle arrays of files, enhancing consistency in file processing. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -112,21 +112,11 @@ type AcceptTypes =
|
||||
| 'Html'
|
||||
| 'Zip'
|
||||
| 'MindMap';
|
||||
export function openFileOrFiles(options?: {
|
||||
acceptType?: AcceptTypes;
|
||||
}): Promise<File | null>;
|
||||
export function openFileOrFiles(options: {
|
||||
acceptType?: AcceptTypes;
|
||||
multiple: false;
|
||||
}): Promise<File | null>;
|
||||
export function openFileOrFiles(options: {
|
||||
acceptType?: AcceptTypes;
|
||||
multiple: true;
|
||||
}): Promise<File[] | null>;
|
||||
export async function openFileOrFiles({
|
||||
acceptType = 'Any',
|
||||
multiple = false,
|
||||
} = {}) {
|
||||
|
||||
export async function openFilesWith(
|
||||
acceptType: AcceptTypes = 'Any',
|
||||
multiple: boolean = true
|
||||
): Promise<File[] | null> {
|
||||
// Feature detection. The API needs to be supported
|
||||
// and the app not run in an iframe.
|
||||
const supportsFileSystemAccess =
|
||||
@@ -138,6 +128,7 @@ export async function openFileOrFiles({
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
|
||||
// If the File System Access API is supported…
|
||||
if (supportsFileSystemAccess && window.showOpenFilePicker) {
|
||||
try {
|
||||
@@ -153,30 +144,14 @@ export async function openFileOrFiles({
|
||||
} satisfies OpenFilePickerOptions;
|
||||
// Show the file picker, optionally allowing multiple files.
|
||||
const handles = await window.showOpenFilePicker(pickerOpts);
|
||||
// Only one file is requested.
|
||||
if (!multiple) {
|
||||
// Add the `FileSystemFileHandle` as `.handle`.
|
||||
const file = await handles[0].getFile();
|
||||
// Add the `FileSystemFileHandle` as `.handle`.
|
||||
// file.handle = handles[0];
|
||||
return file;
|
||||
} else {
|
||||
const files = await Promise.all(
|
||||
handles.map(async handle => {
|
||||
const file = await handle.getFile();
|
||||
// Add the `FileSystemFileHandle` as `.handle`.
|
||||
// file.handle = handles[0];
|
||||
return file;
|
||||
})
|
||||
);
|
||||
return files;
|
||||
}
|
||||
|
||||
return await Promise.all(handles.map(handle => handle.getFile()));
|
||||
} catch (err) {
|
||||
console.error('Error opening file');
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback if the File System Access API is not supported.
|
||||
return new Promise(resolve => {
|
||||
// Append a new `<input type="file" multiple? />` and hide it.
|
||||
@@ -184,9 +159,8 @@ export async function openFileOrFiles({
|
||||
input.classList.add('affine-upload-input');
|
||||
input.style.display = 'none';
|
||||
input.type = 'file';
|
||||
if (multiple) {
|
||||
input.multiple = true;
|
||||
}
|
||||
input.multiple = multiple;
|
||||
|
||||
if (acceptType !== 'Any') {
|
||||
// For example, `accept="image/*"` or `accept="video/*,audio/*"`.
|
||||
input.accept = Object.keys(
|
||||
@@ -198,17 +172,8 @@ export async function openFileOrFiles({
|
||||
input.addEventListener('change', () => {
|
||||
// Remove the `<input type="file" multiple? />` again from the DOM.
|
||||
input.remove();
|
||||
// If no files were selected, return.
|
||||
if (!input.files) {
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
// Return all files or just one file.
|
||||
if (multiple) {
|
||||
resolve(Array.from(input.files));
|
||||
return;
|
||||
}
|
||||
resolve(input.files[0]);
|
||||
|
||||
resolve(input.files ? Array.from(input.files) : null);
|
||||
});
|
||||
// The `cancel` event fires when the user cancels the dialog.
|
||||
input.addEventListener('cancel', () => {
|
||||
@@ -223,11 +188,14 @@ export async function openFileOrFiles({
|
||||
});
|
||||
}
|
||||
|
||||
export function openSingleFileWith(
|
||||
acceptType?: AcceptTypes
|
||||
): Promise<File | null> {
|
||||
return openFilesWith(acceptType, false).then(files => files?.at(0) ?? null);
|
||||
}
|
||||
|
||||
export async function getImageFilesFromLocal() {
|
||||
const imageFiles = await openFileOrFiles({
|
||||
acceptType: 'Images',
|
||||
multiple: true,
|
||||
});
|
||||
const imageFiles = await openFilesWith('Images');
|
||||
if (!imageFiles) return [];
|
||||
return imageFiles;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user