diff --git a/src/mcp_feedback_enhanced/web/routes/main_routes.py b/src/mcp_feedback_enhanced/web/routes/main_routes.py
index b02bda3..2bbd386 100644
--- a/src/mcp_feedback_enhanced/web/routes/main_routes.py
+++ b/src/mcp_feedback_enhanced/web/routes/main_routes.py
@@ -73,7 +73,8 @@ def setup_routes(manager: 'WebUIManager'):
"title": "Interactive Feedback - 回饋收集",
"version": __version__,
"has_session": True,
- "layout_mode": layout_mode
+ "layout_mode": layout_mode,
+ "i18n": manager.i18n
})
@manager.app.get("/api/translations")
diff --git a/src/mcp_feedback_enhanced/web/static/js/app.js b/src/mcp_feedback_enhanced/web/static/js/app.js
index 6dd351e..c375616 100644
--- a/src/mcp_feedback_enhanced/web/static/js/app.js
+++ b/src/mcp_feedback_enhanced/web/static/js/app.js
@@ -220,6 +220,9 @@ class FeedbackApp {
// 初始化圖片處理
this.initImageHandling();
+ // 確保狀態指示器使用正確的翻譯(在國際化系統載入後)
+ this.updateStatusIndicators();
+
// 設置頁面關閉時的清理
window.addEventListener('beforeunload', () => {
if (this.tabManager) {
@@ -571,76 +574,87 @@ class FeedbackApp {
}
/**
- * 更新狀態指示器
+ * 更新狀態指示器(新版本:只更新現有元素的狀態)
*/
updateStatusIndicator() {
- let statusElement = document.getElementById('feedbackStatusIndicator');
+ // 獲取狀態指示器元素
+ const feedbackStatusIndicator = document.getElementById('feedbackStatusIndicator');
+ const combinedStatusIndicator = document.getElementById('combinedFeedbackStatusIndicator');
- // 如果狀態指示器不存在,創建一個
- if (!statusElement) {
- statusElement = document.createElement('div');
- statusElement.id = 'feedbackStatusIndicator';
- statusElement.className = 'feedback-status-indicator';
-
- // 插入到回饋區域的頂部
- const feedbackContainer = document.querySelector('.feedback-container') ||
- document.querySelector('#tab-feedback') ||
- document.body;
- feedbackContainer.insertBefore(statusElement, feedbackContainer.firstChild);
- }
-
- // 更新狀態指示器內容
- let statusHTML = '';
- let statusClass = '';
+ // 根據當前狀態確定圖示、標題和訊息
+ let icon, title, message, status;
switch (this.feedbackState) {
case 'waiting_for_feedback':
- const waitingTitle = window.i18nManager ? window.i18nManager.t('status.waiting.title') : '等待回饋';
- const waitingMessage = window.i18nManager ? window.i18nManager.t('status.waiting.message') : '請提供您的回饋意見';
- statusHTML = `
-
⏳
-
- ${waitingTitle}
- ${waitingMessage}
-
- `;
- statusClass = 'status-waiting';
+ icon = '⏳';
+ title = window.i18nManager ? window.i18nManager.t('status.waiting.title') : '等待回饋';
+ message = window.i18nManager ? window.i18nManager.t('status.waiting.message') : '請提供您的回饋意見';
+ status = 'waiting';
break;
case 'processing':
- const processingTitle = window.i18nManager ? window.i18nManager.t('status.processing.title') : '處理中';
- const processingMessage = window.i18nManager ? window.i18nManager.t('status.processing.message') : '正在提交您的回饋...';
- statusHTML = `
- ⚙️
-
- ${processingTitle}
- ${processingMessage}
-
- `;
- statusClass = 'status-processing';
+ icon = '⚙️';
+ title = window.i18nManager ? window.i18nManager.t('status.processing.title') : '處理中';
+ message = window.i18nManager ? window.i18nManager.t('status.processing.message') : '正在提交您的回饋...';
+ status = 'processing';
break;
case 'feedback_submitted':
const timeStr = this.lastSubmissionTime ?
new Date(this.lastSubmissionTime).toLocaleTimeString() : '';
- const submittedTitle = window.i18nManager ? window.i18nManager.t('status.submitted.title') : '回饋已提交';
- const submittedMessage = window.i18nManager ? window.i18nManager.t('status.submitted.message') : '等待下次 MCP 調用';
- statusHTML = `
- ✅
-
- ${submittedTitle}
- ${submittedMessage} ${timeStr ? `(${timeStr})` : ''}
-
- `;
- statusClass = 'status-submitted';
+ icon = '✅';
+ title = window.i18nManager ? window.i18nManager.t('status.submitted.title') : '回饋已提交';
+ message = window.i18nManager ? window.i18nManager.t('status.submitted.message') : '等待下次 MCP 調用';
+ if (timeStr) {
+ message += ` (${timeStr})`;
+ }
+ status = 'submitted';
break;
+
+ default:
+ // 預設狀態
+ icon = '⏳';
+ title = '等待回饋';
+ message = '請提供您的回饋意見';
+ status = 'waiting';
}
- statusElement.innerHTML = statusHTML;
- statusElement.className = `feedback-status-indicator ${statusClass}`;
+ // 更新分頁模式的狀態指示器
+ if (feedbackStatusIndicator) {
+ this.updateStatusIndicatorElement(feedbackStatusIndicator, status, icon, title, message);
+ }
- // 同步到合併模式的狀態指示器
- this.syncFeedbackStatusToCombined();
+ // 更新合併模式的狀態指示器
+ if (combinedStatusIndicator) {
+ this.updateStatusIndicatorElement(combinedStatusIndicator, status, icon, title, message);
+ }
+
+ console.log(`✅ 狀態指示器已更新: ${status} - ${title}`);
+ }
+
+ /**
+ * 更新單個狀態指示器元素
+ */
+ updateStatusIndicatorElement(element, status, icon, title, message) {
+ if (!element) return;
+
+ // 更新狀態類別
+ element.className = `feedback-status-indicator status-${status}`;
+ element.style.display = 'block';
+
+ // 更新標題(包含圖示)
+ const titleElement = element.querySelector('.status-title');
+ if (titleElement) {
+ titleElement.textContent = `${icon} ${title}`;
+ }
+
+ // 更新訊息
+ const messageElement = element.querySelector('.status-message');
+ if (messageElement) {
+ messageElement.textContent = message;
+ }
+
+ console.log(`🔧 已更新狀態指示器: ${element.id} -> ${status}`);
}
setupWebSocket() {
@@ -805,7 +819,7 @@ class FeedbackApp {
console.log('🔄 處理會話更新:', data.session_info);
// 顯示更新通知
- this.showSuccessMessage(data.message || '會話已更新,正在刷新內容...');
+ this.showSuccessMessage(data.message || '會話已更新,正在局部更新內容...');
// 重置回饋狀態為等待新回饋
this.setFeedbackState('waiting_for_feedback');
@@ -820,7 +834,7 @@ class FeedbackApp {
document.title = `MCP Feedback - ${projectName}`;
}
- // 刷新頁面內容以顯示新的 AI 工作摘要
+ // 使用局部更新替代整頁刷新
this.refreshPageContent();
}
@@ -828,27 +842,155 @@ class FeedbackApp {
}
async refreshPageContent() {
- console.log('🔄 刷新頁面內容...');
+ console.log('🔄 局部更新頁面內容...');
try {
- // 保存當前標籤頁狀態到 localStorage(防止重新載入時丟失)
+ // 保存當前標籤頁狀態到 localStorage
if (this.tabManager) {
this.tabManager.updateLastActivity();
}
- // 延遲一小段時間確保狀態保存完成
- await new Promise(resolve => setTimeout(resolve, 100));
-
- // 重新載入頁面以獲取新的會話內容
- window.location.reload();
+ // 使用局部更新替代整頁刷新
+ await this.updatePageContentPartially();
} catch (error) {
- console.error('刷新頁面內容失敗:', error);
+ console.error('局部更新頁面內容失敗:', error);
// 備用方案:顯示提示讓用戶手動刷新
- this.showMessage('請手動刷新頁面以查看新的 AI 工作摘要', 'info');
+ this.showMessage('更新內容失敗,請手動刷新頁面以查看新的 AI 工作摘要', 'warning');
}
}
+ /**
+ * 局部更新頁面內容,避免整頁刷新
+ */
+ async updatePageContentPartially() {
+ console.log('🔄 開始局部更新頁面內容...');
+
+ try {
+ // 1. 獲取最新的會話資料
+ const response = await fetch('/api/current-session');
+ if (!response.ok) {
+ throw new Error(`API 請求失敗: ${response.status}`);
+ }
+
+ const sessionData = await response.json();
+ console.log('📥 獲取到最新會話資料:', sessionData);
+
+ // 2. 更新 AI 摘要內容
+ this.updateAISummaryContent(sessionData.summary);
+
+ // 3. 重置回饋表單
+ this.resetFeedbackForm();
+
+ // 4. 更新狀態指示器
+ this.updateStatusIndicators();
+
+ // 5. 更新頁面標題
+ if (sessionData.project_directory) {
+ const projectName = sessionData.project_directory.split(/[/\\]/).pop();
+ document.title = `MCP Feedback - ${projectName}`;
+ }
+
+ console.log('✅ 局部更新完成');
+
+ } catch (error) {
+ console.error('❌ 局部更新失敗:', error);
+ throw error; // 重新拋出錯誤,讓調用者處理
+ }
+ }
+
+ /**
+ * 更新 AI 摘要內容
+ */
+ updateAISummaryContent(summary) {
+ console.log('📝 更新 AI 摘要內容...');
+
+ // 更新分頁模式的摘要內容
+ const summaryContent = document.getElementById('summaryContent');
+ if (summaryContent) {
+ summaryContent.textContent = summary;
+ console.log('✅ 已更新分頁模式摘要內容');
+ }
+
+ // 更新合併模式的摘要內容
+ const combinedSummaryContent = document.getElementById('combinedSummaryContent');
+ if (combinedSummaryContent) {
+ combinedSummaryContent.textContent = summary;
+ console.log('✅ 已更新合併模式摘要內容');
+ }
+ }
+
+ /**
+ * 重置回饋表單
+ */
+ resetFeedbackForm() {
+ console.log('🔄 重置回饋表單...');
+
+ // 清空分頁模式的回饋輸入
+ const feedbackText = document.getElementById('feedbackText');
+ if (feedbackText) {
+ feedbackText.value = '';
+ feedbackText.disabled = false;
+ console.log('✅ 已重置分頁模式回饋輸入');
+ }
+
+ // 清空合併模式的回饋輸入
+ const combinedFeedbackText = document.getElementById('combinedFeedbackText');
+ if (combinedFeedbackText) {
+ combinedFeedbackText.value = '';
+ combinedFeedbackText.disabled = false;
+ console.log('✅ 已重置合併模式回饋輸入');
+ }
+
+ // 重置圖片上傳組件
+ this.images = [];
+ this.updateImagePreview();
+
+ // 重新啟用提交按鈕
+ const submitButtons = document.querySelectorAll('.submit-button, #submitButton, #combinedSubmitButton');
+ submitButtons.forEach(button => {
+ if (button) {
+ button.disabled = false;
+ button.textContent = button.getAttribute('data-original-text') || '提交回饋';
+ }
+ });
+
+ console.log('✅ 回饋表單重置完成');
+ }
+
+ /**
+ * 更新狀態指示器
+ */
+ updateStatusIndicators() {
+ console.log('🔄 更新狀態指示器...');
+
+ // 使用國際化系統獲取翻譯文字
+ const waitingTitle = window.i18nManager ? window.i18nManager.t('status.waiting.title') : 'Waiting for Feedback';
+ const waitingMessage = window.i18nManager ? window.i18nManager.t('status.waiting.message') : 'Please provide your feedback on the AI work results';
+
+ // 更新分頁模式的狀態指示器
+ const feedbackStatusIndicator = document.getElementById('feedbackStatusIndicator');
+ if (feedbackStatusIndicator) {
+ this.setStatusIndicator(feedbackStatusIndicator, 'waiting', '⏳', waitingTitle, waitingMessage);
+ }
+
+ // 更新合併模式的狀態指示器
+ const combinedFeedbackStatusIndicator = document.getElementById('combinedFeedbackStatusIndicator');
+ if (combinedFeedbackStatusIndicator) {
+ this.setStatusIndicator(combinedFeedbackStatusIndicator, 'waiting', '⏳', waitingTitle, waitingMessage);
+ }
+
+ console.log('✅ 狀態指示器更新完成');
+ }
+
+ /**
+ * 設置狀態指示器的內容(兼容舊版本調用)
+ */
+ setStatusIndicator(element, status, icon, title, message) {
+ // 直接調用新的更新方法
+ this.updateStatusIndicatorElement(element, status, icon, title, message);
+ }
+
handleStatusUpdate(statusInfo) {
console.log('處理狀態更新:', statusInfo);
@@ -1686,29 +1828,13 @@ class FeedbackApp {
}
syncFeedbackStatusToCombined() {
- // 同步等待回饋狀態指示器到合併模式
- const mainStatusIndicator = document.getElementById('feedbackStatusIndicator');
- const combinedStatusIndicator = document.getElementById('combinedFeedbackStatusIndicator');
-
- if (mainStatusIndicator && combinedStatusIndicator) {
- // 複製狀態
- combinedStatusIndicator.className = mainStatusIndicator.className;
- combinedStatusIndicator.style.display = mainStatusIndicator.style.display;
- combinedStatusIndicator.innerHTML = mainStatusIndicator.innerHTML;
- }
+ // 新版本:直接調用 updateStatusIndicator() 來同步狀態
+ // 因為 updateStatusIndicator() 現在會同時更新兩個狀態指示器
+ console.log('🔄 同步狀態指示器到合併模式...');
+ // 不需要手動複製,updateStatusIndicator() 會處理所有狀態指示器
}
- showSuccessMessage() {
- // 顯示成功提交的消息
- const message = document.createElement('div');
- message.className = 'success-message';
- message.textContent = '回饋已成功提交!';
- document.body.appendChild(message);
- setTimeout(() => {
- message.remove();
- }, 3000);
- }
}
// 注意:應用程式由模板中的 initializeApp() 函數初始化
diff --git a/src/mcp_feedback_enhanced/web/templates/components/status-indicator.html b/src/mcp_feedback_enhanced/web/templates/components/status-indicator.html
index d14caa2..4afebcb 100644
--- a/src/mcp_feedback_enhanced/web/templates/components/status-indicator.html
+++ b/src/mcp_feedback_enhanced/web/templates/components/status-indicator.html
@@ -24,9 +24,8 @@
{% set icon = icon or "⏳" %}
-
{{ icon }}
- {{ title }}
- {{ message }}
+ {{ icon }} {{ title }}
+ {{ message }}
diff --git a/src/mcp_feedback_enhanced/web/templates/feedback.html b/src/mcp_feedback_enhanced/web/templates/feedback.html
index 27acff0..2318419 100644
--- a/src/mcp_feedback_enhanced/web/templates/feedback.html
+++ b/src/mcp_feedback_enhanced/web/templates/feedback.html
@@ -311,34 +311,27 @@
/* 回饋狀態指示器樣式 */
.feedback-status-indicator {
- display: flex;
- align-items: center;
padding: 12px 16px;
margin: 16px 0;
border-radius: 8px;
border: 1px solid;
- background: var(--card-bg);
+ background: var(--bg-secondary);
transition: all 0.3s ease;
}
- .feedback-status-indicator .status-icon {
- font-size: 24px;
- margin-right: 12px;
- min-width: 32px;
- text-align: center;
- }
-
.feedback-status-indicator .status-text {
- flex: 1;
+ width: 100%;
}
- .feedback-status-indicator .status-text strong {
+ .feedback-status-indicator .status-text strong,
+ .feedback-status-indicator .status-title {
display: block;
font-size: 16px;
margin-bottom: 4px;
}
- .feedback-status-indicator .status-text span {
+ .feedback-status-indicator .status-text span,
+ .feedback-status-indicator .status-message {
font-size: 14px;
opacity: 0.8;
}
@@ -431,7 +424,15 @@
請提供您對 AI 工作成果的回饋意見。您可以輸入文字回饋並上傳相關圖片。
-
+
+
+ {% set id = "feedbackStatusIndicator" %}
+ {% set status = "waiting" %}
+ {% set icon = "⏳" %}
+ {% set title = "等待回饋" %}
+ {% set message = "請提供您的回饋意見" %}
+ {% include 'components/status-indicator.html' %}
+
文字回饋