From 206af31d7c1a31013364a44e9b40cf8df304ba50 Mon Sep 17 00:00:00 2001 From: Hannah Date: Fri, 24 Nov 2023 19:03:18 +0100 Subject: [PATCH] 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 --- .changeset/long-candles-burn.md | 7 ++++++ demo/chatbot_multimodal/run.ipynb | 2 +- demo/chatbot_multimodal/run.py | 7 ++++++ js/app/test/chatbot_multimodal.spec.ts | 11 +++++++++ js/chatbot/shared/ChatBot.svelte | 12 ++++------ js/chatbot/shared/LikeDislike.svelte | 33 ++++++++++++-------------- js/icons/src/Dislike.svelte | 4 ++-- js/icons/src/Like.svelte | 4 ++-- 8 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 .changeset/long-candles-burn.md diff --git a/.changeset/long-candles-burn.md b/.changeset/long-candles-burn.md new file mode 100644 index 000000000000..555b19f36017 --- /dev/null +++ b/.changeset/long-candles-burn.md @@ -0,0 +1,7 @@ +--- +"@gradio/chatbot": patch +"@gradio/icons": patch +"gradio": patch +--- + +fix:Improve like/dislike functionality diff --git a/demo/chatbot_multimodal/run.ipynb b/demo/chatbot_multimodal/run.ipynb index 2f88a5d6cf8e..88a58d34ef53 100644 --- a/demo/chatbot_multimodal/run.ipynb +++ b/demo/chatbot_multimodal/run.ipynb @@ -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} \ No newline at end of file +{"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} \ No newline at end of file diff --git a/demo/chatbot_multimodal/run.py b/demo/chatbot_multimodal/run.py index 650905aa2bcf..96bbf34c44e4 100644 --- a/demo/chatbot_multimodal/run.py +++ b/demo/chatbot_multimodal/run.py @@ -5,6 +5,10 @@ # 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 @@ def bot(history): bot, chatbot, chatbot ) + chatbot.like(print_like_dislike, None, None) + + demo.queue() if __name__ == "__main__": demo.launch() diff --git a/js/app/test/chatbot_multimodal.spec.ts b/js/app/test/chatbot_multimodal.spec.ts index 75715e55be10..45a6581c79d3 100644 --- a/js/app/test/chatbot_multimodal.spec.ts +++ b/js/app/test/chatbot_multimodal.spec.ts @@ -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); +}); diff --git a/js/chatbot/shared/ChatBot.svelte b/js/chatbot/shared/ChatBot.svelte index 43bcca773954..335747ea65a5 100644 --- a/js/chatbot/shared/ChatBot.svelte +++ b/js/chatbot/shared/ChatBot.svelte @@ -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" }); } @@ -238,12 +238,8 @@ > {#if likeable && j == 1} handle_like(i, j, message, true)} - /> - handle_like(i, j, message, false)} + handle_action={(selected) => + handle_like(i, j, message, selected)} /> {/if} {#if show_copy_button && message && typeof message === "string"} diff --git a/js/chatbot/shared/LikeDislike.svelte b/js/chatbot/shared/LikeDislike.svelte index 2ce09de0f0e8..46843a40bdfc 100644 --- a/js/chatbot/shared/LikeDislike.svelte +++ b/js/chatbot/shared/LikeDislike.svelte @@ -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; + +