|
@@ -22,7 +22,6 @@ export const fileOpen = <M extends boolean | undefined = false>(opts: {
|
|
|
|
|
|
const mimeTypes = opts.extensions?.reduce((mimeTypes, type) => {
|
|
|
mimeTypes.push(MIME_TYPES[type]);
|
|
|
-
|
|
|
return mimeTypes;
|
|
|
}, [] as string[]);
|
|
|
|
|
@@ -39,34 +38,60 @@ export const fileOpen = <M extends boolean | undefined = false>(opts: {
|
|
|
mimeTypes,
|
|
|
multiple: opts.multiple ?? false,
|
|
|
legacySetup: (resolve, reject, input) => {
|
|
|
+ let isResolved = false;
|
|
|
+ let checkInterval: number | null = null;
|
|
|
+
|
|
|
+ // Increased delay for iOS to ensure file selection is complete
|
|
|
+ const CHECK_INTERVAL = 100; // 100ms
|
|
|
+ const MAX_CHECKS = 50; // 5 seconds total
|
|
|
+ let checkCount = 0;
|
|
|
+
|
|
|
const scheduleRejection = debounce(reject, INPUT_CHANGE_INTERVAL_MS);
|
|
|
- const focusHandler = () => {
|
|
|
- checkForFile();
|
|
|
- document.addEventListener(EVENT.KEYUP, scheduleRejection);
|
|
|
- document.addEventListener(EVENT.POINTER_UP, scheduleRejection);
|
|
|
- scheduleRejection();
|
|
|
- };
|
|
|
+
|
|
|
const checkForFile = () => {
|
|
|
- // this hack might not work when expecting multiple files
|
|
|
+ if (isResolved) return;
|
|
|
+
|
|
|
if (input.files?.length) {
|
|
|
+ isResolved = true;
|
|
|
const ret = opts.multiple ? [...input.files] : input.files[0];
|
|
|
resolve(ret as RetType);
|
|
|
+ return true;
|
|
|
}
|
|
|
+
|
|
|
+ checkCount++;
|
|
|
+ if (checkCount >= MAX_CHECKS) {
|
|
|
+ scheduleRejection();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
};
|
|
|
+
|
|
|
+ const focusHandler = () => {
|
|
|
+ // Start checking for files only after focus event
|
|
|
+ checkInterval = window.setInterval(() => {
|
|
|
+ if (checkForFile()) {
|
|
|
+ clearInterval(checkInterval!);
|
|
|
+ }
|
|
|
+ }, CHECK_INTERVAL);
|
|
|
+
|
|
|
+ document.addEventListener(EVENT.KEYUP, scheduleRejection);
|
|
|
+ document.addEventListener(EVENT.POINTER_UP, scheduleRejection);
|
|
|
+ };
|
|
|
+
|
|
|
requestAnimationFrame(() => {
|
|
|
window.addEventListener(EVENT.FOCUS, focusHandler);
|
|
|
});
|
|
|
- const interval = window.setInterval(() => {
|
|
|
- checkForFile();
|
|
|
- }, INPUT_CHANGE_INTERVAL_MS);
|
|
|
+
|
|
|
return (rejectPromise) => {
|
|
|
- clearInterval(interval);
|
|
|
+ if (checkInterval) {
|
|
|
+ clearInterval(checkInterval);
|
|
|
+ }
|
|
|
scheduleRejection.cancel();
|
|
|
window.removeEventListener(EVENT.FOCUS, focusHandler);
|
|
|
document.removeEventListener(EVENT.KEYUP, scheduleRejection);
|
|
|
document.removeEventListener(EVENT.POINTER_UP, scheduleRejection);
|
|
|
- if (rejectPromise) {
|
|
|
- // so that something is shown in console if we need to debug this
|
|
|
+
|
|
|
+ if (rejectPromise && !isResolved) {
|
|
|
console.warn("Opening the file was canceled (legacy-fs).");
|
|
|
rejectPromise(new AbortError());
|
|
|
}
|