@gradio/upload 0.3.2 → 0.4.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 +13 -0
- package/package.json +4 -4
- package/src/Upload.svelte +44 -31
- package/src/UploadProgress.svelte +174 -0
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# @gradio/upload
|
2
2
|
|
3
|
+
## 0.4.0
|
4
|
+
|
5
|
+
### Features
|
6
|
+
|
7
|
+
- [#6356](https://github.com/gradio-app/gradio/pull/6356) [`854b482f5`](https://github.com/gradio-app/gradio/commit/854b482f598e0dc47673846631643c079576da9c) - Redesign file upload. Thanks [@hannahblair](https://github.com/hannahblair)!
|
8
|
+
- [#6307](https://github.com/gradio-app/gradio/pull/6307) [`f1409f95e`](https://github.com/gradio-app/gradio/commit/f1409f95ed39c5565bed6a601e41f94e30196a57) - Provide status updates on file uploads. Thanks [@freddyaboulton](https://github.com/freddyaboulton)!
|
9
|
+
|
10
|
+
## 0.3.3
|
11
|
+
|
12
|
+
### Fixes
|
13
|
+
|
14
|
+
- [#6279](https://github.com/gradio-app/gradio/pull/6279) [`3cdeabc68`](https://github.com/gradio-app/gradio/commit/3cdeabc6843000310e1a9e1d17190ecbf3bbc780) - Ensure source selection does not get hidden in overflow. Thanks [@hannahblair](https://github.com/hannahblair)!
|
15
|
+
|
3
16
|
## 0.3.2
|
4
17
|
|
5
18
|
### Fixes
|
package/package.json
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
{
|
2
2
|
"name": "@gradio/upload",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.4.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.
|
10
|
+
"@gradio/atoms": "^0.2.1",
|
11
11
|
"@gradio/icons": "^0.2.0",
|
12
|
-
"@gradio/client": "^0.
|
13
|
-
"@gradio/upload": "^0.
|
12
|
+
"@gradio/client": "^0.8.0",
|
13
|
+
"@gradio/upload": "^0.4.0",
|
14
14
|
"@gradio/utils": "^0.2.0"
|
15
15
|
},
|
16
16
|
"main_changeset": true,
|
package/src/Upload.svelte
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
import type { FileData } from "@gradio/client";
|
4
4
|
import { upload_files, upload, prepare_files } from "@gradio/client";
|
5
5
|
import { _ } from "svelte-i18n";
|
6
|
+
import UploadProgress from "./UploadProgress.svelte";
|
6
7
|
|
7
8
|
export let filetype: string | null = null;
|
8
9
|
export let dragging = false;
|
@@ -13,6 +14,11 @@
|
|
13
14
|
export let disable_click = false;
|
14
15
|
export let root: string;
|
15
16
|
export let hidden = false;
|
17
|
+
export let include_sources = false;
|
18
|
+
|
19
|
+
let uploading = false;
|
20
|
+
let upload_id: string;
|
21
|
+
let file_data: FileData[];
|
16
22
|
|
17
23
|
// Needed for wasm support
|
18
24
|
const upload_fn = getContext<typeof upload_files>("upload_files");
|
@@ -35,8 +41,11 @@
|
|
35
41
|
file_data: FileData[]
|
36
42
|
): Promise<(FileData | null)[]> {
|
37
43
|
await tick();
|
38
|
-
|
44
|
+
upload_id = Math.random().toString(36).substring(2, 15);
|
45
|
+
uploading = true;
|
46
|
+
const _file_data = await upload(file_data, root, upload_id, upload_fn);
|
39
47
|
dispatch("load", file_count === "single" ? _file_data?.[0] : _file_data);
|
48
|
+
uploading = false;
|
40
49
|
return _file_data || [];
|
41
50
|
}
|
42
51
|
|
@@ -47,7 +56,7 @@
|
|
47
56
|
return;
|
48
57
|
}
|
49
58
|
let _files: File[] = files.map((f) => new File([f], f.name));
|
50
|
-
|
59
|
+
file_data = await prepare_files(_files);
|
51
60
|
return await handle_upload(file_data);
|
52
61
|
}
|
53
62
|
|
@@ -89,40 +98,44 @@
|
|
89
98
|
}
|
90
99
|
</script>
|
91
100
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
101
|
+
{#if uploading}
|
102
|
+
<UploadProgress {root} {upload_id} files={file_data} />
|
103
|
+
{:else}
|
104
|
+
<button
|
105
|
+
class:hidden
|
106
|
+
class:center
|
107
|
+
class:boundedheight
|
108
|
+
class:flex
|
109
|
+
style:height={include_sources ? "calc(100% - 40px" : "100%"}
|
110
|
+
on:drag|preventDefault|stopPropagation
|
111
|
+
on:dragstart|preventDefault|stopPropagation
|
112
|
+
on:dragend|preventDefault|stopPropagation
|
113
|
+
on:dragover|preventDefault|stopPropagation
|
114
|
+
on:dragenter|preventDefault|stopPropagation
|
115
|
+
on:dragleave|preventDefault|stopPropagation
|
116
|
+
on:drop|preventDefault|stopPropagation
|
117
|
+
on:click={open_file_upload}
|
118
|
+
on:drop={loadFilesFromDrop}
|
119
|
+
on:dragenter={updateDragging}
|
120
|
+
on:dragleave={updateDragging}
|
121
|
+
>
|
122
|
+
<slot />
|
123
|
+
<input
|
124
|
+
type="file"
|
125
|
+
bind:this={hidden_upload}
|
126
|
+
on:change={load_files_from_upload}
|
127
|
+
accept={filetype}
|
128
|
+
multiple={file_count === "multiple" || undefined}
|
129
|
+
webkitdirectory={file_count === "directory" || undefined}
|
130
|
+
mozdirectory={file_count === "directory" || undefined}
|
131
|
+
/>
|
132
|
+
</button>
|
133
|
+
{/if}
|
120
134
|
|
121
135
|
<style>
|
122
136
|
button {
|
123
137
|
cursor: pointer;
|
124
138
|
width: var(--size-full);
|
125
|
-
height: var(--size-full);
|
126
139
|
}
|
127
140
|
|
128
141
|
.hidden {
|
@@ -0,0 +1,174 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
import { FileData } from "@gradio/client";
|
3
|
+
import { onMount, createEventDispatcher } from "svelte";
|
4
|
+
|
5
|
+
type FileDataWithProgress = FileData & { progress: number };
|
6
|
+
|
7
|
+
export let upload_id: string;
|
8
|
+
export let root: string;
|
9
|
+
export let files: FileData[];
|
10
|
+
|
11
|
+
let event_source: EventSource;
|
12
|
+
let progress = false;
|
13
|
+
let current_file_upload: FileDataWithProgress;
|
14
|
+
|
15
|
+
let files_with_progress: FileDataWithProgress[] = files.map((file) => {
|
16
|
+
return {
|
17
|
+
...file,
|
18
|
+
progress: 0
|
19
|
+
};
|
20
|
+
});
|
21
|
+
|
22
|
+
const dispatch = createEventDispatcher();
|
23
|
+
|
24
|
+
function handleProgress(filename: string, chunk_size: number): void {
|
25
|
+
// Find the corresponding file in the array and update its progress
|
26
|
+
files_with_progress = files_with_progress.map((file) => {
|
27
|
+
if (file.orig_name === filename) {
|
28
|
+
file.progress += chunk_size;
|
29
|
+
}
|
30
|
+
return file;
|
31
|
+
});
|
32
|
+
}
|
33
|
+
|
34
|
+
function getProgress(file: FileDataWithProgress): number {
|
35
|
+
return (file.progress * 100) / (file.size || 0) || 0;
|
36
|
+
}
|
37
|
+
|
38
|
+
onMount(() => {
|
39
|
+
event_source = new EventSource(
|
40
|
+
`${root}/upload_progress?upload_id=${upload_id}`
|
41
|
+
);
|
42
|
+
// Event listener for progress updates
|
43
|
+
event_source.onmessage = async function (event) {
|
44
|
+
const _data = JSON.parse(event.data);
|
45
|
+
if (!progress) progress = true;
|
46
|
+
if (_data.msg === "done") {
|
47
|
+
event_source.close();
|
48
|
+
dispatch("done");
|
49
|
+
} else {
|
50
|
+
current_file_upload = _data;
|
51
|
+
handleProgress(_data.orig_name, _data.chunk_size);
|
52
|
+
}
|
53
|
+
};
|
54
|
+
});
|
55
|
+
|
56
|
+
function calculateTotalProgress(files: FileData[]): number {
|
57
|
+
let totalProgress = 0;
|
58
|
+
files.forEach((file) => {
|
59
|
+
totalProgress += getProgress(file as FileDataWithProgress);
|
60
|
+
});
|
61
|
+
|
62
|
+
document.documentElement.style.setProperty(
|
63
|
+
"--upload-progress-width",
|
64
|
+
(totalProgress / files.length).toFixed(2) + "%"
|
65
|
+
);
|
66
|
+
|
67
|
+
return totalProgress / files.length;
|
68
|
+
}
|
69
|
+
|
70
|
+
$: calculateTotalProgress(files_with_progress);
|
71
|
+
</script>
|
72
|
+
|
73
|
+
<div class="wrap" class:progress>
|
74
|
+
<span class="uploading"
|
75
|
+
>Uploading {files_with_progress.length}
|
76
|
+
{files_with_progress.length > 1 ? "files" : "file"}...</span
|
77
|
+
>
|
78
|
+
|
79
|
+
{#if current_file_upload}
|
80
|
+
<div class="file">
|
81
|
+
<span>
|
82
|
+
<div class="progress-bar">
|
83
|
+
<progress
|
84
|
+
style="visibility:hidden;height:0;width:0;"
|
85
|
+
value={getProgress(current_file_upload)}
|
86
|
+
max="100">{getProgress(current_file_upload)}</progress
|
87
|
+
>
|
88
|
+
</div>
|
89
|
+
</span>
|
90
|
+
<span class="file-name">
|
91
|
+
{current_file_upload.orig_name}
|
92
|
+
</span>
|
93
|
+
</div>
|
94
|
+
{/if}
|
95
|
+
</div>
|
96
|
+
|
97
|
+
<style>
|
98
|
+
.wrap {
|
99
|
+
overflow-y: auto;
|
100
|
+
transition: opacity 0.5s ease-in-out;
|
101
|
+
background: var(--block-background-fill);
|
102
|
+
position: relative;
|
103
|
+
display: flex;
|
104
|
+
flex-direction: column;
|
105
|
+
align-items: center;
|
106
|
+
justify-content: center;
|
107
|
+
min-height: var(--size-40);
|
108
|
+
}
|
109
|
+
|
110
|
+
.wrap::after {
|
111
|
+
content: "";
|
112
|
+
position: absolute;
|
113
|
+
top: 0;
|
114
|
+
left: 0;
|
115
|
+
width: var(--upload-progress-width);
|
116
|
+
height: 100%;
|
117
|
+
transition: all 0.5s ease-in-out;
|
118
|
+
z-index: 1;
|
119
|
+
}
|
120
|
+
|
121
|
+
.uploading {
|
122
|
+
font-size: var(--text-lg);
|
123
|
+
font-family: var(--font);
|
124
|
+
z-index: 2;
|
125
|
+
}
|
126
|
+
|
127
|
+
.file-name {
|
128
|
+
margin: var(--spacing-md);
|
129
|
+
font-size: var(--text-lg);
|
130
|
+
color: var(--body-text-color-subdued);
|
131
|
+
}
|
132
|
+
|
133
|
+
.file {
|
134
|
+
font-size: var(--text-md);
|
135
|
+
z-index: 2;
|
136
|
+
display: flex;
|
137
|
+
align-items: center;
|
138
|
+
}
|
139
|
+
|
140
|
+
.file progress {
|
141
|
+
display: inline;
|
142
|
+
height: var(--size-1);
|
143
|
+
width: 100%;
|
144
|
+
transition: all 0.5s ease-in-out;
|
145
|
+
color: var(--color-accent);
|
146
|
+
border: none;
|
147
|
+
}
|
148
|
+
|
149
|
+
.file progress[value]::-webkit-progress-value {
|
150
|
+
background-color: var(--color-accent);
|
151
|
+
border-radius: 20px;
|
152
|
+
}
|
153
|
+
|
154
|
+
.file progress[value]::-webkit-progress-bar {
|
155
|
+
background-color: var(--border-color-accent);
|
156
|
+
border-radius: 20px;
|
157
|
+
}
|
158
|
+
|
159
|
+
.progress-bar {
|
160
|
+
width: 14px;
|
161
|
+
height: 14px;
|
162
|
+
border-radius: 50%;
|
163
|
+
background: radial-gradient(
|
164
|
+
closest-side,
|
165
|
+
var(--block-background-fill) 64%,
|
166
|
+
transparent 53% 100%
|
167
|
+
),
|
168
|
+
conic-gradient(
|
169
|
+
var(--color-accent) var(--upload-progress-width),
|
170
|
+
var(--border-color-accent) 0
|
171
|
+
);
|
172
|
+
transition: all 0.5s ease-in-out;
|
173
|
+
}
|
174
|
+
</style>
|