| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| <title>Chat UI with Per‑Session Summary, Settings & History</title> |
| <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500&display=swap" rel="stylesheet"> |
| |
| <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> |
| <style> |
| |
| * { box-sizing: border-box; } |
| body { |
| margin: 0; |
| padding: 0; |
| font-family: 'Poppins', sans-serif; |
| background: #e0e0e0; |
| overflow: hidden; |
| } |
| |
| .app-container { |
| display: flex; |
| width: 100vw; |
| height: 100vh; |
| transition: all 0.3s ease; |
| } |
| |
| .nav-bar { |
| width: 300px; |
| background: #ffffff; |
| padding: 20px; |
| box-shadow: 2px 0 12px rgba(0,0,0,0.1); |
| overflow-y: auto; |
| transition: width 0.3s ease, padding 0.3s ease; |
| } |
| .nav-bar.hidden { |
| display: none; |
| } |
| .nav-bar h3 { |
| margin-top: 0; |
| font-size: 1.3em; |
| } |
| .nav-bar ul { |
| list-style: none; |
| padding: 0; |
| margin: 0; |
| } |
| .nav-bar li { |
| padding: 10px; |
| margin-bottom: 10px; |
| background: #fff; |
| border-radius: 8px; |
| cursor: pointer; |
| display: flex; |
| align-items: center; |
| justify-content: space-between; |
| transition: background 0.3s; |
| font-size: 1.1em; |
| } |
| .nav-bar li.active, |
| .nav-bar li:hover { |
| background: #667eea; |
| color: #fff; |
| } |
| .session-actions { |
| display: inline-flex; |
| gap: 5px; |
| margin-left: 10px; |
| } |
| .session-summary-btn, |
| .session-settings-btn { |
| background: transparent; |
| border: none; |
| cursor: pointer; |
| font-size: 1.2em; |
| } |
| .session-summary-btn:hover, |
| .session-settings-btn:hover { |
| color: #667eea; |
| } |
| .nav-bar li button.remove-session { |
| background: transparent; |
| border: none; |
| color: inherit; |
| font-size: 1em; |
| cursor: pointer; |
| margin-left: auto; |
| } |
| .new-session-btn { |
| width: 100%; |
| padding: 10px; |
| background: #667eea; |
| color: #fff; |
| border: none; |
| border-radius: 8px; |
| cursor: pointer; |
| font-size: 1.1em; |
| margin-top: 10px; |
| } |
| |
| .chat-wrapper { |
| flex: 1; |
| background: #fff; |
| margin: 20px; |
| border-radius: 20px; |
| box-shadow: 0 12px 40px rgba(0,0,0,0.15); |
| display: flex; |
| flex-direction: column; |
| overflow: hidden; |
| position: relative; |
| transition: width 0.3s ease; |
| } |
| |
| #hamburgerBtn { |
| position: absolute; |
| top: 20px; |
| left: 20px; |
| background: #667eea; |
| color: #fff; |
| border: none; |
| padding: 10px; |
| font-size: 1.4em; |
| border-radius: 4px; |
| cursor: pointer; |
| z-index: 20; |
| } |
| |
| #turnLabel { |
| position: absolute; |
| top: 20px; |
| right: 20px; |
| background: #ff9800; |
| color: #fff; |
| padding: 5px 10px; |
| border-radius: 10px; |
| font-size: 1em; |
| z-index: 15; |
| } |
| |
| .carousel-wrapper { |
| position: relative; |
| flex: 1; |
| background: #F9FBFD; |
| overflow: hidden; |
| margin-top: 80px; |
| } |
| .carousel { |
| display: flex; |
| height: 100%; |
| transition: transform 0.5s ease; |
| } |
| .card { |
| min-width: 100%; |
| height: 100%; |
| padding: 90px 30px 30px 30px; |
| display: flex; |
| flex-direction: column; |
| overflow-y: auto; |
| } |
| .conversation { |
| display: flex; |
| flex-direction: column; |
| gap: 15px; |
| } |
| |
| .message { |
| padding: 10px 16px; |
| border-radius: 16px; |
| font-size: 1em; |
| line-height: 1.5; |
| max-width: 95%; |
| position: relative; |
| box-shadow: 0 2px 8px rgba(0,0,0,0.07); |
| transition: background 0.3s, transform 0.3s; |
| } |
| .user { background: #F0F4FF; border: 1px solid #D9E2FF; align-self: flex-start; } |
| .ai { background: #FFF4E6; border: 1px solid #FFE0B2; align-self: flex-end; } |
| .message-text { |
| display: block; |
| max-height: 80px; |
| overflow: hidden; |
| transition: max-height 0.3s ease; |
| } |
| .message.expanded .message-text { max-height: none; } |
| .toggle-btn { |
| background: none; |
| border: none; |
| color: #667eea; |
| cursor: pointer; |
| font-size: 0.85em; |
| margin-top: 4px; |
| padding: 0; |
| } |
| .vertical-file-list { |
| margin-bottom: 10px; |
| display: flex; |
| flex-direction: column; |
| gap: 5px; |
| } |
| .file-item-vertical { |
| background: #eaeaea; |
| padding: 5px 8px; |
| border-radius: 4px; |
| font-size: 0.9em; |
| } |
| |
| .nav { |
| position: absolute; |
| top: 50%; |
| transform: translateY(-50%); |
| width: 50px; |
| height: 50px; |
| background: rgba(255,255,255,0.5); |
| backdrop-filter: blur(4px); |
| border: none; |
| border-radius: 50%; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| cursor: pointer; |
| z-index: 10; |
| transition: transform 0.3s, background 0.3s; |
| } |
| .nav:hover { transform: translateY(-50%) scale(1.1); background: rgba(255,255,255,0.8); } |
| .nav:disabled { opacity: 0.5; cursor: default; } |
| #prevBtn { left: 15px; } |
| #nextBtn { right: 15px; } |
| |
| .input-container { |
| padding: 20px; |
| background: #FAFAFA; |
| border-top: 1px solid #EEE; |
| display: flex; |
| flex-direction: column; |
| } |
| .file-attachments { |
| display: flex; |
| gap: 10px; |
| overflow-x: auto; |
| padding-bottom: 10px; |
| scrollbar-width: thin; |
| } |
| .file-item { |
| flex: 0 0 auto; |
| background: #eee; |
| padding: 5px 10px; |
| border-radius: 5px; |
| display: flex; |
| align-items: center; |
| gap: 5px; |
| font-size: 0.9em; |
| } |
| .file-item button { |
| background: none; |
| border: none; |
| color: #667eea; |
| cursor: pointer; |
| font-size: 1em; |
| } |
| .input-row { |
| display: flex; |
| align-items: center; |
| gap: 10px; |
| } |
| .attach-button { |
| background: #fff; |
| border: 1px solid #DDD; |
| border-radius: 4px; |
| padding: 8px 12px; |
| cursor: pointer; |
| transition: background 0.3s; |
| } |
| .attach-button:hover { background: #f0f0f0; } |
| .input-container textarea { |
| flex: 1; |
| padding: 12px 15px; |
| font-size: 1em; |
| border: 1px solid #DDD; |
| border-radius: 8px; |
| outline: none; |
| resize: none; |
| overflow-y: auto; |
| min-height: 36px; |
| max-height: 150px; |
| line-height: 1.4em; |
| white-space: pre-wrap; |
| transition: border-color 0.3s; |
| } |
| .input-container textarea:focus { border-color: #667eea; } |
| .input-container button { |
| padding: 12px 20px; |
| font-size: 1em; |
| background: #667eea; |
| color: #fff; |
| border: none; |
| border-radius: 8px; |
| cursor: pointer; |
| transition: background 0.3s; |
| } |
| .input-container button:hover { background: #556cd6; } |
| #fileInput { display: none; } |
| |
| #summaryOverlay { |
| position: fixed; |
| top: 0; |
| right: 0; |
| bottom: 0; |
| width: 60%; |
| background: #fff; |
| box-shadow: -4px 0 12px rgba(0,0,0,0.15); |
| transform: translateX(100%); |
| transition: transform 0.3s ease; |
| z-index: 20; |
| display: flex; |
| flex-direction: column; |
| } |
| #summaryOverlay.active { transform: translateX(0); } |
| .summary-header { |
| padding: 16px; |
| background: #667eea; |
| color: #fff; |
| font-size: 1.2em; |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| } |
| .summary-header-buttons { |
| display: flex; |
| gap: 10px; |
| } |
| .download-summary { |
| background: #fff; |
| color: #667eea; |
| border: 1px solid #667eea; |
| border-radius: 4px; |
| padding: 4px 8px; |
| cursor: pointer; |
| } |
| .download-summary:hover { background: #667eea; color: #fff; } |
| .close-summary { |
| background: none; |
| border: none; |
| color: #fff; |
| font-size: 1.2em; |
| cursor: pointer; |
| } |
| .summary-content { |
| padding: 16px; |
| overflow-y: auto; |
| flex: 1; |
| } |
| |
| #settingsOverlay { |
| position: fixed; |
| top: 0; |
| right: 0; |
| bottom: 0; |
| width: 40%; |
| background: #fff; |
| box-shadow: -4px 0 12px rgba(0,0,0,0.15); |
| transform: translateX(100%); |
| transition: transform 0.3s ease; |
| z-index: 20; |
| display: flex; |
| flex-direction: column; |
| } |
| #settingsOverlay.active { transform: translateX(0); } |
| .settings-header { |
| padding: 16px; |
| background: #667eea; |
| color: #fff; |
| font-size: 1.4em; |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| } |
| .close-settings { |
| background: none; |
| border: none; |
| color: #fff; |
| font-size: 1.4em; |
| cursor: pointer; |
| } |
| .settings-content { |
| padding: 16px; |
| overflow-y: auto; |
| flex: 1; |
| font-size: 1.1em; |
| line-height: 1.4; |
| } |
| .settings-group { |
| margin-bottom: 16px; |
| display: flex; |
| align-items: center; |
| gap: 10px; |
| } |
| .settings-group label { |
| min-width: 100px; |
| } |
| .save-settings { |
| background: #667eea; |
| color: #fff; |
| border: none; |
| border-radius: 8px; |
| padding: 10px 20px; |
| cursor: pointer; |
| } |
| .save-settings:hover { background: #556cd6; } |
| |
| @media (max-width: 600px) { |
| .nav-bar { display: none; } |
| .chat-wrapper { margin: 0; } |
| .message { font-size: 0.95em; max-width: 80%; } |
| .nav { width: 40px; height: 40px; font-size: 1.5em; } |
| .card { padding: 90px 20px 20px 20px; } |
| .input-container { padding: 15px; } |
| .input-row { flex-direction: column; gap: 10px; } |
| .input-container button { width: 100%; } |
| #summaryOverlay, #settingsOverlay { width: 80%; } |
| } |
| </style> |
| </head> |
| <body> |
| <div class="app-container"> |
| |
| <div class="nav-bar" id="navBar"> |
| <h3>Chat History</h3> |
| <ul id="sessionList"></ul> |
| <button class="new-session-btn" id="newSessionBtn">New Chat</button> |
| </div> |
| |
| <div class="chat-wrapper"> |
| |
| <button id="hamburgerBtn">☰</button> |
| |
| <div id="turnLabel">Turn: 0/0</div> |
| <div class="carousel-wrapper"> |
| <button id="prevBtn" class="nav"> |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| <polyline points="15 18 9 12 15 6"></polyline> |
| </svg> |
| </button> |
| <div class="carousel" id="carousel"> |
| |
| </div> |
| <button id="nextBtn" class="nav"> |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#444" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> |
| <polyline points="9 18 15 12 9 6"></polyline> |
| </svg> |
| </button> |
| </div> |
| |
| <div class="input-container"> |
| <div id="fileAttachments" class="file-attachments"></div> |
| <div class="input-row"> |
| <button id="attachBtn" class="attach-button">Attach File</button> |
| <input type="file" id="fileInput" multiple accept="image/*,.pdf"> |
| <textarea id="chatInput" placeholder="Type your message..."></textarea> |
| <button id="sendBtn">Send</button> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="summaryOverlay"> |
| <div class="summary-header"> |
| <span>Chat Summary</span> |
| <div class="summary-header-buttons"> |
| <button id="downloadSummary" class="download-summary">Download</button> |
| <button class="close-summary" id="closeSummaryBtn">×</button> |
| </div> |
| </div> |
| <div class="summary-content" id="summaryContent"> |
| |
| </div> |
| </div> |
|
|
| |
| <div id="settingsOverlay"> |
| <div class="settings-header"> |
| <span>Settings</span> |
| <button class="close-settings" id="closeSettingsBtn">×</button> |
| </div> |
| <div class="settings-content"> |
| <form id="settingsForm"> |
| <div class="settings-group"> |
| <label for="temperature">Temperature:</label> |
| <input type="range" id="temperature" name="temperature" min="0" max="1" step="0.01"> |
| <span id="temperatureValue"></span> |
| </div> |
| <div class="settings-group"> |
| <label for="maxTokens">Max Tokens:</label> |
| <input type="number" id="maxTokens" name="maxTokens" min="10" max="2048"> |
| </div> |
| <div class="settings-group"> |
| <label for="persona">Persona:</label> |
| <select id="persona" name="persona"> |
| <option value="professional">Professional</option> |
| <option value="friendly">Friendly</option> |
| </select> |
| </div> |
| <button type="button" id="saveSettings" class="save-settings">Save Settings</button> |
| </form> |
| </div> |
| </div> |
|
|
| <script> |
| |
| let sessions = []; |
| let currentSessionIndex = 0; |
| let currentCardIndex = 0; |
| |
| |
| function initSessions() { |
| sessions.push({ |
| id: Date.now(), |
| name: "Chat Session 1", |
| messages: [], |
| summary: "# Chat Summary\n\nThis is the default summary for Chat Session 1.", |
| settings: { temperature: 0.7, maxTokens: 256, persona: "professional" } |
| }); |
| currentSessionIndex = 0; |
| currentCardIndex = 0; |
| renderSessionList(); |
| renderCurrentSession(); |
| } |
| |
| |
| function renderSessionList() { |
| const sessionList = document.getElementById('sessionList'); |
| sessionList.innerHTML = ""; |
| sessions.forEach((session, index) => { |
| const li = document.createElement('li'); |
| |
| |
| const nameSpan = document.createElement('span'); |
| nameSpan.textContent = session.name; |
| li.appendChild(nameSpan); |
| |
| |
| const actionsDiv = document.createElement('div'); |
| actionsDiv.className = "session-actions"; |
| |
| const summaryBtn = document.createElement('button'); |
| summaryBtn.className = "session-summary-btn"; |
| summaryBtn.innerHTML = "📄"; |
| summaryBtn.addEventListener('click', (e) => { |
| e.stopPropagation(); |
| currentSessionIndex = index; |
| renderSessionList(); |
| renderCurrentSession(); |
| |
| document.getElementById('summaryContent').innerHTML = marked.parse(sessions[currentSessionIndex].summary); |
| summaryOverlay.classList.add('active'); |
| settingsOverlay.classList.remove('active'); |
| }); |
| actionsDiv.appendChild(summaryBtn); |
| |
| const settingsBtn = document.createElement('button'); |
| settingsBtn.className = "session-settings-btn"; |
| settingsBtn.innerHTML = "⚙"; |
| settingsBtn.addEventListener('click', (e) => { |
| e.stopPropagation(); |
| currentSessionIndex = index; |
| renderSessionList(); |
| renderCurrentSession(); |
| |
| const settings = sessions[currentSessionIndex].settings; |
| temperatureInput.value = settings.temperature; |
| temperatureValue.textContent = settings.temperature; |
| maxTokensInput.value = settings.maxTokens; |
| personaSelect.value = settings.persona; |
| settingsOverlay.classList.add('active'); |
| summaryOverlay.classList.remove('active'); |
| }); |
| actionsDiv.appendChild(settingsBtn); |
| |
| li.appendChild(actionsDiv); |
| |
| |
| const removeBtn = document.createElement('button'); |
| removeBtn.textContent = "×"; |
| removeBtn.className = "remove-session"; |
| removeBtn.addEventListener('click', (e) => { |
| e.stopPropagation(); |
| removeSession(index); |
| }); |
| li.appendChild(removeBtn); |
| |
| li.addEventListener('click', () => { |
| currentSessionIndex = index; |
| currentCardIndex = 0; |
| renderSessionList(); |
| renderCurrentSession(); |
| }); |
| if (index === currentSessionIndex) li.classList.add('active'); |
| sessionList.appendChild(li); |
| }); |
| } |
| |
| |
| document.getElementById('newSessionBtn').addEventListener('click', () => { |
| const newSession = { |
| id: Date.now(), |
| name: "Chat Session " + (sessions.length + 1), |
| messages: [], |
| summary: "# Chat Summary\n\nThis is the default summary for Chat Session " + (sessions.length + 1) + ".", |
| settings: { temperature: 0.7, maxTokens: 256, persona: "professional" } |
| }; |
| sessions.push(newSession); |
| currentSessionIndex = sessions.length - 1; |
| currentCardIndex = 0; |
| renderSessionList(); |
| renderCurrentSession(); |
| }); |
| |
| |
| function removeSession(index) { |
| sessions.splice(index, 1); |
| if (sessions.length === 0) { |
| initSessions(); |
| } else { |
| if (currentSessionIndex >= sessions.length) { |
| currentSessionIndex = sessions.length - 1; |
| } |
| currentCardIndex = 0; |
| } |
| renderSessionList(); |
| renderCurrentSession(); |
| } |
| |
| |
| const carousel = document.getElementById('carousel'); |
| function renderCurrentSession() { |
| const session = sessions[currentSessionIndex]; |
| carousel.innerHTML = ""; |
| session.messages.forEach(message => { |
| const card = document.createElement('div'); |
| card.className = 'card'; |
| let attachmentHTML = ""; |
| if (message.attachments && message.attachments.length > 0) { |
| attachmentHTML = `<div class="vertical-file-list">` + |
| message.attachments.map(name => `<div class="file-item-vertical">${name}</div>`).join("") + |
| `</div>`; |
| } |
| card.innerHTML = ` |
| <div class="conversation"> |
| <div class="message user"> |
| ${attachmentHTML} |
| <span class="message-text">User: ${message.userText}</span> |
| </div> |
| <div class="message ai"> |
| <span class="message-text">AI: ${message.aiResponse}</span> |
| </div> |
| </div> |
| `; |
| carousel.appendChild(card); |
| processMessagesInContainer(card); |
| }); |
| currentCardIndex = session.messages.length > 0 ? session.messages.length - 1 : 0; |
| updateCarousel(); |
| } |
| |
| function updateCarousel() { |
| const cards = document.querySelectorAll('.card'); |
| carousel.style.transform = `translateX(-${currentCardIndex * 100}%)`; |
| prevBtn.disabled = currentCardIndex === 0; |
| nextBtn.disabled = currentCardIndex === cards.length - 1 || cards.length === 0; |
| updateTurnLabel(cards.length); |
| } |
| |
| function updateTurnLabel(totalCards) { |
| const turnLabel = document.getElementById('turnLabel'); |
| turnLabel.textContent = `Turn: ${totalCards ? currentCardIndex + 1 + "/" + totalCards : "0/0"}`; |
| } |
| |
| |
| function processMessage(messageEl) { |
| if (messageEl.dataset.processed) return; |
| const textEl = messageEl.querySelector('.message-text'); |
| if (textEl.scrollHeight > 80) { |
| const toggleBtn = document.createElement('button'); |
| toggleBtn.className = 'toggle-btn'; |
| toggleBtn.textContent = 'Read more'; |
| toggleBtn.addEventListener('click', function() { |
| if (messageEl.classList.contains('expanded')) { |
| messageEl.classList.remove('expanded'); |
| toggleBtn.textContent = 'Read more'; |
| } else { |
| messageEl.classList.add('expanded'); |
| toggleBtn.textContent = 'Read less'; |
| } |
| }); |
| messageEl.appendChild(toggleBtn); |
| } |
| messageEl.dataset.processed = 'true'; |
| } |
| function processMessagesInContainer(container) { |
| container.querySelectorAll('.message').forEach(processMessage); |
| } |
| |
| |
| const attachedFiles = []; |
| function addConversation(userText, aiResponse) { |
| const attachmentNames = attachedFiles.map(file => file.name); |
| const message = { |
| userText, |
| aiResponse, |
| attachments: attachmentNames |
| }; |
| sessions[currentSessionIndex].messages.push(message); |
| clearFileAttachments(); |
| renderCurrentSession(); |
| } |
| function clearFileAttachments() { |
| attachedFiles.length = 0; |
| updateFileAttachments(); |
| } |
| |
| |
| const sendBtn = document.getElementById('sendBtn'); |
| const chatInput = document.getElementById('chatInput'); |
| sendBtn.addEventListener('click', () => { |
| const text = chatInput.value; |
| if (text.trim() !== '') { |
| const aiResponse = "I'm here to help!"; |
| addConversation(text, aiResponse); |
| chatInput.value = ''; |
| chatInput.style.height = "36px"; |
| } |
| }); |
| chatInput.addEventListener('keydown', function(e) { |
| if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { |
| e.preventDefault(); |
| sendBtn.click(); |
| } |
| }); |
| const prevBtn = document.getElementById('prevBtn'); |
| const nextBtn = document.getElementById('nextBtn'); |
| prevBtn.addEventListener('click', () => { |
| if (currentCardIndex > 0) { currentCardIndex--; updateCarousel(); } |
| }); |
| nextBtn.addEventListener('click', () => { |
| const cards = document.querySelectorAll('.card'); |
| if (currentCardIndex < cards.length - 1) { currentCardIndex++; updateCarousel(); } |
| }); |
| |
| const attachBtn = document.getElementById('attachBtn'); |
| const fileInput = document.getElementById('fileInput'); |
| const fileAttachments = document.getElementById('fileAttachments'); |
| attachBtn.addEventListener('click', () => { fileInput.click(); }); |
| fileInput.addEventListener('change', () => { |
| for (const file of fileInput.files) { attachedFiles.push(file); } |
| fileInput.value = ""; |
| updateFileAttachments(); |
| }); |
| function updateFileAttachments() { |
| fileAttachments.innerHTML = ""; |
| attachedFiles.forEach((file, index) => { |
| const fileDiv = document.createElement("div"); |
| fileDiv.className = "file-item"; |
| fileDiv.innerHTML = `<span>${file.name}</span> <button data-index="${index}">×</button>`; |
| fileAttachments.appendChild(fileDiv); |
| }); |
| document.querySelectorAll(".file-item button").forEach(btn => { |
| btn.addEventListener("click", (e) => { |
| const idx = e.target.getAttribute("data-index"); |
| attachedFiles.splice(idx, 1); |
| updateFileAttachments(); |
| }); |
| }); |
| } |
| |
| |
| const summaryOverlay = document.getElementById('summaryOverlay'); |
| const closeSummaryBtn = document.getElementById('closeSummaryBtn'); |
| const summaryContent = document.getElementById('summaryContent'); |
| const downloadSummaryBtn = document.getElementById('downloadSummary'); |
| |
| closeSummaryBtn.addEventListener('click', () => { summaryOverlay.classList.remove('active'); }); |
| downloadSummaryBtn.addEventListener('click', () => { |
| const blob = new Blob([sessions[currentSessionIndex].summary], { type: "text/markdown" }); |
| const url = URL.createObjectURL(blob); |
| const a = document.createElement("a"); |
| a.href = url; |
| a.download = "summary.md"; |
| a.click(); |
| URL.revokeObjectURL(url); |
| }); |
| |
| |
| const settingsOverlay = document.getElementById('settingsOverlay'); |
| const closeSettingsBtn = document.getElementById('closeSettingsBtn'); |
| const temperatureInput = document.getElementById('temperature'); |
| const temperatureValue = document.getElementById('temperatureValue'); |
| const maxTokensInput = document.getElementById('maxTokens'); |
| const personaSelect = document.getElementById('persona'); |
| const saveSettingsBtn = document.getElementById('saveSettings'); |
| |
| closeSettingsBtn.addEventListener('click', () => { settingsOverlay.classList.remove('active'); }); |
| temperatureInput.addEventListener('input', () => { |
| temperatureValue.textContent = temperatureInput.value; |
| }); |
| saveSettingsBtn.addEventListener('click', () => { |
| sessions[currentSessionIndex].settings = { |
| temperature: parseFloat(temperatureInput.value), |
| maxTokens: parseInt(maxTokensInput.value), |
| persona: personaSelect.value |
| }; |
| console.log('Session settings saved:', sessions[currentSessionIndex].settings); |
| settingsOverlay.classList.remove('active'); |
| }); |
| |
| |
| document.addEventListener('click', (e) => { |
| if (summaryOverlay.classList.contains('active') && |
| !summaryOverlay.contains(e.target)) { |
| summaryOverlay.classList.remove('active'); |
| } |
| if (settingsOverlay.classList.contains('active') && |
| !settingsOverlay.contains(e.target)) { |
| settingsOverlay.classList.remove('active'); |
| } |
| }); |
| |
| |
| document.addEventListener('keydown', (e) => { |
| if (document.activeElement !== chatInput) { |
| if (e.key === 'ArrowLeft' && currentCardIndex > 0) { |
| currentCardIndex--; |
| updateCarousel(); |
| } else if (e.key === 'ArrowRight') { |
| const cards = document.querySelectorAll('.card'); |
| if (currentCardIndex < cards.length - 1) { |
| currentCardIndex++; |
| updateCarousel(); |
| } |
| } |
| } |
| }); |
| |
| |
| const hamburgerBtn = document.getElementById('hamburgerBtn'); |
| const navBar = document.getElementById('navBar'); |
| hamburgerBtn.addEventListener('click', (e) => { |
| e.stopPropagation(); |
| if (navBar.classList.contains('hidden')) { |
| navBar.classList.remove('hidden'); |
| } else { |
| navBar.classList.add('hidden'); |
| } |
| }); |
| |
| |
| initSessions(); |
| </script> |
| </body> |
| </html> |
|
|