Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 84 additions & 74 deletions views/mainPages/chatbot.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.15/codemirror.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.15/theme/monokai.min.css">
<script src="/Assets/Scripts/main.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/styles/monokai.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min.js"></script>
<script src="/Assets/Scripts/logout.js"></script>
<style>
:root {
Expand Down Expand Up @@ -414,22 +416,6 @@
font-style: italic;
}

pre {
font-family: Consolas;
position: relative;
border: .1rem solid var(--main-border-color);
background: #000;
padding: 1em;
border-radius: 5px;
overflow-x: auto;
line-height: 1;
margin: 10px 0;
}

pre code {
font-family: 'Courier New', monospace;
color: var(--text-light);
}

.code-copy-button {
position: absolute;
Expand Down Expand Up @@ -529,21 +515,25 @@
}

.message-bubble code {
background-color: #383838;
border-radius: 2px;
padding: 1px;
padding: .2em .4em;
margin: 0;
font-size: 85%;
white-space: break-spaces;
background-color: #656c7633;
border-radius: 6px;
}

.message-bubble pre code {
background-color: transparent;
border-radius: 0;
padding: 0;
font-size: 100%;
}

.message-bubble pre{
.message-bubble pre {
color: white;
}


.chat-header-title span,
.chat-header-title span a,
Expand All @@ -560,7 +550,7 @@
height: 30px;
background: linear-gradient(145deg, #3d444d, #0d1117);
border-radius: 50%;
display: none;
display: none;
color: white;
align-items: center;
justify-content: center;
Expand Down Expand Up @@ -722,7 +712,7 @@
.light-theme .chat-list-item:hover,
.sepia-theme .chat-list-item:hover,
.contrast-theme .chat-list-item:hover {
border-color:#007bff;
border-color: #007bff;
}

.chat-list-item button {
Expand Down Expand Up @@ -1187,6 +1177,16 @@
opacity: 1;
}

pre {
font-family: 'Courier New', monospace;
font-size: 14px;
line-height: 1.5;
background-color: #2d2d2d;
color: #f8f8f2;
padding: 10px;
border-radius: 5px;
overflow-x: auto;
}
</style>
</head>

Expand Down Expand Up @@ -1364,6 +1364,13 @@
const fontSizeValue = document.getElementById('font-size-value');
const settingsOverlay = document.getElementById('settings-popup-overlay'); // Get overlay

// Initialize Highlight.js for dynamically added code blocks
function applySyntaxHighlighting() {
const codeBlocks = document.querySelectorAll('pre code');
codeBlocks.forEach((block) => {
hljs.highlightElement(block);
});
}

const scrollDownBtn = document.getElementById('scroll-down-btn');

Expand Down Expand Up @@ -1655,78 +1662,81 @@
isWaitingForResponse = false;
hideTypingIndicator();
});
}// Add copy buttons to code blocks in AI messages
function addCopyButtonsToCodeBlocks(messageDiv) {
const codeBlocks = messageDiv.querySelectorAll('pre code');
codeBlocks.forEach((codeBlock) => {
const preElement = codeBlock.closest('pre');
if (preElement && !preElement.querySelector('.code-copy-button')) {
const copyButton = document.createElement('button');
copyButton.className = 'code-copy-button';
copyButton.title = 'Copy code';
copyButton.innerHTML = '<i class="fas fa-copy"></i>';

copyButton.addEventListener('click', (e) => {
e.stopPropagation();

// Extract only the original code, ignoring any appended output
const code = codeBlock.getAttribute('data-original-code') || codeBlock.textContent.trim();
copyToClipboard(code);

// Visual feedback
copyButton.innerHTML = '<i class="fas fa-check"></i>';
copyButton.style.color = '#4CAF50';
setTimeout(() => {
copyButton.innerHTML = '<i class="fas fa-copy"></i>';
copyButton.style.color = '';
}, 2000);
});

preElement.appendChild(copyButton);
}
});
}

// Add a message to the chat
// Add a message to the chat
// Helper function to copy text to clipboard
function copyToClipboard(text) {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed'; // Prevent scrolling to the bottom of the page
document.body.appendChild(textarea);
textarea.select();

try {
document.execCommand('copy');
} catch (err) {
console.error('Failed to copy text:', err);
} finally {
document.body.removeChild(textarea);
}
}

// Example usage in the `addMessage` function
function addMessage(text, sender) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${sender}-message`;

const content = sender === 'ai' ? marked.parse(text) : text;
messageDiv.innerHTML = `<div class="message-bubble">${content}</div>`;

// Add copy buttons to code blocks in AI messages
if (sender === 'ai') {
setTimeout(() => {
applySyntaxHighlighting(); // Apply Highlight.js

// Store the original code in a data attribute before Highlight.js modifies it
const codeBlocks = messageDiv.querySelectorAll('pre code');
codeBlocks.forEach((codeBlock) => {
const preElement = codeBlock.closest('pre');
if (preElement && !preElement.querySelector('.code-copy-button')) {
const copyButton = document.createElement('button');
copyButton.className = 'code-copy-button';
copyButton.title = 'Copy code';
copyButton.innerHTML = '<i class="fas fa-copy"></i>';

copyButton.addEventListener('click', (e) => {
e.stopPropagation();
const code = codeBlock.textContent;
copyToClipboard(code);

// Visual feedback
copyButton.innerHTML = '<i class="fas fa-check"></i>';
copyButton.style.color = '#4CAF50';
setTimeout(() => {
copyButton.innerHTML = '<i class="fas fa-copy"></i>';
copyButton.style.color = '';
}, 2000);
});

preElement.appendChild(copyButton);
}
codeBlock.setAttribute('data-original-code', codeBlock.textContent.trim());
});

addCopyButtonsToCodeBlocks(messageDiv); // Add copy buttons
}, 0);
}

chatMessages.appendChild(messageDiv);
setTimeout(() => messageDiv.classList.add('show'), 10);
chatMessages.scrollTop = chatMessages.scrollHeight;
}

// Helper function to copy text to clipboard (same as before)
function copyToClipboard(text) {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
document.body.appendChild(textarea);
textarea.select();

try {
if (navigator.clipboard) {
navigator.clipboard.writeText(text).catch(err => {
console.error('Clipboard API failed, using fallback', err);
document.execCommand('copy');
});
} else {
document.execCommand('copy');
}
} catch (err) {
console.error('Copy failed:', err);
} finally {
document.body.removeChild(textarea);
}
}

// Show typing indicator
function showTypingIndicator() {
const indicator = document.createElement('div');
Expand Down