@gradio/gallery 0.14.0 → 0.15.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,29 @@
1
1
  # @gradio/gallery
2
2
 
3
+ ## 0.15.0
4
+
5
+ ### Features
6
+
7
+ - [#10303](https://github.com/gradio-app/gradio/pull/10303) [`f19ca89`](https://github.com/gradio-app/gradio/commit/f19ca89cdd4040dbaa41bbc3b9915edc032603a0) - Add preview_open and preview_close events to Gallery. Thanks @freddyaboulton!
8
+
9
+ ## 0.14.1
10
+
11
+ ### Fixes
12
+
13
+ - [#10269](https://github.com/gradio-app/gradio/pull/10269) [`890eaa3`](https://github.com/gradio-app/gradio/commit/890eaa3a9e53dab5bcb16c5d017ae0470109b8fb) - Allow displaying SVG images securely in `gr.Image` and `gr.Gallery` components. Thanks @abidlabs!
14
+
15
+ ### Dependency updates
16
+
17
+ - @gradio/atoms@0.13.0
18
+ - @gradio/utils@0.10.0
19
+ - @gradio/upload@0.14.4
20
+ - @gradio/client@1.9.0
21
+ - @gradio/icons@0.9.0
22
+ - @gradio/statustracker@0.10.0
23
+ - @gradio/image@0.20.0
24
+ - @gradio/video@0.13.0
25
+ - @gradio/file@0.12.0
26
+
3
27
  ## 0.14.0
4
28
 
5
29
  ### Features
package/Index.svelte CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  <script lang="ts">
6
6
  import type { GalleryImage, GalleryVideo } from "./types";
7
+ import type { FileData } from "@gradio/client";
7
8
  import type { Gradio, ShareData, SelectData } from "@gradio/utils";
8
9
  import { Block, UploadText } from "@gradio/atoms";
9
10
  import Gallery from "./shared/Gallery.svelte";
@@ -45,6 +46,8 @@
45
46
  error: string;
46
47
  prop_change: Record<string, any>;
47
48
  clear_status: LoadingStatus;
49
+ preview_open: never;
50
+ preview_close: never;
48
51
  }>;
49
52
  export let show_fullscreen_button = true;
50
53
 
@@ -52,6 +55,30 @@
52
55
 
53
56
  $: no_value = value === null ? true : value.length === 0;
54
57
  $: selected_index, dispatch("prop_change", { selected_index });
58
+
59
+ async function process_upload_files(
60
+ files: FileData[]
61
+ ): Promise<GalleryData[]> {
62
+ const processed_files = await Promise.all(
63
+ files.map(async (x) => {
64
+ if (x.path?.toLowerCase().endsWith(".svg") && x.url) {
65
+ const response = await fetch(x.url);
66
+ const svgContent = await response.text();
67
+ return {
68
+ ...x,
69
+ url: `data:image/svg+xml,${encodeURIComponent(svgContent)}`
70
+ };
71
+ }
72
+ return x;
73
+ })
74
+ );
75
+
76
+ return processed_files.map((x) =>
77
+ x.mime_type?.includes("video")
78
+ ? { video: x, caption: null }
79
+ : { image: x, caption: null }
80
+ );
81
+ }
55
82
  </script>
56
83
 
57
84
  <Block
@@ -83,14 +110,11 @@
83
110
  i18n={gradio.i18n}
84
111
  upload={(...args) => gradio.client.upload(...args)}
85
112
  stream_handler={(...args) => gradio.client.stream(...args)}
86
- on:upload={(e) => {
113
+ on:upload={async (e) => {
87
114
  const files = Array.isArray(e.detail) ? e.detail : [e.detail];
88
- value = files.map((x) =>
89
- x.mime_type?.includes("video")
90
- ? { video: x, caption: null }
91
- : { image: x, caption: null }
92
- );
115
+ value = await process_upload_files(files);
93
116
  gradio.dispatch("upload", value);
117
+ gradio.dispatch("change", value);
94
118
  }}
95
119
  on:error={({ detail }) => {
96
120
  loading_status = loading_status || {};
@@ -106,6 +130,8 @@
106
130
  on:select={(e) => gradio.dispatch("select", e.detail)}
107
131
  on:share={(e) => gradio.dispatch("share", e.detail)}
108
132
  on:error={(e) => gradio.dispatch("error", e.detail)}
133
+ on:preview_open={() => gradio.dispatch("preview_open")}
134
+ on:preview_close={() => gradio.dispatch("preview_close")}
109
135
  {label}
110
136
  {show_label}
111
137
  {columns}
package/dist/Index.svelte CHANGED
@@ -35,6 +35,24 @@ $:
35
35
  no_value = value === null ? true : value.length === 0;
36
36
  $:
37
37
  selected_index, dispatch("prop_change", { selected_index });
38
+ async function process_upload_files(files) {
39
+ const processed_files = await Promise.all(
40
+ files.map(async (x) => {
41
+ if (x.path?.toLowerCase().endsWith(".svg") && x.url) {
42
+ const response = await fetch(x.url);
43
+ const svgContent = await response.text();
44
+ return {
45
+ ...x,
46
+ url: `data:image/svg+xml,${encodeURIComponent(svgContent)}`
47
+ };
48
+ }
49
+ return x;
50
+ })
51
+ );
52
+ return processed_files.map(
53
+ (x) => x.mime_type?.includes("video") ? { video: x, caption: null } : { image: x, caption: null }
54
+ );
55
+ }
38
56
  </script>
39
57
 
40
58
  <Block
@@ -66,14 +84,11 @@ $:
66
84
  i18n={gradio.i18n}
67
85
  upload={(...args) => gradio.client.upload(...args)}
68
86
  stream_handler={(...args) => gradio.client.stream(...args)}
69
- on:upload={(e) => {
87
+ on:upload={async (e) => {
70
88
  const files = Array.isArray(e.detail) ? e.detail : [e.detail];
71
- value = files.map((x) =>
72
- x.mime_type?.includes("video")
73
- ? { video: x, caption: null }
74
- : { image: x, caption: null }
75
- );
89
+ value = await process_upload_files(files);
76
90
  gradio.dispatch("upload", value);
91
+ gradio.dispatch("change", value);
77
92
  }}
78
93
  on:error={({ detail }) => {
79
94
  loading_status = loading_status || {};
@@ -89,6 +104,8 @@ $:
89
104
  on:select={(e) => gradio.dispatch("select", e.detail)}
90
105
  on:share={(e) => gradio.dispatch("share", e.detail)}
91
106
  on:error={(e) => gradio.dispatch("error", e.detail)}
107
+ on:preview_open={() => gradio.dispatch("preview_open")}
108
+ on:preview_close={() => gradio.dispatch("preview_close")}
92
109
  {label}
93
110
  {show_label}
94
111
  {columns}
@@ -35,6 +35,8 @@ declare const __propDef: {
35
35
  error: string;
36
36
  prop_change: Record<string, any>;
37
37
  clear_status: LoadingStatus;
38
+ preview_open: never;
39
+ preview_close: never;
38
40
  }>;
39
41
  show_fullscreen_button?: boolean | undefined;
40
42
  };
@@ -12,14 +12,7 @@ import { Video } from "@gradio/video/shared";
12
12
  import { dequal } from "dequal";
13
13
  import { createEventDispatcher, onMount } from "svelte";
14
14
  import { tick } from "svelte";
15
- import {
16
- Download,
17
- Image as ImageIcon,
18
- Maximize,
19
- Minimize,
20
- Clear,
21
- Play
22
- } from "@gradio/icons";
15
+ import { Download, Image as ImageIcon, Clear, Play } from "@gradio/icons";
23
16
  import { FileData } from "@gradio/client";
24
17
  import { format_gallery_for_sharing } from "./utils";
25
18
  export let show_label = true;
@@ -229,7 +222,10 @@ onMount(() => {
229
222
  <IconButton
230
223
  Icon={Clear}
231
224
  label="Close"
232
- on:click={() => (selected_index = null)}
225
+ on:click={() => {
226
+ selected_index = null;
227
+ dispatch("preview_close");
228
+ }}
233
229
  />
234
230
  {/if}
235
231
  </IconButtonWrapper>
@@ -330,7 +326,12 @@ onMount(() => {
330
326
  <button
331
327
  class="thumbnail-item thumbnail-lg"
332
328
  class:selected={selected_index === i}
333
- on:click={() => (selected_index = i)}
329
+ on:click={() => {
330
+ if (selected_index === null && allow_preview) {
331
+ dispatch("preview_open");
332
+ }
333
+ selected_index = i;
334
+ }}
334
335
  aria-label={"Thumbnail " + (i + 1) + " of " + resolved_value.length}
335
336
  >
336
337
  {#if "image" in entry}
@@ -28,6 +28,8 @@ declare const __propDef: {
28
28
  error: CustomEvent<string>;
29
29
  change: CustomEvent<undefined>;
30
30
  select: CustomEvent<SelectData>;
31
+ preview_open: CustomEvent<undefined>;
32
+ preview_close: CustomEvent<undefined>;
31
33
  } & {
32
34
  [evt: string]: CustomEvent<any>;
33
35
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/gallery",
3
- "version": "0.14.0",
3
+ "version": "0.15.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.2",
11
- "@gradio/atoms": "^0.12.0",
12
- "@gradio/client": "^1.8.0",
13
- "@gradio/upload": "^0.14.3",
14
- "@gradio/image": "^0.19.0",
15
- "@gradio/icons": "^0.8.1",
16
- "@gradio/statustracker": "^0.9.7",
17
- "@gradio/utils": "^0.9.0",
18
- "@gradio/video": "^0.12.1",
19
- "@gradio/file": "^0.11.3"
11
+ "@gradio/atoms": "^0.13.0",
12
+ "@gradio/icons": "^0.9.0",
13
+ "@gradio/statustracker": "^0.10.0",
14
+ "@gradio/image": "^0.20.0",
15
+ "@gradio/upload": "^0.14.4",
16
+ "@gradio/utils": "^0.10.0",
17
+ "@gradio/video": "^0.13.0",
18
+ "@gradio/client": "^1.9.0",
19
+ "@gradio/file": "^0.12.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@gradio/preview": "^0.13.0"
@@ -16,14 +16,7 @@
16
16
  import { tick } from "svelte";
17
17
  import type { GalleryImage, GalleryVideo } from "../types";
18
18
 
19
- import {
20
- Download,
21
- Image as ImageIcon,
22
- Maximize,
23
- Minimize,
24
- Clear,
25
- Play
26
- } from "@gradio/icons";
19
+ import { Download, Image as ImageIcon, Clear, Play } from "@gradio/icons";
27
20
  import { FileData } from "@gradio/client";
28
21
  import { format_gallery_for_sharing } from "./utils";
29
22
  import type { I18nFormatter } from "@gradio/utils";
@@ -56,6 +49,8 @@
56
49
  const dispatch = createEventDispatcher<{
57
50
  change: undefined;
58
51
  select: SelectData;
52
+ preview_open: undefined;
53
+ preview_close: undefined;
59
54
  }>();
60
55
 
61
56
  // tracks whether the value of the gallery was reset
@@ -287,7 +282,10 @@
287
282
  <IconButton
288
283
  Icon={Clear}
289
284
  label="Close"
290
- on:click={() => (selected_index = null)}
285
+ on:click={() => {
286
+ selected_index = null;
287
+ dispatch("preview_close");
288
+ }}
291
289
  />
292
290
  {/if}
293
291
  </IconButtonWrapper>
@@ -388,7 +386,12 @@
388
386
  <button
389
387
  class="thumbnail-item thumbnail-lg"
390
388
  class:selected={selected_index === i}
391
- on:click={() => (selected_index = i)}
389
+ on:click={() => {
390
+ if (selected_index === null && allow_preview) {
391
+ dispatch("preview_open");
392
+ }
393
+ selected_index = i;
394
+ }}
392
395
  aria-label={"Thumbnail " + (i + 1) + " of " + resolved_value.length}
393
396
  >
394
397
  {#if "image" in entry}