|
""" |
|
modules/interface.py - UI-Komponenten-Modul für den Dr. Franz Psychochatbot |
|
|
|
Dieses Modul definiert die Benutzeroberfläche des Chatbots: |
|
- Gradio-Interface-Komponenten |
|
- Benutzererfahrung optimieren |
|
- Responsive Design sicherstellen |
|
""" |
|
|
|
import gradio as gr |
|
from typing import List, Dict, Any, Tuple, Callable, Optional |
|
import random |
|
import time |
|
|
|
|
|
import config |
|
|
|
class Interface: |
|
"""Klasse zur Verwaltung der Benutzeroberfläche""" |
|
|
|
def __init__(self, chat_function: Callable[[str], str], clear_function: Callable[[], Tuple[None, str]]): |
|
""" |
|
Initialisiert die Interface-Komponente |
|
|
|
Args: |
|
chat_function: Die Hauptfunktion für die Chatbot-Logik |
|
clear_function: Die Funktion zum Zurücksetzen der Konversation |
|
""" |
|
self.chat_function = chat_function |
|
self.clear_function = clear_function |
|
self.theme = gr.themes.Soft( |
|
primary_hue=config.UI_PRIMARY_COLOR, |
|
secondary_hue=config.UI_SECONDARY_COLOR |
|
) |
|
|
|
def create_interface(self) -> gr.Blocks: |
|
""" |
|
Erstellt das Gradio-Interface |
|
|
|
Returns: |
|
Das konfigurierte Gradio-Interface |
|
""" |
|
with gr.Blocks(theme=self.theme) as demo: |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown(f"# {config.CHATBOT_EMOJI} {config.CHATBOT_TITLE}") |
|
gr.Markdown(f"*{config.CHATBOT_DESCRIPTION}*") |
|
|
|
|
|
with gr.Row(): |
|
|
|
with gr.Column(scale=4): |
|
chatbot = gr.Chatbot( |
|
height=config.UI_CHATBOX_HEIGHT, |
|
label="Therapiesitzung", |
|
elem_id="chatbox", |
|
show_label=True, |
|
avatar_images=(None, None), |
|
show_copy_button=True, |
|
show_share_button=True |
|
) |
|
|
|
|
|
with gr.Row(): |
|
user_input = gr.Textbox( |
|
placeholder="Teilen Sie Ihre Gedanken mit Dr. Franz...", |
|
label="Ihre Aussage", |
|
scale=4, |
|
elem_id="user-input", |
|
show_label=True |
|
) |
|
send = gr.Button("Senden", variant="primary", elem_id="send-btn") |
|
|
|
|
|
with gr.Row(): |
|
clear = gr.Button("Neue Sitzung", elem_id="clear-btn") |
|
thinking = gr.HTML( |
|
"<div id='thinking-indicator' style='display:none; text-align:center;'>" |
|
"<i>Dr. Franz denkt nach...</i></div>" |
|
) |
|
|
|
|
|
with gr.Column(scale=1): |
|
gr.Markdown(f"### Über {config.CHATBOT_NAME}") |
|
gr.Markdown(""" |
|
Dr. Franz ist ein experimenteller KI-Psychoanalytiker, der Ihre Gedanken und Emotionen analysiert. |
|
|
|
**Hinweis:** Dieser Chatbot dient nur der Unterhaltung und ersetzt keine professionelle psychologische Beratung. |
|
|
|
**Funktionen:** |
|
- Psychoanalytische Gesprächsführung |
|
- Emotionsanalyse |
|
- Kontextbewusstsein |
|
|
|
Dieser Chatbot verwendet die HuggingFace Inference API. |
|
""") |
|
|
|
|
|
mood_indicator = gr.HTML( |
|
"<div id='mood-container' style='text-align:center; margin-top:20px;'>" |
|
"<div id='mood-label'>Therapeutische Intensität</div>" |
|
"<div id='mood-indicator' style='font-size:24px;'>😐</div>" |
|
"</div>" |
|
) |
|
|
|
|
|
gr.HTML(""" |
|
<script> |
|
// Funktion zum Anzeigen des "Denkt nach..."-Indikators |
|
function showThinking() { |
|
document.getElementById('thinking-indicator').style.display = 'block'; |
|
|
|
// Zufällige Stimmung anzeigen |
|
const moods = ['🧐', '🤔', '😑', '😒', '🙄']; |
|
document.getElementById('mood-indicator').innerText = moods[Math.floor(Math.random() * moods.length)]; |
|
} |
|
|
|
// Funktion zum Ausblenden des "Denkt nach..."-Indikators |
|
function hideThinking() { |
|
document.getElementById('thinking-indicator').style.display = 'none'; |
|
|
|
// Zufällige Stimmung anzeigen |
|
const moods = ['😏', '🧐', '😐', '🤨', '😌']; |
|
document.getElementById('mood-indicator').innerText = moods[Math.floor(Math.random() * moods.length)]; |
|
} |
|
|
|
// Event-Listener für den Senden-Button |
|
document.addEventListener('DOMContentLoaded', function() { |
|
const sendBtn = document.getElementById('send-btn'); |
|
if (sendBtn) { |
|
sendBtn.addEventListener('click', showThinking); |
|
} |
|
|
|
// Beobachter für Änderungen im Chat-Bereich |
|
const observer = new MutationObserver(function(mutations) { |
|
hideThinking(); |
|
}); |
|
|
|
// Beobachtung starten, sobald das Element verfügbar ist |
|
setTimeout(function() { |
|
const chatbox = document.getElementById('chatbox'); |
|
if (chatbox) { |
|
observer.observe(chatbox, { childList: true, subtree: true }); |
|
} |
|
}, 1000); |
|
}); |
|
</script> |
|
""") |
|
|
|
|
|
def respond(msg, history): |
|
if not msg.strip(): |
|
return history, "" |
|
|
|
|
|
time.sleep(0.5) |
|
|
|
|
|
reply = self.chat_function(msg) |
|
|
|
history = history or [] |
|
history.append((msg, reply)) |
|
return history, "" |
|
|
|
send.click(respond, inputs=[user_input, chatbot], outputs=[chatbot, user_input]) |
|
user_input.submit(respond, inputs=[user_input, chatbot], outputs=[chatbot, user_input]) |
|
clear.click(self.clear_function, inputs=[], outputs=[chatbot, user_input]) |
|
|
|
return demo |
|
|
|
def launch_interface(self, demo: gr.Blocks) -> None: |
|
""" |
|
Startet das Gradio-Interface |
|
|
|
Args: |
|
demo: Das zu startende Gradio-Interface |
|
""" |
|
demo.launch( |
|
server_name=config.SERVER_NAME, |
|
share=config.SHARE, |
|
show_error=config.SHOW_ERROR |
|
) |
|
|