Skip to content

Commit

Permalink
Add gr.BrowserState change event (#10245)
Browse files Browse the repository at this point in the history
* changes

* changes

* add changeset

* format

* changes

---------

Co-authored-by: gradio-pr-bot <[email protected]>
  • Loading branch information
abidlabs and gradio-pr-bot authored Dec 23, 2024
1 parent 3f19210 commit 3e4e0de
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changeset/solid-moments-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@gradio/browserstate": minor
"gradio": minor
---

feat:Add `gr.BrowserState` change event
2 changes: 1 addition & 1 deletion demo/browserstate/run.ipynb
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: browserstate"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import random\n", "import string\n", "import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", " gr.Markdown(\"Your Username and Password will get saved in the browser's local storage. \"\n", " \"If you refresh the page, the values will be retained.\")\n", " username = gr.Textbox(label=\"Username\")\n", " password = gr.Textbox(label=\"Password\", type=\"password\")\n", " btn = gr.Button(\"Generate Randomly\")\n", " local_storage = gr.BrowserState([\"\", \"\"])\n", "\n", " @btn.click(outputs=[username, password])\n", " def generate_randomly():\n", " u = \"\".join(random.choices(string.ascii_letters + string.digits, k=10))\n", " p = \"\".join(random.choices(string.ascii_letters + string.digits, k=10))\n", " return u, p\n", "\n", " @demo.load(inputs=[local_storage], outputs=[username, password])\n", " def load_from_local_storage(saved_values):\n", " print(\"loading from local storage\", saved_values)\n", " return saved_values[0], saved_values[1]\n", "\n", " @gr.on([username.change, password.change], inputs=[username, password], outputs=[local_storage])\n", " def save_to_local_storage(username, password):\n", " return [username, password]\n", "\n", "demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: browserstate"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import random\n", "import string\n", "import gradio as gr\n", "import time\n", "with gr.Blocks() as demo:\n", " gr.Markdown(\"Your Username and Password will get saved in the browser's local storage. \"\n", " \"If you refresh the page, the values will be retained.\")\n", " username = gr.Textbox(label=\"Username\")\n", " password = gr.Textbox(label=\"Password\", type=\"password\")\n", " btn = gr.Button(\"Generate Randomly\")\n", " local_storage = gr.BrowserState([\"\", \"\"])\n", " saved_message = gr.Markdown(\"\u2705 Saved to local storage\", visible=False)\n", "\n", " @btn.click(outputs=[username, password])\n", " def generate_randomly():\n", " u = \"\".join(random.choices(string.ascii_letters + string.digits, k=10))\n", " p = \"\".join(random.choices(string.ascii_letters + string.digits, k=10))\n", " return u, p\n", "\n", " @demo.load(inputs=[local_storage], outputs=[username, password])\n", " def load_from_local_storage(saved_values):\n", " print(\"loading from local storage\", saved_values)\n", " return saved_values[0], saved_values[1]\n", "\n", " @gr.on([username.change, password.change], inputs=[username, password], outputs=[local_storage])\n", " def save_to_local_storage(username, password):\n", " return [username, password]\n", "\n", " @gr.on(local_storage.change, outputs=[saved_message])\n", " def show_saved_message():\n", " timestamp = time.strftime(\"%I:%M:%S %p\")\n", " return gr.Markdown(\n", " f\"\u2705 Saved to local storage at {timestamp}\",\n", " visible=True\n", " )\n", "\n", "demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
11 changes: 10 additions & 1 deletion demo/browserstate/run.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import random
import string
import gradio as gr

import time
with gr.Blocks() as demo:
gr.Markdown("Your Username and Password will get saved in the browser's local storage. "
"If you refresh the page, the values will be retained.")
username = gr.Textbox(label="Username")
password = gr.Textbox(label="Password", type="password")
btn = gr.Button("Generate Randomly")
local_storage = gr.BrowserState(["", ""])
saved_message = gr.Markdown("✅ Saved to local storage", visible=False)

@btn.click(outputs=[username, password])
def generate_randomly():
Expand All @@ -25,4 +26,12 @@ def load_from_local_storage(saved_values):
def save_to_local_storage(username, password):
return [username, password]

@gr.on(local_storage.change, outputs=[saved_message])
def show_saved_message():
timestamp = time.strftime("%I:%M:%S %p")
return gr.Markdown(
f"✅ Saved to local storage at {timestamp}",
visible=True
)

demo.launch()
2 changes: 2 additions & 0 deletions gradio/components/browser_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
from gradio_client.documentation import document

from gradio.components.base import Component
from gradio.events import Events


@document()
class BrowserState(Component):
EVENTS = [Events.change]
"""
Special component that stores state in the browser's localStorage in an encrypted format.
"""
Expand Down
12 changes: 11 additions & 1 deletion js/browserstate/Index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
import { beforeUpdate } from "svelte";
import { encrypt, decrypt } from "./crypto";
import { dequal } from "dequal/lite";
import type { Gradio } from "@gradio/utils";
export let storage_key: string;
export let secret: string;
export let default_value: any;
export let value = default_value;
let initialized = false;
let old_value = value;
export let gradio: Gradio<{
change: never;
}>;
function load_value(): void {
const stored = localStorage.getItem(storage_key);
Expand Down Expand Up @@ -40,7 +44,13 @@
}
}
$: value && !dequal(value, old_value) && save_value();
$: value &&
(() => {
if (!dequal(value, old_value)) {
save_value();
gradio.dispatch("change");
}
})();
beforeUpdate(() => {
if (!initialized) {
Expand Down
3 changes: 2 additions & 1 deletion js/browserstate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
},
"dependencies": {
"dequal": "^2.0.2",
"crypto-js": "^4.1.1"
"crypto-js": "^4.1.1",
"@gradio/utils": "workspace:^"
},
"peerDependencies": {
"svelte": "^4.0.0"
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3e4e0de

Please sign in to comment.