mirror of
https://github.com/Minidoracat/mcp-feedback-enhanced.git
synced 2025-07-27 02:22:26 +08:00
1、添加复制消息功能;2 资源加载 优化,全使用本地资源
This commit is contained in:
parent
fab9003b98
commit
4dcf449c99
@ -30,8 +30,8 @@ class I18nManager:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._current_language = None
|
self._current_language = None
|
||||||
self._translations = {}
|
self._translations = {}
|
||||||
self._supported_languages = ["zh-TW", "en", "zh-CN"]
|
self._supported_languages = ["zh-CN", "zh-TW", "en"]
|
||||||
self._fallback_language = "en"
|
self._fallback_language = "zh-CN"
|
||||||
self._config_file = self._get_config_file_path()
|
self._config_file = self._get_config_file_path()
|
||||||
self._locales_dir = Path(__file__).parent / "web" / "locales"
|
self._locales_dir = Path(__file__).parent / "web" / "locales"
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ class I18nManager:
|
|||||||
|
|
||||||
def get_current_language(self) -> str:
|
def get_current_language(self) -> str:
|
||||||
"""獲取當前語言"""
|
"""獲取當前語言"""
|
||||||
return self._current_language or "zh-TW"
|
return self._current_language or "zh-CN"
|
||||||
|
|
||||||
def set_language(self, language: str) -> bool:
|
def set_language(self, language: str) -> bool:
|
||||||
"""設定語言"""
|
"""設定語言"""
|
||||||
|
@ -753,7 +753,7 @@
|
|||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
||||||
max-width: 500px;
|
max-width: 750px;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -854,11 +854,149 @@
|
|||||||
|
|
||||||
.detail-value.summary {
|
.detail-value.summary {
|
||||||
background: var(--bg-secondary);
|
background: var(--bg-secondary);
|
||||||
padding: 8px 12px;
|
padding: 0;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border-left: 3px solid var(--accent-color);
|
border-left: 3px solid var(--accent-color);
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-actions {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-copy-summary {
|
||||||
|
background: var(--accent-color);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all var(--transition-fast) ease;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-copy-summary:hover {
|
||||||
|
opacity: 1;
|
||||||
|
background: #1976d2;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-content {
|
||||||
|
padding: 8px 12px;
|
||||||
|
padding-right: 50px; /* 为复制按钮留出空间 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 为会话详情弹窗中的摘要内容应用与反馈页面相同的 Markdown 样式 */
|
||||||
|
.detail-value.summary .summary-content h1,
|
||||||
|
.detail-value.summary .summary-content h2,
|
||||||
|
.detail-value.summary .summary-content h3,
|
||||||
|
.detail-value.summary .summary-content h4,
|
||||||
|
.detail-value.summary .summary-content h5,
|
||||||
|
.detail-value.summary .summary-content h6 {
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin: 16px 0 8px 0;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value.summary .summary-content h1 { font-size: 20px; }
|
||||||
|
.detail-value.summary .summary-content h2 { font-size: 18px; }
|
||||||
|
.detail-value.summary .summary-content h3 { font-size: 16px; }
|
||||||
|
.detail-value.summary .summary-content h4 { font-size: 14px; }
|
||||||
|
.detail-value.summary .summary-content h5 { font-size: 13px; }
|
||||||
|
.detail-value.summary .summary-content h6 { font-size: 12px; }
|
||||||
|
|
||||||
|
.detail-value.summary .summary-content p {
|
||||||
|
margin: 8px 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value.summary .summary-content strong {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value.summary .summary-content em {
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value.summary .summary-content code {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-family: 'Consolas', 'Monaco', monospace;
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value.summary .summary-content pre {
|
||||||
|
background: var(--bg-tertiary);
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow-x: auto;
|
||||||
|
margin: 12px 0;
|
||||||
|
border-left: 3px solid var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value.summary .summary-content pre code {
|
||||||
|
background: none;
|
||||||
|
padding: 0;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value.summary .summary-content ul,
|
||||||
|
.detail-value.summary .summary-content ol {
|
||||||
|
margin: 8px 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value.summary .summary-content li {
|
||||||
|
margin: 4px 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value.summary .summary-content blockquote {
|
||||||
|
border-left: 4px solid var(--accent-color);
|
||||||
|
margin: 12px 0;
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: rgba(0, 122, 204, 0.05);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 复制提示样式 */
|
||||||
|
.copy-toast {
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
padding: 12px 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: white;
|
||||||
|
z-index: 10000;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(100px);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-toast.show {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-toast-success {
|
||||||
|
background: var(--success-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-toast-error {
|
||||||
|
background: var(--error-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-footer {
|
.modal-footer {
|
||||||
@ -924,6 +1062,36 @@
|
|||||||
background: var(--bg-secondary);
|
background: var(--bg-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-header .btn-copy-message {
|
||||||
|
background: var(--accent-color);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
font-size: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all var(--transition-fast) ease;
|
||||||
|
opacity: 0.7;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-header .btn-copy-message:hover {
|
||||||
|
opacity: 1;
|
||||||
|
background: #1976d2;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-message-item:hover .btn-copy-message {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
.message-header {
|
.message-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -369,7 +369,6 @@ body {
|
|||||||
|
|
||||||
/* 容器樣式 */
|
/* 容器樣式 */
|
||||||
.container {
|
.container {
|
||||||
max-width: 1200px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
class I18nManager {
|
class I18nManager {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.currentLanguage = 'zh-TW';
|
this.currentLanguage = 'zh-CN';
|
||||||
this.translations = {};
|
this.translations = {};
|
||||||
this.loadingPromise = null;
|
this.loadingPromise = null;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,9 @@
|
|||||||
|
|
||||||
console.log('🔍 顯示會話詳情:', sessionData.session_id);
|
console.log('🔍 顯示會話詳情:', sessionData.session_id);
|
||||||
|
|
||||||
|
// 存储当前会话数据,供复制功能使用
|
||||||
|
this.currentSessionData = sessionData;
|
||||||
|
|
||||||
// 關閉現有彈窗
|
// 關閉現有彈窗
|
||||||
this.closeModal();
|
this.closeModal();
|
||||||
|
|
||||||
@ -166,7 +169,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span class="detail-label">${i18n ? i18n.t('sessionManagement.aiSummary') : 'AI 摘要'}:</span>
|
<span class="detail-label">${i18n ? i18n.t('sessionManagement.aiSummary') : 'AI 摘要'}:</span>
|
||||||
<div class="detail-value summary">${this.escapeHtml(details.summary)}</div>
|
<div class="detail-value summary">
|
||||||
|
<div class="summary-actions">
|
||||||
|
<button class="btn-copy-summary" title="复制源码" aria-label="复制源码">📋</button>
|
||||||
|
</div>
|
||||||
|
<div class="summary-content">${this.renderMarkdownSafely(details.summary)}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${this.createUserMessagesSection(details)}
|
${this.createUserMessagesSection(details)}
|
||||||
</div>
|
</div>
|
||||||
@ -241,11 +249,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
messagesHtml += `
|
messagesHtml += `
|
||||||
<div class="user-message-item">
|
<div class="user-message-item" data-message-index="${index}">
|
||||||
<div class="message-header">
|
<div class="message-header">
|
||||||
<span class="message-index">#${index + 1}</span>
|
<span class="message-index">#${index + 1}</span>
|
||||||
<span class="message-time">${timestamp}</span>
|
<span class="message-time">${timestamp}</span>
|
||||||
<span class="message-method">${submissionMethod}</span>
|
<span class="message-method">${submissionMethod}</span>
|
||||||
|
<button class="btn-copy-message" title="复制消息内容" aria-label="复制消息内容" data-message-content="${this.escapeHtml(message.content)}">📋</button>
|
||||||
</div>
|
</div>
|
||||||
${contentHtml}
|
${contentHtml}
|
||||||
</div>
|
</div>
|
||||||
@ -310,6 +319,24 @@
|
|||||||
};
|
};
|
||||||
document.addEventListener('keydown', this.keydownHandler);
|
document.addEventListener('keydown', this.keydownHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 复制摘要按钮
|
||||||
|
const copyBtn = this.currentModal.querySelector('.btn-copy-summary');
|
||||||
|
if (copyBtn) {
|
||||||
|
DOMUtils.addEventListener(copyBtn, 'click', function() {
|
||||||
|
self.copySummaryToClipboard();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制用户消息按钮
|
||||||
|
const copyMessageBtns = this.currentModal.querySelectorAll('.btn-copy-message');
|
||||||
|
copyMessageBtns.forEach(function(btn) {
|
||||||
|
DOMUtils.addEventListener(btn, 'click', function(e) {
|
||||||
|
e.stopPropagation(); // 防止事件冒泡
|
||||||
|
const messageContent = btn.getAttribute('data-message-content');
|
||||||
|
self.copyMessageToClipboard(messageContent);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -355,12 +382,198 @@
|
|||||||
*/
|
*/
|
||||||
SessionDetailsModal.prototype.escapeHtml = function(text) {
|
SessionDetailsModal.prototype.escapeHtml = function(text) {
|
||||||
if (!text) return '';
|
if (!text) return '';
|
||||||
|
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
div.textContent = text;
|
div.textContent = text;
|
||||||
return div.innerHTML;
|
return div.innerHTML;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 安全地渲染 Markdown 內容
|
||||||
|
*/
|
||||||
|
SessionDetailsModal.prototype.renderMarkdownSafely = function(content) {
|
||||||
|
if (!content) return '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 检查 marked 和 DOMPurify 是否可用
|
||||||
|
if (typeof window.marked === 'undefined' || typeof window.DOMPurify === 'undefined') {
|
||||||
|
console.warn('⚠️ Markdown 库未载入,使用纯文字显示');
|
||||||
|
return this.escapeHtml(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 marked 解析 Markdown
|
||||||
|
const htmlContent = window.marked.parse(content);
|
||||||
|
|
||||||
|
// 使用 DOMPurify 清理 HTML
|
||||||
|
const cleanHtml = window.DOMPurify.sanitize(htmlContent, {
|
||||||
|
ALLOWED_TAGS: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'br', 'strong', 'em', 'code', 'pre', 'ul', 'ol', 'li', 'blockquote', 'a', 'hr', 'del', 's', 'table', 'thead', 'tbody', 'tr', 'td', 'th'],
|
||||||
|
ALLOWED_ATTR: ['href', 'title', 'class', 'align', 'style'],
|
||||||
|
ALLOW_DATA_ATTR: false
|
||||||
|
});
|
||||||
|
|
||||||
|
return cleanHtml;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Markdown 渲染失败:', error);
|
||||||
|
return this.escapeHtml(content);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制摘要内容到剪贴板
|
||||||
|
*/
|
||||||
|
SessionDetailsModal.prototype.copySummaryToClipboard = function() {
|
||||||
|
const self = this; // 定义 self 变量
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 获取原始摘要内容(Markdown 源码)
|
||||||
|
const summaryContent = this.currentSessionData && this.currentSessionData.summary ?
|
||||||
|
this.currentSessionData.summary : '';
|
||||||
|
|
||||||
|
if (!summaryContent) {
|
||||||
|
console.warn('⚠️ 没有摘要内容可复制');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 传统复制方法
|
||||||
|
const fallbackCopyTextToClipboard = function(text) {
|
||||||
|
const textArea = document.createElement('textarea');
|
||||||
|
textArea.value = text;
|
||||||
|
textArea.style.position = 'fixed';
|
||||||
|
textArea.style.left = '-999999px';
|
||||||
|
textArea.style.top = '-999999px';
|
||||||
|
document.body.appendChild(textArea);
|
||||||
|
textArea.focus();
|
||||||
|
textArea.select();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const successful = document.execCommand('copy');
|
||||||
|
if (successful) {
|
||||||
|
console.log('✅ 摘要内容已复制到剪贴板(传统方法)');
|
||||||
|
self.showToast('✅ 摘要已复制到剪贴板', 'success');
|
||||||
|
} else {
|
||||||
|
console.error('❌ 复制失败(传统方法)');
|
||||||
|
self.showToast('❌ 复制失败,请手动复制', 'error');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('❌ 复制失败:', err);
|
||||||
|
self.showToast('❌ 复制失败,请手动复制', 'error');
|
||||||
|
} finally {
|
||||||
|
document.body.removeChild(textArea);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 使用现代 Clipboard API
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
navigator.clipboard.writeText(summaryContent).then(function() {
|
||||||
|
console.log('✅ 摘要内容已复制到剪贴板');
|
||||||
|
self.showToast('✅ 摘要已复制到剪贴板', 'success');
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.error('❌ 复制失败:', err);
|
||||||
|
// 降级到传统方法
|
||||||
|
fallbackCopyTextToClipboard(summaryContent);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 降级到传统方法
|
||||||
|
fallbackCopyTextToClipboard(summaryContent);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 复制摘要时发生错误:', error);
|
||||||
|
this.showToast('❌ 复制失败,请手动复制', 'error');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制用户消息内容到剪贴板
|
||||||
|
*/
|
||||||
|
SessionDetailsModal.prototype.copyMessageToClipboard = function(messageContent) {
|
||||||
|
if (!messageContent) {
|
||||||
|
console.warn('⚠️ 没有消息内容可复制');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 使用现代 Clipboard API
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
navigator.clipboard.writeText(messageContent).then(function() {
|
||||||
|
console.log('✅ 用户消息已复制到剪贴板');
|
||||||
|
self.showToast('✅ 消息已复制到剪贴板', 'success');
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.error('❌ 复制失败:', err);
|
||||||
|
// 降级到传统方法
|
||||||
|
fallbackCopyTextToClipboard(messageContent);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 降级到传统方法
|
||||||
|
fallbackCopyTextToClipboard(messageContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 传统复制方法
|
||||||
|
const fallbackCopyTextToClipboard = function(text) {
|
||||||
|
const textArea = document.createElement('textarea');
|
||||||
|
textArea.value = text;
|
||||||
|
textArea.style.position = 'fixed';
|
||||||
|
textArea.style.left = '-999999px';
|
||||||
|
textArea.style.top = '-999999px';
|
||||||
|
document.body.appendChild(textArea);
|
||||||
|
textArea.focus();
|
||||||
|
textArea.select();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const successful = document.execCommand('copy');
|
||||||
|
if (successful) {
|
||||||
|
console.log('✅ 用户消息已复制到剪贴板(传统方法)');
|
||||||
|
self.showToast('✅ 消息已复制到剪贴板', 'success');
|
||||||
|
} else {
|
||||||
|
console.error('❌ 复制失败(传统方法)');
|
||||||
|
self.showToast('❌ 复制失败,请手动复制', 'error');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('❌ 复制失败:', err);
|
||||||
|
self.showToast('❌ 复制失败,请手动复制', 'error');
|
||||||
|
} finally {
|
||||||
|
document.body.removeChild(textArea);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 复制用户消息时发生错误:', error);
|
||||||
|
this.showToast('❌ 复制失败,请手动复制', 'error');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示提示消息
|
||||||
|
*/
|
||||||
|
SessionDetailsModal.prototype.showToast = function(message, type) {
|
||||||
|
// 创建提示元素
|
||||||
|
const toast = document.createElement('div');
|
||||||
|
toast.className = 'copy-toast copy-toast-' + type;
|
||||||
|
toast.textContent = message;
|
||||||
|
|
||||||
|
// 添加到弹窗中
|
||||||
|
if (this.currentModal) {
|
||||||
|
this.currentModal.appendChild(toast);
|
||||||
|
|
||||||
|
// 显示动画
|
||||||
|
setTimeout(function() {
|
||||||
|
toast.classList.add('show');
|
||||||
|
}, 10);
|
||||||
|
|
||||||
|
// 自动隐藏
|
||||||
|
setTimeout(function() {
|
||||||
|
toast.classList.remove('show');
|
||||||
|
setTimeout(function() {
|
||||||
|
if (toast.parentNode) {
|
||||||
|
toast.parentNode.removeChild(toast);
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 檢查是否有彈窗開啟
|
* 檢查是否有彈窗開啟
|
||||||
*/
|
*/
|
||||||
|
6
src/mcp_feedback_enhanced/web/static/js/vendor/marked.min.js
vendored
Normal file
6
src/mcp_feedback_enhanced/web/static/js/vendor/marked.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
3
src/mcp_feedback_enhanced/web/static/js/vendor/purify.min.js
vendored
Normal file
3
src/mcp_feedback_enhanced/web/static/js/vendor/purify.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-TW" id="html-root">
|
<html lang="zh-CN" id="html-root">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
@ -735,8 +735,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="language-selector-dropdown">
|
<div class="language-selector-dropdown">
|
||||||
<select id="settingsLanguageSelect" class="language-setting-select">
|
<select id="settingsLanguageSelect" class="language-setting-select">
|
||||||
<option value="zh-TW" data-i18n="languages.zh-TW">繁體中文</option>
|
|
||||||
<option value="zh-CN" data-i18n="languages.zh-CN">简体中文</option>
|
<option value="zh-CN" data-i18n="languages.zh-CN">简体中文</option>
|
||||||
|
<option value="zh-TW" data-i18n="languages.zh-TW">繁體中文</option>
|
||||||
<option value="en" data-i18n="languages.en">English</option>
|
<option value="en" data-i18n="languages.en">English</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -1051,9 +1051,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- WebSocket 和 JavaScript -->
|
<!-- WebSocket 和 JavaScript -->
|
||||||
<!-- Markdown 支援庫 -->
|
<!-- Markdown 支援庫 - 本地版本 -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked@14.1.3/marked.min.js"></script>
|
<script src="/static/js/vendor/marked.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.2.2/dist/purify.min.js"></script>
|
<script src="/static/js/vendor/purify.min.js"></script>
|
||||||
<script src="/static/js/i18n.js?v=2025010510"></script>
|
<script src="/static/js/i18n.js?v=2025010510"></script>
|
||||||
<!-- 載入所有模組 -->
|
<!-- 載入所有模組 -->
|
||||||
<!-- 核心模組(最先載入) -->
|
<!-- 核心模組(最先載入) -->
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-TW" id="html-root">
|
<html lang="zh-CN" id="html-root">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
@ -129,7 +129,6 @@
|
|||||||
/* 主容器 - 有會話時顯示 */
|
/* 主容器 - 有會話時顯示 */
|
||||||
.main-container {
|
.main-container {
|
||||||
display: none;
|
display: none;
|
||||||
max-width: 1200px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user