diff --git a/client/js/src/types.ts b/client/js/src/types.ts
index 84baddf2bafe1..3df3bc752971a 100644
--- a/client/js/src/types.ts
+++ b/client/js/src/types.ts
@@ -186,6 +186,7 @@ export interface Config {
api_prefix?: string;
fill_height?: boolean;
fill_width?: boolean;
+ pwa?: boolean;
}
// todo: DRY up types
diff --git a/gradio/blocks.py b/gradio/blocks.py
index b4f227822d894..12afb5a759a93 100644
--- a/gradio/blocks.py
+++ b/gradio/blocks.py
@@ -1083,6 +1083,7 @@ def __init__(
self.renderables: list[Renderable] = []
self.state_holder: StateHolder
self.custom_mount_path: str | None = None
+ self.pwa = False
# For analytics_enabled and allow_flagging: (1) first check for
# parameter, (2) check for env variable, (3) default to True/"manual"
@@ -2171,6 +2172,7 @@ def get_config_file(self) -> BlocksConfigDict:
"fill_height": self.fill_height,
"fill_width": self.fill_width,
"theme_hash": self.theme_hash,
+ "pwa": self.pwa,
}
config.update(self.default_config.get_config()) # type: ignore
config["connect_heartbeat"] = utils.connect_heartbeat(
@@ -2450,9 +2452,10 @@ def reverse(text):
if block.key is None:
block.key = f"__{block._id}__"
- self.config = self.get_config_file()
+ self.pwa = utils.get_space() is not None if pwa is None else pwa
self.max_threads = max_threads
self._queue.max_thread_count = max_threads
+ self.config = self.get_config_file()
self.ssr_mode = (
False
@@ -2532,7 +2535,6 @@ def reverse(text):
"http" if share_server_address is not None else "https"
)
self.has_launched = True
- self.pwa = utils.get_space() is not None if pwa is None else pwa
self.protocol = (
"https"
diff --git a/gradio/data_classes.py b/gradio/data_classes.py
index 15c3f3b264753..a04ea90c0df2d 100644
--- a/gradio/data_classes.py
+++ b/gradio/data_classes.py
@@ -383,6 +383,7 @@ class BlocksConfigDict(TypedDict):
root: NotRequired[str | None]
username: NotRequired[str | None]
api_prefix: str
+ pwa: NotRequired[bool]
class MediaStreamChunk(TypedDict):
diff --git a/js/core/src/Blocks.svelte b/js/core/src/Blocks.svelte
index 7009dc9abf8eb..d0143b490b8ea 100644
--- a/js/core/src/Blocks.svelte
+++ b/js/core/src/Blocks.svelte
@@ -844,7 +844,7 @@
{/if}
-{#if settings_visible && $_layout}
+{#if settings_visible && $_layout && app.config}
@@ -860,6 +860,7 @@
on:close={(event) => {
set_settings_visible(false);
}}
+ pwa_enabled={app.config.pwa}
{root}
{space_id}
/>
diff --git a/js/core/src/api_docs/Settings.svelte b/js/core/src/api_docs/Settings.svelte
index 3f37c1d447f64..40df0261cc598 100644
--- a/js/core/src/api_docs/Settings.svelte
+++ b/js/core/src/api_docs/Settings.svelte
@@ -4,9 +4,11 @@
import SettingsBanner from "./SettingsBanner.svelte";
export let root: string;
export let space_id: string | null;
+ export let pwa_enabled: boolean | undefined;
import { BaseDropdown as Dropdown } from "@gradio/dropdown";
import { language_choices, changeLocale } from "../i18n";
- import { locale } from "svelte-i18n";
+ import { locale, _ } from "svelte-i18n";
+ import { setupi18n } from "../i18n";
if (root === "") {
root = location.protocol + "//" + location.host + location.pathname;
@@ -19,8 +21,10 @@
const url = new URL(window.location.href);
if (theme === "system") {
url.searchParams.delete("__theme");
+ current_theme = "system";
} else {
url.searchParams.set("__theme", theme);
+ current_theme = theme;
}
window.location.href = url.toString();
}
@@ -30,12 +34,16 @@
if ("parentIFrame" in window) {
window.parentIFrame?.scrollTo(0, 0);
}
+ const url = new URL(window.location.href);
+ const theme = url.searchParams.get("__theme");
+ current_theme = theme as "light" | "dark" | "system" || "system";
return () => {
document.body.style.overflow = "auto";
};
});
let current_locale: string;
+ let current_theme: "light" | "dark" | "system" = "system";
locale.subscribe((value) => {
if (value) {
@@ -47,6 +55,7 @@
const new_locale = e.detail;
changeLocale(new_locale);
}
+ setupi18n();
@@ -55,22 +64,31 @@
{#if space_id === null}
-
Display Theme
+
{$_("common.display_theme")}
-
- setTheme("light")}>☀︎ Light
+ setTheme("light")}
+ >
+ ☀︎ Light
-
- setTheme("dark")}>⏾ Dark
+ setTheme("dark")}
+ >
+ ⏾ Dark
-
- setTheme("system")}>🖥︎ System
+ setTheme("system")}
+ >
+ 🖥︎ System
{/if}
-
Language
+
{$_("common.language")}
Gradio automatically detects the language of your browser. You can also choose a language manually:
@@ -83,13 +101,17 @@
on:change={handleLanguageChange}
/>
-
-
Progressive Web App
-
+
+
{$_("common.pwa")}
+
+ {#if pwa_enabled}
You can install this app as a Progressive Web App on your device. Visit {root} and click the install button in the URL bar of your browser.
+ > and click the install button in the URL address bar of your browser.
+ {:else}
+ Progressive Web App is not enabled for this app. To enable it, start your Gradio app with launch(pwa=True)
.
+ {/if}
@@ -128,11 +150,30 @@
border: 1px solid var(--border-color-primary);
border-radius: var(--radius-md);
padding: var(--size-2) var(--size-2-5);
- color: var(--body-text-color-subdued);
- color: var(--body-text-color);
line-height: 1;
user-select: none;
text-transform: capitalize;
+ cursor: pointer;
+ }
+
+ .current-theme {
+ border: 1px solid var(--body-text-color-subdued);
+ color: var(--body-text-color);
+ }
+
+ .inactive-theme {
+ color: var(--body-text-color-subdued);
+ }
+
+ .inactive-theme:hover,
+ .inactive-theme:focus {
+ box-shadow: var(--shadow-drop);
+ color: var(--body-text-color);
+ }
+
+ .theme-button button {
+ all: unset;
+ cursor: pointer;
}
diff --git a/js/core/src/i18n.ts b/js/core/src/i18n.ts
index c072ac8fc5b4e..4896a4a210b5b 100644
--- a/js/core/src/i18n.ts
+++ b/js/core/src/i18n.ts
@@ -25,7 +25,7 @@ export function process_langs(): LangsRecord {
const processed_langs = process_langs();
const available_locales = Object.keys(processed_langs);
-export const language_choices = Object.entries(processed_langs).map(([code, data]) => [
+export const language_choices: [string, string][] = Object.entries(processed_langs).map(([code, data]) => [
data._name || code,
code
]);
diff --git a/js/core/src/lang/en.json b/js/core/src/lang/en.json
index 8f3d0f8c1fb3e..65fb919c2cde1 100644
--- a/js/core/src/lang/en.json
+++ b/js/core/src/lang/en.json
@@ -53,7 +53,10 @@
"share": "Share",
"submit": "Submit",
"undo": "Undo",
- "no_devices": "No devices found"
+ "no_devices": "No devices found",
+ "language": "Language",
+ "display_theme": "Display Theme",
+ "pwa": "Progressive Web App"
},
"dataframe": {
"incorrect_format": "Incorrect format, only CSV and TSV files are supported",