Jade/views/layouts/main.html

205 lines
8.0 KiB
HTML

<!DOCTYPE html>
<html data-theme="dark" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<title>JADE</title>
<link rel="stylesheet" href="dependencies/bulma.css">
<script defer
src="https://kit.fontawesome.com/f515f7ad51.js"
crossorigin="anonymous"></script>
<link defer rel="stylesheet" href="dependencies/russo.css">
<link rel="stylesheet" href="/style.css">
<script src="dependencies/htmx.js"></script>
<script src="dependencies/ws.js"></script>
<script defer src="dependencies/sortable.js"></script>
<script defer src="dependencies/pricing-table.js"></script>
<!-- highlight.js -->
<link defer rel="stylesheet" href="dependencies/default.css">
<script defer src="dependencies/highlight.js"></script>
<script defer src="dependencies/marked.js"></script>
<script defer src="wasm_exec.js"></script>
<script>
window.addEventListener('load', function() {
hljs.highlightAll();
const go = new Go();
WebAssembly.instantiateStreaming(fetch("main-v0.4.wasm"), go.importObject).then((result) => {
go.run(result.instance);
});
});
</script>
</head>
<body>
{{ embed }}
<script>
function copyToClipboardCode(button) {
// Get the code element next to the button
var codeElement = button.parentElement.nextElementSibling;
// Create a temporary textarea element
var tempTextarea = document.createElement('textarea');
tempTextarea.value = codeElement.textContent;
// Append the temporary textarea to the document body
document.body.appendChild(tempTextarea);
// Select the text in the temporary textarea
tempTextarea.select();
// Copy the selected text to the clipboard
document.execCommand('copy');
// Remove the temporary textarea from the document body
document.body.removeChild(tempTextarea);
// Change the button text to indicate successful copy
var originalText = button.innerHTML;
button.innerHTML = '<i class="fa-solid fa-check"></i>';
// Revert the button text after a short delay
setTimeout(function () {
button.innerHTML = originalText;
}, 2000);
}
function copyToClipboard(button) {
// Get the container element for all the message content
var messageContentContainer = button.closest('.message-bot').querySelector('#content-column .content');
// Get the text content of all the messages
var messageContent = messageContentContainer.textContent.trim();
// Create a temporary textarea element
var tempTextarea = document.createElement('textarea');
tempTextarea.value = messageContent;
// Append the temporary textarea to the document body
document.body.appendChild(tempTextarea);
// Select the text in the temporary textarea
tempTextarea.select();
// Copy the selected text to the clipboard
document.execCommand('copy');
// Remove the temporary textarea from the document body
document.body.removeChild(tempTextarea);
// Change the button text to indicate successful copy
var originalText = button.innerHTML;
button.innerHTML = '<i class="fa-solid fa-check"></i>';
// Revert the button text after a short delay
setTimeout(function () {
button.innerHTML = originalText;
}, 2000);
}
let lastSelectedIndex = null;
function toggleSelection(element) {
const elements = Array.from(document.getElementsByClassName('icon-llm'));
const index = elements.indexOf(element);
if (document.body.classList.contains('shift-pressed') && lastSelectedIndex !== null) {
const [start, end] = [lastSelectedIndex, index].sort((a, b) => a - b);
let allSelected = true;
for (let i = start; i <= end; i++) {
if (!elements[i].classList.contains('selected')) {
allSelected = false;
break;
}
}
for (let i = start; i <= end; i++) {
if (allSelected) {
elements[i].classList.remove('selected');
elements[i].classList.add('unselected');
} else {
elements[i].classList.add('selected');
elements[i].classList.remove('unselected');
}
}
lastSelectedIndex = null;
const elements2 = Array.from(document.getElementsByClassName('icon-text'));
for (let i = 0; i < elements2.length; i++) {
elements2[i].classList.remove('shiftselected');
}
} else if (document.body.classList.contains('shift-pressed') && lastSelectedIndex === null) {
lastSelectedIndex = index;
element.classList.toggle('shiftselected');
} else {
element.classList.toggle('selected');
element.classList.toggle('unselected');
}
// If at least one model is selected, enable the delete button
if (document.getElementsByClassName('selected icon-llm').length > 0) {
document.getElementById('delete-model-button').disabled = false;
} else {
document.getElementById('delete-model-button').disabled = true;
}
toggleSendButton();
}
function getSelectedModelsIDs() {
var selectedModelsIDs = [];
var selectedModels = document.getElementsByClassName('selected icon-llm');
for (var i = 0; i < selectedModels.length; i++) {
selectedModelsIDs.push(selectedModels[i].getAttribute('data-id'));
}
return selectedModelsIDs.length > 0 ? JSON.stringify(selectedModelsIDs) : '[]';
}
</script>
<script>
// Wait for a message-bot to appear in the chat and if so, delete the placeholder
// Select the node that will be observed for mutations
const targetNode = document.body;
// Options for the observer (which mutations to observe)
const config = { childList: true, subtree: true };
// Callback function to execute when mutations are observed
const callback = function (mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
for (let node of mutation.addedNodes) {
if (node.nodeType === 1 && node.classList.contains('message-bot') && !node.classList.contains('message-placeholder')) {
// A new element with the class "message-bot" has been added
// Remove the placeholder
const botPlaceholder = document.querySelector('.message-bot.message-placeholder');
if (botPlaceholder) {
botPlaceholder.remove();
}
const userPlaceholder = document.querySelector('.message-user.message-placeholder');
if (userPlaceholder) {
userPlaceholder.remove();
}
}
}
}
}
};
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode, config);
</script>
</body>
</html>