@gradio/gallery 0.16.2 → 0.17.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 +16 -0
- package/Index.svelte +178 -30
- package/dist/Index.svelte +178 -30
- package/dist/Index.svelte.d.ts +21 -2
- package/dist/shared/Gallery.svelte +39 -10
- package/dist/shared/Gallery.svelte.d.ts +3 -1
- package/dist/shared/utils.d.ts +2 -1
- package/dist/shared/utils.js +16 -0
- package/dist/types.d.ts +2 -0
- package/package.json +8 -8
- package/shared/Gallery.svelte +39 -10
- package/shared/utils.ts +21 -1
- package/types.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @gradio/gallery
|
|
2
2
|
|
|
3
|
+
## 0.17.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- [#12804](https://github.com/gradio-app/gradio/pull/12804) [`fc366b4`](https://github.com/gradio-app/gradio/commit/fc366b485325c900b0c2b85ba05b7d23a81a0dee) - Allow webcam uploads and clipboard paste for gallery. Thanks @freddyaboulton!
|
|
8
|
+
|
|
9
|
+
### Dependency updates
|
|
10
|
+
|
|
11
|
+
- @gradio/atoms@0.21.0
|
|
12
|
+
- @gradio/client@2.0.4
|
|
13
|
+
- @gradio/statustracker@0.12.3
|
|
14
|
+
- @gradio/file@0.14.2
|
|
15
|
+
- @gradio/image@0.25.2
|
|
16
|
+
- @gradio/upload@0.17.5
|
|
17
|
+
- @gradio/video@0.20.2
|
|
18
|
+
|
|
3
19
|
## 0.16.2
|
|
4
20
|
|
|
5
21
|
### Fixes
|
package/Index.svelte
CHANGED
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
<script lang="ts">
|
|
7
7
|
import { tick } from "svelte";
|
|
8
8
|
import type { FileData } from "@gradio/client";
|
|
9
|
-
import { Block, UploadText } from "@gradio/atoms";
|
|
9
|
+
import { Block, UploadText, SelectSource } from "@gradio/atoms";
|
|
10
10
|
import Gallery from "./shared/Gallery.svelte";
|
|
11
11
|
import { StatusTracker } from "@gradio/statustracker";
|
|
12
12
|
import { Gradio } from "@gradio/utils";
|
|
13
13
|
import { BaseFileUpload } from "@gradio/file";
|
|
14
|
+
import { Webcam } from "@gradio/image";
|
|
14
15
|
import type { GalleryProps, GalleryEvents, GalleryData } from "./types";
|
|
16
|
+
import { handle_save } from "./shared/utils";
|
|
15
17
|
|
|
16
18
|
let upload_promise = $state<Promise<(FileData | null)[]>>();
|
|
17
19
|
|
|
@@ -29,15 +31,12 @@
|
|
|
29
31
|
|
|
30
32
|
const props = $props();
|
|
31
33
|
const gradio = new GalleryGradio<GalleryEvents, GalleryProps>(props, {
|
|
32
|
-
selected_index: null
|
|
34
|
+
selected_index: null,
|
|
35
|
+
file_types: ["image", "video"]
|
|
33
36
|
});
|
|
34
37
|
|
|
35
38
|
let fullscreen = $state(false);
|
|
36
39
|
|
|
37
|
-
let no_value = $derived(
|
|
38
|
-
gradio.props.value === null ? true : gradio.props.value.length === 0
|
|
39
|
-
);
|
|
40
|
-
|
|
41
40
|
function handle_delete(
|
|
42
41
|
event: CustomEvent<{ file: FileData; index: number }>
|
|
43
42
|
): void {
|
|
@@ -71,6 +70,82 @@
|
|
|
71
70
|
: { image: x, caption: null }
|
|
72
71
|
);
|
|
73
72
|
}
|
|
73
|
+
|
|
74
|
+
let upload_input: BaseFileUpload;
|
|
75
|
+
|
|
76
|
+
let active_source = $state<
|
|
77
|
+
"upload" | "webcam" | "webcam-video" | "clipboard" | null
|
|
78
|
+
>(gradio.props.sources ? gradio.props.sources[0] : "upload");
|
|
79
|
+
|
|
80
|
+
let no_value = $derived(
|
|
81
|
+
gradio.props.value === null ? true : gradio.props.value.length === 0
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
let sources = $derived.by(() => {
|
|
85
|
+
if (
|
|
86
|
+
gradio.props.file_types?.includes("video") &&
|
|
87
|
+
gradio.props.sources.includes("webcam")
|
|
88
|
+
) {
|
|
89
|
+
return gradio.props.sources.concat(["webcam-video"]);
|
|
90
|
+
} else {
|
|
91
|
+
return gradio.props.sources;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
async function paste_clipboard(): Promise<void> {
|
|
96
|
+
navigator.clipboard.read().then(async (items) => {
|
|
97
|
+
let file: File | null = null;
|
|
98
|
+
for (let i = 0; i < items.length; i++) {
|
|
99
|
+
const type = items[i].types.find((t) =>
|
|
100
|
+
(gradio.props.file_types || ["image"]).some((ft) =>
|
|
101
|
+
t.startsWith(ft + "/")
|
|
102
|
+
)
|
|
103
|
+
);
|
|
104
|
+
if (type) {
|
|
105
|
+
const blob = await items[i].getType(type);
|
|
106
|
+
file = new File([blob], `clipboard.${type.replace("image/", "")}`);
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (file) {
|
|
111
|
+
const f = await handle_save(
|
|
112
|
+
file,
|
|
113
|
+
(f) => gradio.shared.client.upload(f, gradio.shared.root),
|
|
114
|
+
"clipboard_upload"
|
|
115
|
+
);
|
|
116
|
+
const processed_files = await process_upload_files(f);
|
|
117
|
+
gradio.props.value?.push(...processed_files);
|
|
118
|
+
gradio.dispatch("change", gradio.props.value);
|
|
119
|
+
active_source = null;
|
|
120
|
+
} else {
|
|
121
|
+
gradio.dispatch("warning", "No image or video found in clipboard");
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function handle_select_source(
|
|
127
|
+
source: "upload" | "webcam" | "clipboard"
|
|
128
|
+
): Promise<void> {
|
|
129
|
+
switch (source) {
|
|
130
|
+
case "clipboard":
|
|
131
|
+
await paste_clipboard();
|
|
132
|
+
break;
|
|
133
|
+
default:
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function onsource_change(
|
|
139
|
+
source: "upload" | "webcam" | "webcam-video" | "clipboard"
|
|
140
|
+
): Promise<void> {
|
|
141
|
+
await tick();
|
|
142
|
+
if (source === "clipboard") {
|
|
143
|
+
await paste_clipboard();
|
|
144
|
+
} else {
|
|
145
|
+
active_source = source;
|
|
146
|
+
no_value = true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
74
149
|
</script>
|
|
75
150
|
|
|
76
151
|
<Block
|
|
@@ -96,31 +171,96 @@
|
|
|
96
171
|
gradio.dispatch("clear_status", gradio.shared.loading_status)}
|
|
97
172
|
/>
|
|
98
173
|
{#if gradio.shared.interactive && no_value}
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
max_file_size={gradio.shared.max_file_size}
|
|
105
|
-
file_count={"multiple"}
|
|
106
|
-
file_types={gradio.props.file_types}
|
|
107
|
-
i18n={gradio.i18n}
|
|
108
|
-
upload={(...args) => gradio.shared.client.upload(...args)}
|
|
109
|
-
stream_handler={(...args) => gradio.shared.client.stream(...args)}
|
|
110
|
-
onupload={async (event_data) => {
|
|
111
|
-
const files = Array.isArray(event_data) ? event_data : [event_data];
|
|
112
|
-
gradio.props.value = await process_upload_files(files);
|
|
113
|
-
gradio.dispatch("upload", gradio.props.value);
|
|
114
|
-
gradio.dispatch("change", gradio.props.value);
|
|
115
|
-
}}
|
|
116
|
-
onerror={(event_data) => {
|
|
117
|
-
gradio.shared.loading_status = gradio.shared.loading_status || {};
|
|
118
|
-
gradio.shared.loading_status.status = "error";
|
|
119
|
-
gradio.dispatch("error", event_data);
|
|
120
|
-
}}
|
|
174
|
+
<div
|
|
175
|
+
class={!gradio.props.value ||
|
|
176
|
+
(active_source && active_source.includes("webcam"))
|
|
177
|
+
? "hidden-upload-input"
|
|
178
|
+
: ""}
|
|
121
179
|
>
|
|
122
|
-
<
|
|
123
|
-
|
|
180
|
+
<BaseFileUpload
|
|
181
|
+
bind:upload_promise
|
|
182
|
+
bind:this={upload_input}
|
|
183
|
+
value={null}
|
|
184
|
+
root={gradio.shared.root}
|
|
185
|
+
label={gradio.shared.label}
|
|
186
|
+
max_file_size={gradio.shared.max_file_size}
|
|
187
|
+
file_count={"multiple"}
|
|
188
|
+
file_types={gradio.props.file_types}
|
|
189
|
+
i18n={gradio.i18n}
|
|
190
|
+
upload={(...args) => gradio.shared.client.upload(...args)}
|
|
191
|
+
stream_handler={(...args) => gradio.shared.client.stream(...args)}
|
|
192
|
+
onupload={async (e) => {
|
|
193
|
+
const files = Array.isArray(e) ? e : [e];
|
|
194
|
+
gradio.props.value = await process_upload_files(files);
|
|
195
|
+
active_source = null;
|
|
196
|
+
gradio.dispatch("upload", gradio.props.value);
|
|
197
|
+
gradio.dispatch("change", gradio.props.value);
|
|
198
|
+
}}
|
|
199
|
+
onerror={({ detail }) => {
|
|
200
|
+
gradio.shared.loading_status = gradio.shared.loading_status || {};
|
|
201
|
+
gradio.shared.loading_status.status = "error";
|
|
202
|
+
gradio.dispatch("error", detail);
|
|
203
|
+
}}
|
|
204
|
+
>
|
|
205
|
+
<UploadText i18n={gradio.i18n} type="gallery" />
|
|
206
|
+
</BaseFileUpload>
|
|
207
|
+
</div>
|
|
208
|
+
{#if active_source === "webcam"}
|
|
209
|
+
<Webcam
|
|
210
|
+
root={gradio.shared.root}
|
|
211
|
+
value={null}
|
|
212
|
+
on:capture={async (e) => {
|
|
213
|
+
const f = await handle_save(
|
|
214
|
+
e.detail,
|
|
215
|
+
(f) => gradio.shared.client.upload(f, gradio.shared.root),
|
|
216
|
+
"webcam_upload"
|
|
217
|
+
);
|
|
218
|
+
const processed_files = await process_upload_files(f);
|
|
219
|
+
gradio.props.value?.push(...processed_files);
|
|
220
|
+
active_source = null;
|
|
221
|
+
gradio.dispatch("change", gradio.props.value);
|
|
222
|
+
}}
|
|
223
|
+
on:error
|
|
224
|
+
on:drag
|
|
225
|
+
on:close_stream
|
|
226
|
+
mirror_webcam={true}
|
|
227
|
+
streaming={false}
|
|
228
|
+
mode="image"
|
|
229
|
+
include_audio={false}
|
|
230
|
+
i18n={gradio.i18n}
|
|
231
|
+
upload={(...args) => gradio.shared.client.upload(...args)}
|
|
232
|
+
/>
|
|
233
|
+
{:else if active_source === "webcam-video"}
|
|
234
|
+
<Webcam
|
|
235
|
+
root={gradio.shared.root}
|
|
236
|
+
value={null}
|
|
237
|
+
on:capture={async (e) => {
|
|
238
|
+
const f = { ...e.detail };
|
|
239
|
+
f.mime_type = "video/webm";
|
|
240
|
+
const processed_files = await process_upload_files([f]);
|
|
241
|
+
gradio.props.value?.push(...processed_files);
|
|
242
|
+
active_source = null;
|
|
243
|
+
gradio.dispatch("change", gradio.props.value);
|
|
244
|
+
}}
|
|
245
|
+
on:error
|
|
246
|
+
on:drag
|
|
247
|
+
on:close_stream
|
|
248
|
+
mirror_webcam={true}
|
|
249
|
+
streaming={false}
|
|
250
|
+
mode="video"
|
|
251
|
+
include_audio={false}
|
|
252
|
+
i18n={gradio.i18n}
|
|
253
|
+
upload={(...args) => gradio.shared.client.upload(...args)}
|
|
254
|
+
/>
|
|
255
|
+
{/if}
|
|
256
|
+
{#if sources.length > 1 || sources.includes("clipboard")}
|
|
257
|
+
<SelectSource
|
|
258
|
+
{sources}
|
|
259
|
+
bind:active_source
|
|
260
|
+
handle_clear={() => gradio.dispatch("clear")}
|
|
261
|
+
handle_select={handle_select_source}
|
|
262
|
+
/>
|
|
263
|
+
{/if}
|
|
124
264
|
{:else}
|
|
125
265
|
<Gallery
|
|
126
266
|
onchange={() => gradio.dispatch("change")}
|
|
@@ -145,6 +285,8 @@
|
|
|
145
285
|
gradio.dispatch("upload", new_value);
|
|
146
286
|
gradio.dispatch("change", gradio.props.value);
|
|
147
287
|
}}
|
|
288
|
+
{sources}
|
|
289
|
+
{onsource_change}
|
|
148
290
|
label={gradio.shared.label}
|
|
149
291
|
show_label={gradio.shared.show_label}
|
|
150
292
|
columns={gradio.props.columns}
|
|
@@ -181,3 +323,9 @@
|
|
|
181
323
|
/>
|
|
182
324
|
{/if}
|
|
183
325
|
</Block>
|
|
326
|
+
|
|
327
|
+
<style>
|
|
328
|
+
.hidden-upload-input {
|
|
329
|
+
display: none;
|
|
330
|
+
}
|
|
331
|
+
</style>
|
package/dist/Index.svelte
CHANGED
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
<script lang="ts">
|
|
7
7
|
import { tick } from "svelte";
|
|
8
8
|
import type { FileData } from "@gradio/client";
|
|
9
|
-
import { Block, UploadText } from "@gradio/atoms";
|
|
9
|
+
import { Block, UploadText, SelectSource } from "@gradio/atoms";
|
|
10
10
|
import Gallery from "./shared/Gallery.svelte";
|
|
11
11
|
import { StatusTracker } from "@gradio/statustracker";
|
|
12
12
|
import { Gradio } from "@gradio/utils";
|
|
13
13
|
import { BaseFileUpload } from "@gradio/file";
|
|
14
|
+
import { Webcam } from "@gradio/image";
|
|
14
15
|
import type { GalleryProps, GalleryEvents, GalleryData } from "./types";
|
|
16
|
+
import { handle_save } from "./shared/utils";
|
|
15
17
|
|
|
16
18
|
let upload_promise = $state<Promise<(FileData | null)[]>>();
|
|
17
19
|
|
|
@@ -29,15 +31,12 @@
|
|
|
29
31
|
|
|
30
32
|
const props = $props();
|
|
31
33
|
const gradio = new GalleryGradio<GalleryEvents, GalleryProps>(props, {
|
|
32
|
-
selected_index: null
|
|
34
|
+
selected_index: null,
|
|
35
|
+
file_types: ["image", "video"]
|
|
33
36
|
});
|
|
34
37
|
|
|
35
38
|
let fullscreen = $state(false);
|
|
36
39
|
|
|
37
|
-
let no_value = $derived(
|
|
38
|
-
gradio.props.value === null ? true : gradio.props.value.length === 0
|
|
39
|
-
);
|
|
40
|
-
|
|
41
40
|
function handle_delete(
|
|
42
41
|
event: CustomEvent<{ file: FileData; index: number }>
|
|
43
42
|
): void {
|
|
@@ -71,6 +70,82 @@
|
|
|
71
70
|
: { image: x, caption: null }
|
|
72
71
|
);
|
|
73
72
|
}
|
|
73
|
+
|
|
74
|
+
let upload_input: BaseFileUpload;
|
|
75
|
+
|
|
76
|
+
let active_source = $state<
|
|
77
|
+
"upload" | "webcam" | "webcam-video" | "clipboard" | null
|
|
78
|
+
>(gradio.props.sources ? gradio.props.sources[0] : "upload");
|
|
79
|
+
|
|
80
|
+
let no_value = $derived(
|
|
81
|
+
gradio.props.value === null ? true : gradio.props.value.length === 0
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
let sources = $derived.by(() => {
|
|
85
|
+
if (
|
|
86
|
+
gradio.props.file_types?.includes("video") &&
|
|
87
|
+
gradio.props.sources.includes("webcam")
|
|
88
|
+
) {
|
|
89
|
+
return gradio.props.sources.concat(["webcam-video"]);
|
|
90
|
+
} else {
|
|
91
|
+
return gradio.props.sources;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
async function paste_clipboard(): Promise<void> {
|
|
96
|
+
navigator.clipboard.read().then(async (items) => {
|
|
97
|
+
let file: File | null = null;
|
|
98
|
+
for (let i = 0; i < items.length; i++) {
|
|
99
|
+
const type = items[i].types.find((t) =>
|
|
100
|
+
(gradio.props.file_types || ["image"]).some((ft) =>
|
|
101
|
+
t.startsWith(ft + "/")
|
|
102
|
+
)
|
|
103
|
+
);
|
|
104
|
+
if (type) {
|
|
105
|
+
const blob = await items[i].getType(type);
|
|
106
|
+
file = new File([blob], `clipboard.${type.replace("image/", "")}`);
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (file) {
|
|
111
|
+
const f = await handle_save(
|
|
112
|
+
file,
|
|
113
|
+
(f) => gradio.shared.client.upload(f, gradio.shared.root),
|
|
114
|
+
"clipboard_upload"
|
|
115
|
+
);
|
|
116
|
+
const processed_files = await process_upload_files(f);
|
|
117
|
+
gradio.props.value?.push(...processed_files);
|
|
118
|
+
gradio.dispatch("change", gradio.props.value);
|
|
119
|
+
active_source = null;
|
|
120
|
+
} else {
|
|
121
|
+
gradio.dispatch("warning", "No image or video found in clipboard");
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function handle_select_source(
|
|
127
|
+
source: "upload" | "webcam" | "clipboard"
|
|
128
|
+
): Promise<void> {
|
|
129
|
+
switch (source) {
|
|
130
|
+
case "clipboard":
|
|
131
|
+
await paste_clipboard();
|
|
132
|
+
break;
|
|
133
|
+
default:
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function onsource_change(
|
|
139
|
+
source: "upload" | "webcam" | "webcam-video" | "clipboard"
|
|
140
|
+
): Promise<void> {
|
|
141
|
+
await tick();
|
|
142
|
+
if (source === "clipboard") {
|
|
143
|
+
await paste_clipboard();
|
|
144
|
+
} else {
|
|
145
|
+
active_source = source;
|
|
146
|
+
no_value = true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
74
149
|
</script>
|
|
75
150
|
|
|
76
151
|
<Block
|
|
@@ -96,31 +171,96 @@
|
|
|
96
171
|
gradio.dispatch("clear_status", gradio.shared.loading_status)}
|
|
97
172
|
/>
|
|
98
173
|
{#if gradio.shared.interactive && no_value}
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
max_file_size={gradio.shared.max_file_size}
|
|
105
|
-
file_count={"multiple"}
|
|
106
|
-
file_types={gradio.props.file_types}
|
|
107
|
-
i18n={gradio.i18n}
|
|
108
|
-
upload={(...args) => gradio.shared.client.upload(...args)}
|
|
109
|
-
stream_handler={(...args) => gradio.shared.client.stream(...args)}
|
|
110
|
-
onupload={async (event_data) => {
|
|
111
|
-
const files = Array.isArray(event_data) ? event_data : [event_data];
|
|
112
|
-
gradio.props.value = await process_upload_files(files);
|
|
113
|
-
gradio.dispatch("upload", gradio.props.value);
|
|
114
|
-
gradio.dispatch("change", gradio.props.value);
|
|
115
|
-
}}
|
|
116
|
-
onerror={(event_data) => {
|
|
117
|
-
gradio.shared.loading_status = gradio.shared.loading_status || {};
|
|
118
|
-
gradio.shared.loading_status.status = "error";
|
|
119
|
-
gradio.dispatch("error", event_data);
|
|
120
|
-
}}
|
|
174
|
+
<div
|
|
175
|
+
class={!gradio.props.value ||
|
|
176
|
+
(active_source && active_source.includes("webcam"))
|
|
177
|
+
? "hidden-upload-input"
|
|
178
|
+
: ""}
|
|
121
179
|
>
|
|
122
|
-
<
|
|
123
|
-
|
|
180
|
+
<BaseFileUpload
|
|
181
|
+
bind:upload_promise
|
|
182
|
+
bind:this={upload_input}
|
|
183
|
+
value={null}
|
|
184
|
+
root={gradio.shared.root}
|
|
185
|
+
label={gradio.shared.label}
|
|
186
|
+
max_file_size={gradio.shared.max_file_size}
|
|
187
|
+
file_count={"multiple"}
|
|
188
|
+
file_types={gradio.props.file_types}
|
|
189
|
+
i18n={gradio.i18n}
|
|
190
|
+
upload={(...args) => gradio.shared.client.upload(...args)}
|
|
191
|
+
stream_handler={(...args) => gradio.shared.client.stream(...args)}
|
|
192
|
+
onupload={async (e) => {
|
|
193
|
+
const files = Array.isArray(e) ? e : [e];
|
|
194
|
+
gradio.props.value = await process_upload_files(files);
|
|
195
|
+
active_source = null;
|
|
196
|
+
gradio.dispatch("upload", gradio.props.value);
|
|
197
|
+
gradio.dispatch("change", gradio.props.value);
|
|
198
|
+
}}
|
|
199
|
+
onerror={({ detail }) => {
|
|
200
|
+
gradio.shared.loading_status = gradio.shared.loading_status || {};
|
|
201
|
+
gradio.shared.loading_status.status = "error";
|
|
202
|
+
gradio.dispatch("error", detail);
|
|
203
|
+
}}
|
|
204
|
+
>
|
|
205
|
+
<UploadText i18n={gradio.i18n} type="gallery" />
|
|
206
|
+
</BaseFileUpload>
|
|
207
|
+
</div>
|
|
208
|
+
{#if active_source === "webcam"}
|
|
209
|
+
<Webcam
|
|
210
|
+
root={gradio.shared.root}
|
|
211
|
+
value={null}
|
|
212
|
+
on:capture={async (e) => {
|
|
213
|
+
const f = await handle_save(
|
|
214
|
+
e.detail,
|
|
215
|
+
(f) => gradio.shared.client.upload(f, gradio.shared.root),
|
|
216
|
+
"webcam_upload"
|
|
217
|
+
);
|
|
218
|
+
const processed_files = await process_upload_files(f);
|
|
219
|
+
gradio.props.value?.push(...processed_files);
|
|
220
|
+
active_source = null;
|
|
221
|
+
gradio.dispatch("change", gradio.props.value);
|
|
222
|
+
}}
|
|
223
|
+
on:error
|
|
224
|
+
on:drag
|
|
225
|
+
on:close_stream
|
|
226
|
+
mirror_webcam={true}
|
|
227
|
+
streaming={false}
|
|
228
|
+
mode="image"
|
|
229
|
+
include_audio={false}
|
|
230
|
+
i18n={gradio.i18n}
|
|
231
|
+
upload={(...args) => gradio.shared.client.upload(...args)}
|
|
232
|
+
/>
|
|
233
|
+
{:else if active_source === "webcam-video"}
|
|
234
|
+
<Webcam
|
|
235
|
+
root={gradio.shared.root}
|
|
236
|
+
value={null}
|
|
237
|
+
on:capture={async (e) => {
|
|
238
|
+
const f = { ...e.detail };
|
|
239
|
+
f.mime_type = "video/webm";
|
|
240
|
+
const processed_files = await process_upload_files([f]);
|
|
241
|
+
gradio.props.value?.push(...processed_files);
|
|
242
|
+
active_source = null;
|
|
243
|
+
gradio.dispatch("change", gradio.props.value);
|
|
244
|
+
}}
|
|
245
|
+
on:error
|
|
246
|
+
on:drag
|
|
247
|
+
on:close_stream
|
|
248
|
+
mirror_webcam={true}
|
|
249
|
+
streaming={false}
|
|
250
|
+
mode="video"
|
|
251
|
+
include_audio={false}
|
|
252
|
+
i18n={gradio.i18n}
|
|
253
|
+
upload={(...args) => gradio.shared.client.upload(...args)}
|
|
254
|
+
/>
|
|
255
|
+
{/if}
|
|
256
|
+
{#if sources.length > 1 || sources.includes("clipboard")}
|
|
257
|
+
<SelectSource
|
|
258
|
+
{sources}
|
|
259
|
+
bind:active_source
|
|
260
|
+
handle_clear={() => gradio.dispatch("clear")}
|
|
261
|
+
handle_select={handle_select_source}
|
|
262
|
+
/>
|
|
263
|
+
{/if}
|
|
124
264
|
{:else}
|
|
125
265
|
<Gallery
|
|
126
266
|
onchange={() => gradio.dispatch("change")}
|
|
@@ -145,6 +285,8 @@
|
|
|
145
285
|
gradio.dispatch("upload", new_value);
|
|
146
286
|
gradio.dispatch("change", gradio.props.value);
|
|
147
287
|
}}
|
|
288
|
+
{sources}
|
|
289
|
+
{onsource_change}
|
|
148
290
|
label={gradio.shared.label}
|
|
149
291
|
show_label={gradio.shared.show_label}
|
|
150
292
|
columns={gradio.props.columns}
|
|
@@ -181,3 +323,9 @@
|
|
|
181
323
|
/>
|
|
182
324
|
{/if}
|
|
183
325
|
</Block>
|
|
326
|
+
|
|
327
|
+
<style>
|
|
328
|
+
.hidden-upload-input {
|
|
329
|
+
display: none;
|
|
330
|
+
}
|
|
331
|
+
</style>
|
package/dist/Index.svelte.d.ts
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
export { default as BaseGallery } from "./shared/Gallery.svelte";
|
|
2
2
|
export { default as BaseExample } from "./Example.svelte";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
4
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
5
|
+
$$bindings?: Bindings;
|
|
6
|
+
} & Exports;
|
|
7
|
+
(internal: unknown, props: Props & {
|
|
8
|
+
$$events?: Events;
|
|
9
|
+
$$slots?: Slots;
|
|
10
|
+
}): Exports & {
|
|
11
|
+
$set?: any;
|
|
12
|
+
$on?: any;
|
|
13
|
+
};
|
|
14
|
+
z_$$bindings?: Bindings;
|
|
15
|
+
}
|
|
16
|
+
declare const Index: $$__sveltets_2_IsomorphicComponent<$$ComponentProps, {
|
|
17
|
+
error: CustomEvent<string>;
|
|
18
|
+
drag: CustomEvent<any>;
|
|
19
|
+
close_stream: CustomEvent<undefined>;
|
|
20
|
+
} & {
|
|
21
|
+
[evt: string]: CustomEvent<any>;
|
|
22
|
+
}, {}, {}, "">;
|
|
23
|
+
type Index = InstanceType<typeof Index>;
|
|
5
24
|
export default Index;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
IconButtonWrapper,
|
|
8
8
|
FullscreenButton
|
|
9
9
|
} from "@gradio/atoms";
|
|
10
|
-
import type
|
|
10
|
+
import { type CustomButton as CustomButtonType } from "@gradio/utils";
|
|
11
11
|
import { ModifyUpload, Upload as UploadComponent } from "@gradio/upload";
|
|
12
12
|
import { Image } from "@gradio/image/shared";
|
|
13
13
|
import { Video } from "@gradio/video/shared";
|
|
@@ -21,13 +21,15 @@
|
|
|
21
21
|
Image as ImageIcon,
|
|
22
22
|
Clear,
|
|
23
23
|
Play,
|
|
24
|
-
Upload as UploadIcon
|
|
24
|
+
Upload as UploadIcon,
|
|
25
|
+
Webcam,
|
|
26
|
+
Video as VideoIcon,
|
|
27
|
+
ImagePaste
|
|
25
28
|
} from "@gradio/icons";
|
|
26
29
|
import { FileData } from "@gradio/client";
|
|
27
30
|
import type { Client } from "@gradio/client";
|
|
28
31
|
import { format_gallery_for_sharing } from "./utils";
|
|
29
32
|
import type { I18nFormatter } from "@gradio/utils";
|
|
30
|
-
import { on } from "svelte/events";
|
|
31
33
|
|
|
32
34
|
type GalleryData = GalleryImage | GalleryVideo;
|
|
33
35
|
|
|
@@ -51,6 +53,7 @@
|
|
|
51
53
|
fullscreen = false,
|
|
52
54
|
root = "",
|
|
53
55
|
file_types = ["image", "video"],
|
|
56
|
+
sources,
|
|
54
57
|
max_file_size = null,
|
|
55
58
|
upload,
|
|
56
59
|
stream_handler,
|
|
@@ -66,7 +69,8 @@
|
|
|
66
69
|
onpreview_close = () => {},
|
|
67
70
|
onfullscreen = (data) => {},
|
|
68
71
|
ondelete = () => {},
|
|
69
|
-
onupload = () => {}
|
|
72
|
+
onupload = () => {},
|
|
73
|
+
onsource_change = () => {}
|
|
70
74
|
}: {
|
|
71
75
|
show_label: boolean;
|
|
72
76
|
label: string;
|
|
@@ -87,6 +91,7 @@
|
|
|
87
91
|
fullscreen: boolean;
|
|
88
92
|
root: string;
|
|
89
93
|
file_types: string[] | null;
|
|
94
|
+
sources: ("upload" | "webcam" | "clipboard" | "webcam-video")[];
|
|
90
95
|
max_file_size: number | null;
|
|
91
96
|
upload: Client["upload"] | undefined;
|
|
92
97
|
stream_handler: Client["stream"] | undefined;
|
|
@@ -103,6 +108,7 @@
|
|
|
103
108
|
onfullscreen: (data: any) => void;
|
|
104
109
|
ondelete: (data: any) => void;
|
|
105
110
|
onupload: (data: FileData | FileData[]) => void;
|
|
111
|
+
onsource_change: (source: string) => void;
|
|
106
112
|
} = $props();
|
|
107
113
|
|
|
108
114
|
let upload_promise: Promise<any> | null = null;
|
|
@@ -189,8 +195,6 @@
|
|
|
189
195
|
() => ((selected_index ?? 0) + 1) % (resolved_value?.length ?? 0)
|
|
190
196
|
);
|
|
191
197
|
|
|
192
|
-
$inspect("selected_index", selected_index);
|
|
193
|
-
|
|
194
198
|
function handle_preview_click(event: MouseEvent): void {
|
|
195
199
|
const element = event.target as HTMLElement;
|
|
196
200
|
const x = event.offsetX;
|
|
@@ -410,10 +414,7 @@
|
|
|
410
414
|
{/if}
|
|
411
415
|
|
|
412
416
|
{#if show_fullscreen_button}
|
|
413
|
-
<FullscreenButton
|
|
414
|
-
{fullscreen}
|
|
415
|
-
on:fullscreen={(e) => onfullscreen(e)}
|
|
416
|
-
/>
|
|
417
|
+
<FullscreenButton {fullscreen} onclick={(e) => onfullscreen(e)} />
|
|
417
418
|
{/if}
|
|
418
419
|
|
|
419
420
|
{#if show_share_button}
|
|
@@ -541,6 +542,7 @@
|
|
|
541
542
|
{i18n}
|
|
542
543
|
onclear={() => {
|
|
543
544
|
value = [];
|
|
545
|
+
onsource_change("upload");
|
|
544
546
|
onclear();
|
|
545
547
|
}}
|
|
546
548
|
>
|
|
@@ -564,6 +566,33 @@
|
|
|
564
566
|
/>
|
|
565
567
|
</IconButton>
|
|
566
568
|
{/if}
|
|
569
|
+
{#if sources.includes("webcam")}
|
|
570
|
+
<IconButton
|
|
571
|
+
Icon={Webcam}
|
|
572
|
+
label={i18n("common.webcam")}
|
|
573
|
+
onclick={() => {
|
|
574
|
+
onsource_change("webcam");
|
|
575
|
+
}}
|
|
576
|
+
/>
|
|
577
|
+
{/if}
|
|
578
|
+
{#if sources.includes("webcam-video")}
|
|
579
|
+
<IconButton
|
|
580
|
+
Icon={VideoIcon}
|
|
581
|
+
label={i18n("common.video")}
|
|
582
|
+
onclick={() => {
|
|
583
|
+
onsource_change("webcam-video");
|
|
584
|
+
}}
|
|
585
|
+
/>
|
|
586
|
+
{/if}
|
|
587
|
+
{#if sources.includes("clipboard")}
|
|
588
|
+
<IconButton
|
|
589
|
+
label={i18n("upload_text.paste_clipboard")}
|
|
590
|
+
onclick={() => {
|
|
591
|
+
onsource_change("clipboard");
|
|
592
|
+
}}
|
|
593
|
+
Icon={ImagePaste}
|
|
594
|
+
/>
|
|
595
|
+
{/if}
|
|
567
596
|
</ModifyUpload>
|
|
568
597
|
{/if}
|
|
569
598
|
<div
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type CustomButton as CustomButtonType } from "@gradio/utils";
|
|
2
2
|
import type { GalleryImage, GalleryVideo } from "../types";
|
|
3
3
|
import { FileData } from "@gradio/client";
|
|
4
4
|
import type { Client } from "@gradio/client";
|
|
@@ -24,6 +24,7 @@ type $$ComponentProps = {
|
|
|
24
24
|
fullscreen: boolean;
|
|
25
25
|
root: string;
|
|
26
26
|
file_types: string[] | null;
|
|
27
|
+
sources: ("upload" | "webcam" | "clipboard" | "webcam-video")[];
|
|
27
28
|
max_file_size: number | null;
|
|
28
29
|
upload: Client["upload"] | undefined;
|
|
29
30
|
stream_handler: Client["stream"] | undefined;
|
|
@@ -40,6 +41,7 @@ type $$ComponentProps = {
|
|
|
40
41
|
onfullscreen: (data: any) => void;
|
|
41
42
|
ondelete: (data: any) => void;
|
|
42
43
|
onupload: (data: FileData | FileData[]) => void;
|
|
44
|
+
onsource_change: (source: string) => void;
|
|
43
45
|
};
|
|
44
46
|
declare const Gallery: import("svelte").Component<$$ComponentProps, {}, "value" | "selected_index">;
|
|
45
47
|
type Gallery = ReturnType<typeof Gallery>;
|
package/dist/shared/utils.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FileData, Client } from "@gradio/client";
|
|
2
2
|
export declare function format_gallery_for_sharing(value: [FileData, string | null][] | null): Promise<string>;
|
|
3
|
+
export declare function handle_save(img_blob: Blob, upload: Client["upload"], filename?: string): Promise<FileData[]>;
|
package/dist/shared/utils.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { uploadToHuggingFace } from "@gradio/utils";
|
|
2
|
+
import { FileData, Client } from "@gradio/client";
|
|
2
3
|
export async function format_gallery_for_sharing(value) {
|
|
3
4
|
if (!value)
|
|
4
5
|
return "";
|
|
@@ -11,3 +12,18 @@ export async function format_gallery_for_sharing(value) {
|
|
|
11
12
|
.map((url) => `<img src="${url}" style="height: 400px" />`)
|
|
12
13
|
.join("")}</div>`;
|
|
13
14
|
}
|
|
15
|
+
export async function handle_save(img_blob, upload, filename = "uploaded_file") {
|
|
16
|
+
const ext = img_blob.type.split("/")[1] || "png";
|
|
17
|
+
const f_ = new File([img_blob], `${filename}.${ext}`);
|
|
18
|
+
const files = [
|
|
19
|
+
new FileData({
|
|
20
|
+
path: f_.name,
|
|
21
|
+
orig_name: f_.name,
|
|
22
|
+
blob: f_,
|
|
23
|
+
size: f_.size,
|
|
24
|
+
mime_type: f_.type,
|
|
25
|
+
is_stream: false
|
|
26
|
+
})
|
|
27
|
+
];
|
|
28
|
+
return (await upload(...files));
|
|
29
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export interface GalleryProps {
|
|
|
22
22
|
buttons: (string | CustomButton)[];
|
|
23
23
|
type: "numpy" | "pil" | "filepath";
|
|
24
24
|
fit_columns: boolean;
|
|
25
|
+
sources: ("upload" | "webcam-video" | "webcam" | "clipboard")[];
|
|
25
26
|
}
|
|
26
27
|
export interface GalleryEvents {
|
|
27
28
|
change: GalleryData[] | null;
|
|
@@ -39,4 +40,5 @@ export interface GalleryEvents {
|
|
|
39
40
|
custom_button_click: {
|
|
40
41
|
id: number;
|
|
41
42
|
};
|
|
43
|
+
warning: string;
|
|
42
44
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gradio/gallery",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
"private": false,
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"dequal": "^2.0.3",
|
|
11
|
-
"@gradio/atoms": "^0.
|
|
12
|
-
"@gradio/client": "^2.0.
|
|
11
|
+
"@gradio/atoms": "^0.21.0",
|
|
12
|
+
"@gradio/client": "^2.0.4",
|
|
13
|
+
"@gradio/file": "^0.14.2",
|
|
14
|
+
"@gradio/image": "^0.25.2",
|
|
15
|
+
"@gradio/statustracker": "^0.12.3",
|
|
13
16
|
"@gradio/icons": "^0.15.1",
|
|
14
|
-
"@gradio/file": "^0.14.1",
|
|
15
|
-
"@gradio/statustracker": "^0.12.2",
|
|
16
|
-
"@gradio/image": "^0.25.1",
|
|
17
|
-
"@gradio/upload": "^0.17.4",
|
|
18
17
|
"@gradio/utils": "^0.11.2",
|
|
19
|
-
"@gradio/video": "^0.20.
|
|
18
|
+
"@gradio/video": "^0.20.2",
|
|
19
|
+
"@gradio/upload": "^0.17.5"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@gradio/preview": "^0.15.2"
|
package/shared/Gallery.svelte
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
IconButtonWrapper,
|
|
8
8
|
FullscreenButton
|
|
9
9
|
} from "@gradio/atoms";
|
|
10
|
-
import type
|
|
10
|
+
import { type CustomButton as CustomButtonType } from "@gradio/utils";
|
|
11
11
|
import { ModifyUpload, Upload as UploadComponent } from "@gradio/upload";
|
|
12
12
|
import { Image } from "@gradio/image/shared";
|
|
13
13
|
import { Video } from "@gradio/video/shared";
|
|
@@ -21,13 +21,15 @@
|
|
|
21
21
|
Image as ImageIcon,
|
|
22
22
|
Clear,
|
|
23
23
|
Play,
|
|
24
|
-
Upload as UploadIcon
|
|
24
|
+
Upload as UploadIcon,
|
|
25
|
+
Webcam,
|
|
26
|
+
Video as VideoIcon,
|
|
27
|
+
ImagePaste
|
|
25
28
|
} from "@gradio/icons";
|
|
26
29
|
import { FileData } from "@gradio/client";
|
|
27
30
|
import type { Client } from "@gradio/client";
|
|
28
31
|
import { format_gallery_for_sharing } from "./utils";
|
|
29
32
|
import type { I18nFormatter } from "@gradio/utils";
|
|
30
|
-
import { on } from "svelte/events";
|
|
31
33
|
|
|
32
34
|
type GalleryData = GalleryImage | GalleryVideo;
|
|
33
35
|
|
|
@@ -51,6 +53,7 @@
|
|
|
51
53
|
fullscreen = false,
|
|
52
54
|
root = "",
|
|
53
55
|
file_types = ["image", "video"],
|
|
56
|
+
sources,
|
|
54
57
|
max_file_size = null,
|
|
55
58
|
upload,
|
|
56
59
|
stream_handler,
|
|
@@ -66,7 +69,8 @@
|
|
|
66
69
|
onpreview_close = () => {},
|
|
67
70
|
onfullscreen = (data) => {},
|
|
68
71
|
ondelete = () => {},
|
|
69
|
-
onupload = () => {}
|
|
72
|
+
onupload = () => {},
|
|
73
|
+
onsource_change = () => {}
|
|
70
74
|
}: {
|
|
71
75
|
show_label: boolean;
|
|
72
76
|
label: string;
|
|
@@ -87,6 +91,7 @@
|
|
|
87
91
|
fullscreen: boolean;
|
|
88
92
|
root: string;
|
|
89
93
|
file_types: string[] | null;
|
|
94
|
+
sources: ("upload" | "webcam" | "clipboard" | "webcam-video")[];
|
|
90
95
|
max_file_size: number | null;
|
|
91
96
|
upload: Client["upload"] | undefined;
|
|
92
97
|
stream_handler: Client["stream"] | undefined;
|
|
@@ -103,6 +108,7 @@
|
|
|
103
108
|
onfullscreen: (data: any) => void;
|
|
104
109
|
ondelete: (data: any) => void;
|
|
105
110
|
onupload: (data: FileData | FileData[]) => void;
|
|
111
|
+
onsource_change: (source: string) => void;
|
|
106
112
|
} = $props();
|
|
107
113
|
|
|
108
114
|
let upload_promise: Promise<any> | null = null;
|
|
@@ -189,8 +195,6 @@
|
|
|
189
195
|
() => ((selected_index ?? 0) + 1) % (resolved_value?.length ?? 0)
|
|
190
196
|
);
|
|
191
197
|
|
|
192
|
-
$inspect("selected_index", selected_index);
|
|
193
|
-
|
|
194
198
|
function handle_preview_click(event: MouseEvent): void {
|
|
195
199
|
const element = event.target as HTMLElement;
|
|
196
200
|
const x = event.offsetX;
|
|
@@ -410,10 +414,7 @@
|
|
|
410
414
|
{/if}
|
|
411
415
|
|
|
412
416
|
{#if show_fullscreen_button}
|
|
413
|
-
<FullscreenButton
|
|
414
|
-
{fullscreen}
|
|
415
|
-
on:fullscreen={(e) => onfullscreen(e)}
|
|
416
|
-
/>
|
|
417
|
+
<FullscreenButton {fullscreen} onclick={(e) => onfullscreen(e)} />
|
|
417
418
|
{/if}
|
|
418
419
|
|
|
419
420
|
{#if show_share_button}
|
|
@@ -541,6 +542,7 @@
|
|
|
541
542
|
{i18n}
|
|
542
543
|
onclear={() => {
|
|
543
544
|
value = [];
|
|
545
|
+
onsource_change("upload");
|
|
544
546
|
onclear();
|
|
545
547
|
}}
|
|
546
548
|
>
|
|
@@ -564,6 +566,33 @@
|
|
|
564
566
|
/>
|
|
565
567
|
</IconButton>
|
|
566
568
|
{/if}
|
|
569
|
+
{#if sources.includes("webcam")}
|
|
570
|
+
<IconButton
|
|
571
|
+
Icon={Webcam}
|
|
572
|
+
label={i18n("common.webcam")}
|
|
573
|
+
onclick={() => {
|
|
574
|
+
onsource_change("webcam");
|
|
575
|
+
}}
|
|
576
|
+
/>
|
|
577
|
+
{/if}
|
|
578
|
+
{#if sources.includes("webcam-video")}
|
|
579
|
+
<IconButton
|
|
580
|
+
Icon={VideoIcon}
|
|
581
|
+
label={i18n("common.video")}
|
|
582
|
+
onclick={() => {
|
|
583
|
+
onsource_change("webcam-video");
|
|
584
|
+
}}
|
|
585
|
+
/>
|
|
586
|
+
{/if}
|
|
587
|
+
{#if sources.includes("clipboard")}
|
|
588
|
+
<IconButton
|
|
589
|
+
label={i18n("upload_text.paste_clipboard")}
|
|
590
|
+
onclick={() => {
|
|
591
|
+
onsource_change("clipboard");
|
|
592
|
+
}}
|
|
593
|
+
Icon={ImagePaste}
|
|
594
|
+
/>
|
|
595
|
+
{/if}
|
|
567
596
|
</ModifyUpload>
|
|
568
597
|
{/if}
|
|
569
598
|
<div
|
package/shared/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { uploadToHuggingFace } from "@gradio/utils";
|
|
2
|
-
import
|
|
2
|
+
import { FileData, Client } from "@gradio/client";
|
|
3
3
|
|
|
4
4
|
export async function format_gallery_for_sharing(
|
|
5
5
|
value: [FileData, string | null][] | null
|
|
@@ -16,3 +16,23 @@ export async function format_gallery_for_sharing(
|
|
|
16
16
|
.map((url) => `<img src="${url}" style="height: 400px" />`)
|
|
17
17
|
.join("")}</div>`;
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
export async function handle_save(
|
|
21
|
+
img_blob: Blob,
|
|
22
|
+
upload: Client["upload"],
|
|
23
|
+
filename: string = "uploaded_file"
|
|
24
|
+
): Promise<FileData[]> {
|
|
25
|
+
const ext = img_blob.type.split("/")[1] || "png";
|
|
26
|
+
const f_ = new File([img_blob], `${filename}.${ext}`);
|
|
27
|
+
const files = [
|
|
28
|
+
new FileData({
|
|
29
|
+
path: f_.name,
|
|
30
|
+
orig_name: f_.name,
|
|
31
|
+
blob: f_,
|
|
32
|
+
size: f_.size,
|
|
33
|
+
mime_type: f_.type,
|
|
34
|
+
is_stream: false
|
|
35
|
+
})
|
|
36
|
+
];
|
|
37
|
+
return (await upload(...files)) as FileData[];
|
|
38
|
+
}
|
package/types.ts
CHANGED
|
@@ -26,6 +26,7 @@ export interface GalleryProps {
|
|
|
26
26
|
buttons: (string | CustomButton)[];
|
|
27
27
|
type: "numpy" | "pil" | "filepath";
|
|
28
28
|
fit_columns: boolean;
|
|
29
|
+
sources: ("upload" | "webcam-video" | "webcam" | "clipboard")[];
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
export interface GalleryEvents {
|
|
@@ -39,4 +40,5 @@ export interface GalleryEvents {
|
|
|
39
40
|
share: any;
|
|
40
41
|
error: any;
|
|
41
42
|
custom_button_click: { id: number };
|
|
43
|
+
warning: string;
|
|
42
44
|
}
|