@gradio/upload 0.3.0-beta.3 → 0.3.0-beta.6

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,38 +1,56 @@
1
1
  # @gradio/upload
2
2
 
3
- ## 0.3.0-beta.3
3
+ ## 0.3.0-beta.6
4
4
 
5
- ### Patch Changes
5
+ ### Features
6
+
7
+ - [#6143](https://github.com/gradio-app/gradio/pull/6143) [`e4f7b4b40`](https://github.com/gradio-app/gradio/commit/e4f7b4b409323b01aa01b39e15ce6139e29aa073) - fix circular dependency with client + upload. Thanks [@pngwn](https://github.com/pngwn)!
8
+ - [#6136](https://github.com/gradio-app/gradio/pull/6136) [`667802a6c`](https://github.com/gradio-app/gradio/commit/667802a6cdbfb2ce454a3be5a78e0990b194548a) - JS Component Documentation. Thanks [@freddyaboulton](https://github.com/freddyaboulton)!
9
+ - [#6094](https://github.com/gradio-app/gradio/pull/6094) [`c476bd5a5`](https://github.com/gradio-app/gradio/commit/c476bd5a5b70836163b9c69bf4bfe068b17fbe13) - Image v4. Thanks [@pngwn](https://github.com/pngwn)!
10
+
11
+ ## 0.3.0-beta.5
12
+
13
+ ### Features
14
+
15
+ - [#6044](https://github.com/gradio-app/gradio/pull/6044) [`9053c95a1`](https://github.com/gradio-app/gradio/commit/9053c95a10de12aef572018ee37c71106d2da675) - Simplify File Component. Thanks [@freddyaboulton](https://github.com/freddyaboulton)!
16
+
17
+ ### Fixes
6
18
 
7
- - Updated dependencies [[`0b4fd5b6d`](https://github.com/gradio-app/gradio/commit/0b4fd5b6db96fc95a155e5e935e17e1ab11d1161)]:
8
- - @gradio/utils@0.2.0-beta.3
9
- - @gradio/atoms@0.2.0-beta.3
10
- - @gradio/upload@0.3.0-beta.3
19
+ - [#6046](https://github.com/gradio-app/gradio/pull/6046) [`dbb7de5e0`](https://github.com/gradio-app/gradio/commit/dbb7de5e02c53fee05889d696d764d212cb96c74) - fix tests. Thanks [@pngwn](https://github.com/pngwn)!
11
20
 
12
- ## 0.3.0-beta.2
21
+ ## 0.3.0-beta.4
22
+
23
+ ### Features
24
+
25
+ - [#5938](https://github.com/gradio-app/gradio/pull/5938) [`13ed8a485`](https://github.com/gradio-app/gradio/commit/13ed8a485d5e31d7d75af87fe8654b661edcca93) - V4: Use beta release versions for '@gradio' packages. Thanks [@freddyaboulton](https://github.com/freddyaboulton)!
26
+
27
+ ## 0.3.3
13
28
 
14
29
  ### Patch Changes
15
30
 
16
- - Updated dependencies [[`14fc612d8`](https://github.com/gradio-app/gradio/commit/14fc612d84bf6b1408eccd3a40fab41f25477571)]:
17
- - @gradio/utils@0.2.0-beta.2
18
- - @gradio/atoms@0.2.0-beta.2
19
- - @gradio/upload@0.3.0-beta.2
31
+ - Updated dependencies [[`e70805d54`](https://github.com/gradio-app/gradio/commit/e70805d54cc792452545f5d8eccc1aa0212a4695)]:
32
+ - @gradio/atoms@0.2.0
20
33
 
21
- ## 0.3.0-beta.1
34
+ ## 0.3.2
22
35
 
23
36
  ### Patch Changes
24
37
 
25
38
  - Updated dependencies []:
26
- - @gradio/utils@0.2.0-beta.1
27
- - @gradio/atoms@0.2.0-beta.1
28
- - @gradio/upload@0.3.0-beta.1
39
+ - @gradio/atoms@0.1.4
40
+
41
+ ## 0.3.1
42
+
43
+ ### Patch Changes
44
+
45
+ - Updated dependencies [[`8f0fed857`](https://github.com/gradio-app/gradio/commit/8f0fed857d156830626eb48b469d54d211a582d2)]:
46
+ - @gradio/icons@0.2.0
47
+ - @gradio/atoms@0.1.3
29
48
 
30
- ## 0.3.0-beta.0
49
+ ## 0.3.0
31
50
 
32
51
  ### Features
33
52
 
34
- - [#5507](https://github.com/gradio-app/gradio/pull/5507) [`1385dc688`](https://github.com/gradio-app/gradio/commit/1385dc6881f2d8ae7a41106ec21d33e2ef04d6a9) - Custom components. Thanks [@pngwn](https://github.com/pngwn)!
35
- - [#5498](https://github.com/gradio-app/gradio/pull/5498) [`681f10c31`](https://github.com/gradio-app/gradio/commit/681f10c315a75cc8cd0473c9a0167961af7696db) - release first version. Thanks [@pngwn](https://github.com/pngwn)!
53
+ - [#5554](https://github.com/gradio-app/gradio/pull/5554) [`75ddeb390`](https://github.com/gradio-app/gradio/commit/75ddeb390d665d4484667390a97442081b49a423) - Accessibility Improvements. Thanks [@hannahblair](https://github.com/hannahblair)!
36
54
 
37
55
  ## 0.2.1
38
56
 
@@ -121,4 +139,4 @@ From the backend, streamed outputs are served from the `/stream/` endpoint inste
121
139
  ### Patch Changes
122
140
 
123
141
  - Updated dependencies []:
124
- - @gradio/atoms@0.0.2
142
+ - @gradio/atoms@0.0.2
package/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # `@gradio/upload`
2
+
3
+ ```html
4
+ <script>
5
+ import { Upload, ModifyUpload, normalise_file, get_fetchable_url_or_file, upload, prepare_files } from "@gradio/upload";
6
+ </script>
7
+ ```
8
+
9
+ Upload
10
+ ```javascript
11
+ export let filetype: string | null = null;
12
+ export let dragging = false;
13
+ export let boundedheight = true;
14
+ export let center = true;
15
+ export let flex = true;
16
+ export let file_count = "single";
17
+ export let disable_click = false;
18
+ export let root: string;
19
+ export let hidden = false;
20
+ ```
21
+
22
+ ModifyUpload
23
+ ```javascript
24
+ export let editable = false;
25
+ export let undoable = false;
26
+ export let absolute = true;
27
+ export let i18n: I18nFormatter;
28
+ ```
29
+
30
+ ```javascript
31
+ export function normalise_file(
32
+ file: FileData | null,
33
+ server_url: string,
34
+ proxy_url: string | null
35
+ ): FileData | null;
36
+
37
+ export function normalise_file(
38
+ file: FileData[] | null,
39
+ server_url: string,
40
+ proxy_url: string | null
41
+ ): FileData[] | null;
42
+
43
+ export function normalise_file(
44
+ file: FileData[] | FileData | null,
45
+ server_url: string, // root: string,
46
+ proxy_url: string | null // root_url: string | null
47
+ ): FileData[] | FileData | null;
48
+
49
+ export function normalise_file(
50
+ file: FileData[] | FileData | null,
51
+ server_url: string, // root: string,
52
+ proxy_url: string | null // root_url: string | null
53
+ ): FileData[] | FileData | null;
54
+
55
+ export function get_fetchable_url_or_file(
56
+ path: string | null,
57
+ server_url: string,
58
+ proxy_url: string | null
59
+ ): string
60
+
61
+ export async function upload(
62
+ file_data: FileData[],
63
+ root: string,
64
+ upload_fn: typeof upload_files = upload_files
65
+ ): Promise<(FileData | null)[] | null>
66
+
67
+ export async function prepare_files(
68
+ files: File[],
69
+ is_stream?: boolean
70
+ ): Promise<FileData[]> {
71
+ return files.map(
72
+ (f, i) =>
73
+ new FileData({
74
+ path: f.name,
75
+ orig_name: f.name,
76
+ blob: f,
77
+ size: f.size,
78
+ mime_type: f.type,
79
+ is_stream
80
+ })
81
+ );
82
+ }
83
+ ```
package/package.json CHANGED
@@ -1,17 +1,20 @@
1
1
  {
2
2
  "name": "@gradio/upload",
3
- "version": "0.3.0-beta.3",
3
+ "version": "0.3.0-beta.6",
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/atoms": "^0.2.0-beta.3",
11
- "@gradio/icons": "^0.2.0-beta.0",
12
- "@gradio/client": "^0.3.1",
13
- "@gradio/upload": "^0.3.0-beta.3",
14
- "@gradio/utils": "^0.2.0-beta.3"
10
+ "@gradio/atoms": "^0.2.0-beta.6",
11
+ "@gradio/icons": "^0.2.0-beta.3",
12
+ "@gradio/client": "^0.7.0-beta.1",
13
+ "@gradio/upload": "^0.3.0-beta.6",
14
+ "@gradio/utils": "^0.2.0-beta.6"
15
15
  },
16
- "main_changeset": true
16
+ "main_changeset": true,
17
+ "exports": {
18
+ ".": "./src/index.ts"
19
+ }
17
20
  }
@@ -11,9 +11,9 @@
11
11
  export let i18n: I18nFormatter;
12
12
 
13
13
  const dispatch = createEventDispatcher<{
14
- edit: never;
15
- clear: never;
16
- undo: never;
14
+ edit?: never;
15
+ clear?: never;
16
+ undo?: never;
17
17
  }>();
18
18
  </script>
19
19
 
package/src/Upload.svelte CHANGED
@@ -1,12 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { createEventDispatcher, tick, getContext } from "svelte";
3
- import type { FileData } from "./types";
4
- import { blobToBase64, normalise_file } from "./utils";
5
- import { upload_files as default_upload_files } from "@gradio/client";
6
-
7
- const upload_files =
8
- getContext<typeof default_upload_files>("upload_files") ??
9
- default_upload_files;
3
+ import type { FileData } from "@gradio/client";
4
+ import { upload_files, upload, prepare_files } from "@gradio/client";
5
+ import { _ } from "svelte-i18n";
10
6
 
11
7
  export let filetype: string | null = null;
12
8
  export let dragging = false;
@@ -16,6 +12,10 @@
16
12
  export let file_count = "single";
17
13
  export let disable_click = false;
18
14
  export let root: string;
15
+ export let hidden = false;
16
+
17
+ // Needed for wasm support
18
+ const upload_fn = getContext<typeof upload_files>("upload_files");
19
19
 
20
20
  let hidden_upload: HTMLInputElement;
21
21
 
@@ -25,79 +25,74 @@
25
25
  dragging = !dragging;
26
26
  }
27
27
 
28
- function openFileUpload(): void {
28
+ export function open_file_upload(): void {
29
29
  if (disable_click) return;
30
30
  hidden_upload.value = "";
31
31
  hidden_upload.click();
32
32
  }
33
33
 
34
- async function handle_upload(file_data: FileData[]): Promise<void> {
34
+ async function handle_upload(
35
+ file_data: FileData[]
36
+ ): Promise<(FileData | null)[]> {
35
37
  await tick();
36
- let files = (Array.isArray(file_data) ? file_data : [file_data]).map(
37
- (file_data) => file_data.blob!
38
- );
39
-
40
- await upload_files(root, files).then(async (response) => {
41
- if (response.error) {
42
- (Array.isArray(file_data) ? file_data : [file_data]).forEach(
43
- async (file_data, i) => {
44
- file_data.data = await blobToBase64(file_data.blob!);
45
- file_data.blob = undefined;
46
- }
47
- );
48
- } else {
49
- (Array.isArray(file_data) ? file_data : [file_data]).forEach((f, i) => {
50
- if (response.files) {
51
- f.orig_name = f.name;
52
- f.name = response.files[i];
53
- f.is_file = true;
54
- f.blob = undefined;
55
- normalise_file(f, root, null);
56
- }
57
- });
58
- }
59
- });
60
- dispatch("load", file_count === "single" ? file_data[0] : file_data);
38
+ const _file_data = await upload(file_data, root, upload_fn);
39
+ dispatch("load", file_count === "single" ? _file_data?.[0] : _file_data);
40
+ return _file_data || [];
61
41
  }
62
42
 
63
- async function loadFiles(files: FileList): Promise<void> {
64
- let _files: File[] = Array.from(files);
43
+ export async function load_files(
44
+ files: File[] | Blob[]
45
+ ): Promise<(FileData | null)[] | void> {
65
46
  if (!files.length) {
66
47
  return;
67
48
  }
68
- if (file_count === "single") {
69
- _files = [files[0]];
70
- }
71
- var all_file_data: FileData[] = [];
72
- _files.forEach((f, i) => {
73
- all_file_data[i] = {
74
- name: f.name,
75
- size: f.size,
76
- data: "",
77
- blob: f
78
- };
79
- });
80
- await handle_upload(all_file_data);
49
+
50
+ let _files: File[] = files.map((f) => new File([f], f.name));
51
+
52
+ let file_data = await prepare_files(_files);
53
+ return await handle_upload(file_data);
81
54
  }
82
55
 
83
- async function loadFilesFromUpload(e: Event): Promise<void> {
56
+ async function load_files_from_upload(e: Event): Promise<void> {
84
57
  const target = e.target as HTMLInputElement;
85
-
86
58
  if (!target.files) return;
87
- await loadFiles(target.files);
59
+ await load_files(Array.from(target.files));
60
+ }
61
+
62
+ function is_valid_mimetype(
63
+ file_accept: string | null,
64
+ mime_type: string
65
+ ): boolean {
66
+ if (!file_accept) {
67
+ return true;
68
+ }
69
+ if (file_accept === "*") {
70
+ return true;
71
+ }
72
+ if (file_accept.endsWith("/*")) {
73
+ return mime_type.startsWith(file_accept.slice(0, -1));
74
+ }
75
+ return file_accept === mime_type;
88
76
  }
89
77
 
90
78
  async function loadFilesFromDrop(e: DragEvent): Promise<void> {
91
79
  dragging = false;
92
80
  if (!e.dataTransfer?.files) return;
93
- await loadFiles(e.dataTransfer.files);
81
+
82
+ const files_to_load = Array.from(e.dataTransfer.files).filter((f) => {
83
+ if (is_valid_mimetype(filetype, f.type)) {
84
+ return true;
85
+ }
86
+ dispatch("error", `Invalid file type only ${filetype} allowed.`);
87
+ return false;
88
+ });
89
+
90
+ await load_files(files_to_load);
94
91
  }
95
92
  </script>
96
93
 
97
- <!-- TODO: fix -->
98
- <!-- svelte-ignore a11y-click-events-have-key-events -->
99
- <!-- svelte-ignore a11y-no-static-element-interactions -->
100
- <div
94
+ <button
95
+ class:hidden
101
96
  class:center
102
97
  class:boundedheight
103
98
  class:flex
@@ -108,7 +103,7 @@
108
103
  on:dragenter|preventDefault|stopPropagation
109
104
  on:dragleave|preventDefault|stopPropagation
110
105
  on:drop|preventDefault|stopPropagation
111
- on:click={openFileUpload}
106
+ on:click={open_file_upload}
112
107
  on:drop={loadFilesFromDrop}
113
108
  on:dragenter={updateDragging}
114
109
  on:dragleave={updateDragging}
@@ -117,23 +112,30 @@
117
112
  <input
118
113
  type="file"
119
114
  bind:this={hidden_upload}
120
- on:change={loadFilesFromUpload}
115
+ on:change={load_files_from_upload}
121
116
  accept={filetype}
122
117
  multiple={file_count === "multiple" || undefined}
123
118
  webkitdirectory={file_count === "directory" || undefined}
124
119
  mozdirectory={file_count === "directory" || undefined}
125
120
  />
126
- </div>
121
+ </button>
127
122
 
128
123
  <style>
129
- div {
124
+ button {
130
125
  cursor: pointer;
131
126
  width: var(--size-full);
132
127
  height: var(--size-full);
133
128
  }
134
129
 
130
+ .hidden {
131
+ display: none;
132
+ height: 0;
133
+ position: absolute;
134
+ }
135
+
135
136
  .center {
136
- text-align: center;
137
+ display: flex;
138
+ justify-content: center;
137
139
  }
138
140
  .flex {
139
141
  display: flex;
package/src/index.ts CHANGED
@@ -1,8 +1,2 @@
1
1
  export { default as Upload } from "./Upload.svelte";
2
2
  export { default as ModifyUpload } from "./ModifyUpload.svelte";
3
- export type { FileData } from "./types";
4
- export {
5
- normalise_file,
6
- get_fetchable_url_or_file,
7
- blobToBase64
8
- } from "./utils";
package/src/types.ts DELETED
@@ -1,11 +0,0 @@
1
- export interface FileData {
2
- name: string;
3
- orig_name?: string;
4
- size?: number;
5
- data: string;
6
- blob?: File;
7
- is_file?: boolean;
8
- is_stream?: boolean;
9
- mime_type?: string;
10
- alt_text?: string;
11
- }
package/src/utils.ts DELETED
@@ -1,87 +0,0 @@
1
- import type { FileData } from "./types";
2
-
3
- export function normalise_file(
4
- file: string | FileData | null,
5
- root: string,
6
- root_url: string | null
7
- ): FileData | null;
8
-
9
- export function normalise_file(
10
- file: FileData[] | null,
11
- root: string,
12
- root_url: string | null
13
- ): FileData[] | null;
14
-
15
- export function normalise_file(
16
- file: FileData[] | FileData | null,
17
- root: string,
18
- root_url: string | null
19
- ): FileData[] | FileData | null;
20
-
21
- export function normalise_file(
22
- file: FileData[] | FileData | string | null,
23
- root: string,
24
- root_url: string | null
25
- ): FileData[] | FileData | null {
26
- if (file == null) return null;
27
- if (typeof file === "string") {
28
- return {
29
- name: "file_data",
30
- data: file
31
- };
32
- } else if (Array.isArray(file)) {
33
- const normalized_file: (FileData | null)[] = [];
34
-
35
- for (const x of file) {
36
- if (x === null) {
37
- normalized_file.push(null);
38
- } else {
39
- normalized_file.push(normalise_file(x, root, root_url));
40
- }
41
- }
42
-
43
- return normalized_file as FileData[];
44
- } else if (file.is_file) {
45
- file.data = get_fetchable_url_or_file(file.name, root, root_url);
46
- } else if (file.is_stream) {
47
- if (root_url == null) {
48
- file.data = root + "/stream/" + file.name;
49
- } else {
50
- file.data = "/proxy=" + root_url + "stream/" + file.name;
51
- }
52
- }
53
- return file;
54
- }
55
-
56
- function is_url(str: string): boolean {
57
- try {
58
- const url = new URL(str);
59
- return url.protocol === "http:" || url.protocol === "https:";
60
- } catch {
61
- return false;
62
- }
63
- }
64
-
65
- export function get_fetchable_url_or_file(
66
- path: string | null,
67
- root: string,
68
- root_url: string | null
69
- ): string {
70
- if (path == null) {
71
- return root_url ? `/proxy=${root_url}file=` : `${root}/file=`;
72
- }
73
- if (is_url(path)) {
74
- return path;
75
- }
76
- return root_url ? `/proxy=${root_url}file=${path}` : `${root}/file=${path}`;
77
- }
78
-
79
- export const blobToBase64 = (blob: File): Promise<string> => {
80
- const reader = new FileReader();
81
- reader.readAsDataURL(blob);
82
- return new Promise((resolve) => {
83
- reader.onloadend = (): void => {
84
- resolve(reader.result as string);
85
- };
86
- });
87
- };