mirror of
https://github.com/gradio-app/gradio.git
synced 2025-01-30 11:00:11 +08:00
Improve like/dislike functionality (#6572)
* amend like/dislike logic * add like/dislike to chatbot demo and add e2e test * add changeset * e2e test changes * revert chatbot_component changes * tweak * generate notebooks * tweak --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
parent
2b625ad940
commit
206af31d7c
7
.changeset/long-candles-burn.md
Normal file
7
.changeset/long-candles-burn.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
"@gradio/chatbot": patch
|
||||
"@gradio/icons": patch
|
||||
"gradio": patch
|
||||
---
|
||||
|
||||
fix:Improve like/dislike functionality
|
@ -1 +1 @@
|
||||
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: chatbot_multimodal"]}, {"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": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/chatbot_multimodal/avatar.png"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "import time\n", "\n", "# Chatbot demo with multimodal input (text, markdown, LaTeX, code blocks, image, audio, & video). Plus shows support for streaming text.\n", "\n", "\n", "def add_text(history, text):\n", " history = history + [(text, None)]\n", " return history, gr.Textbox(value=\"\", interactive=False)\n", "\n", "\n", "def add_file(history, file):\n", " history = history + [((file.name,), None)]\n", " return history\n", "\n", "\n", "def bot(history):\n", " response = \"**That's cool!**\"\n", " history[-1][1] = \"\"\n", " for character in response:\n", " history[-1][1] += character\n", " time.sleep(0.05)\n", " yield history\n", "\n", "\n", "with gr.Blocks() as demo:\n", " chatbot = gr.Chatbot(\n", " [],\n", " elem_id=\"chatbot\",\n", " bubble_full_width=False,\n", " avatar_images=(None, (os.path.join(os.path.abspath(''), \"avatar.png\"))),\n", " )\n", "\n", " with gr.Row():\n", " txt = gr.Textbox(\n", " scale=4,\n", " show_label=False,\n", " placeholder=\"Enter text and press enter, or upload an image\",\n", " container=False,\n", " )\n", " btn = gr.UploadButton(\"\ud83d\udcc1\", file_types=[\"image\", \"video\", \"audio\"])\n", "\n", " txt_msg = txt.submit(add_text, [chatbot, txt], [chatbot, txt], queue=False).then(\n", " bot, chatbot, chatbot, api_name=\"bot_response\"\n", " )\n", " txt_msg.then(lambda: gr.Textbox(interactive=True), None, [txt], queue=False)\n", " file_msg = btn.upload(add_file, [chatbot, btn], [chatbot], queue=False).then(\n", " bot, chatbot, chatbot\n", " )\n", "\n", "demo.queue()\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
|
||||
{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: chatbot_multimodal"]}, {"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": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/chatbot_multimodal/avatar.png"]}, {"cell_type": "code", "execution_count": null, "id": "44380577570523278879349135829904343037", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "import time\n", "\n", "# Chatbot demo with multimodal input (text, markdown, LaTeX, code blocks, image, audio, & video). Plus shows support for streaming text.\n", "\n", "\n", "def print_like_dislike(x: gr.LikeData):\n", " print(x.index, x.value, x.liked)\n", "\n", "\n", "def add_text(history, text):\n", " history = history + [(text, None)]\n", " return history, gr.Textbox(value=\"\", interactive=False)\n", "\n", "\n", "def add_file(history, file):\n", " history = history + [((file.name,), None)]\n", " return history\n", "\n", "\n", "def bot(history):\n", " response = \"**That's cool!**\"\n", " history[-1][1] = \"\"\n", " for character in response:\n", " history[-1][1] += character\n", " time.sleep(0.05)\n", " yield history\n", "\n", "\n", "with gr.Blocks() as demo:\n", " chatbot = gr.Chatbot(\n", " [],\n", " elem_id=\"chatbot\",\n", " bubble_full_width=False,\n", " avatar_images=(None, (os.path.join(os.path.abspath(''), \"avatar.png\"))),\n", " )\n", "\n", " with gr.Row():\n", " txt = gr.Textbox(\n", " scale=4,\n", " show_label=False,\n", " placeholder=\"Enter text and press enter, or upload an image\",\n", " container=False,\n", " )\n", " btn = gr.UploadButton(\"\ud83d\udcc1\", file_types=[\"image\", \"video\", \"audio\"])\n", "\n", " txt_msg = txt.submit(add_text, [chatbot, txt], [chatbot, txt], queue=False).then(\n", " bot, chatbot, chatbot, api_name=\"bot_response\"\n", " )\n", " txt_msg.then(lambda: gr.Textbox(interactive=True), None, [txt], queue=False)\n", " file_msg = btn.upload(add_file, [chatbot, btn], [chatbot], queue=False).then(\n", " bot, chatbot, chatbot\n", " )\n", "\n", " chatbot.like(print_like_dislike, None, None)\n", "\n", "\n", "demo.queue()\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
|
@ -5,6 +5,10 @@ import time
|
||||
# Chatbot demo with multimodal input (text, markdown, LaTeX, code blocks, image, audio, & video). Plus shows support for streaming text.
|
||||
|
||||
|
||||
def print_like_dislike(x: gr.LikeData):
|
||||
print(x.index, x.value, x.liked)
|
||||
|
||||
|
||||
def add_text(history, text):
|
||||
history = history + [(text, None)]
|
||||
return history, gr.Textbox(value="", interactive=False)
|
||||
@ -49,6 +53,9 @@ with gr.Blocks() as demo:
|
||||
bot, chatbot, chatbot
|
||||
)
|
||||
|
||||
chatbot.like(print_like_dislike, None, None)
|
||||
|
||||
|
||||
demo.queue()
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
||||
|
@ -177,3 +177,14 @@ test("when a new message is sent the chatbot should scroll to the latest message
|
||||
const bot_message_text = bot_message.textContent();
|
||||
await expect(bot_message_text).toBeTruthy();
|
||||
});
|
||||
|
||||
test("chatbot like and dislike functionality", async ({ page }) => {
|
||||
await page.getByTestId("textbox").click();
|
||||
await page.getByTestId("textbox").fill("hello");
|
||||
await page.keyboard.press("Enter");
|
||||
await page.getByLabel("like", { exact: true }).click();
|
||||
await page.getByLabel("dislike").click();
|
||||
|
||||
expect(await page.getByLabel("clicked dislike").count()).toEqual(1);
|
||||
expect(await page.getByLabel("clicked like").count()).toEqual(0);
|
||||
});
|
||||
|
@ -98,12 +98,12 @@
|
||||
i: number,
|
||||
j: number,
|
||||
message: string | { file: FileData; alt_text: string | null } | null,
|
||||
liked: boolean
|
||||
selected: string | null
|
||||
): void {
|
||||
dispatch("like", {
|
||||
index: [i, j],
|
||||
value: message,
|
||||
liked: liked
|
||||
liked: selected === "like"
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@ -238,12 +238,8 @@
|
||||
>
|
||||
{#if likeable && j == 1}
|
||||
<LikeDislike
|
||||
action="like"
|
||||
handle_action={() => handle_like(i, j, message, true)}
|
||||
/>
|
||||
<LikeDislike
|
||||
action="dislike"
|
||||
handle_action={() => handle_like(i, j, message, false)}
|
||||
handle_action={(selected) =>
|
||||
handle_like(i, j, message, selected)}
|
||||
/>
|
||||
{/if}
|
||||
{#if show_copy_button && message && typeof message === "string"}
|
||||
|
@ -2,32 +2,29 @@
|
||||
import { Like } from "@gradio/icons";
|
||||
import { Dislike } from "@gradio/icons";
|
||||
|
||||
export let action: "like" | "dislike";
|
||||
export let handle_action: () => void;
|
||||
export let handle_action: (selected: string | null) => void;
|
||||
|
||||
let actioned = false;
|
||||
let Icon = action === "like" ? Like : Dislike;
|
||||
|
||||
function action_feedback(): void {
|
||||
actioned = true;
|
||||
}
|
||||
let selected: "like" | "dislike" | null = null;
|
||||
</script>
|
||||
|
||||
<button
|
||||
on:click={() => {
|
||||
action_feedback();
|
||||
handle_action();
|
||||
selected = "like";
|
||||
handle_action(selected);
|
||||
}}
|
||||
on:keydown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
action_feedback();
|
||||
handle_action();
|
||||
}
|
||||
}}
|
||||
title={action + " message"}
|
||||
aria-label={actioned ? `clicked ${action}` : action}
|
||||
aria-label={selected === "like" ? "clicked like" : "like"}
|
||||
>
|
||||
<Icon {actioned} />
|
||||
<Like selected={selected === "like"} />
|
||||
</button>
|
||||
|
||||
<button
|
||||
on:click={() => {
|
||||
selected = "dislike";
|
||||
handle_action(selected);
|
||||
}}
|
||||
aria-label={selected === "dislike" ? "clicked dislike" : "dislike"}
|
||||
>
|
||||
<Dislike selected={selected === "dislike"} />
|
||||
</button>
|
||||
|
||||
<style>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
export let actioned: boolean;
|
||||
export let selected: boolean;
|
||||
</script>
|
||||
|
||||
<svg
|
||||
@ -7,7 +7,7 @@
|
||||
width="15px"
|
||||
height="15px"
|
||||
viewBox="0 0 24 24"
|
||||
fill={actioned ? "currentColor" : "none"}
|
||||
fill={selected ? "currentColor" : "none"}
|
||||
stroke-width="1.5"
|
||||
color="currentColor"
|
||||
><path
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
export let actioned: boolean;
|
||||
export let selected: boolean;
|
||||
</script>
|
||||
|
||||
<svg
|
||||
@ -7,7 +7,7 @@
|
||||
width="15px"
|
||||
height="15px"
|
||||
viewBox="0 0 24 24"
|
||||
fill={actioned ? "currentColor" : "none"}
|
||||
fill={selected ? "currentColor" : "none"}
|
||||
stroke-width="1.5"
|
||||
color="currentColor"
|
||||
><path
|
||||
|
Loading…
Reference in New Issue
Block a user