diff --git a/assets/pasted-20251125-161909-096e4e24.png b/assets/pasted-20251125-161909-096e4e24.png new file mode 100644 index 0000000..430fe42 Binary files /dev/null and b/assets/pasted-20251125-161909-096e4e24.png differ diff --git a/static/css/custom.css b/static/css/custom.css index 189b1b0..1ab544b 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -181,3 +181,30 @@ body { .song-artist { color: #B3B3B3; } + +.typing-indicator span { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + background-color: #B3B3B3; + margin: 0 2px; + animation: typing 1s infinite; +} + +.typing-indicator span:nth-child(2) { + animation-delay: 0.2s; +} + +.typing-indicator span:nth-child(3) { + animation-delay: 0.4s; +} + +@keyframes typing { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-5px); + } +} diff --git a/static/js/chat.js b/static/js/chat.js index b5f9315..6cf19a2 100644 --- a/static/js/chat.js +++ b/static/js/chat.js @@ -16,6 +16,7 @@ document.addEventListener('DOMContentLoaded', function() { // Add user message to chat box appendMessage(userMessage, 'user-message'); chatInput.value = ''; + showTypingIndicator(); fetch(window.location.href, { method: 'POST', @@ -30,6 +31,7 @@ document.addEventListener('DOMContentLoaded', function() { }) .then(response => response.json()) .then(data => { + removeTypingIndicator(); // Add AI message to chat box appendMessage(data.ai_message, 'ai-message'); @@ -40,6 +42,7 @@ document.addEventListener('DOMContentLoaded', function() { }) .catch(error => { console.error('Error:', error); + removeTypingIndicator(); appendMessage('Sorry, something went wrong.', 'ai-message'); }); }); @@ -54,6 +57,21 @@ document.addEventListener('DOMContentLoaded', function() { chatBox.scrollTop = chatBox.scrollHeight; // Scroll to bottom } + function showTypingIndicator() { + const typingIndicator = document.createElement('div'); + typingIndicator.classList.add('chat-message', 'ai-message', 'typing-indicator'); + typingIndicator.innerHTML = '
...
'; + chatBox.appendChild(typingIndicator); + chatBox.scrollTop = chatBox.scrollHeight; + } + + function removeTypingIndicator() { + const typingIndicator = document.querySelector('.typing-indicator'); + if (typingIndicator) { + typingIndicator.remove(); + } + } + function displayPlaylist(playlist) { let playlistContainer = document.querySelector('.playlist-container'); if (!playlistContainer) { diff --git a/staticfiles/css/custom.css b/staticfiles/css/custom.css index 189b1b0..1ab544b 100644 --- a/staticfiles/css/custom.css +++ b/staticfiles/css/custom.css @@ -181,3 +181,30 @@ body { .song-artist { color: #B3B3B3; } + +.typing-indicator span { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + background-color: #B3B3B3; + margin: 0 2px; + animation: typing 1s infinite; +} + +.typing-indicator span:nth-child(2) { + animation-delay: 0.2s; +} + +.typing-indicator span:nth-child(3) { + animation-delay: 0.4s; +} + +@keyframes typing { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-5px); + } +} diff --git a/staticfiles/js/chat.js b/staticfiles/js/chat.js index b5f9315..6cf19a2 100644 --- a/staticfiles/js/chat.js +++ b/staticfiles/js/chat.js @@ -16,6 +16,7 @@ document.addEventListener('DOMContentLoaded', function() { // Add user message to chat box appendMessage(userMessage, 'user-message'); chatInput.value = ''; + showTypingIndicator(); fetch(window.location.href, { method: 'POST', @@ -30,6 +31,7 @@ document.addEventListener('DOMContentLoaded', function() { }) .then(response => response.json()) .then(data => { + removeTypingIndicator(); // Add AI message to chat box appendMessage(data.ai_message, 'ai-message'); @@ -40,6 +42,7 @@ document.addEventListener('DOMContentLoaded', function() { }) .catch(error => { console.error('Error:', error); + removeTypingIndicator(); appendMessage('Sorry, something went wrong.', 'ai-message'); }); }); @@ -54,6 +57,21 @@ document.addEventListener('DOMContentLoaded', function() { chatBox.scrollTop = chatBox.scrollHeight; // Scroll to bottom } + function showTypingIndicator() { + const typingIndicator = document.createElement('div'); + typingIndicator.classList.add('chat-message', 'ai-message', 'typing-indicator'); + typingIndicator.innerHTML = '...
'; + chatBox.appendChild(typingIndicator); + chatBox.scrollTop = chatBox.scrollHeight; + } + + function removeTypingIndicator() { + const typingIndicator = document.querySelector('.typing-indicator'); + if (typingIndicator) { + typingIndicator.remove(); + } + } + function displayPlaylist(playlist) { let playlistContainer = document.querySelector('.playlist-container'); if (!playlistContainer) {