@gradio/gallery 0.16.1 → 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/Index.svelte CHANGED
@@ -6,14 +6,16 @@
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
- let upload_promise = $state<Promise<any>>();
18
+ let upload_promise = $state<Promise<(FileData | null)[]>>();
17
19
 
18
20
  class GalleryGradio extends Gradio<GalleryEvents, GalleryProps> {
19
21
  async get_data() {
@@ -28,14 +30,13 @@
28
30
  }
29
31
 
30
32
  const props = $props();
31
- const gradio = new GalleryGradio<GalleryEvents, GalleryProps>(props);
33
+ const gradio = new GalleryGradio<GalleryEvents, GalleryProps>(props, {
34
+ selected_index: null,
35
+ file_types: ["image", "video"]
36
+ });
32
37
 
33
38
  let fullscreen = $state(false);
34
39
 
35
- let no_value = $derived(
36
- gradio.props.value === null ? true : gradio.props.value.length === 0
37
- );
38
-
39
40
  function handle_delete(
40
41
  event: CustomEvent<{ file: FileData; index: number }>
41
42
  ): void {
@@ -69,6 +70,82 @@
69
70
  : { image: x, caption: null }
70
71
  );
71
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
+ }
72
149
  </script>
73
150
 
74
151
  <Block
@@ -94,46 +171,113 @@
94
171
  gradio.dispatch("clear_status", gradio.shared.loading_status)}
95
172
  />
96
173
  {#if gradio.shared.interactive && no_value}
97
- <BaseFileUpload
98
- bind:upload_promise
99
- value={null}
100
- root={gradio.shared.root}
101
- label={gradio.shared.label}
102
- max_file_size={gradio.shared.max_file_size}
103
- file_count={"multiple"}
104
- file_types={gradio.props.file_types}
105
- i18n={gradio.i18n}
106
- upload={(...args) => gradio.shared.client.upload(...args)}
107
- stream_handler={(...args) => gradio.shared.client.stream(...args)}
108
- on:upload={async (e) => {
109
- const files = Array.isArray(e.detail) ? e.detail : [e.detail];
110
- gradio.props.value = await process_upload_files(files);
111
- gradio.dispatch("upload", gradio.props.value);
112
- gradio.dispatch("change", gradio.props.value);
113
- }}
114
- on:error={({ detail }) => {
115
- gradio.shared.loading_status = gradio.shared.loading_status || {};
116
- gradio.shared.loading_status.status = "error";
117
- gradio.dispatch("error", detail);
118
- }}
174
+ <div
175
+ class={!gradio.props.value ||
176
+ (active_source && active_source.includes("webcam"))
177
+ ? "hidden-upload-input"
178
+ : ""}
119
179
  >
120
- <UploadText i18n={gradio.i18n} type="gallery" />
121
- </BaseFileUpload>
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}
122
264
  {:else}
123
265
  <Gallery
124
- on:change={() => gradio.dispatch("change")}
125
- on:clear={() => gradio.dispatch("change")}
126
- on:select={(e) => gradio.dispatch("select", e.detail)}
127
- on:share={(e) => gradio.dispatch("share", e.detail)}
128
- on:error={(e) => gradio.dispatch("error", e.detail)}
129
- on:preview_open={() => gradio.dispatch("preview_open")}
130
- on:preview_close={() => gradio.dispatch("preview_close")}
131
- on:fullscreen={({ detail }) => {
266
+ onchange={() => gradio.dispatch("change")}
267
+ onclear={() => gradio.dispatch("change")}
268
+ onselect={(e) => gradio.dispatch("select", e)}
269
+ onshare={(e) => gradio.dispatch("share", e.detail)}
270
+ onerror={(e) => gradio.dispatch("error", e.detail)}
271
+ onpreview_open={() => {
272
+ gradio.dispatch("preview_open");
273
+ }}
274
+ onpreview_close={() => gradio.dispatch("preview_close")}
275
+ onfullscreen={({ detail }) => {
132
276
  fullscreen = detail;
133
277
  }}
134
- on:delete={handle_delete}
135
- on:upload={async (e) => {
136
- const files = Array.isArray(e.detail) ? e.detail : [e.detail];
278
+ ondelete={handle_delete}
279
+ onupload={async (e) => {
280
+ const files = Array.isArray(e) ? e : [e];
137
281
  const new_value = await process_upload_files(files);
138
282
  gradio.props.value = gradio.props.value
139
283
  ? [...gradio.props.value, ...new_value]
@@ -141,6 +285,8 @@
141
285
  gradio.dispatch("upload", new_value);
142
286
  gradio.dispatch("change", gradio.props.value);
143
287
  }}
288
+ {sources}
289
+ {onsource_change}
144
290
  label={gradio.shared.label}
145
291
  show_label={gradio.shared.show_label}
146
292
  columns={gradio.props.columns}
@@ -177,3 +323,9 @@
177
323
  />
178
324
  {/if}
179
325
  </Block>
326
+
327
+ <style>
328
+ .hidden-upload-input {
329
+ display: none;
330
+ }
331
+ </style>
package/dist/Index.svelte CHANGED
@@ -6,14 +6,16 @@
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
- let upload_promise = $state<Promise<any>>();
18
+ let upload_promise = $state<Promise<(FileData | null)[]>>();
17
19
 
18
20
  class GalleryGradio extends Gradio<GalleryEvents, GalleryProps> {
19
21
  async get_data() {
@@ -28,14 +30,13 @@
28
30
  }
29
31
 
30
32
  const props = $props();
31
- const gradio = new GalleryGradio<GalleryEvents, GalleryProps>(props);
33
+ const gradio = new GalleryGradio<GalleryEvents, GalleryProps>(props, {
34
+ selected_index: null,
35
+ file_types: ["image", "video"]
36
+ });
32
37
 
33
38
  let fullscreen = $state(false);
34
39
 
35
- let no_value = $derived(
36
- gradio.props.value === null ? true : gradio.props.value.length === 0
37
- );
38
-
39
40
  function handle_delete(
40
41
  event: CustomEvent<{ file: FileData; index: number }>
41
42
  ): void {
@@ -69,6 +70,82 @@
69
70
  : { image: x, caption: null }
70
71
  );
71
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
+ }
72
149
  </script>
73
150
 
74
151
  <Block
@@ -94,46 +171,113 @@
94
171
  gradio.dispatch("clear_status", gradio.shared.loading_status)}
95
172
  />
96
173
  {#if gradio.shared.interactive && no_value}
97
- <BaseFileUpload
98
- bind:upload_promise
99
- value={null}
100
- root={gradio.shared.root}
101
- label={gradio.shared.label}
102
- max_file_size={gradio.shared.max_file_size}
103
- file_count={"multiple"}
104
- file_types={gradio.props.file_types}
105
- i18n={gradio.i18n}
106
- upload={(...args) => gradio.shared.client.upload(...args)}
107
- stream_handler={(...args) => gradio.shared.client.stream(...args)}
108
- on:upload={async (e) => {
109
- const files = Array.isArray(e.detail) ? e.detail : [e.detail];
110
- gradio.props.value = await process_upload_files(files);
111
- gradio.dispatch("upload", gradio.props.value);
112
- gradio.dispatch("change", gradio.props.value);
113
- }}
114
- on:error={({ detail }) => {
115
- gradio.shared.loading_status = gradio.shared.loading_status || {};
116
- gradio.shared.loading_status.status = "error";
117
- gradio.dispatch("error", detail);
118
- }}
174
+ <div
175
+ class={!gradio.props.value ||
176
+ (active_source && active_source.includes("webcam"))
177
+ ? "hidden-upload-input"
178
+ : ""}
119
179
  >
120
- <UploadText i18n={gradio.i18n} type="gallery" />
121
- </BaseFileUpload>
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}
122
264
  {:else}
123
265
  <Gallery
124
- on:change={() => gradio.dispatch("change")}
125
- on:clear={() => gradio.dispatch("change")}
126
- on:select={(e) => gradio.dispatch("select", e.detail)}
127
- on:share={(e) => gradio.dispatch("share", e.detail)}
128
- on:error={(e) => gradio.dispatch("error", e.detail)}
129
- on:preview_open={() => gradio.dispatch("preview_open")}
130
- on:preview_close={() => gradio.dispatch("preview_close")}
131
- on:fullscreen={({ detail }) => {
266
+ onchange={() => gradio.dispatch("change")}
267
+ onclear={() => gradio.dispatch("change")}
268
+ onselect={(e) => gradio.dispatch("select", e)}
269
+ onshare={(e) => gradio.dispatch("share", e.detail)}
270
+ onerror={(e) => gradio.dispatch("error", e.detail)}
271
+ onpreview_open={() => {
272
+ gradio.dispatch("preview_open");
273
+ }}
274
+ onpreview_close={() => gradio.dispatch("preview_close")}
275
+ onfullscreen={({ detail }) => {
132
276
  fullscreen = detail;
133
277
  }}
134
- on:delete={handle_delete}
135
- on:upload={async (e) => {
136
- const files = Array.isArray(e.detail) ? e.detail : [e.detail];
278
+ ondelete={handle_delete}
279
+ onupload={async (e) => {
280
+ const files = Array.isArray(e) ? e : [e];
137
281
  const new_value = await process_upload_files(files);
138
282
  gradio.props.value = gradio.props.value
139
283
  ? [...gradio.props.value, ...new_value]
@@ -141,6 +285,8 @@
141
285
  gradio.dispatch("upload", new_value);
142
286
  gradio.dispatch("change", gradio.props.value);
143
287
  }}
288
+ {sources}
289
+ {onsource_change}
144
290
  label={gradio.shared.label}
145
291
  show_label={gradio.shared.show_label}
146
292
  columns={gradio.props.columns}
@@ -177,3 +323,9 @@
177
323
  />
178
324
  {/if}
179
325
  </Block>
326
+
327
+ <style>
328
+ .hidden-upload-input {
329
+ display: none;
330
+ }
331
+ </style>
@@ -1,5 +1,24 @@
1
1
  export { default as BaseGallery } from "./shared/Gallery.svelte";
2
2
  export { default as BaseExample } from "./Example.svelte";
3
- declare const Index: import("svelte").Component<$$ComponentProps, {}, "">;
4
- type Index = ReturnType<typeof Index>;
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;