mirror of
https://github.com/Minidoracat/mcp-feedback-enhanced.git
synced 2025-07-27 10:42:25 +08:00
🐛 修復 Copilot 審查問題並完善會話歷史 i18n 支援
- 修復 fallbackCopyTextToClipboard 函數定義順序錯誤 - 修復會話歷史區塊語言切換不生效問題 - 修復 renderHistory 函數名稱錯誤 - 添加複製按鈕的多語言支援 - 優化調試日誌管理,添加 DEBUG_MODE 控制 - 統一程式碼註釋為繁體中文
This commit is contained in:
parent
788d7b61cc
commit
de6838c79c
@ -238,7 +238,10 @@
|
|||||||
"summary": "Summary",
|
"summary": "Summary",
|
||||||
"noSummary": "No summary available",
|
"noSummary": "No summary available",
|
||||||
"unknown": "Unknown"
|
"unknown": "Unknown"
|
||||||
}
|
},
|
||||||
|
"copySessionContent": "Copy Session Content",
|
||||||
|
"copyUserContent": "Copy User Content",
|
||||||
|
"exportSession": "Export This Session"
|
||||||
},
|
},
|
||||||
"sessionHistory": {
|
"sessionHistory": {
|
||||||
"management": {
|
"management": {
|
||||||
|
@ -238,7 +238,10 @@
|
|||||||
"summary": "总结",
|
"summary": "总结",
|
||||||
"noSummary": "暂无总结",
|
"noSummary": "暂无总结",
|
||||||
"unknown": "未知"
|
"unknown": "未知"
|
||||||
}
|
},
|
||||||
|
"copySessionContent": "复制会话内容",
|
||||||
|
"copyUserContent": "复制用户内容",
|
||||||
|
"exportSession": "导出此会话"
|
||||||
},
|
},
|
||||||
"sessionHistory": {
|
"sessionHistory": {
|
||||||
"management": {
|
"management": {
|
||||||
|
@ -243,7 +243,10 @@
|
|||||||
"noSummary": "暫無摘要",
|
"noSummary": "暫無摘要",
|
||||||
"unknown": "未知"
|
"unknown": "未知"
|
||||||
},
|
},
|
||||||
"noSummary": "無摘要"
|
"noSummary": "無摘要",
|
||||||
|
"copySessionContent": "複製會話內容",
|
||||||
|
"copyUserContent": "複製用戶內容",
|
||||||
|
"exportSession": "匯出此會話"
|
||||||
},
|
},
|
||||||
"sessionHistory": {
|
"sessionHistory": {
|
||||||
"management": {
|
"management": {
|
||||||
|
@ -227,6 +227,11 @@ class I18nManager {
|
|||||||
const stats = window.feedbackApp.sessionManager.dataManager.getStats();
|
const stats = window.feedbackApp.sessionManager.dataManager.getStats();
|
||||||
window.feedbackApp.sessionManager.uiRenderer.renderStats(stats);
|
window.feedbackApp.sessionManager.uiRenderer.renderStats(stats);
|
||||||
console.log('🌐 已更新統計資訊的語言顯示');
|
console.log('🌐 已更新統計資訊的語言顯示');
|
||||||
|
|
||||||
|
// 重新渲染會話歷史以更新所有動態創建的元素
|
||||||
|
const sessionHistory = window.feedbackApp.sessionManager.dataManager.getSessionHistory();
|
||||||
|
window.feedbackApp.sessionManager.uiRenderer.renderSessionHistory(sessionHistory);
|
||||||
|
console.log('🌐 已更新會話歷史的語言顯示');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
this.currentModal = null;
|
this.currentModal = null;
|
||||||
this.keydownHandler = null;
|
this.keydownHandler = null;
|
||||||
|
|
||||||
console.log('🔍 SessionDetailsModal 初始化完成');
|
// console.log('🔍 SessionDetailsModal 初始化完成');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,7 +43,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('🔍 顯示會話詳情:', sessionData.session_id);
|
// console.log('🔍 顯示會話詳情:', sessionData.session_id);
|
||||||
|
|
||||||
// 存储当前会话数据,供复制功能使用
|
// 存储当前会话数据,供复制功能使用
|
||||||
this.currentSessionData = sessionData;
|
this.currentSessionData = sessionData;
|
||||||
@ -62,7 +62,7 @@
|
|||||||
* 格式化會話詳情
|
* 格式化會話詳情
|
||||||
*/
|
*/
|
||||||
SessionDetailsModal.prototype.formatSessionDetails = function(sessionData) {
|
SessionDetailsModal.prototype.formatSessionDetails = function(sessionData) {
|
||||||
console.log('🔍 格式化會話詳情:', sessionData);
|
// console.log('🔍 格式化會話詳情:', sessionData);
|
||||||
|
|
||||||
// 處理會話 ID - 顯示完整 session ID
|
// 處理會話 ID - 顯示完整 session ID
|
||||||
const sessionId = sessionData.session_id || '未知';
|
const sessionId = sessionData.session_id || '未知';
|
||||||
@ -171,7 +171,7 @@
|
|||||||
<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">
|
<div class="detail-value summary">
|
||||||
<div class="summary-actions">
|
<div class="summary-actions">
|
||||||
<button class="btn-copy-summary" title="复制源码" aria-label="复制源码">📋</button>
|
<button class="btn-copy-summary" title="複製摘要" aria-label="複製摘要">📋</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="summary-content">${this.renderMarkdownSafely(details.summary)}</div>
|
<div class="summary-content">${this.renderMarkdownSafely(details.summary)}</div>
|
||||||
</div>
|
</div>
|
||||||
@ -254,7 +254,7 @@
|
|||||||
<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>
|
<button class="btn-copy-message" title="複製消息內容" aria-label="複製消息內容" data-message-content="${this.escapeHtml(message.content)}">📋</button>
|
||||||
</div>
|
</div>
|
||||||
${contentHtml}
|
${contentHtml}
|
||||||
</div>
|
</div>
|
||||||
@ -346,7 +346,7 @@
|
|||||||
if (!this.currentModal) return;
|
if (!this.currentModal) return;
|
||||||
|
|
||||||
// 彈窗已經通過 CSS 動畫自動顯示,無需額外處理
|
// 彈窗已經通過 CSS 動畫自動顯示,無需額外處理
|
||||||
console.log('🔍 會話詳情彈窗已顯示');
|
// console.log('🔍 會話詳情彈窗已顯示');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -395,9 +395,9 @@
|
|||||||
if (!content) return '';
|
if (!content) return '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 检查 marked 和 DOMPurify 是否可用
|
// 檢查 marked 和 DOMPurify 是否可用
|
||||||
if (typeof window.marked === 'undefined' || typeof window.DOMPurify === 'undefined') {
|
if (typeof window.marked === 'undefined' || typeof window.DOMPurify === 'undefined') {
|
||||||
console.warn('⚠️ Markdown 库未载入,使用纯文字显示');
|
console.warn('⚠️ Markdown 庫未載入,使用純文字顯示');
|
||||||
return this.escapeHtml(content);
|
return this.escapeHtml(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,156 +413,131 @@
|
|||||||
|
|
||||||
return cleanHtml;
|
return cleanHtml;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Markdown 渲染失败:', error);
|
console.error('❌ Markdown 渲染失敗:', error);
|
||||||
return this.escapeHtml(content);
|
return this.escapeHtml(content);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复制摘要内容到剪贴板
|
* 傳統複製文字到剪貼板的方法
|
||||||
*/
|
*/
|
||||||
SessionDetailsModal.prototype.copySummaryToClipboard = function() {
|
SessionDetailsModal.prototype.fallbackCopyTextToClipboard = function(text, successMessage) {
|
||||||
const self = this; // 定义 self 变量
|
const self = this;
|
||||||
|
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 {
|
try {
|
||||||
// 获取原始摘要内容(Markdown 源码)
|
const successful = document.execCommand('copy');
|
||||||
const summaryContent = this.currentSessionData && this.currentSessionData.summary ?
|
if (successful) {
|
||||||
this.currentSessionData.summary : '';
|
// console.log('✅ 內容已複製到剪貼板(傳統方法)');
|
||||||
|
self.showToast(successMessage, 'success');
|
||||||
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 {
|
} else {
|
||||||
// 降级到传统方法
|
console.error('❌ 複製失敗(傳統方法)');
|
||||||
fallbackCopyTextToClipboard(summaryContent);
|
self.showToast('❌ 複製失敗,請手動複製', 'error');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
console.error('❌ 复制摘要时发生错误:', error);
|
console.error('❌ 複製失敗:', err);
|
||||||
this.showToast('❌ 复制失败,请手动复制', 'error');
|
self.showToast('❌ 複製失敗,請手動複製', 'error');
|
||||||
|
} finally {
|
||||||
|
document.body.removeChild(textArea);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复制用户消息内容到剪贴板
|
* 複製摘要內容到剪貼板
|
||||||
|
*/
|
||||||
|
SessionDetailsModal.prototype.copySummaryToClipboard = function() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 獲取原始摘要內容(Markdown 原始碼)
|
||||||
|
const summaryContent = this.currentSessionData && this.currentSessionData.summary ?
|
||||||
|
this.currentSessionData.summary : '';
|
||||||
|
|
||||||
|
if (!summaryContent) {
|
||||||
|
console.warn('⚠️ 沒有摘要內容可複製');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用現代 Clipboard API
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
navigator.clipboard.writeText(summaryContent).then(function() {
|
||||||
|
// console.log('✅ 摘要內容已複製到剪貼板');
|
||||||
|
self.showToast('✅ 摘要已複製到剪貼板', 'success');
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.error('❌ 複製失敗:', err);
|
||||||
|
// 降級到傳統方法
|
||||||
|
self.fallbackCopyTextToClipboard(summaryContent, '✅ 摘要已複製到剪貼板');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 降級到傳統方法
|
||||||
|
this.fallbackCopyTextToClipboard(summaryContent, '✅ 摘要已複製到剪貼板');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 複製摘要時發生錯誤:', error);
|
||||||
|
this.showToast('❌ 複製失敗,請手動複製', 'error');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 複製用戶消息內容到剪貼板
|
||||||
*/
|
*/
|
||||||
SessionDetailsModal.prototype.copyMessageToClipboard = function(messageContent) {
|
SessionDetailsModal.prototype.copyMessageToClipboard = function(messageContent) {
|
||||||
if (!messageContent) {
|
if (!messageContent) {
|
||||||
console.warn('⚠️ 没有消息内容可复制');
|
console.warn('⚠️ 沒有消息內容可複製');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 使用现代 Clipboard API
|
// 使用現代 Clipboard API
|
||||||
if (navigator.clipboard && window.isSecureContext) {
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
navigator.clipboard.writeText(messageContent).then(function() {
|
navigator.clipboard.writeText(messageContent).then(function() {
|
||||||
console.log('✅ 用户消息已复制到剪贴板');
|
// console.log('✅ 用戶消息已複製到剪貼板');
|
||||||
self.showToast('✅ 消息已复制到剪贴板', 'success');
|
self.showToast('✅ 消息已複製到剪貼板', 'success');
|
||||||
}).catch(function(err) {
|
}).catch(function(err) {
|
||||||
console.error('❌ 复制失败:', err);
|
console.error('❌ 複製失敗:', err);
|
||||||
// 降级到传统方法
|
// 降級到傳統方法
|
||||||
fallbackCopyTextToClipboard(messageContent);
|
self.fallbackCopyTextToClipboard(messageContent, '✅ 消息已複製到剪貼板');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 降级到传统方法
|
// 降級到傳統方法
|
||||||
fallbackCopyTextToClipboard(messageContent);
|
this.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) {
|
} catch (error) {
|
||||||
console.error('❌ 复制用户消息时发生错误:', error);
|
console.error('❌ 複製用戶消息時發生錯誤:', error);
|
||||||
this.showToast('❌ 复制失败,请手动复制', 'error');
|
this.showToast('❌ 複製失敗,請手動複製', 'error');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示提示消息
|
* 顯示提示消息
|
||||||
*/
|
*/
|
||||||
SessionDetailsModal.prototype.showToast = function(message, type) {
|
SessionDetailsModal.prototype.showToast = function(message, type) {
|
||||||
// 创建提示元素
|
// 創建提示元素
|
||||||
const toast = document.createElement('div');
|
const toast = document.createElement('div');
|
||||||
toast.className = 'copy-toast copy-toast-' + type;
|
toast.className = 'copy-toast copy-toast-' + type;
|
||||||
toast.textContent = message;
|
toast.textContent = message;
|
||||||
|
|
||||||
// 添加到弹窗中
|
// 添加到彈窗中
|
||||||
if (this.currentModal) {
|
if (this.currentModal) {
|
||||||
this.currentModal.appendChild(toast);
|
this.currentModal.appendChild(toast);
|
||||||
|
|
||||||
// 显示动画
|
// 顯示動畫
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
toast.classList.add('show');
|
toast.classList.add('show');
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
// 自动隐藏
|
// 自動隱藏
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
toast.classList.remove('show');
|
toast.classList.remove('show');
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
@ -608,12 +583,12 @@
|
|||||||
*/
|
*/
|
||||||
SessionDetailsModal.prototype.cleanup = function() {
|
SessionDetailsModal.prototype.cleanup = function() {
|
||||||
this.forceCloseAll();
|
this.forceCloseAll();
|
||||||
console.log('🔍 SessionDetailsModal 清理完成');
|
// console.log('🔍 SessionDetailsModal 清理完成');
|
||||||
};
|
};
|
||||||
|
|
||||||
// 將 SessionDetailsModal 加入命名空間
|
// 將 SessionDetailsModal 加入命名空間
|
||||||
window.MCPFeedback.Session.DetailsModal = SessionDetailsModal;
|
window.MCPFeedback.Session.DetailsModal = SessionDetailsModal;
|
||||||
|
|
||||||
console.log('✅ SessionDetailsModal 模組載入完成');
|
// console.log('✅ SessionDetailsModal 模組載入完成');
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
console;
|
console;
|
||||||
const StatusUtils = window.MCPFeedback.Utils.Status;
|
const StatusUtils = window.MCPFeedback.Utils.Status;
|
||||||
|
|
||||||
|
// 調試模式標誌 - 生產環境應設為 false
|
||||||
|
const DEBUG_MODE = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 會話 UI 渲染器
|
* 會話 UI 渲染器
|
||||||
*/
|
*/
|
||||||
@ -80,31 +83,31 @@
|
|||||||
* 初始化專案路徑顯示
|
* 初始化專案路徑顯示
|
||||||
*/
|
*/
|
||||||
SessionUIRenderer.prototype.initializeProjectPathDisplay = function() {
|
SessionUIRenderer.prototype.initializeProjectPathDisplay = function() {
|
||||||
console.log('🎨 初始化專案路徑顯示');
|
if (DEBUG_MODE) console.log('🎨 初始化專案路徑顯示');
|
||||||
|
|
||||||
const projectPathElement = document.getElementById('projectPathDisplay');
|
const projectPathElement = document.getElementById('projectPathDisplay');
|
||||||
console.log('🎨 初始化時找到專案路徑元素:', !!projectPathElement);
|
if (DEBUG_MODE) console.log('🎨 初始化時找到專案路徑元素:', !!projectPathElement);
|
||||||
|
|
||||||
if (projectPathElement) {
|
if (projectPathElement) {
|
||||||
const fullPath = projectPathElement.getAttribute('data-full-path');
|
const fullPath = projectPathElement.getAttribute('data-full-path');
|
||||||
console.log('🎨 初始化時的完整路徑:', fullPath);
|
if (DEBUG_MODE) console.log('🎨 初始化時的完整路徑:', fullPath);
|
||||||
|
|
||||||
if (fullPath) {
|
if (fullPath) {
|
||||||
// 使用工具函數截斷路徑
|
// 使用工具函數截斷路徑
|
||||||
const pathResult = window.MCPFeedback.Utils.truncatePathFromRight(fullPath, 2, 40);
|
const pathResult = window.MCPFeedback.Utils.truncatePathFromRight(fullPath, 2, 40);
|
||||||
console.log('🎨 初始化時路徑處理:', { fullPath, shortPath: pathResult.truncated });
|
if (DEBUG_MODE) console.log('🎨 初始化時路徑處理:', { fullPath, shortPath: pathResult.truncated });
|
||||||
|
|
||||||
// 更新顯示文字
|
// 更新顯示文字
|
||||||
DOMUtils.safeSetTextContent(projectPathElement, pathResult.truncated);
|
DOMUtils.safeSetTextContent(projectPathElement, pathResult.truncated);
|
||||||
|
|
||||||
// 添加點擊複製功能
|
// 添加點擊複製功能
|
||||||
if (!projectPathElement.hasAttribute('data-copy-handler')) {
|
if (!projectPathElement.hasAttribute('data-copy-handler')) {
|
||||||
console.log('🎨 初始化時添加點擊複製功能');
|
if (DEBUG_MODE) console.log('🎨 初始化時添加點擊複製功能');
|
||||||
projectPathElement.setAttribute('data-copy-handler', 'true');
|
projectPathElement.setAttribute('data-copy-handler', 'true');
|
||||||
projectPathElement.addEventListener('click', function() {
|
projectPathElement.addEventListener('click', function() {
|
||||||
console.log('🎨 初始化的專案路徑被點擊');
|
if (DEBUG_MODE) console.log('🎨 初始化的專案路徑被點擊');
|
||||||
const fullPath = this.getAttribute('data-full-path');
|
const fullPath = this.getAttribute('data-full-path');
|
||||||
console.log('🎨 初始化時準備複製路徑:', fullPath);
|
if (DEBUG_MODE) console.log('🎨 初始化時準備複製路徑:', fullPath);
|
||||||
|
|
||||||
if (fullPath) {
|
if (fullPath) {
|
||||||
const successMessage = window.i18nManager ?
|
const successMessage = window.i18nManager ?
|
||||||
@ -114,12 +117,12 @@
|
|||||||
window.i18nManager.t('app.pathCopyFailed', '複製路徑失敗') :
|
window.i18nManager.t('app.pathCopyFailed', '複製路徑失敗') :
|
||||||
'複製路徑失敗';
|
'複製路徑失敗';
|
||||||
|
|
||||||
console.log('🎨 初始化時調用複製函數');
|
if (DEBUG_MODE) console.log('🎨 初始化時調用複製函數');
|
||||||
window.MCPFeedback.Utils.copyToClipboard(fullPath, successMessage, errorMessage);
|
window.MCPFeedback.Utils.copyToClipboard(fullPath, successMessage, errorMessage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('🎨 初始化時點擊複製功能已存在');
|
if (DEBUG_MODE) console.log('🎨 初始化時點擊複製功能已存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加 tooltip 位置自動調整
|
// 添加 tooltip 位置自動調整
|
||||||
@ -168,7 +171,7 @@
|
|||||||
* 執行實際的當前會話渲染
|
* 執行實際的當前會話渲染
|
||||||
*/
|
*/
|
||||||
SessionUIRenderer.prototype._performCurrentSessionRender = function(sessionData, isNewSession) {
|
SessionUIRenderer.prototype._performCurrentSessionRender = function(sessionData, isNewSession) {
|
||||||
console.log('🎨 渲染當前會話:', sessionData);
|
if (DEBUG_MODE) console.log('🎨 渲染當前會話:', sessionData);
|
||||||
|
|
||||||
// 更新快取
|
// 更新快取
|
||||||
this.lastRenderedData.currentSessionId = sessionData.session_id;
|
this.lastRenderedData.currentSessionId = sessionData.session_id;
|
||||||
@ -176,7 +179,7 @@
|
|||||||
|
|
||||||
// 如果是新會話,重置活躍時間定時器
|
// 如果是新會話,重置活躍時間定時器
|
||||||
if (isNewSession) {
|
if (isNewSession) {
|
||||||
console.log('🎨 檢測到新會話,重置活躍時間定時器');
|
if (DEBUG_MODE) console.log('🎨 檢測到新會話,重置活躍時間定時器');
|
||||||
this.resetActiveTimeTimer();
|
this.resetActiveTimeTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,17 +261,17 @@
|
|||||||
* 更新頂部狀態列的專案路徑顯示
|
* 更新頂部狀態列的專案路徑顯示
|
||||||
*/
|
*/
|
||||||
SessionUIRenderer.prototype.updateTopProjectPathDisplay = function(sessionData) {
|
SessionUIRenderer.prototype.updateTopProjectPathDisplay = function(sessionData) {
|
||||||
console.log('🎨 updateProjectPathDisplay 被調用:', sessionData);
|
if (DEBUG_MODE) console.log('🎨 updateProjectPathDisplay 被調用:', sessionData);
|
||||||
|
|
||||||
const projectPathElement = document.getElementById('projectPathDisplay');
|
const projectPathElement = document.getElementById('projectPathDisplay');
|
||||||
console.log('🎨 找到專案路徑元素:', !!projectPathElement);
|
if (DEBUG_MODE) console.log('🎨 找到專案路徑元素:', !!projectPathElement);
|
||||||
|
|
||||||
if (projectPathElement && sessionData.project_directory) {
|
if (projectPathElement && sessionData.project_directory) {
|
||||||
const fullPath = sessionData.project_directory;
|
const fullPath = sessionData.project_directory;
|
||||||
|
|
||||||
// 使用工具函數截斷路徑
|
// 使用工具函數截斷路徑
|
||||||
const pathResult = window.MCPFeedback.Utils.truncatePathFromRight(fullPath, 2, 40);
|
const pathResult = window.MCPFeedback.Utils.truncatePathFromRight(fullPath, 2, 40);
|
||||||
console.log('🎨 路徑處理:', { fullPath, shortPath: pathResult.truncated });
|
if (DEBUG_MODE) console.log('🎨 路徑處理:', { fullPath, shortPath: pathResult.truncated });
|
||||||
|
|
||||||
// 更新顯示文字
|
// 更新顯示文字
|
||||||
DOMUtils.safeSetTextContent(projectPathElement, pathResult.truncated);
|
DOMUtils.safeSetTextContent(projectPathElement, pathResult.truncated);
|
||||||
@ -278,12 +281,12 @@
|
|||||||
|
|
||||||
// 添加點擊複製功能(如果還沒有)
|
// 添加點擊複製功能(如果還沒有)
|
||||||
if (!projectPathElement.hasAttribute('data-copy-handler')) {
|
if (!projectPathElement.hasAttribute('data-copy-handler')) {
|
||||||
console.log('🎨 添加點擊複製功能');
|
if (DEBUG_MODE) console.log('🎨 添加點擊複製功能');
|
||||||
projectPathElement.setAttribute('data-copy-handler', 'true');
|
projectPathElement.setAttribute('data-copy-handler', 'true');
|
||||||
projectPathElement.addEventListener('click', function() {
|
projectPathElement.addEventListener('click', function() {
|
||||||
console.log('🎨 專案路徑被點擊');
|
if (DEBUG_MODE) console.log('🎨 專案路徑被點擊');
|
||||||
const fullPath = this.getAttribute('data-full-path');
|
const fullPath = this.getAttribute('data-full-path');
|
||||||
console.log('🎨 準備複製路徑:', fullPath);
|
if (DEBUG_MODE) console.log('🎨 準備複製路徑:', fullPath);
|
||||||
|
|
||||||
if (fullPath) {
|
if (fullPath) {
|
||||||
const successMessage = window.i18nManager ?
|
const successMessage = window.i18nManager ?
|
||||||
@ -293,12 +296,12 @@
|
|||||||
window.i18nManager.t('app.pathCopyFailed', '複製路徑失敗') :
|
window.i18nManager.t('app.pathCopyFailed', '複製路徑失敗') :
|
||||||
'複製路徑失敗';
|
'複製路徑失敗';
|
||||||
|
|
||||||
console.log('🎨 調用複製函數');
|
if (DEBUG_MODE) console.log('🎨 調用複製函數');
|
||||||
window.MCPFeedback.Utils.copyToClipboard(fullPath, successMessage, errorMessage);
|
window.MCPFeedback.Utils.copyToClipboard(fullPath, successMessage, errorMessage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('🎨 點擊複製功能已存在');
|
if (DEBUG_MODE) console.log('🎨 點擊複製功能已存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加 tooltip 位置自動調整
|
// 添加 tooltip 位置自動調整
|
||||||
@ -352,7 +355,7 @@
|
|||||||
SessionUIRenderer.prototype.updateSessionStatusBar = function(sessionData) {
|
SessionUIRenderer.prototype.updateSessionStatusBar = function(sessionData) {
|
||||||
if (!sessionData) return;
|
if (!sessionData) return;
|
||||||
|
|
||||||
console.log('🎨 更新會話狀態列:', sessionData);
|
if (DEBUG_MODE) console.log('🎨 更新會話狀態列:', sessionData);
|
||||||
|
|
||||||
// 更新當前會話 ID - 顯示縮短版本,完整ID存在data-full-id中
|
// 更新當前會話 ID - 顯示縮短版本,完整ID存在data-full-id中
|
||||||
const currentSessionElement = document.getElementById('currentSessionId');
|
const currentSessionElement = document.getElementById('currentSessionId');
|
||||||
@ -413,7 +416,7 @@
|
|||||||
* 執行實際的會話歷史渲染
|
* 執行實際的會話歷史渲染
|
||||||
*/
|
*/
|
||||||
SessionUIRenderer.prototype._performHistoryRender = function(sessionHistory) {
|
SessionUIRenderer.prototype._performHistoryRender = function(sessionHistory) {
|
||||||
console.log('🎨 渲染會話歷史:', sessionHistory.length, '個會話');
|
if (DEBUG_MODE) console.log('🎨 渲染會話歷史:', sessionHistory.length, '個會話');
|
||||||
|
|
||||||
// 更新快取
|
// 更新快取
|
||||||
this.lastRenderedData.historyLength = sessionHistory.length;
|
this.lastRenderedData.historyLength = sessionHistory.length;
|
||||||
@ -477,23 +480,39 @@
|
|||||||
SessionUIRenderer.prototype.createSessionHeader = function(sessionData) {
|
SessionUIRenderer.prototype.createSessionHeader = function(sessionData) {
|
||||||
const header = DOMUtils.createElement('div', { className: 'session-header' });
|
const header = DOMUtils.createElement('div', { className: 'session-header' });
|
||||||
|
|
||||||
// 會話 ID
|
// 會話 ID 容器
|
||||||
const sessionIdLabel = window.i18nManager ? window.i18nManager.t('sessionManagement.sessionId') : '會話 ID';
|
const sessionIdContainer = DOMUtils.createElement('div', {
|
||||||
const sessionId = DOMUtils.createElement('div', {
|
className: 'session-id'
|
||||||
className: 'session-id',
|
|
||||||
textContent: sessionIdLabel + ': ' + (sessionData.session_id || '').substring(0, 8) + '...'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 會話 ID 標籤
|
||||||
|
const sessionIdLabel = DOMUtils.createElement('span', {
|
||||||
|
attributes: {
|
||||||
|
'data-i18n': 'sessionManagement.sessionId'
|
||||||
|
},
|
||||||
|
textContent: window.i18nManager ? window.i18nManager.t('sessionManagement.sessionId') : '會話 ID'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 會話 ID 值
|
||||||
|
const sessionIdValue = DOMUtils.createElement('span', {
|
||||||
|
textContent: ': ' + (sessionData.session_id || '').substring(0, 8) + '...'
|
||||||
|
});
|
||||||
|
|
||||||
|
sessionIdContainer.appendChild(sessionIdLabel);
|
||||||
|
sessionIdContainer.appendChild(sessionIdValue);
|
||||||
|
|
||||||
// 狀態徽章
|
// 狀態徽章
|
||||||
const statusContainer = DOMUtils.createElement('div', { className: 'session-status' });
|
const statusContainer = DOMUtils.createElement('div', { className: 'session-status' });
|
||||||
const statusText = StatusUtils.getStatusText(sessionData.status);
|
const statusText = StatusUtils.getStatusText(sessionData.status);
|
||||||
|
|
||||||
// 添加調試信息
|
// 添加調試信息
|
||||||
console.log('🎨 會話狀態調試:', {
|
if (DEBUG_MODE) {
|
||||||
sessionId: sessionData.session_id ? sessionData.session_id.substring(0, 8) + '...' : 'unknown',
|
console.log('🎨 會話狀態調試:', {
|
||||||
rawStatus: sessionData.status,
|
sessionId: sessionData.session_id ? sessionData.session_id.substring(0, 8) + '...' : 'unknown',
|
||||||
displayText: statusText
|
rawStatus: sessionData.status,
|
||||||
});
|
displayText: statusText
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const statusBadge = DOMUtils.createElement('span', {
|
const statusBadge = DOMUtils.createElement('span', {
|
||||||
className: 'status-badge ' + (sessionData.status || 'waiting'),
|
className: 'status-badge ' + (sessionData.status || 'waiting'),
|
||||||
@ -501,7 +520,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
statusContainer.appendChild(statusBadge);
|
statusContainer.appendChild(statusBadge);
|
||||||
header.appendChild(sessionId);
|
header.appendChild(sessionIdContainer);
|
||||||
header.appendChild(statusContainer);
|
header.appendChild(statusContainer);
|
||||||
|
|
||||||
return header;
|
return header;
|
||||||
@ -513,31 +532,57 @@
|
|||||||
SessionUIRenderer.prototype.createSessionInfo = function(sessionData, isHistory) {
|
SessionUIRenderer.prototype.createSessionInfo = function(sessionData, isHistory) {
|
||||||
const info = DOMUtils.createElement('div', { className: 'session-info' });
|
const info = DOMUtils.createElement('div', { className: 'session-info' });
|
||||||
|
|
||||||
// 時間資訊
|
// 時間資訊容器
|
||||||
|
const timeContainer = DOMUtils.createElement('div', {
|
||||||
|
className: 'session-time'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 時間標籤
|
||||||
|
const timeLabelKey = isHistory ? 'sessionManagement.createdTime' : 'sessionManagement.createdTime';
|
||||||
|
const timeLabel = DOMUtils.createElement('span', {
|
||||||
|
attributes: {
|
||||||
|
'data-i18n': timeLabelKey
|
||||||
|
},
|
||||||
|
textContent: window.i18nManager ? window.i18nManager.t(timeLabelKey) : '建立時間'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 時間值
|
||||||
const timeText = sessionData.created_at ?
|
const timeText = sessionData.created_at ?
|
||||||
TimeUtils.formatTimestamp(sessionData.created_at, { format: 'time' }) :
|
TimeUtils.formatTimestamp(sessionData.created_at, { format: 'time' }) :
|
||||||
'--:--:--';
|
'--:--:--';
|
||||||
|
const timeValue = DOMUtils.createElement('span', {
|
||||||
const timeLabel = isHistory ?
|
textContent: ': ' + timeText
|
||||||
(window.i18nManager ? window.i18nManager.t('sessionManagement.sessionDetails.duration') : '完成時間') :
|
|
||||||
(window.i18nManager ? window.i18nManager.t('sessionManagement.createdTime') : '建立時間');
|
|
||||||
|
|
||||||
const timeElement = DOMUtils.createElement('div', {
|
|
||||||
className: 'session-time',
|
|
||||||
textContent: timeLabel + ': ' + timeText
|
|
||||||
});
|
});
|
||||||
|
|
||||||
info.appendChild(timeElement);
|
timeContainer.appendChild(timeLabel);
|
||||||
|
timeContainer.appendChild(timeValue);
|
||||||
|
info.appendChild(timeContainer);
|
||||||
|
|
||||||
// 歷史會話顯示持續時間
|
// 歷史會話顯示持續時間
|
||||||
if (isHistory) {
|
if (isHistory) {
|
||||||
const duration = this.calculateDisplayDuration(sessionData);
|
const duration = this.calculateDisplayDuration(sessionData);
|
||||||
const durationLabel = window.i18nManager ? window.i18nManager.t('sessionManagement.sessionDetails.duration') : '持續時間';
|
|
||||||
const durationElement = DOMUtils.createElement('div', {
|
// 持續時間容器
|
||||||
className: 'session-duration',
|
const durationContainer = DOMUtils.createElement('div', {
|
||||||
textContent: durationLabel + ': ' + duration
|
className: 'session-duration'
|
||||||
});
|
});
|
||||||
info.appendChild(durationElement);
|
|
||||||
|
// 持續時間標籤
|
||||||
|
const durationLabel = DOMUtils.createElement('span', {
|
||||||
|
attributes: {
|
||||||
|
'data-i18n': 'sessionManagement.sessionDetails.duration'
|
||||||
|
},
|
||||||
|
textContent: window.i18nManager ? window.i18nManager.t('sessionManagement.sessionDetails.duration') : '持續時間'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 持續時間值
|
||||||
|
const durationValue = DOMUtils.createElement('span', {
|
||||||
|
textContent: ': ' + duration
|
||||||
|
});
|
||||||
|
|
||||||
|
durationContainer.appendChild(durationLabel);
|
||||||
|
durationContainer.appendChild(durationValue);
|
||||||
|
info.appendChild(durationContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
@ -564,13 +609,13 @@
|
|||||||
SessionUIRenderer.prototype.createSessionActions = function(sessionData, isHistory) {
|
SessionUIRenderer.prototype.createSessionActions = function(sessionData, isHistory) {
|
||||||
const actions = DOMUtils.createElement('div', { className: 'session-actions' });
|
const actions = DOMUtils.createElement('div', { className: 'session-actions' });
|
||||||
|
|
||||||
const buttonText = isHistory ?
|
// 查看詳情按鈕
|
||||||
(window.i18nManager ? window.i18nManager.t('sessionManagement.viewDetails') : '查看') :
|
|
||||||
(window.i18nManager ? window.i18nManager.t('sessionManagement.viewDetails') : '詳細資訊');
|
|
||||||
|
|
||||||
const viewButton = DOMUtils.createElement('button', {
|
const viewButton = DOMUtils.createElement('button', {
|
||||||
className: 'btn-small',
|
className: 'btn-small',
|
||||||
textContent: buttonText
|
attributes: {
|
||||||
|
'data-i18n': 'sessionManagement.viewDetails'
|
||||||
|
},
|
||||||
|
textContent: window.i18nManager ? window.i18nManager.t('sessionManagement.viewDetails') : '詳細資訊'
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加查看詳情點擊事件
|
// 添加查看詳情點擊事件
|
||||||
@ -586,7 +631,10 @@
|
|||||||
if (isHistory) {
|
if (isHistory) {
|
||||||
const exportButton = DOMUtils.createElement('button', {
|
const exportButton = DOMUtils.createElement('button', {
|
||||||
className: 'btn-small btn-export',
|
className: 'btn-small btn-export',
|
||||||
textContent: window.i18nManager ? window.i18nManager.t('sessionHistory.management.exportSingle') : '匯出',
|
attributes: {
|
||||||
|
'data-i18n': 'sessionHistory.management.exportSingle'
|
||||||
|
},
|
||||||
|
textContent: window.i18nManager ? window.i18nManager.t('sessionHistory.management.exportSingle') : '匯出此會話',
|
||||||
style: 'margin-left: 4px; font-size: 11px; padding: 2px 6px;'
|
style: 'margin-left: 4px; font-size: 11px; padding: 2px 6px;'
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -695,7 +743,7 @@
|
|||||||
self.updateActiveTime();
|
self.updateActiveTime();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
console.log('🎨 活躍時間定時器已啟動');
|
if (DEBUG_MODE) console.log('🎨 活躍時間定時器已啟動');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -705,7 +753,7 @@
|
|||||||
if (this.activeTimeTimer) {
|
if (this.activeTimeTimer) {
|
||||||
clearInterval(this.activeTimeTimer);
|
clearInterval(this.activeTimeTimer);
|
||||||
this.activeTimeTimer = null;
|
this.activeTimeTimer = null;
|
||||||
console.log('🎨 活躍時間定時器已停止');
|
if (DEBUG_MODE) console.log('🎨 活躍時間定時器已停止');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -758,12 +806,12 @@
|
|||||||
currentSessionId: null
|
currentSessionId: null
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('🎨 SessionUIRenderer 清理完成');
|
if (DEBUG_MODE) console.log('🎨 SessionUIRenderer 清理完成');
|
||||||
};
|
};
|
||||||
|
|
||||||
// 將 SessionUIRenderer 加入命名空間
|
// 將 SessionUIRenderer 加入命名空間
|
||||||
window.MCPFeedback.Session.UIRenderer = SessionUIRenderer;
|
window.MCPFeedback.Session.UIRenderer = SessionUIRenderer;
|
||||||
|
|
||||||
console.log('✅ SessionUIRenderer 模組載入完成');
|
if (DEBUG_MODE) console.log('✅ SessionUIRenderer 模組載入完成');
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -657,8 +657,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="session-actions">
|
<div class="session-actions">
|
||||||
<button class="btn-small" id="viewSessionDetails" data-i18n="sessionManagement.viewDetails">詳細資訊</button>
|
<button class="btn-small" id="viewSessionDetails" data-i18n="sessionManagement.viewDetails">詳細資訊</button>
|
||||||
<button class="btn-small btn-primary" id="copyCurrentSessionContent" title="复制当前会话内容">📋 复制会话内容</button>
|
<button class="btn-small btn-primary" id="copyCurrentSessionContent"
|
||||||
<button class="btn-small btn-secondary" id="copyCurrentUserContent" title="复制当前用户发送的内容">📝 复制用户内容</button>
|
data-i18n="sessionManagement.copySessionContent"
|
||||||
|
data-i18n-title="sessionManagement.copySessionContent"
|
||||||
|
aria-label="複製會話內容">
|
||||||
|
📋 <span data-i18n="sessionManagement.copySessionContent">複製會話內容</span>
|
||||||
|
</button>
|
||||||
|
<button class="btn-small btn-secondary" id="copyCurrentUserContent"
|
||||||
|
data-i18n="sessionManagement.copyUserContent"
|
||||||
|
data-i18n-title="sessionManagement.copyUserContent"
|
||||||
|
aria-label="複製用戶內容">
|
||||||
|
📝 <span data-i18n="sessionManagement.copyUserContent">複製用戶內容</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user