diff options
-rw-r--r-- | html/matt-chat/index.html | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/html/matt-chat/index.html b/html/matt-chat/index.html new file mode 100644 index 0000000..2160c58 --- /dev/null +++ b/html/matt-chat/index.html @@ -0,0 +1,188 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Ollama chat</title> + <style> + body { + font-family: Arial, sans-serif; + margin: 0; + padding: 20px; + background-color: #f7f7f7; + } + #chat-container { + background-color: white; + border: 1px solid #ccc; + border-radius: 8px; + padding: 20px; + max-width: 600px; + margin: 0 auto; + height: 400px; + overflow-y: auto; + } + #user-input { + width: calc(100% - 20px); + padding: 10px; + border-radius: 4px; + border: 1px solid #ddd; + font-size: 16px; + margin-top: 10px; + } + #send-button { + padding: 10px 15px; + border-radius: 4px; + background-color: #007BFF; + color: white; + border: none; + cursor: pointer; + margin-top: 10px; + } + #send-button:hover { + background-color: #0056b3; + } + .message { + white-space: pre-wrap; + margin-bottom: 10px; + padding: 10px; + border-radius: 8px; + background-color: #f1f1f1; + max-width: 80%; + } + .user-message { + background-color: #007BFF; + color: white; + text-align: right; + margin-right: 20px; + } + .bot-message { + background-color: #f0f0f0; + color: #333; + margin-left: 20px; + } + </style> +</head> +<body> + + <div id="chat-container"> + <!-- Messages will appear here --> + </div> + + <label for="model-select">Select Model:</label> + <select id="model-select"> + <option value="llama3.1:8b">llama3.1:8b</option> + <option value="qwen2.5-coder:1.5b">qwen2.5-coder:1.5b</option> + <option value="qwen2.5-coder:7b">qwen2.5-coder:7b</option> + </select> + + <textarea id="user-input" placeholder="Type your message..."></textarea> + <button id="send-button">Send</button> + + <script> + // Function to add a message to the chat container + function addMessage(message, sender = "user") { + const chatContainer = document.getElementById("chat-container"); + const messageElement = document.createElement("div"); + messageElement.classList.add("message", sender === "user" ? "user-message" : "bot-message"); + messageElement.textContent = message; + chatContainer.appendChild(messageElement); + chatContainer.scrollTop = chatContainer.scrollHeight; // Auto-scroll to the bottom + } + + // Function to handle sending the message + async function sendMessage() { + const userInput = document.getElementById("user-input"); + const userMessage = userInput.value.trim(); + + if (!userMessage) return; + + addMessage(userMessage, "user"); + userInput.value = ""; + + // Create and add loading indicator + const loadingIndicator = document.createElement("div"); + loadingIndicator.id = "loading-indicator"; + loadingIndicator.classList.add("message", "bot-message"); + loadingIndicator.textContent = "..."; + document.getElementById("chat-container").appendChild(loadingIndicator); + + // Start animation for this specific indicator + const animationInterval = animateLoadingIndicator(loadingIndicator); + + try { + const modelSelect = document.getElementById("model-select"); + const selectedModel = modelSelect.value; + + const response = await fetch("http://localhost:11434/v1/chat/completions", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + model: selectedModel, + messages: [{ role: "user", content: userMessage }], + }), + }); + + if (!response.ok) { + throw new Error('Error communicating with Ollama API'); + } + + // Handle the response + const data = await response.json(); + const botResponse = data.choices[0].message.content; + + // Clear loading indicator + clearInterval(animationInterval); + loadingIndicator.remove(); + + // Add bot's response to chat + addMessage(botResponse, "bot"); + + } catch (error) { + console.error("Error:", error); + clearInterval(animationInterval); + loadingIndicator.remove(); + addMessage("Sorry, there was an error processing your request.", "bot"); + } + } + + document.addEventListener("DOMContentLoaded", () => { + const modelSelect = document.getElementById("model-select"); + + // Load the saved model from local storage + const savedModel = localStorage.getItem("selectedModel"); + if (savedModel) { + modelSelect.value = savedModel; + } + + // Save the selected model to local storage when changed + modelSelect.addEventListener("change", () => { + localStorage.setItem("selectedModel", modelSelect.value); + }); + }); + + // Function to animate the loading indicator + function animateLoadingIndicator(indicator) { + let dots = 0; + return setInterval(() => { + dots = (dots + 1) % 4; + if (indicator && document.contains(indicator)) { + indicator.textContent = '.'.repeat(dots || 1); + } + }, 500); + } + + // Event listener for the "Send" button + document.getElementById("send-button").addEventListener("click", sendMessage); + + // Optional: Allow pressing Enter to send the message + document.getElementById("user-input").addEventListener("keypress", function (e) { + if (e.key === "Enter") { + e.preventDefault(); // Prevent line break + sendMessage(); + } + }); + </script> +</body> +</html> |