Make <Gallery /> Wasm-compatible (#6967)

* Use @gradio/image/shared/Image.svelte in the Gallery component for Wasm support

* Make the download button on the Gallery component Wasm-compatible

* add changeset

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
Yuichiro Tachibana (Tsuchiya) 2024-01-09 11:34:46 +09:00 committed by GitHub
parent 793bf8f7b1
commit 5e0016267f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 31 additions and 13 deletions

View File

@ -0,0 +1,8 @@
---
"@gradio/app": patch
"@gradio/gallery": patch
"@gradio/image": patch
"gradio": patch
---
fix:Make <Gallery /> Wasm-compatible

View File

@ -97,6 +97,8 @@
loading_text = (event as CustomEvent).detail + "...";
});
}
export let fetch_implementation: typeof fetch = fetch;
setContext("fetch_implementation", fetch_implementation);
export let space: string | null;
export let host: string | null;

View File

@ -160,7 +160,8 @@ export function create(options: Options): GradioAppController {
worker_proxy,
client,
upload_files,
mount_css: overridden_mount_css
mount_css: overridden_mount_css,
fetch_implementation: overridden_fetch
}
});
}

View File

@ -14,6 +14,7 @@
"@gradio/statustracker": "workspace:^",
"@gradio/upload": "workspace:^",
"@gradio/utils": "workspace:^",
"@gradio/wasm": "workspace:^",
"dequal": "^2.0.2"
},
"main": "./Index.svelte",

View File

@ -2,11 +2,12 @@
import { BlockLabel, Empty, ShareButton } from "@gradio/atoms";
import { ModifyUpload } from "@gradio/upload";
import type { SelectData } from "@gradio/utils";
import { Image } from "@gradio/image/shared";
import { dequal } from "dequal";
import { createEventDispatcher } from "svelte";
import { createEventDispatcher, getContext } from "svelte";
import { tick } from "svelte";
import { Download, Image } from "@gradio/icons";
import { Download, Image as ImageIcon } from "@gradio/icons";
import { normalise_file, type FileData } from "@gradio/client";
import { format_gallery_for_sharing } from "./utils";
import { IconButton } from "@gradio/atoms";
@ -166,10 +167,11 @@
// and their remote URLs are directly passed to the client as `value[].image.url`.
// The `download` attribute of the <a> tag doesn't work for remote URLs (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download),
// so we need to download the image via JS as below.
const fetch_implementation = getContext<typeof fetch>("fetch_implementation");
async function download(file_url: string, name: string): Promise<void> {
let response;
try {
response = await fetch(file_url);
response = await fetch_implementation(file_url);
} catch (error) {
if (error instanceof TypeError) {
// If CORS is not allowed (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#checking_that_the_fetch_was_successful),
@ -199,10 +201,10 @@
<svelte:window bind:innerHeight={window_height} />
{#if show_label}
<BlockLabel {show_label} Icon={Image} label={label || "Gallery"} />
<BlockLabel {show_label} Icon={ImageIcon} label={label || "Gallery"} />
{/if}
{#if value == null || resolved_value == null || resolved_value.length === 0}
<Empty unpadded_box={true} size="large"><Image /></Empty>
<Empty unpadded_box={true} size="large"><ImageIcon /></Empty>
{:else}
{#if selected_image && allow_preview}
<button on:keydown={on_keydown} class="preview">
@ -238,12 +240,12 @@
style="height: calc(100% - {selected_image.caption ? '80px' : '60px'})"
aria-label="detailed view of selected image"
>
<img
<Image
data-testid="detailed-image"
src={selected_image.image.url}
alt={selected_image.caption || ""}
title={selected_image.caption || null}
class:with-caption={!!selected_image.caption}
class={selected_image.caption && "with-caption"}
loading="lazy"
/>
</button>
@ -265,7 +267,7 @@
class:selected={selected_index === i}
aria-label={"Thumbnail " + (i + 1) + " of " + resolved_value.length}
>
<img
<Image
src={image.image.url}
title={image.caption || null}
data-testid={"thumbnail " + (i + 1)}
@ -306,7 +308,7 @@
on:click={() => (selected_index = i)}
aria-label={"Thumbnail " + (i + 1) + " of " + resolved_value.length}
>
<img
<Image
alt={entry.caption || ""}
src={typeof entry.image === "string"
? entry.image
@ -355,13 +357,13 @@
width: 100%;
display: flex;
}
.preview img {
.preview :global(img) {
width: var(--size-full);
height: var(--size-full);
object-fit: contain;
}
.preview img.with-caption {
.preview :global(img.with-caption) {
height: var(--size-full);
}
@ -449,7 +451,7 @@
gap: var(--spacing-lg);
}
.thumbnail-lg > img {
.thumbnail-lg > :global(img) {
width: var(--size-full);
height: var(--size-full);
overflow: hidden;

View File

@ -22,6 +22,7 @@
"main": "./Index.svelte",
"exports": {
".": "./Index.svelte",
"./shared": "./shared/index.ts",
"./example": "./Example.svelte",
"./shared": "./shared/index.ts",
"./package.json": "./package.json"

View File

@ -944,6 +944,9 @@ importers:
'@gradio/utils':
specifier: workspace:^
version: link:../utils
'@gradio/wasm':
specifier: workspace:^
version: link:../wasm
dequal:
specifier: ^2.0.2
version: 2.0.2