diff --git a/static/css/assistant.css b/static/css/assistant.css
index 22e9eea..20ac518 100644
--- a/static/css/assistant.css
+++ b/static/css/assistant.css
@@ -1,6 +1,7 @@
/* ChatGPT Assistent Styles - Verbesserte Version */
#chatgpt-assistant {
font-family: 'Inter', sans-serif;
+ bottom: 4.5rem;
}
#assistant-chat {
@@ -10,6 +11,7 @@
border-radius: 0.75rem;
overflow: hidden;
max-width: calc(100vw - 2rem);
+ max-height: 80vh !important;
}
#assistant-toggle {
@@ -142,14 +144,21 @@
.typing-indicator span {
height: 8px;
width: 8px;
- background-color: #888;
border-radius: 50%;
display: inline-block;
margin: 0 2px;
- opacity: 0.4;
+ opacity: 0.6;
animation: bounce 1.4s infinite ease-in-out;
}
+body.dark .typing-indicator span {
+ background-color: rgba(255, 255, 255, 0.7);
+}
+
+body:not(.dark) .typing-indicator span {
+ background-color: rgba(107, 114, 128, 0.8);
+}
+
.typing-indicator span:nth-child(1) { animation-delay: 0s; }
.typing-indicator span:nth-child(2) { animation-delay: 0.2s; }
.typing-indicator span:nth-child(3) { animation-delay: 0.4s; }
@@ -173,11 +182,12 @@
@media (max-width: 640px) {
#assistant-chat {
width: calc(100vw - 2rem) !important;
+ max-height: 70vh !important;
}
#chatgpt-assistant {
right: 1rem;
- bottom: 1rem;
+ bottom: 5rem;
}
}
@@ -200,4 +210,27 @@ main {
footer {
flex-shrink: 0;
+}
+
+/* Verbesserte Farbkontraste für Nachrichtenblasen */
+.user-message {
+ background-color: rgba(124, 58, 237, 0.1) !important;
+ color: #4B5563 !important;
+}
+
+body.dark .user-message {
+ background-color: rgba(124, 58, 237, 0.2) !important;
+ color: #F9FAFB !important;
+}
+
+.assistant-message {
+ background-color: #F3F4F6 !important;
+ color: #1F2937 !important;
+ border-left: 3px solid #8B5CF6;
+}
+
+body.dark .assistant-message {
+ background-color: rgba(31, 41, 55, 0.5) !important;
+ color: #F9FAFB !important;
+ border-left: 3px solid #8B5CF6;
}
\ No newline at end of file
diff --git a/static/js/modules/chatgpt-assistant.js b/static/js/modules/chatgpt-assistant.js
index 0da90a2..0a7819c 100644
--- a/static/js/modules/chatgpt-assistant.js
+++ b/static/js/modules/chatgpt-assistant.js
@@ -247,130 +247,63 @@ class ChatGPTAssistant {
const bubble = document.createElement('div');
bubble.className = sender === 'user'
- ? 'bg-primary-100 dark:bg-primary-900 text-gray-800 dark:text-white rounded-lg py-2 px-3 max-w-[85%]'
- : 'bg-gray-100 dark:bg-dark-700 text-gray-800 dark:text-white rounded-lg py-2 px-3 max-w-[85%]';
-
- // Formatierung des Texts (mit Markdown für Assistent-Nachrichten)
- let formattedText = '';
-
- if (sender === 'assistant' && this.markdownParser) {
- // Für Assistentnachrichten Markdown verwenden
- try {
- formattedText = this.markdownParser.parse(text);
-
- // CSS für Markdown-Formatierung hinzufügen
- const markdownStyles = `
- .markdown-bubble h1, .markdown-bubble h2, .markdown-bubble h3,
- .markdown-bubble h4, .markdown-bubble h5, .markdown-bubble h6 {
- font-weight: bold;
- margin-top: 0.5rem;
- margin-bottom: 0.5rem;
- }
- .markdown-bubble h1 { font-size: 1.4rem; }
- .markdown-bubble h2 { font-size: 1.3rem; }
- .markdown-bubble h3 { font-size: 1.2rem; }
- .markdown-bubble h4 { font-size: 1.1rem; }
- .markdown-bubble ul, .markdown-bubble ol {
- padding-left: 1.5rem;
- margin: 0.5rem 0;
- }
- .markdown-bubble ul { list-style-type: disc; }
- .markdown-bubble ol { list-style-type: decimal; }
- .markdown-bubble p { margin: 0.5rem 0; }
- .markdown-bubble code {
- font-family: monospace;
- background-color: rgba(0, 0, 0, 0.1);
- padding: 1px 4px;
- border-radius: 3px;
- }
- .markdown-bubble pre {
- background-color: rgba(0, 0, 0, 0.1);
- padding: 0.5rem;
- border-radius: 4px;
- overflow-x: auto;
- margin: 0.5rem 0;
- }
- .markdown-bubble pre code {
- background-color: transparent;
- padding: 0;
- }
- .markdown-bubble blockquote {
- border-left: 3px solid rgba(0, 0, 0, 0.2);
- padding-left: 0.8rem;
- margin: 0.5rem 0;
- font-style: italic;
- }
- .dark .markdown-bubble code {
- background-color: rgba(255, 255, 255, 0.1);
- }
- .dark .markdown-bubble pre {
- background-color: rgba(255, 255, 255, 0.1);
- }
- .dark .markdown-bubble blockquote {
- border-left-color: rgba(255, 255, 255, 0.2);
- }
- `;
-
- // Füge die Styles hinzu, wenn sie noch nicht vorhanden sind
- if (!document.querySelector('#markdown-chat-styles')) {
- const style = document.createElement('style');
- style.id = 'markdown-chat-styles';
- style.textContent = markdownStyles;
- document.head.appendChild(style);
- }
-
- // Klasse für Markdown-Formatierung hinzufügen
- bubble.classList.add('markdown-bubble');
- } catch (error) {
- console.error('Fehler bei der Markdown-Formatierung:', error);
- // Fallback zur einfachen Formatierung
- formattedText = text.split('\n').map(line => {
- if (line.trim() === '') return '
';
- return `
${line}
`; - }).join(''); - } + ? 'user-message rounded-lg py-2 px-3 max-w-[85%]' + : 'assistant-message rounded-lg py-2 px-3 max-w-[85%]'; + + // Nachrichtentext einfügen, falls Markdown-Parser verfügbar, nutzen + if (this.markdownParser) { + bubble.innerHTML = this.markdownParser.parse(text); } else { - // Für Benutzernachrichten einfache Formatierung - formattedText = text.split('\n').map(line => { - if (line.trim() === '') return '${line}
`; - }).join(''); + bubble.textContent = text; } - bubble.innerHTML = formattedText; + // Links in der Nachricht klickbar machen + const links = bubble.querySelectorAll('a'); + links.forEach(link => { + link.target = '_blank'; + link.rel = 'noopener noreferrer'; + link.className = 'text-primary-600 dark:text-primary-400 underline'; + }); + + // Code-Blöcke stylen + const codeBlocks = bubble.querySelectorAll('pre'); + codeBlocks.forEach(block => { + block.className = 'bg-gray-100 dark:bg-dark-900 p-2 rounded my-2 overflow-x-auto'; + }); + + const inlineCode = bubble.querySelectorAll('code:not(pre code)'); + inlineCode.forEach(code => { + code.className = 'bg-gray-100 dark:bg-dark-900 px-1 rounded font-mono text-sm'; + }); messageEl.appendChild(bubble); + this.chatHistory.appendChild(messageEl); - if (this.chatHistory) { - this.chatHistory.appendChild(messageEl); - - // Scroll zum Ende des Verlaufs - this.chatHistory.scrollTop = this.chatHistory.scrollHeight; - } + // Scrolle zum Ende des Chat-Verlaufs + this.chatHistory.scrollTop = this.chatHistory.scrollHeight; } /** - * Zeigt Vorschläge als klickbare Pills an - * @param {string[]} suggestions - Liste von Vorschlägen + * Zeigt Vorschläge für mögliche Fragen an + * @param {Array} suggestions - Array von Vorschlägen */ showSuggestions(suggestions) { - if (!this.suggestionArea) return; + if (!this.suggestionArea || !suggestions || !suggestions.length) return; // Vorherige Vorschläge entfernen this.suggestionArea.innerHTML = ''; - if (suggestions && suggestions.length > 0) { - suggestions.forEach(suggestion => { - const pill = document.createElement('button'); - pill.className = 'suggestion-pill text-sm bg-gray-200 dark:bg-dark-600 hover:bg-gray-300 dark:hover:bg-dark-500 text-gray-800 dark:text-gray-200 rounded-full px-3 py-1 mb-2 transition-colors'; - pill.textContent = suggestion; - this.suggestionArea.appendChild(pill); - }); - - this.suggestionArea.classList.remove('hidden'); - } else { - this.suggestionArea.classList.add('hidden'); - } + // Neue Vorschläge hinzufügen + suggestions.forEach((text, index) => { + const pill = document.createElement('button'); + pill.className = 'suggestion-pill text-sm px-3 py-1.5 rounded-full bg-primary-100 dark:bg-primary-900 text-primary-800 dark:text-primary-200 hover:bg-primary-200 dark:hover:bg-primary-800 transition-all duration-200'; + pill.style.animationDelay = `${index * 0.1}s`; + pill.textContent = text; + this.suggestionArea.appendChild(pill); + }); + + // Vorschlagsbereich anzeigen + this.suggestionArea.classList.remove('hidden'); } /** @@ -512,26 +445,33 @@ class ChatGPTAssistant { } /** - * Zeigt einen Ladeindikator im Chat an + * Zeigt eine Ladeanimation an */ showLoadingIndicator() { if (!this.chatHistory) return; - // Entferne vorhandenen Ladeindikator (falls vorhanden) - this.removeLoadingIndicator(); + // Prüfen, ob bereits ein Ladeindikator angezeigt wird + if (document.getElementById('assistant-loading-indicator')) return; const loadingEl = document.createElement('div'); - loadingEl.id = 'assistant-loading'; loadingEl.className = 'flex justify-start'; + loadingEl.id = 'assistant-loading-indicator'; const bubble = document.createElement('div'); - bubble.className = 'bg-gray-100 dark:bg-dark-700 text-gray-800 dark:text-white rounded-lg py-2 px-3'; - bubble.innerHTML = '