From ca9db3a508b192b0c8df1c3da3ed8da39a01cdba Mon Sep 17 00:00:00 2001 From: Cb1ock Date: Sat, 25 Oct 2025 22:10:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9A=E4=B8=BA=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=9D=97=E6=B7=BB=E5=8A=A0=E5=A4=8D=E5=88=B6=E6=8C=89?= =?UTF-8?q?=E9=92=AE=EF=BC=8C=E4=BC=98=E5=8C=96=E7=94=A8=E6=88=B7=E4=BD=93?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/js/main.js | 60 +++++++++++++++++++++++++++++++++++++++++++++++ static/style.css | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/static/js/main.js b/static/js/main.js index c927070..fe8ac26 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -869,6 +869,9 @@ class SnapSolver { hljs.highlightElement(block); }); } + + // 为所有代码块添加复制按钮 + this.addCopyButtonsToCodeBlocks(element); } catch (error) { console.error('Markdown解析错误:', error); // 发生错误时也保留换行格式 @@ -879,6 +882,60 @@ class SnapSolver { element.scrollTop = element.scrollHeight; } + // 为代码块添加复制按钮 + addCopyButtonsToCodeBlocks(element) { + const codeBlocks = element.querySelectorAll('pre code'); + + codeBlocks.forEach((codeBlock) => { + // 检查是否已经有复制按钮 + if (codeBlock.parentElement.querySelector('.code-copy-btn')) { + return; + } + + // 创建包装器 + const wrapper = document.createElement('div'); + wrapper.className = 'code-block-wrapper'; + + // 将pre元素包装起来 + const preElement = codeBlock.parentElement; + preElement.parentNode.insertBefore(wrapper, preElement); + wrapper.appendChild(preElement); + + // 创建复制按钮 + const copyBtn = document.createElement('button'); + copyBtn.className = 'code-copy-btn'; + copyBtn.innerHTML = ' 复制'; + copyBtn.title = '复制代码'; + + // 添加点击事件 + copyBtn.addEventListener('click', async () => { + try { + const codeText = codeBlock.textContent; + await navigator.clipboard.writeText(codeText); + + // 更新按钮状态 + copyBtn.innerHTML = ' 已复制'; + copyBtn.classList.add('copied'); + + // 显示提示 + window.uiManager?.showToast('代码已复制到剪贴板', 'success'); + + // 2秒后恢复原状 + setTimeout(() => { + copyBtn.innerHTML = ' 复制'; + copyBtn.classList.remove('copied'); + }, 2000); + } catch (error) { + console.error('复制失败:', error); + window.uiManager?.showToast('复制失败,请手动选择复制', 'error'); + } + }); + + // 将按钮添加到包装器 + wrapper.appendChild(copyBtn); + }); + } + initializeCropper() { try { // 如果当前没有截图,不要初始化裁剪器 @@ -1100,6 +1157,9 @@ class SnapSolver { const successMessage = '已复制到服务端剪贴板'; this.updateClipboardStatus(successMessage, 'success'); window.uiManager?.showToast(successMessage, 'success'); + + // 清空输入框 + this.clipboardTextarea.value = ''; } else { const errorMessage = result?.message || '发送失败,请稍后重试'; this.updateClipboardStatus(errorMessage, 'error'); diff --git a/static/style.css b/static/style.css index 17e9f3b..d01c8e4 100644 --- a/static/style.css +++ b/static/style.css @@ -3557,6 +3557,49 @@ textarea:focus { color: var(--danger); } +/* 代码块复制按钮样式 */ +.code-block-wrapper { + position: relative; + margin: 1rem 0; +} + +.code-block-wrapper pre { + margin: 0; + padding: 1rem; + background-color: var(--surface-alt); + border-radius: 0.5rem; + border: 1px solid var(--border-color); + overflow-x: auto; +} + +.code-copy-btn { + position: absolute; + top: 0.5rem; + right: 0.5rem; + background-color: var(--primary); + color: white; + border: none; + border-radius: 0.25rem; + padding: 0.25rem 0.5rem; + font-size: 0.75rem; + cursor: pointer; + opacity: 0.8; + transition: opacity 0.2s ease; + z-index: 10; +} + +.code-copy-btn:hover { + opacity: 1; +} + +.code-copy-btn:active { + background-color: var(--primary-dark); +} + +.code-copy-btn.copied { + background-color: var(--success-color); +} + /* 滑块值显示优化 */ #temperatureValue, #thinkBudgetPercentValue {