Allow use of file extensions in gr.File in iOS (#8905)

* process file extensions in ios

* tweak

* add changeset

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
Hannah 2024-07-29 19:24:36 +01:00 committed by GitHub
parent 4c2d37db84
commit 4b14ea860d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 59 additions and 5 deletions

View File

@ -0,0 +1,6 @@
---
"@gradio/upload": patch
"gradio": patch
---
fix:Allow use of file extensions in gr.File in iOS

View File

@ -25,6 +25,7 @@
let upload_id: string;
let file_data: FileData[];
let accept_file_types: string | null;
let use_post_upload_validation: boolean | null = null;
const get_ios = (): boolean => {
if (typeof navigator !== "undefined") {
@ -38,13 +39,17 @@
const dispatch = createEventDispatcher();
const validFileTypes = ["image", "video", "audio", "text", "file"];
const processFileType = (type: string): string => {
if (type.startsWith(".") || type.endsWith("/*")) {
const process_file_type = (type: string): string => {
if (ios && type.startsWith(".")) {
use_post_upload_validation = true;
return type;
}
if (ios && type === "file") {
if (ios && type.includes("file/*")) {
return "*";
}
if (type.startsWith(".") || type.endsWith("/*")) {
return type;
}
if (validFileTypes.includes(type)) {
return type + "/*";
}
@ -54,11 +59,11 @@
$: if (filetype == null) {
accept_file_types = null;
} else if (typeof filetype === "string") {
accept_file_types = processFileType(filetype);
accept_file_types = process_file_type(filetype);
} else if (ios && filetype.includes("file/*")) {
accept_file_types = "*";
} else {
filetype = filetype.map(processFileType);
filetype = filetype.map(process_file_type);
accept_file_types = filetype.join(", ");
}
@ -125,10 +130,53 @@
(f) =>
new File([f], f instanceof File ? f.name : "file", { type: f.type })
);
if (ios && use_post_upload_validation) {
_files = _files.filter((file) => {
if (is_valid_file(file)) {
return true;
}
dispatch(
"error",
`Invalid file type: ${file.name}. Only ${filetype} allowed.`
);
return false;
});
if (_files.length === 0) {
return [];
}
}
file_data = await prepare_files(_files);
return await handle_upload(file_data);
}
function is_valid_file(file: File): boolean {
if (!filetype) return true;
const allowed_types = Array.isArray(filetype) ? filetype : [filetype];
return allowed_types.some((type) => {
const processed_type = process_file_type(type);
if (processed_type.startsWith(".")) {
return file.name.toLowerCase().endsWith(processed_type.toLowerCase());
}
if (processed_type === "*") {
return true;
}
if (processed_type.endsWith("/*")) {
const [category] = processed_type.split("/");
return file.type.startsWith(category + "/");
}
return file.type === processed_type;
});
}
async function load_files_from_upload(e: Event): Promise<void> {
const target = e.target as HTMLInputElement;
if (!target.files) return;