✨ feat: enhance chatgpt assistant styling and functionality improvements
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
/* ChatGPT Assistent Styles - Verbesserte Version */
|
/* ChatGPT Assistent Styles - Verbesserte Version */
|
||||||
#chatgpt-assistant {
|
#chatgpt-assistant {
|
||||||
font-family: 'Inter', sans-serif;
|
font-family: 'Inter', sans-serif;
|
||||||
|
bottom: 4.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#assistant-chat {
|
#assistant-chat {
|
||||||
@@ -10,6 +11,7 @@
|
|||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-width: calc(100vw - 2rem);
|
max-width: calc(100vw - 2rem);
|
||||||
|
max-height: 80vh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#assistant-toggle {
|
#assistant-toggle {
|
||||||
@@ -142,14 +144,21 @@
|
|||||||
.typing-indicator span {
|
.typing-indicator span {
|
||||||
height: 8px;
|
height: 8px;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
background-color: #888;
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0 2px;
|
margin: 0 2px;
|
||||||
opacity: 0.4;
|
opacity: 0.6;
|
||||||
animation: bounce 1.4s infinite ease-in-out;
|
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(1) { animation-delay: 0s; }
|
||||||
.typing-indicator span:nth-child(2) { animation-delay: 0.2s; }
|
.typing-indicator span:nth-child(2) { animation-delay: 0.2s; }
|
||||||
.typing-indicator span:nth-child(3) { animation-delay: 0.4s; }
|
.typing-indicator span:nth-child(3) { animation-delay: 0.4s; }
|
||||||
@@ -173,11 +182,12 @@
|
|||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
#assistant-chat {
|
#assistant-chat {
|
||||||
width: calc(100vw - 2rem) !important;
|
width: calc(100vw - 2rem) !important;
|
||||||
|
max-height: 70vh !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chatgpt-assistant {
|
#chatgpt-assistant {
|
||||||
right: 1rem;
|
right: 1rem;
|
||||||
bottom: 1rem;
|
bottom: 5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,3 +211,26 @@ main {
|
|||||||
footer {
|
footer {
|
||||||
flex-shrink: 0;
|
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;
|
||||||
|
}
|
||||||
@@ -247,130 +247,63 @@ class ChatGPTAssistant {
|
|||||||
|
|
||||||
const bubble = document.createElement('div');
|
const bubble = document.createElement('div');
|
||||||
bubble.className = sender === 'user'
|
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%]'
|
? 'user-message 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%]';
|
: 'assistant-message rounded-lg py-2 px-3 max-w-[85%]';
|
||||||
|
|
||||||
// Formatierung des Texts (mit Markdown für Assistent-Nachrichten)
|
// Nachrichtentext einfügen, falls Markdown-Parser verfügbar, nutzen
|
||||||
let formattedText = '';
|
if (this.markdownParser) {
|
||||||
|
bubble.innerHTML = this.markdownParser.parse(text);
|
||||||
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 '<br>';
|
|
||||||
return `<p>${line}</p>`;
|
|
||||||
}).join('');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Für Benutzernachrichten einfache Formatierung
|
bubble.textContent = text;
|
||||||
formattedText = text.split('\n').map(line => {
|
|
||||||
if (line.trim() === '') return '<br>';
|
|
||||||
return `<p>${line}</p>`;
|
|
||||||
}).join('');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
messageEl.appendChild(bubble);
|
||||||
|
this.chatHistory.appendChild(messageEl);
|
||||||
|
|
||||||
if (this.chatHistory) {
|
// Scrolle zum Ende des Chat-Verlaufs
|
||||||
this.chatHistory.appendChild(messageEl);
|
this.chatHistory.scrollTop = this.chatHistory.scrollHeight;
|
||||||
|
|
||||||
// Scroll zum Ende des Verlaufs
|
|
||||||
this.chatHistory.scrollTop = this.chatHistory.scrollHeight;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zeigt Vorschläge als klickbare Pills an
|
* Zeigt Vorschläge für mögliche Fragen an
|
||||||
* @param {string[]} suggestions - Liste von Vorschlägen
|
* @param {Array} suggestions - Array von Vorschlägen
|
||||||
*/
|
*/
|
||||||
showSuggestions(suggestions) {
|
showSuggestions(suggestions) {
|
||||||
if (!this.suggestionArea) return;
|
if (!this.suggestionArea || !suggestions || !suggestions.length) return;
|
||||||
|
|
||||||
// Vorherige Vorschläge entfernen
|
// Vorherige Vorschläge entfernen
|
||||||
this.suggestionArea.innerHTML = '';
|
this.suggestionArea.innerHTML = '';
|
||||||
|
|
||||||
if (suggestions && suggestions.length > 0) {
|
// Neue Vorschläge hinzufügen
|
||||||
suggestions.forEach(suggestion => {
|
suggestions.forEach((text, index) => {
|
||||||
const pill = document.createElement('button');
|
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.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.textContent = suggestion;
|
pill.style.animationDelay = `${index * 0.1}s`;
|
||||||
this.suggestionArea.appendChild(pill);
|
pill.textContent = text;
|
||||||
});
|
this.suggestionArea.appendChild(pill);
|
||||||
|
});
|
||||||
|
|
||||||
this.suggestionArea.classList.remove('hidden');
|
// Vorschlagsbereich anzeigen
|
||||||
} else {
|
this.suggestionArea.classList.remove('hidden');
|
||||||
this.suggestionArea.classList.add('hidden');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -512,26 +445,33 @@ class ChatGPTAssistant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zeigt einen Ladeindikator im Chat an
|
* Zeigt eine Ladeanimation an
|
||||||
*/
|
*/
|
||||||
showLoadingIndicator() {
|
showLoadingIndicator() {
|
||||||
if (!this.chatHistory) return;
|
if (!this.chatHistory) return;
|
||||||
|
|
||||||
// Entferne vorhandenen Ladeindikator (falls vorhanden)
|
// Prüfen, ob bereits ein Ladeindikator angezeigt wird
|
||||||
this.removeLoadingIndicator();
|
if (document.getElementById('assistant-loading-indicator')) return;
|
||||||
|
|
||||||
const loadingEl = document.createElement('div');
|
const loadingEl = document.createElement('div');
|
||||||
loadingEl.id = 'assistant-loading';
|
|
||||||
loadingEl.className = 'flex justify-start';
|
loadingEl.className = 'flex justify-start';
|
||||||
|
loadingEl.id = 'assistant-loading-indicator';
|
||||||
|
|
||||||
const bubble = document.createElement('div');
|
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.className = 'assistant-message rounded-lg py-3 px-4 max-w-[85%] flex items-center';
|
||||||
bubble.innerHTML = '<div class="typing-indicator"><span></span><span></span><span></span></div>';
|
|
||||||
|
|
||||||
|
const typingIndicator = document.createElement('div');
|
||||||
|
typingIndicator.className = 'typing-indicator';
|
||||||
|
typingIndicator.innerHTML = `
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
`;
|
||||||
|
|
||||||
|
bubble.appendChild(typingIndicator);
|
||||||
loadingEl.appendChild(bubble);
|
loadingEl.appendChild(bubble);
|
||||||
this.chatHistory.appendChild(loadingEl);
|
|
||||||
|
|
||||||
// Scroll zum Ende des Verlaufs
|
this.chatHistory.appendChild(loadingEl);
|
||||||
this.chatHistory.scrollTop = this.chatHistory.scrollHeight;
|
this.chatHistory.scrollTop = this.chatHistory.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,7 +479,7 @@ class ChatGPTAssistant {
|
|||||||
* Entfernt den Ladeindikator aus dem Chat
|
* Entfernt den Ladeindikator aus dem Chat
|
||||||
*/
|
*/
|
||||||
removeLoadingIndicator() {
|
removeLoadingIndicator() {
|
||||||
const loadingIndicator = document.getElementById('assistant-loading');
|
const loadingIndicator = document.getElementById('assistant-loading-indicator');
|
||||||
if (loadingIndicator) {
|
if (loadingIndicator) {
|
||||||
loadingIndicator.remove();
|
loadingIndicator.remove();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -307,7 +307,7 @@
|
|||||||
class="nav-link flex items-center"
|
class="nav-link flex items-center"
|
||||||
x-bind:class="darkMode
|
x-bind:class="darkMode
|
||||||
? 'bg-gradient-to-r from-purple-900/90 to-indigo-800/90 text-white font-medium px-4 py-2 rounded-xl hover:shadow-lg hover:shadow-purple-800/30 transition-all duration-300'
|
? 'bg-gradient-to-r from-purple-900/90 to-indigo-800/90 text-white font-medium px-4 py-2 rounded-xl hover:shadow-lg hover:shadow-purple-800/30 transition-all duration-300'
|
||||||
: 'bg-gradient-to-r from-purple-600/30 to-indigo-500/30 text-gray-800 font-medium px-4 py-2 rounded-xl hover:shadow-md transition-all duration-300'">
|
: 'bg-gradient-to-r from-purple-600 to-indigo-500 text-white font-medium px-4 py-2 rounded-xl hover:shadow-md transition-all duration-300'">
|
||||||
<i class="fa-solid fa-robot mr-2"></i>KI-Chat
|
<i class="fa-solid fa-robot mr-2"></i>KI-Chat
|
||||||
</button>
|
</button>
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
@@ -467,7 +467,7 @@
|
|||||||
class="block w-full text-left py-3.5 px-4 rounded-xl transition-all duration-200 flex items-center"
|
class="block w-full text-left py-3.5 px-4 rounded-xl transition-all duration-200 flex items-center"
|
||||||
x-bind:class="darkMode
|
x-bind:class="darkMode
|
||||||
? 'bg-gradient-to-r from-purple-600/30 to-blue-500/30 text-white hover:from-purple-600/40 hover:to-blue-500/40'
|
? 'bg-gradient-to-r from-purple-600/30 to-blue-500/30 text-white hover:from-purple-600/40 hover:to-blue-500/40'
|
||||||
: 'bg-gradient-to-r from-purple-500/10 to-blue-400/10 text-gray-900 hover:from-purple-500/20 hover:to-blue-400/20'">
|
: 'bg-gradient-to-r from-purple-600 to-blue-500 text-white hover:from-purple-600/90 hover:to-blue-500/90'">
|
||||||
<i class="fa-solid fa-robot w-5 mr-3"></i>KI-Chat
|
<i class="fa-solid fa-robot w-5 mr-3"></i>KI-Chat
|
||||||
</button>
|
</button>
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
|
|||||||
Reference in New Issue
Block a user