@gradio/image 0.25.3 → 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 +30 -0
- package/dist/shared/ImagePreview.svelte +7 -1
- package/dist/shared/ImagePreview.svelte.d.ts +1 -1
- package/dist/shared/stream_utils.d.ts +2 -2
- package/dist/shared/stream_utils.js +2 -2
- package/package.json +7 -7
- package/shared/ImagePreview.svelte +7 -1
- package/shared/stream_utils.test.ts +44 -97
- package/shared/stream_utils.ts +4 -4
- package/Image.test.ts +0 -68
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
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
|
+
|
|
18
|
+
## 0.25.4
|
|
19
|
+
|
|
20
|
+
### Dependency updates
|
|
21
|
+
|
|
22
|
+
- @gradio/statustracker@0.12.5
|
|
23
|
+
- @gradio/utils@0.12.0
|
|
24
|
+
- @gradio/atoms@0.22.2
|
|
25
|
+
- @gradio/upload@0.17.7
|
|
26
|
+
|
|
27
|
+
## 0.25.3
|
|
28
|
+
|
|
29
|
+
### Dependency updates
|
|
30
|
+
|
|
31
|
+
- @gradio/client@2.1.0
|
|
32
|
+
|
|
3
33
|
## 0.25.3
|
|
4
34
|
|
|
5
35
|
### 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
|
|
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.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Gradio UI packages",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "",
|
|
@@ -10,15 +10,15 @@
|
|
|
10
10
|
"cropperjs": "^2.0.1",
|
|
11
11
|
"lazy-brush": "^2.0.2",
|
|
12
12
|
"resize-observer-polyfill": "^1.5.1",
|
|
13
|
-
"@gradio/
|
|
14
|
-
"@gradio/
|
|
13
|
+
"@gradio/client": "^2.1.0",
|
|
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/
|
|
17
|
-
"@gradio/statustracker": "^0.12.4",
|
|
18
|
-
"@gradio/utils": "^0.11.3"
|
|
18
|
+
"@gradio/utils": "^0.12.1"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"@gradio/preview": "^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
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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: "
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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).
|
|
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
|
|
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(
|
|
63
|
+
await set_local_stream(new MediaStream(), mock_video_source);
|
|
93
64
|
|
|
94
|
-
expect(mock_video_source.srcObject).
|
|
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
|
{
|
package/shared/stream_utils.ts
CHANGED
|
@@ -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
|
|
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
|
-
});
|