gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
33.39k stars 2.52k forks source link

How to show multi-images as a gallery in a ChatBot windows? #4673

Open main-voice opened 1 year ago

main-voice commented 1 year ago

Is your feature request related to a problem? Please describe.
I want to show multi-images in a chatbot windows, and the ideal case is that embed the gallery component into the chat windows instead of being independent. But I can't find the method. I also want to write some html & css & JS code manually however the browser cannot recognize these JS code and it doesn't work. Is there anyone can help me :(

Describe the solution you'd like
The ideal case is that embed the gallery component into the chat windows instead of totally being independent.

Additional context
Below is my code, I added some css code and JS code (the goal is to show multi-interactive images in a chatBot windows). Not sure if Gradio support user add many complex JS code manually (A reminder: actually if you run the code, and after you input anything to get three images, when you move the mouse over the image, you'll notice the shape of mouse will change, which shows it's clickable but there isn't any valid feedback) (maybe you can ignore some long css style code and focus on how to make my own JS code take effect or just to debug using console.log function)

Last but not least, just thanks for any feedback 🙏

import gradio as gr
import random
import time

def respond(message, chat_history):
    bot_message = random.choice(["How are you?", "I love you", "I'm very hungry"])

    css_code = """
    <style>
        .gallery {
            display: flex;
            flex-wrap: flex;
            flex-direction: row;
            justify-content: flex-start;
            align-items: center;
        }
        .gallery-image {
            display: inline-block;
            object-fit: cover;
            cursor: pointer;
        }
        /* The Modal (background) */
        .modal {
            display: none; /* Hidden by default */
            position: fixed; /* Stay in place */
            z-index: 1; /* Sit on top */
            padding-top: 100px; /* Location of the box */
            left: 0;
            top: 0;
            width: 100%; /* Full width */
            height: 100%; /* Full height */
            overflow: auto; /* Enable scroll if needed */
            background-color: rgb(0,0,0); /* Fallback color */
            background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
        }
        /* Modal Content (Image) */
        .modal-content {
            margin: auto;
            display: block;
            width: 80%;
            max-width: 700px;
        }
        /* Add Animation */
        .modal-content {
            -webkit-animation-name: zoom;
            -webkit-animation-duration: 0.6s;
            animation-name: zoom;
            animation-duration: 0.6s;
        }
        @-webkit-keyframes zoom {
            from {-webkit-transform:scale(0)} 
            to {-webkit-transform:scale(1)}
        }
        @keyframes zoom {
            from {transform:scale(0)} 
            to {transform:scale(1)}
        }
        /* The Close Button */
        .close {
            position: absolute;
            top: 15px;
            right: 35px;
            color: #f1f1f1;
            font-size: 40px;
            font-weight: bold;
            transition: 0.3s;
        }
        .close:hover,
        .close:focus {
            color: #bbb;
            text-decoration: none;
            cursor: pointer;
        }
    </style>
    """
    bot_message += css_code

    # add images to bot_message
    gallery_html = "<div class='gallery'>"
    images = [
            "https://images.unsplash.com/photo-1546456073-92b9f0a8d413?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=387&q=80", 
            "https://images.unsplash.com/photo-1601412436009-d964bd02edbc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=464&q=80", 
            "https://images.unsplash.com/photo-1554151228-14d9def656e4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=386&q=80"
            ]

    for image in images:
        gallery_html += f"<img src='{image}' class='gallery-image' onclick='openModal(\"{image}\")'>"
    gallery_html += "</div>"
    bot_message += gallery_html

    # Add the modal
    modal_html = """
    <!-- The Modal -->
    <div id="myModal" class="modal">
        <span class="close" onclick="closeModal()">&times;</span>
        <img class="modal-content" id="img01">
    </div>
    """
    bot_message += modal_html

    # Add the JavaScript
    js_code = """
    <script>
    function openModal(src) {
        var modal = document.getElementById("myModal");
        var img = document.getElementById("img01");
        modal.style.display = "block";
        img.src = src;
    }
    function closeModal() {
        var modal = document.getElementById("myModal");
        modal.style.display = "none";
    }
    </script>
    """
    bot_message += js_code

    chat_history.append((message, bot_message))
    return "", chat_history

with gr.Blocks() as demo:
    chatbot = gr.Chatbot(elem_id="gradio")
    msg = gr.Textbox()
    clear = gr.ClearButton([msg, chatbot])

    msg.submit(respond, [msg, chatbot], [msg, chatbot])

if __name__ == "__main__":
    demo.launch()
main-voice commented 1 year ago

Hi abidlabs (@abidlabs ) would you please write some comment so that I can know if my way is feasible. Another question: can I add a button or other interactive component inside a chatbot window?