@gradio/upload 0.12.0 → 0.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @gradio/upload
2
2
 
3
+ ## 0.12.2
4
+
5
+ ### Dependency updates
6
+
7
+ - @gradio/atoms@0.7.9
8
+ - @gradio/client@1.5.0
9
+ - @gradio/icons@0.7.0
10
+
11
+ ## 0.12.1
12
+
13
+ ### Fixes
14
+
15
+ - [#8879](https://github.com/gradio-app/gradio/pull/8879) [`67c08bf`](https://github.com/gradio-app/gradio/commit/67c08bfb9e59d801081591b8a59232c32d4467cf) - Fix file uploading in iOS. Thanks @hannahblair!
16
+ - [#8905](https://github.com/gradio-app/gradio/pull/8905) [`4b14ea8`](https://github.com/gradio-app/gradio/commit/4b14ea860d5055410a3a2257974b61a5c8eaac9d) - Allow use of file extensions in gr.File in iOS. Thanks @hannahblair!
17
+
18
+ ### Dependency updates
19
+
20
+ - @gradio/atoms@0.7.8
21
+ - @gradio/icons@0.6.1
22
+ - @gradio/utils@0.5.2
23
+
3
24
  ## 0.12.0
4
25
 
5
26
  ### Features
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@gradio/upload",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
7
7
  "author": "",
8
8
  "license": "ISC",
9
9
  "dependencies": {
10
- "@gradio/icons": "^0.6.0",
11
- "@gradio/utils": "^0.5.1",
12
- "@gradio/atoms": "^0.7.7",
10
+ "@gradio/atoms": "^0.7.9",
11
+ "@gradio/client": "^1.5.0",
12
+ "@gradio/icons": "^0.7.0",
13
13
  "@gradio/wasm": "^0.12.0",
14
- "@gradio/client": "^1.4.0"
14
+ "@gradio/utils": "^0.5.2"
15
15
  },
16
16
  "main_changeset": true,
17
17
  "exports": {
package/src/Upload.svelte CHANGED
@@ -25,10 +25,28 @@
25
25
  let upload_id: string;
26
26
  let file_data: FileData[];
27
27
  let accept_file_types: string | null;
28
+ let use_post_upload_validation: boolean | null = null;
29
+
30
+ const get_ios = (): boolean => {
31
+ if (typeof navigator !== "undefined") {
32
+ const userAgent = navigator.userAgent.toLowerCase();
33
+ return userAgent.indexOf("iphone") > -1 || userAgent.indexOf("ipad") > -1;
34
+ }
35
+ return false;
36
+ };
37
+
38
+ $: ios = get_ios();
28
39
 
29
40
  const dispatch = createEventDispatcher();
30
41
  const validFileTypes = ["image", "video", "audio", "text", "file"];
31
- const processFileType = (type: string): string => {
42
+ const process_file_type = (type: string): string => {
43
+ if (ios && type.startsWith(".")) {
44
+ use_post_upload_validation = true;
45
+ return type;
46
+ }
47
+ if (ios && type.includes("file/*")) {
48
+ return "*";
49
+ }
32
50
  if (type.startsWith(".") || type.endsWith("/*")) {
33
51
  return type;
34
52
  }
@@ -41,9 +59,11 @@
41
59
  $: if (filetype == null) {
42
60
  accept_file_types = null;
43
61
  } else if (typeof filetype === "string") {
44
- accept_file_types = processFileType(filetype);
62
+ accept_file_types = process_file_type(filetype);
63
+ } else if (ios && filetype.includes("file/*")) {
64
+ accept_file_types = "*";
45
65
  } else {
46
- filetype = filetype.map(processFileType);
66
+ filetype = filetype.map(process_file_type);
47
67
  accept_file_types = filetype.join(", ");
48
68
  }
49
69
 
@@ -110,10 +130,53 @@
110
130
  (f) =>
111
131
  new File([f], f instanceof File ? f.name : "file", { type: f.type })
112
132
  );
133
+
134
+ if (ios && use_post_upload_validation) {
135
+ _files = _files.filter((file) => {
136
+ if (is_valid_file(file)) {
137
+ return true;
138
+ }
139
+ dispatch(
140
+ "error",
141
+ `Invalid file type: ${file.name}. Only ${filetype} allowed.`
142
+ );
143
+ return false;
144
+ });
145
+
146
+ if (_files.length === 0) {
147
+ return [];
148
+ }
149
+ }
150
+
113
151
  file_data = await prepare_files(_files);
114
152
  return await handle_upload(file_data);
115
153
  }
116
154
 
155
+ function is_valid_file(file: File): boolean {
156
+ if (!filetype) return true;
157
+
158
+ const allowed_types = Array.isArray(filetype) ? filetype : [filetype];
159
+
160
+ return allowed_types.some((type) => {
161
+ const processed_type = process_file_type(type);
162
+
163
+ if (processed_type.startsWith(".")) {
164
+ return file.name.toLowerCase().endsWith(processed_type.toLowerCase());
165
+ }
166
+
167
+ if (processed_type === "*") {
168
+ return true;
169
+ }
170
+
171
+ if (processed_type.endsWith("/*")) {
172
+ const [category] = processed_type.split("/");
173
+ return file.type.startsWith(category + "/");
174
+ }
175
+
176
+ return file.type === processed_type;
177
+ });
178
+ }
179
+
117
180
  async function load_files_from_upload(e: Event): Promise<void> {
118
181
  const target = e.target as HTMLInputElement;
119
182
  if (!target.files) return;