@gradio/image 0.25.4 → 0.26.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,20 @@
1
1
  # @gradio/image
2
2
 
3
+ ## 0.26.0
4
+
5
+ ### Features
6
+
7
+ - [#12998](https://github.com/gradio-app/gradio/pull/12998) [`d5e1b8f`](https://github.com/gradio-app/gradio/commit/d5e1b8f6cb7473b70fc8c082589996d5e0402810) - use a real browser environment for unit tests. Thanks @pngwn!
8
+
9
+ ### Fixes
10
+
11
+ - [#13004](https://github.com/gradio-app/gradio/pull/13004) [`73d4065`](https://github.com/gradio-app/gradio/commit/73d4065db6a75961693fad60dd26e8dbaa2a56d1) - fix(image): pass onclick to FullscreenButton in ImagePreview. Thanks @galleon!
12
+
13
+ ### Dependency updates
14
+
15
+ - @gradio/utils@0.12.1
16
+ - @gradio/statustracker@0.13.0
17
+
3
18
  ## 0.25.4
4
19
 
5
20
  ### Dependency updates
@@ -62,7 +62,13 @@
62
62
  {on_custom_button_click}
63
63
  >
64
64
  {#if buttons.some((btn) => typeof btn === "string" && btn === "fullscreen")}
65
- <FullscreenButton {fullscreen} on:fullscreen />
65
+ <FullscreenButton
66
+ {fullscreen}
67
+ onclick={(is_fullscreen) => {
68
+ fullscreen = is_fullscreen;
69
+ dispatch("fullscreen", is_fullscreen);
70
+ }}
71
+ />
66
72
  {/if}
67
73
  {#if buttons.some((btn) => typeof btn === "string" && btn === "download")}
68
74
  <DownloadLink href={value.url} download={value.orig_name || "image"}>
@@ -27,12 +27,12 @@ declare const ImagePreview: $$__sveltets_2_IsomorphicComponent<{
27
27
  fullscreen?: boolean;
28
28
  show_button_background?: boolean;
29
29
  }, {
30
- fullscreen: CustomEvent<any>;
31
30
  share: CustomEvent<import("@gradio/utils").ShareData>;
32
31
  error: CustomEvent<string>;
33
32
  load: Event;
34
33
  change: CustomEvent<string>;
35
34
  select: CustomEvent<SelectData>;
35
+ fullscreen: CustomEvent<boolean>;
36
36
  } & {
37
37
  [evt: string]: CustomEvent<any>;
38
38
  }, {}, {}, string>;
@@ -1,7 +1,7 @@
1
1
  export declare function get_devices(): Promise<MediaDeviceInfo[]>;
2
2
  export declare function handle_error(error: string): void;
3
- export declare function set_local_stream(local_stream: MediaStream | null, video_source: HTMLVideoElement): void;
4
- export declare function get_video_stream(include_audio: boolean, video_source: HTMLVideoElement, webcam_constraints: {
3
+ export declare function set_local_stream(local_stream: MediaStream | null, video_source: HTMLVideoElement): Promise<void>;
4
+ export declare function get_video_stream(include_audio: boolean, video_source: HTMLVideoElement, webcam_constraints?: {
5
5
  [key: string]: any;
6
6
  } | null, device_id?: string): Promise<MediaStream>;
7
7
  export declare function set_available_devices(devices: MediaDeviceInfo[]): MediaDeviceInfo[];
@@ -4,10 +4,10 @@ export function get_devices() {
4
4
  export function handle_error(error) {
5
5
  throw new Error(error);
6
6
  }
7
- export function set_local_stream(local_stream, video_source) {
7
+ export async function set_local_stream(local_stream, video_source) {
8
8
  video_source.srcObject = local_stream;
9
9
  video_source.muted = true;
10
- video_source.play();
10
+ await video_source.play();
11
11
  }
12
12
  export async function get_video_stream(include_audio, video_source, webcam_constraints, device_id) {
13
13
  const constraints = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/image",
3
- "version": "0.25.4",
3
+ "version": "0.26.0",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
6
  "author": "",
@@ -12,13 +12,13 @@
12
12
  "resize-observer-polyfill": "^1.5.1",
13
13
  "@gradio/client": "^2.1.0",
14
14
  "@gradio/atoms": "^0.22.2",
15
+ "@gradio/statustracker": "^0.13.0",
16
+ "@gradio/upload": "^0.17.7",
15
17
  "@gradio/icons": "^0.15.1",
16
- "@gradio/statustracker": "^0.12.5",
17
- "@gradio/utils": "^0.12.0",
18
- "@gradio/upload": "^0.17.7"
18
+ "@gradio/utils": "^0.12.1"
19
19
  },
20
20
  "devDependencies": {
21
- "@gradio/preview": "^0.16.0"
21
+ "@gradio/preview": "^0.16.1"
22
22
  },
23
23
  "main_changeset": true,
24
24
  "main": "./Index.svelte",
@@ -62,7 +62,13 @@
62
62
  {on_custom_button_click}
63
63
  >
64
64
  {#if buttons.some((btn) => typeof btn === "string" && btn === "fullscreen")}
65
- <FullscreenButton {fullscreen} on:fullscreen />
65
+ <FullscreenButton
66
+ {fullscreen}
67
+ onclick={(is_fullscreen) => {
68
+ fullscreen = is_fullscreen;
69
+ dispatch("fullscreen", is_fullscreen);
70
+ }}
71
+ />
66
72
  {/if}
67
73
  {#if buttons.some((btn) => typeof btn === "string" && btn === "download")}
68
74
  <DownloadLink href={value.url} download={value.orig_name || "image"}>
@@ -5,121 +5,68 @@ import {
5
5
  set_available_devices,
6
6
  set_local_stream
7
7
  } from "./stream_utils";
8
-
9
- let test_device: MediaDeviceInfo = {
10
- deviceId: "test-device",
11
- kind: "videoinput",
12
- label: "Test Device",
13
- groupId: "camera",
14
- toJSON: () => ({
15
- deviceId: "test-device",
8
+ import * as stream_utils from "./stream_utils";
9
+
10
+ let test_devices: MediaDeviceInfo[] = [
11
+ {
12
+ deviceId: "",
13
+ groupId: "",
14
+ kind: "audioinput",
15
+ label: "",
16
+ toJSON: () => ({
17
+ deviceId: "",
18
+ groupId: "",
19
+ kind: "audioinput",
20
+ label: ""
21
+ })
22
+ },
23
+ {
24
+ deviceId: "",
25
+ groupId: "",
16
26
  kind: "videoinput",
17
- label: "Test Device",
18
- groupId: "camera"
19
- })
20
- };
21
-
22
- const mock_enumerateDevices = vi.fn(async () => {
23
- return new Promise<MediaDeviceInfo[]>((resolve) => {
24
- resolve([test_device]);
25
- });
26
- });
27
- const mock_getUserMedia = vi.fn(async () => {
28
- return new Promise<MediaStream>((resolve) => {
29
- resolve(new MediaStream());
30
- });
31
- });
32
-
33
- class MockMediaStream extends EventTarget {
34
- id: string;
35
- active: boolean;
36
-
37
- constructor() {
38
- super();
39
- this.id = "mock-stream-id";
40
- this.active = true;
41
- }
42
-
43
- getTracks(): MediaStreamTrack[] {
44
- return [];
45
- }
46
-
47
- getAudioTracks(): MediaStreamTrack[] {
48
- return [];
49
- }
50
-
51
- getVideoTracks(): MediaStreamTrack[] {
52
- return [];
53
- }
54
-
55
- addTrack(): void {}
56
- removeTrack(): void {}
57
- getTrackById(): MediaStreamTrack | null {
58
- return null;
59
- }
60
-
61
- clone(): MediaStream {
62
- return this as unknown as MediaStream;
27
+ label: "",
28
+ toJSON: () => ({
29
+ deviceId: "",
30
+ groupId: "",
31
+ kind: "videoinput",
32
+ label: ""
33
+ })
34
+ },
35
+ {
36
+ deviceId: "",
37
+ groupId: "",
38
+ kind: "audiooutput",
39
+ label: "",
40
+ toJSON: () => ({
41
+ deviceId: "",
42
+ groupId: "",
43
+ kind: "audiooutput",
44
+ label: ""
45
+ })
63
46
  }
64
- }
65
-
66
- // @ts-ignore - Override global MediaStream for testing
67
- window.MediaStream = MockMediaStream as any;
68
-
69
- Object.defineProperty(global.navigator, "mediaDevices", {
70
- value: {
71
- getUserMedia: mock_getUserMedia,
72
- enumerateDevices: mock_enumerateDevices
73
- }
74
- });
47
+ ];
75
48
 
76
49
  describe("stream_utils", () => {
77
50
  test("get_devices should enumerate media devices", async () => {
78
51
  const devices = await get_devices();
79
- expect(devices).toEqual([test_device]);
52
+ expect(Array.isArray(devices)).toBe(true);
80
53
  });
81
54
 
82
- test("set_local_stream should set the local stream to the video source", () => {
83
- const mock_stream = new MockMediaStream() as unknown as MediaStream;
84
-
55
+ test("set_local_stream should set the local stream to the video source", async () => {
85
56
  const mock_video_source = {
86
- srcObject: null as MediaStream | null,
57
+ srcObject: null,
87
58
  muted: false,
88
- play: vi.fn()
59
+ play: vi.fn().mockResolvedValue(undefined)
89
60
  };
90
61
 
91
62
  // @ts-ignore
92
- set_local_stream(mock_stream, mock_video_source);
63
+ await set_local_stream(new MediaStream(), mock_video_source);
93
64
 
94
- expect(mock_video_source.srcObject).toEqual(mock_stream);
65
+ expect(mock_video_source.srcObject).toBeInstanceOf(MediaStream);
95
66
  expect(mock_video_source.muted).toBeTruthy();
96
67
  expect(mock_video_source.play).toHaveBeenCalled();
97
68
  });
98
69
 
99
- test("get_video_stream requests user media with the correct constraints and sets the local stream", async () => {
100
- const mock_video_source = {
101
- srcObject: null as MediaStream | null,
102
- muted: false,
103
- play: vi.fn().mockResolvedValue(undefined)
104
- } as unknown as HTMLVideoElement;
105
- const mock_stream = new MockMediaStream() as unknown as MediaStream;
106
-
107
- global.navigator.mediaDevices.getUserMedia = vi
108
- .fn()
109
- .mockResolvedValue(mock_stream);
110
-
111
- await get_video_stream(true, mock_video_source, null);
112
-
113
- expect(navigator.mediaDevices.getUserMedia).toHaveBeenCalledWith({
114
- video: { width: { ideal: 1920 }, height: { ideal: 1440 } },
115
- audio: true
116
- });
117
-
118
- expect(mock_video_source.srcObject).toBe(mock_stream);
119
- expect(mock_video_source.muted).toBe(true);
120
- expect(mock_video_source.play).toHaveBeenCalled();
121
- });
122
-
123
70
  test("set_available_devices should return only video input devices", () => {
124
71
  const mockDevices: MediaDeviceInfo[] = [
125
72
  {
@@ -6,19 +6,19 @@ export function handle_error(error: string): void {
6
6
  throw new Error(error);
7
7
  }
8
8
 
9
- export function set_local_stream(
9
+ export async function set_local_stream(
10
10
  local_stream: MediaStream | null,
11
11
  video_source: HTMLVideoElement
12
- ): void {
12
+ ): Promise<void> {
13
13
  video_source.srcObject = local_stream;
14
14
  video_source.muted = true;
15
- video_source.play();
15
+ await video_source.play();
16
16
  }
17
17
 
18
18
  export async function get_video_stream(
19
19
  include_audio: boolean,
20
20
  video_source: HTMLVideoElement,
21
- webcam_constraints: { [key: string]: any } | null,
21
+ webcam_constraints?: { [key: string]: any } | null,
22
22
  device_id?: string
23
23
  ): Promise<MediaStream> {
24
24
  const constraints: MediaStreamConstraints = {
package/Image.test.ts DELETED
@@ -1,68 +0,0 @@
1
- import {
2
- test,
3
- describe,
4
- assert,
5
- afterEach,
6
- vi,
7
- beforeAll,
8
- beforeEach
9
- } from "vitest";
10
- import { cleanup, render } from "@self/tootils";
11
- import { setupi18n } from "../core/src/i18n";
12
-
13
- import Image from "./Index.svelte";
14
- import type { LoadingStatus } from "@gradio/statustracker";
15
-
16
- const loading_status = {
17
- eta: 0,
18
- queue_position: 1,
19
- queue_size: 1,
20
- status: "complete" as LoadingStatus["status"],
21
- scroll_to_output: false,
22
- visible: true,
23
- fn_index: 0,
24
- show_progress: "full" as LoadingStatus["show_progress"]
25
- };
26
-
27
- describe("Image", () => {
28
- beforeAll(() => {
29
- window.HTMLMediaElement.prototype.play = vi.fn();
30
- window.HTMLMediaElement.prototype.pause = vi.fn();
31
- });
32
- beforeEach(async () => {
33
- await setupi18n();
34
- });
35
- afterEach(() => cleanup());
36
-
37
- test.skip("image change event trigger fires when value is changed and only fires once", async () => {
38
- const { component, listen } = await render(Image, {
39
- show_label: true,
40
- loading_status,
41
- value: {
42
- url: "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png",
43
- orig_name: "bus.png",
44
- path: "https://raw.githubusercontent.com/gradio-app/gradio/main/test/test_files/bus.png"
45
- },
46
- streaming: false,
47
- pending: false,
48
- label: "Test Label",
49
- width: 224,
50
- height: 224,
51
- mirror_webcam: false,
52
- // brush_color: "#000000",
53
- // brush_radius: 5,
54
- // mask_opacity: 0.5,
55
- interactive: true,
56
- buttons: ["download", "share", "fullscreen"]
57
- });
58
-
59
- const mock = listen("change");
60
-
61
- component.value = {
62
- url: "https://github.com/gradio-app/gradio/blob/main/gradio/media_assets/images/cheetah1.jpg",
63
- orig_name: "cheetah1.jpg",
64
- path: "https://github.com/gradio-app/gradio/blob/main/gradio/media_assets/images/cheetah1.jpg"
65
- };
66
- assert.equal(mock.callCount, 1);
67
- });
68
- });