@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 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.2",
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.0",
10
+ "@gradio/atoms": "^0.2.1",
11
11
  "@gradio/icons": "^0.2.0",
12
- "@gradio/client": "^0.7.1",
13
- "@gradio/upload": "^0.3.2",
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
- const _file_data = await upload(file_data, root, upload_fn);
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
- let file_data = await prepare_files(_files);
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
- <button
93
- class:hidden
94
- class:center
95
- class:boundedheight
96
- class:flex
97
- on:drag|preventDefault|stopPropagation
98
- on:dragstart|preventDefault|stopPropagation
99
- on:dragend|preventDefault|stopPropagation
100
- on:dragover|preventDefault|stopPropagation
101
- on:dragenter|preventDefault|stopPropagation
102
- on:dragleave|preventDefault|stopPropagation
103
- on:drop|preventDefault|stopPropagation
104
- on:click={open_file_upload}
105
- on:drop={loadFilesFromDrop}
106
- on:dragenter={updateDragging}
107
- on:dragleave={updateDragging}
108
- >
109
- <slot />
110
- <input
111
- type="file"
112
- bind:this={hidden_upload}
113
- on:change={load_files_from_upload}
114
- accept={filetype}
115
- multiple={file_count === "multiple" || undefined}
116
- webkitdirectory={file_count === "directory" || undefined}
117
- mozdirectory={file_count === "directory" || undefined}
118
- />
119
- </button>
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>