diff --git a/src/ui.js b/src/ui.js
index 25d6096..87e7cfc 100644
--- a/src/ui.js
+++ b/src/ui.js
@@ -909,6 +909,41 @@ async function openUncloseaiEmbeddedModalNew() {
const actions = [
{ text: "🔄 Refresh Models", action: loadModels },
+ { text: "📋 Full Raw", action: async () => {
+ try {
+ const history = getChatHistory();
+ let rawContent = '';
+ history.forEach(msg => {
+ if (msg.role === 'user') {
+ rawContent += `**You:** ${msg.content}\n\n`;
+ } else if (msg.role === 'assistant') {
+ rawContent += `**AI:** ${msg.content}\n\n`;
+ }
+ });
+ await navigator.clipboard.writeText(rawContent);
+ alert("Full chat copied as raw markdown!");
+ } catch (error) {
+ alert("Failed to copy: " + error.message);
+ }
+ }},
+ { text: "📄 Full HTML", action: async () => {
+ try {
+ const history = getChatHistory();
+ let htmlContent = '
';
+ history.forEach(msg => {
+ if (msg.role === 'user') {
+ htmlContent += `
You:
${marked.parse(msg.content)}
`;
+ } else if (msg.role === 'assistant') {
+ htmlContent += `
AI:
${marked.parse(msg.content)}
`;
+ }
+ });
+ htmlContent += '
';
+ await navigator.clipboard.writeText(htmlContent);
+ alert("Full chat copied as HTML!");
+ } catch (error) {
+ alert("Failed to copy: " + error.message);
+ }
+ }},
{ text: "🗑️ Clear Chat", action: async () => {
if (confirm("Clear all conversation history?")) {
chatBox.innerHTML = '';
@@ -1099,8 +1134,48 @@ async function openUncloseaiEmbeddedModalNew() {
border-radius: 18px 18px 4px 18px;
max-width: 80%;
word-wrap: break-word;
+ position: relative;
`;
userMsg.textContent = message;
+
+ // Add delete button to user message
+ const userDeleteBtn = document.createElement("button");
+ userDeleteBtn.textContent = "×";
+ userDeleteBtn.style.cssText = `
+ position: absolute;
+ top: -8px;
+ right: -8px;
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ background: rgba(255, 0, 0, 0.8);
+ color: white;
+ border: none;
+ cursor: pointer;
+ font-size: 12px;
+ display: none;
+ transition: all 0.2s;
+ `;
+ userDeleteBtn.onclick = (e) => {
+ e.stopPropagation();
+ // Remove from chat history
+ const currentHistory = getChatHistory();
+ const updatedHistory = currentHistory.filter(msg => !(msg.role === 'user' && msg.content === message));
+ updateChatHistory(updatedHistory);
+ saveConversationHistory(updatedHistory);
+
+ userMsg.remove();
+ };
+
+ // Show delete button on hover
+ userMsg.onmouseenter = () => {
+ userDeleteBtn.style.display = 'block';
+ };
+ userMsg.onmouseleave = () => {
+ userDeleteBtn.style.display = 'none';
+ };
+
+ userMsg.appendChild(userDeleteBtn);
chatBox.appendChild(userMsg);
// Add AI response placeholder
@@ -1241,13 +1316,66 @@ async function openUncloseaiEmbeddedModalNew() {
transition: all 0.2s;
`;
deleteBtn.onclick = () => {
- if (confirm("Delete this message?")) {
- userMsg.remove();
- aiMsg.remove();
+ userMsg.remove();
+ aiMsg.remove();
+ };
+
+ // Copy Raw (Markdown) button
+ const copyRawBtn = document.createElement("button");
+ copyRawBtn.textContent = "📋";
+ copyRawBtn.title = "Copy raw (Markdown)";
+ copyRawBtn.style.cssText = `
+ background: none;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ padding: 4px 8px;
+ cursor: pointer;
+ font-size: 12px;
+ transition: all 0.2s;
+ `;
+ copyRawBtn.onclick = async () => {
+ try {
+ await navigator.clipboard.writeText(response);
+ const originalText = copyRawBtn.textContent;
+ copyRawBtn.textContent = "✓";
+ setTimeout(() => {
+ copyRawBtn.textContent = originalText;
+ }, 1000);
+ } catch (error) {
+ alert("Failed to copy: " + error.message);
+ }
+ };
+
+ // Copy HTML button
+ const copyHtmlBtn = document.createElement("button");
+ copyHtmlBtn.textContent = "📄";
+ copyHtmlBtn.title = "Copy HTML";
+ copyHtmlBtn.style.cssText = `
+ background: none;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ padding: 4px 8px;
+ cursor: pointer;
+ font-size: 12px;
+ transition: all 0.2s;
+ `;
+ copyHtmlBtn.onclick = async () => {
+ try {
+ const htmlContent = marked.parse(response);
+ await navigator.clipboard.writeText(htmlContent);
+ const originalText = copyHtmlBtn.textContent;
+ copyHtmlBtn.textContent = "✓";
+ setTimeout(() => {
+ copyHtmlBtn.textContent = originalText;
+ }, 1000);
+ } catch (error) {
+ alert("Failed to copy: " + error.message);
}
};
messageActions.appendChild(ttsBtn);
+ messageActions.appendChild(copyRawBtn);
+ messageActions.appendChild(copyHtmlBtn);
messageActions.appendChild(deleteBtn);
aiMsg.appendChild(messageActions);
@@ -1337,8 +1465,57 @@ You have complete knowledge of this page content and can reference any details,
border-radius: 18px 18px 4px 18px;
max-width: 80%;
word-wrap: break-word;
+ position: relative;
`;
userMsg.textContent = msg.content;
+
+ // Add delete button to historical user message
+ const userDeleteBtn = document.createElement("button");
+ userDeleteBtn.textContent = "×";
+ userDeleteBtn.style.cssText = `
+ position: absolute;
+ top: -8px;
+ right: -8px;
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ background: rgba(255, 0, 0, 0.8);
+ color: white;
+ border: none;
+ cursor: pointer;
+ font-size: 12px;
+ display: none;
+ transition: all 0.2s;
+ `;
+ userDeleteBtn.onclick = (e) => {
+ e.stopPropagation();
+ // Remove from chat history by index
+ const currentHistory = loadConversationHistory();
+ if (index >= 0 && index < currentHistory.length) {
+ currentHistory.splice(index, 1);
+ saveConversationHistory(currentHistory);
+
+ // Update the chat.js module history
+ const systemMsg = currentHistory.find(msg => msg.role === 'system');
+ const newHistory = [
+ { role: 'system', content: getSystemMessage() },
+ ...currentHistory
+ ];
+ updateChatHistory(newHistory);
+ }
+
+ userMsg.remove();
+ };
+
+ // Show delete button on hover
+ userMsg.onmouseenter = () => {
+ userDeleteBtn.style.display = 'block';
+ };
+ userMsg.onmouseleave = () => {
+ userDeleteBtn.style.display = 'none';
+ };
+
+ userMsg.appendChild(userDeleteBtn);
chatBox.appendChild(userMsg);
console.log("Added user message to chatBox");
} else if (msg.role === 'assistant') {
@@ -1455,7 +1632,62 @@ You have complete knowledge of this page content and can reference any details,
// TODO: Remove from chat history
};
+ // Copy Raw (Markdown) button
+ const copyRawBtn = document.createElement("button");
+ copyRawBtn.textContent = "📋";
+ copyRawBtn.title = "Copy raw (Markdown)";
+ copyRawBtn.style.cssText = `
+ background: none;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ padding: 4px 8px;
+ cursor: pointer;
+ font-size: 12px;
+ transition: all 0.2s;
+ `;
+ copyRawBtn.onclick = async () => {
+ try {
+ await navigator.clipboard.writeText(msg.content);
+ const originalText = copyRawBtn.textContent;
+ copyRawBtn.textContent = "✓";
+ setTimeout(() => {
+ copyRawBtn.textContent = originalText;
+ }, 1000);
+ } catch (error) {
+ alert("Failed to copy: " + error.message);
+ }
+ };
+
+ // Copy HTML button
+ const copyHtmlBtn = document.createElement("button");
+ copyHtmlBtn.textContent = "📄";
+ copyHtmlBtn.title = "Copy HTML";
+ copyHtmlBtn.style.cssText = `
+ background: none;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ padding: 4px 8px;
+ cursor: pointer;
+ font-size: 12px;
+ transition: all 0.2s;
+ `;
+ copyHtmlBtn.onclick = async () => {
+ try {
+ const htmlContent = marked.parse(msg.content);
+ await navigator.clipboard.writeText(htmlContent);
+ const originalText = copyHtmlBtn.textContent;
+ copyHtmlBtn.textContent = "✓";
+ setTimeout(() => {
+ copyHtmlBtn.textContent = originalText;
+ }, 1000);
+ } catch (error) {
+ alert("Failed to copy: " + error.message);
+ }
+ };
+
messageActions.appendChild(ttsBtn);
+ messageActions.appendChild(copyRawBtn);
+ messageActions.appendChild(copyHtmlBtn);
messageActions.appendChild(deleteBtn);
aiMsg.appendChild(messageActions);
@@ -1657,7 +1889,62 @@ You have complete knowledge of this page content and can reference any details,
introMsg.remove();
};
+ // Copy Raw (Markdown) button
+ const copyRawBtn = document.createElement("button");
+ copyRawBtn.textContent = "📋";
+ copyRawBtn.title = "Copy raw (Markdown)";
+ copyRawBtn.style.cssText = `
+ background: none;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ padding: 4px 8px;
+ cursor: pointer;
+ font-size: 12px;
+ transition: all 0.2s;
+ `;
+ copyRawBtn.onclick = async () => {
+ try {
+ await navigator.clipboard.writeText(response);
+ const originalText = copyRawBtn.textContent;
+ copyRawBtn.textContent = "✓";
+ setTimeout(() => {
+ copyRawBtn.textContent = originalText;
+ }, 1000);
+ } catch (error) {
+ alert("Failed to copy: " + error.message);
+ }
+ };
+
+ // Copy HTML button
+ const copyHtmlBtn = document.createElement("button");
+ copyHtmlBtn.textContent = "📄";
+ copyHtmlBtn.title = "Copy HTML";
+ copyHtmlBtn.style.cssText = `
+ background: none;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ padding: 4px 8px;
+ cursor: pointer;
+ font-size: 12px;
+ transition: all 0.2s;
+ `;
+ copyHtmlBtn.onclick = async () => {
+ try {
+ const htmlContent = marked.parse(response);
+ await navigator.clipboard.writeText(htmlContent);
+ const originalText = copyHtmlBtn.textContent;
+ copyHtmlBtn.textContent = "✓";
+ setTimeout(() => {
+ copyHtmlBtn.textContent = originalText;
+ }, 1000);
+ } catch (error) {
+ alert("Failed to copy: " + error.message);
+ }
+ };
+
messageActions.appendChild(ttsBtn);
+ messageActions.appendChild(copyRawBtn);
+ messageActions.appendChild(copyHtmlBtn);
messageActions.appendChild(deleteBtn);
introMsg.appendChild(messageActions);
@@ -2165,15 +2452,14 @@ export async function openUncloseaiEmbeddedModal() {
"position: absolute; top: 2px; right: 2px; width: 20px; height: 20px; font-size: 12px; background: rgba(255,0,0,0.7); color: white; border: none; border-radius: 50%; cursor: pointer;";
deleteBtn.onclick = ((messageIndex) => {
return () => {
- if (confirm("Delete this message?")) {
- const savedHistory = loadConversationHistory();
- if (messageIndex >= 0 && messageIndex < savedHistory.length) {
- savedHistory.splice(messageIndex, 1);
- localStorage.setItem(
- getPageSpecificKey("hermes-conversation-history"),
- JSON.stringify(savedHistory),
- );
- // Update global chat history
+ const savedHistory = loadConversationHistory();
+ if (messageIndex >= 0 && messageIndex < savedHistory.length) {
+ savedHistory.splice(messageIndex, 1);
+ localStorage.setItem(
+ getPageSpecificKey("hermes-conversation-history"),
+ JSON.stringify(savedHistory),
+ );
+ // Update global chat history
chatHistory = [
{
role: "system",
@@ -2513,11 +2799,9 @@ Format: Start with "Greetings! I'm Hermes..." and make it sound natural and enga
deleteBtn.style.cssText =
"position: absolute; top: 2px; right: 2px; width: 20px; height: 20px; font-size: 12px; background: rgba(255,0,0,0.7); color: white; border: none; border-radius: 50%; cursor: pointer;";
deleteBtn.onclick = () => {
- if (confirm("Delete this message?")) {
- div.remove();
- // Update stored history
- restoreConversationHistory();
- }
+ div.remove();
+ // Update stored history
+ restoreConversationHistory();
};
div.appendChild(deleteBtn);