Add copy button to code blocks

This commit is contained in:
turboderp
2024-03-08 21:50:31 +01:00
parent adbbe3c04c
commit 75cc4cee4f
2 changed files with 84 additions and 0 deletions

View File

@@ -448,3 +448,45 @@
cursor: pointer;
}
.code-block {
position: relative;
}
.code-block pre {
}
.copy-btn {
background-color: var(--button-background);
font-size: var(--font-size-small);
border-radius: 5px;
border: 1px solid var(--button-border);
color: var(--button-textcolor);
position: absolute;
top: 10px;
right: 10px;
padding-left: 10px;
padding-right: 10px;
padding-top: 2px;
padding-bottom: 4px;
height: 40px;
display: none;
cursor: pointer;
}
.copy-btn.clicked {
background-color: var(--button-disabled-background);
border: 1px solid var(--button-disabled-border);
}
.copy-btn.clicked:hover {
cursor: unset;
filter: unset;
}
.copy-btn:hover {
filter: brightness(var(--hover-brightness));
cursor: pointer;
}
.code-block:hover .copy-btn {
display: block;
}

View File

@@ -7,6 +7,22 @@ import * as overlay from "./overlay.js";
import * as chatsettings from "./chatsettings.js";
import * as roles from "./roles.js";
// Copy button for code blocks
const renderer = new marked.Renderer();
renderer.code = function(code, infostring, escaped) {
const uniqueId = `copy-${Math.random().toString(16).slice(2)}`;
return `
<div class="code-block">
<pre><code>${code}</code></pre>
<button id="${uniqueId}" data-clipboard-text="${escape(code)}" class="copy-btn">⎘ Copy</button>
</div>
`;
};
marked.setOptions({ renderer });
export class Chat {
constructor() {
this.page = util.newDiv(null, "models");
@@ -31,6 +47,32 @@ export class Chat {
this.items = new Map();
this.labels = new Map();
this.currentView = null;
// Handle copy button in any dynamically added child elements
layout.addEventListener('click', function(event) {
if (event.target && event.target.classList.contains('copy-btn')) {
const text = unescape(event.target.getAttribute('data-clipboard-text'));
navigator.clipboard.writeText(text).then(() => {
event.target.classList.add("clicked");
event.target.textContent = '✓ Copied';
console.log('Text copied to clipboard');
}).catch(err => {
console.error('Error in copying text: ', err);
});
}
});
layout.addEventListener('mouseleave', function(event) {
if (event.target && event.target.classList.contains('code-block')) {
const button = event.target.querySelector('.copy-btn');
if (button) {
button.textContent = '⎘ Copy'; // Revert button text to "Copy"
button.classList.remove("clicked");
}
}
}, true);
}
onEnter(getResponse = false) {