@gradio/upload 0.3.0-beta.4 → 0.3.0
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 +26 -0
- package/README.md +83 -0
- package/package.json +10 -7
- package/src/ModifyUpload.svelte +3 -3
- package/src/Upload.svelte +59 -55
- package/src/index.ts +0 -6
- package/src/types.ts +0 -11
- package/src/utils.ts +0 -87
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
# @gradio/upload
|
2
2
|
|
3
|
+
## 0.3.0
|
4
|
+
|
5
|
+
### Features
|
6
|
+
|
7
|
+
- [#5498](https://github.com/gradio-app/gradio/pull/5498) [`287fe6782`](https://github.com/gradio-app/gradio/commit/287fe6782825479513e79a5cf0ba0fbfe51443d7) - fix circular dependency with client + upload. Thanks [@pngwn](https://github.com/pngwn)!
|
8
|
+
- [#5498](https://github.com/gradio-app/gradio/pull/5498) [`287fe6782`](https://github.com/gradio-app/gradio/commit/287fe6782825479513e79a5cf0ba0fbfe51443d7) - Image v4. Thanks [@pngwn](https://github.com/pngwn)!
|
9
|
+
- [#5498](https://github.com/gradio-app/gradio/pull/5498) [`287fe6782`](https://github.com/gradio-app/gradio/commit/287fe6782825479513e79a5cf0ba0fbfe51443d7) - Custom components. Thanks [@pngwn](https://github.com/pngwn)!
|
10
|
+
|
11
|
+
## 0.3.0-beta.6
|
12
|
+
|
13
|
+
### Features
|
14
|
+
|
15
|
+
- [#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)!
|
16
|
+
- [#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)!
|
17
|
+
- [#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)!
|
18
|
+
|
19
|
+
## 0.3.0-beta.5
|
20
|
+
|
21
|
+
### Features
|
22
|
+
|
23
|
+
- [#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)!
|
24
|
+
|
25
|
+
### Fixes
|
26
|
+
|
27
|
+
- [#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)!
|
28
|
+
|
3
29
|
## 0.3.0-beta.4
|
4
30
|
|
5
31
|
### Features
|
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
|
3
|
+
"version": "0.3.0",
|
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
|
11
|
-
"@gradio/icons": "^0.2.0
|
12
|
-
"@gradio/client": "^0.
|
13
|
-
"@gradio/upload": "^0.3.0
|
14
|
-
"@gradio/utils": "^0.2.0
|
10
|
+
"@gradio/atoms": "^0.2.0",
|
11
|
+
"@gradio/icons": "^0.2.0",
|
12
|
+
"@gradio/client": "^0.7.0",
|
13
|
+
"@gradio/upload": "^0.3.0",
|
14
|
+
"@gradio/utils": "^0.2.0"
|
15
15
|
},
|
16
|
-
"main_changeset": true
|
16
|
+
"main_changeset": true,
|
17
|
+
"exports": {
|
18
|
+
".": "./src/index.ts"
|
19
|
+
}
|
17
20
|
}
|
package/src/ModifyUpload.svelte
CHANGED
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 "
|
4
|
-
import {
|
5
|
-
import {
|
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,76 +25,74 @@
|
|
25
25
|
dragging = !dragging;
|
26
26
|
}
|
27
27
|
|
28
|
-
function
|
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(
|
34
|
+
async function handle_upload(
|
35
|
+
file_data: FileData[]
|
36
|
+
): Promise<(FileData | null)[]> {
|
35
37
|
await tick();
|
36
|
-
|
37
|
-
|
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
|
64
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
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
|
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
|
-
|
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
94
|
<button
|
95
|
+
class:hidden
|
98
96
|
class:center
|
99
97
|
class:boundedheight
|
100
98
|
class:flex
|
@@ -105,7 +103,7 @@
|
|
105
103
|
on:dragenter|preventDefault|stopPropagation
|
106
104
|
on:dragleave|preventDefault|stopPropagation
|
107
105
|
on:drop|preventDefault|stopPropagation
|
108
|
-
on:click={
|
106
|
+
on:click={open_file_upload}
|
109
107
|
on:drop={loadFilesFromDrop}
|
110
108
|
on:dragenter={updateDragging}
|
111
109
|
on:dragleave={updateDragging}
|
@@ -114,7 +112,7 @@
|
|
114
112
|
<input
|
115
113
|
type="file"
|
116
114
|
bind:this={hidden_upload}
|
117
|
-
on:change={
|
115
|
+
on:change={load_files_from_upload}
|
118
116
|
accept={filetype}
|
119
117
|
multiple={file_count === "multiple" || undefined}
|
120
118
|
webkitdirectory={file_count === "directory" || undefined}
|
@@ -129,6 +127,12 @@
|
|
129
127
|
height: var(--size-full);
|
130
128
|
}
|
131
129
|
|
130
|
+
.hidden {
|
131
|
+
display: none;
|
132
|
+
height: 0;
|
133
|
+
position: absolute;
|
134
|
+
}
|
135
|
+
|
132
136
|
.center {
|
133
137
|
display: flex;
|
134
138
|
justify-content: center;
|
package/src/index.ts
CHANGED
package/src/types.ts
DELETED
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
|
-
};
|