Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

New API Docs page with in-browser playground and updated aesthetics. [@gary149](https://github.com/gary149) in [PR 2652](https://github.com/gradio-app/gradio/pull/2652)

### Revamped Login page

Previously our login page had its own CSS, had no dark mode, and had an ugly json message on the wrong credentials. Made the page more aesthetically consistent, added dark mode support, and a nicer error message. [@aliabid94](https://github.com/aliabid94) in [PR 2684](https://github.com/gradio-app/gradio/pull/2684)

### Accessing the Requests Object Directly

You can now access the Request object directly in your Python function by [@abidlabs](https://github.com/abidlabs) in [PR 2641](https://github.com/gradio-app/gradio/pull/2641). This means that you can access request headers, the client IP address, and so on. In order to use it, add a parameter to your function and set its type hint to be `gr.Request`. Here's a simple example:
Expand Down
50 changes: 1 addition & 49 deletions ui/packages/app/src/Blocks.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
export let autoscroll: boolean = false;
export let show_api: boolean = true;
export let control_page_title = false;
export let app_mode: boolean;

let app_mode = window.__gradio_mode__ === "app";
let loading_status = create_loading_status_store();

$: app_state.update((s) => ({ ...s, autoscroll }));
Expand Down Expand Up @@ -389,54 +389,6 @@
set_prop(instance_map[id], "pending", pending_status === "pending");
}
}

function handle_darkmode() {
let url = new URL(window.location.toString());

const color_mode: "light" | "dark" | "system" | null = url.searchParams.get(
"__theme"
) as "light" | "dark" | "system" | null;

if (color_mode !== null) {
if (color_mode === "dark") {
darkmode();
} else if (color_mode === "system") {
use_system_theme();
}
// light is default, so we don't need to do anything else
} else if (url.searchParams.get("__dark-theme") === "true") {
darkmode();
} else {
use_system_theme();
}
}

function use_system_theme() {
update_scheme();
window
?.matchMedia("(prefers-color-scheme: dark)")
?.addEventListener("change", update_scheme);

function update_scheme() {
const is_dark =
window?.matchMedia?.("(prefers-color-scheme: dark)").matches ?? null;

if (is_dark) {
darkmode();
}
}
}

function darkmode() {
target.classList.add("dark");
if (app_mode) {
document.body.style.backgroundColor = "rgb(11, 15, 25)"; // bg-gray-950 for scrolling outside the body
}
}

if (window.__gradio_mode__ !== "website") {
handle_darkmode();
}
</script>

<svelte:head>
Expand Down
77 changes: 60 additions & 17 deletions ui/packages/app/src/Login.svelte
Original file line number Diff line number Diff line change
@@ -1,29 +1,72 @@
<script lang="ts">
import { Component as Form } from "./components/Form";
import { Component as Textbox } from "./components/Textbox";
export let root: string;
export let id: number;
export let auth_message: string | null;
export let app_mode: boolean;

window.__gradio_loader__[id].$set({ status: "complete" });
let username = "";
let password = "";
let incorrect_credentials = false;

const submit = async () => {
const formData = new FormData();
formData.append("username", username);
formData.append("password", password);

let response = await fetch(root + "login", {
method: "POST",
body: formData
});
if (response.status === 400) {
incorrect_credentials = true;
username = "";
password = "";
} else {
location.reload();
}
};
</script>

<div class="login container mt-8">
<form
class="mx-auto p-4 bg-gray-50 shadow-md w-1/2"
id="login"
method="POST"
action={root + "login"}
>
<h2 class="text-2xl font-semibold my-2">login</h2>
<div
class="dark:bg-gray-950 w-full flex flex-col items-center justify-center"
class:min-h-screen={app_mode}
>
<div class="gr-panel !p-8">
<h2 class="text-2xl font-semibold mb-6">login</h2>
{#if auth_message}
<p class="my-4">{auth_message}</p>
{/if}
<label class="block uppercase mt-4" for="username">username</label>
<input class="p-2 block" type="text" name="username" />
<label class="block uppercase mt-4" for="password">password</label>
<input class="p-2 block" type="password" name="password" />
<input
type="submit"
class="block bg-amber-500 hover:bg-amber-400 dark:hover:bg-amber-600 transition px-4 py-2 rounded text-white font-semibold cursor-pointer mt-4"
/>
</form>
{#if incorrect_credentials}
<p class="my-4 text-red-600 font-semibold">Incorrect Credentials</p>
{/if}
<Form>
<Textbox
label="username"
lines={1}
show_label={true}
max_lines={1}
mode="dynamic"
on:submit={submit}
bind:value={username}
/>
<Textbox
label="password"
lines={1}
show_label={true}
max_lines={1}
mode="dynamic"
type="password"
on:submit={submit}
bind:value={password}
/>
</Form>

<button
class="gr-button gr-button-lg gr-button-primary w-full mt-4"
on:click={submit}>Login</button
>
</div>
</div>
6 changes: 4 additions & 2 deletions ui/packages/app/src/components/Textbox/Textbox.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

export let style: Styles = {};

export let loading_status: LoadingStatus;
export let loading_status: LoadingStatus | undefined = undefined;

export let mode: "static" | "dynamic";
</script>
Expand All @@ -29,7 +29,9 @@
{elem_id}
disable={typeof style.container === "boolean" && !style.container}
>
<StatusTracker {...loading_status} />
{#if loading_status}
<StatusTracker {...loading_status} />
{/if}

<TextBox
bind:value
Expand Down
62 changes: 60 additions & 2 deletions ui/packages/app/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ interface Config {
}

let app_id: string | null = null;
let app_mode = window.__gradio_mode__ === "app";

async function reload_check(root: string) {
const result = await (await fetch(root + "app_id")).text();
Expand Down Expand Up @@ -152,7 +153,8 @@ function mount_app(
props: {
auth_message: config.auth_message,
root: config.root,
id
id,
app_mode
}
});
} else {
Expand All @@ -167,7 +169,13 @@ function mount_app(
new Blocks({
target: wrapper,
//@ts-ignore
props: { ...config, target: wrapper, id, autoscroll: autoscroll }
props: {
...config,
target: wrapper,
id,
autoscroll: autoscroll,
app_mode
}
});
}

Expand Down Expand Up @@ -214,6 +222,9 @@ function create_custom_element() {
});

this.root.append(this.wrapper);
if (window.__gradio_mode__ !== "website") {
handle_darkmode(this.wrapper);
}
}

async connectedCallback() {
Expand Down Expand Up @@ -272,6 +283,9 @@ function create_custom_element() {
async function unscoped_mount() {
const target = document.querySelector("#root")! as HTMLDivElement;
target.classList.add("gradio-container");
if (window.__gradio_mode__ !== "website") {
handle_darkmode(target);
}

window.__gradio_loader__[0] = new Loader({
target: target,
Expand All @@ -287,6 +301,50 @@ async function unscoped_mount() {
mount_app({ ...config, control_page_title: true }, false, target, 0);
}

function handle_darkmode(target: HTMLDivElement) {
let url = new URL(window.location.toString());

const color_mode: "light" | "dark" | "system" | null = url.searchParams.get(
"__theme"
) as "light" | "dark" | "system" | null;

if (color_mode !== null) {
if (color_mode === "dark") {
darkmode(target);
} else if (color_mode === "system") {
use_system_theme(target);
}
// light is default, so we don't need to do anything else
} else if (url.searchParams.get("__dark-theme") === "true") {
darkmode(target);
} else {
use_system_theme(target);
}
}

function use_system_theme(target: HTMLDivElement) {
update_scheme();
window
?.matchMedia("(prefers-color-scheme: dark)")
?.addEventListener("change", update_scheme);

function update_scheme() {
const is_dark =
window?.matchMedia?.("(prefers-color-scheme: dark)").matches ?? null;

if (is_dark) {
darkmode(target);
}
}
}

function darkmode(target: HTMLDivElement) {
target.classList.add("dark");
if (app_mode) {
document.body.style.backgroundColor = "rgb(11, 15, 25)"; // bg-gray-950 for scrolling outside the body
}
}

// dev mode or if inside an iframe
if (BUILD_MODE === "dev" || window.location !== window.parent.location) {
window.scoped_css_attach = (link) => {
Expand Down