File size: 4,416 Bytes
234355e
 
 
f56efb4
5925fe4
f81a19e
606e801
f56efb4
606e801
f56efb4
234355e
f56efb4
5925fe4
e11d07e
f56efb4
5925fe4
 
f56efb4
5925fe4
f56efb4
5925fe4
f56efb4
234355e
 
 
 
 
 
 
 
 
 
 
 
5dec097
 
 
 
f56efb4
5925fe4
5dec097
f56efb4
 
 
5dec097
f56efb4
 
 
 
234355e
 
 
 
 
5925fe4
234355e
5dec097
f56efb4
5dec097
f56efb4
234355e
 
 
 
 
 
f56efb4
5925fe4
234355e
5dec097
5925fe4
234355e
f56efb4
234355e
f56efb4
 
 
 
 
 
5dec097
f56efb4
 
 
 
 
f2ce449
f56efb4
 
 
 
 
 
 
 
8cb7e04
f56efb4
 
 
 
 
42a91de
f56efb4
 
 
 
 
 
42a91de
5dec097
234355e
 
f56efb4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import gradio as gr
from gradio_htmlinjector import HTMLInjector

# 1) Choix dans la popup -> ajoute (Oui/Non, confirmation)
def handle_choice(choice: str, chat_history: list[tuple[str, str]]):
    c = (choice or "").strip().lower()
    if c in {"oui", "o", "yes", "y"}:
        user_choice, reply = "Oui", "✅ Vous avez choisi **OUI**. Action validée."
    elif c in {"non", "n", "no"}:
        user_choice, reply = "Non", "❌ Vous avez choisi **NON**. Action annulée."
    else:
        return chat_history, ""  # ignore valeurs inattendues
    return chat_history + [(user_choice, reply)], ""  # reset du pont

# 2) Soumission utilisateur : réponse fixe
def on_submit(user_msg: str, chat_history: list[tuple[str, str]]):
    if not user_msg:
        return chat_history, ""  # rien
    assistant_reply = "Ceci est une réponse de démonstration.\n\nConfirmez-vous l’action ?"
    return chat_history + [(user_msg, assistant_reply)], ""  # clear textbox

# 3) Injection HTML/CSS + helper
def inject_assets():
    js = r"""
    function setGradioValue(elemId, value){
      const root = (window.gradioApp && window.gradioApp()) || document;
      const host = root.querySelector(`#${elemId}`);
      if (!host) return;
      const input = host.querySelector('input, textarea');
      if (!input) return;
      input.value = value;
      input.dispatchEvent(new Event('input',  {bubbles:true}));
      input.dispatchEvent(new Event('change', {bubbles:true}));
    }
    """
    css = r"""
    #confirm-modal{
      display:none; position:fixed; inset:0; z-index:9999;
      background: rgba(0,0,0,.45); align-items:center; justify-content:center;
    }
    #confirm-card{
      background: var(--panel-background-fill, #fff); color: var(--body-text-color, #111);
      border: 1px solid var(--border-color-primary, #ccc); border-radius: 10px;
      padding: 20px; min-width: 320px; max-width: 90vw; box-shadow: 0 10px 30px rgba(0,0,0,.2);
    }
    #confirm-actions{ display:flex; gap:8px; justify-content:flex-end; margin-top:14px; }
    #confirm-actions button{ cursor:pointer; padding:8px 14px; border-radius:8px; border:1px solid #bbb; background:#f4f4f5; }
    #confirm-actions button.primary{ background:#2563eb; color:#fff; border-color:transparent; }
    #bridge-choice{ display:none; }  /* pont caché mais monté */
    """
    html = r"""
    <div id="confirm-modal" role="dialog" aria-modal="true" aria-labelledby="confirm-title">
      <div id="confirm-card">
        <h3 id="confirm-title">Confirmer ?</h3>
        <p>Souhaitez-vous continuer ?</p>
        <div id="confirm-actions">
          <button type="button"
            onclick="setGradioValue('bridge-choice','non'); document.getElementById('confirm-modal').style.display='none'; document.body.style.overflow=''">Non</button>
          <button type="button" class="primary"
            onclick="setGradioValue('bridge-choice','oui'); document.getElementById('confirm-modal').style.display='none'; document.body.style.overflow=''">Oui</button>
        </div>
      </div>
    </div>
    """
    return {"css": css, "js": js, "body_html": html}

# 4) UI
with gr.Blocks(title="Démo Chat + Popup", fill_height=True) as demo:
    html_injector = HTMLInjector()

    chat = gr.Chatbot(label="Chatbot", height=420)
    user_in = gr.Textbox(placeholder="Tapez un message…", lines=2)
    bridge_choice = gr.Textbox(visible=True, elem_id="bridge-choice")  # pont oui/non

    # (A) submit -> (user, question)
    evt = user_in.submit(
        fn=on_submit,
        inputs=[user_in, chat],
        outputs=[chat, user_in],
    )

    # (B) puis -> ouvrir la popup côté client (sans inputs/outputs)
    evt.then(
        fn=None,
        inputs=None,
        outputs=None,
        js="""
() => {
  const start = Date.now();
  (function tick(){
    const modal = document.getElementById('confirm-modal');
    if (modal) {
      modal.style.display = 'flex';
      document.body.style.overflow = 'hidden';
      return;
    }
    if (Date.now() - start < 3000) setTimeout(tick, 60);
  })();
}
        """,
    )

    # (C) clic Oui/Non -> ajoute (Oui/Non, confirmation)
    bridge_choice.change(
        fn=handle_choice,
        inputs=[bridge_choice, chat],
        outputs=[chat, bridge_choice],
    )

    # Injection initiale (structure + styles + helper)
    demo.load(fn=inject_assets, inputs=None, outputs=[html_injector])

demo.launch()