2025-06-03 06:50:19 +08:00
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* MCP Feedback Enhanced - 主應用程式
|
|
|
|
|
* =================================
|
2025-06-06 16:44:24 +08:00
|
|
|
|
*
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 模組化重構版本,整合所有功能模組
|
2025-06-13 05:48:08 +08:00
|
|
|
|
* 依賴模組載入順序:utils -> tab-manager -> websocket-manager -> connection-monitor ->
|
|
|
|
|
* session-manager -> image-handler -> settings-manager -> ui-manager ->
|
|
|
|
|
* auto-refresh-manager -> app
|
2025-06-03 06:50:19 +08:00
|
|
|
|
*/
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
(function() {
|
|
|
|
|
'use strict';
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 確保命名空間存在
|
|
|
|
|
window.MCPFeedback = window.MCPFeedback || {};
|
|
|
|
|
const Utils = window.MCPFeedback.Utils;
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 主應用程式建構函數
|
|
|
|
|
*/
|
|
|
|
|
function FeedbackApp(sessionId) {
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 會話信息
|
|
|
|
|
this.sessionId = sessionId;
|
|
|
|
|
this.currentSessionId = null;
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 模組管理器
|
|
|
|
|
this.tabManager = null;
|
|
|
|
|
this.webSocketManager = null;
|
2025-06-13 05:48:08 +08:00
|
|
|
|
this.connectionMonitor = null;
|
|
|
|
|
this.sessionManager = null;
|
2025-06-10 07:19:47 +08:00
|
|
|
|
this.imageHandler = null;
|
|
|
|
|
this.settingsManager = null;
|
|
|
|
|
this.uiManager = null;
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 應用程式狀態
|
|
|
|
|
this.isInitialized = false;
|
|
|
|
|
this.pendingSubmission = null;
|
2025-06-03 15:09:08 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
console.log('🚀 FeedbackApp 建構函數初始化完成');
|
2025-06-06 22:11:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 初始化應用程式
|
2025-06-06 22:11:18 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.init = function() {
|
|
|
|
|
const self = this;
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
console.log('🚀 初始化 MCP Feedback Enhanced 應用程式');
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
|
|
|
try {
|
|
|
|
|
// 等待國際化系統
|
|
|
|
|
self.waitForI18n()
|
|
|
|
|
.then(function() {
|
|
|
|
|
return self.initializeManagers();
|
|
|
|
|
})
|
|
|
|
|
.then(function() {
|
|
|
|
|
return self.setupEventListeners();
|
|
|
|
|
})
|
|
|
|
|
.then(function() {
|
|
|
|
|
return self.setupCleanupHandlers();
|
|
|
|
|
})
|
|
|
|
|
.then(function() {
|
|
|
|
|
self.isInitialized = true;
|
|
|
|
|
console.log('✅ MCP Feedback Enhanced 應用程式初始化完成');
|
|
|
|
|
resolve();
|
|
|
|
|
})
|
|
|
|
|
.catch(function(error) {
|
|
|
|
|
console.error('❌ 應用程式初始化失敗:', error);
|
|
|
|
|
reject(error);
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('❌ 應用程式初始化異常:', error);
|
|
|
|
|
reject(error);
|
2025-06-06 16:44:24 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 等待國際化系統載入
|
2025-06-06 22:11:18 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.waitForI18n = function() {
|
|
|
|
|
return new Promise(function(resolve) {
|
|
|
|
|
if (window.i18nManager) {
|
|
|
|
|
window.i18nManager.init().then(resolve).catch(resolve);
|
2025-06-07 04:34:54 +08:00
|
|
|
|
} else {
|
2025-06-10 07:19:47 +08:00
|
|
|
|
resolve();
|
2025-06-07 04:34:54 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
});
|
|
|
|
|
};
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 初始化所有管理器
|
2025-06-06 22:11:18 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.initializeManagers = function() {
|
|
|
|
|
const self = this;
|
2025-06-07 04:34:54 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
|
|
|
try {
|
|
|
|
|
console.log('🔧 初始化管理器...');
|
2025-06-07 04:34:54 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 1. 初始化設定管理器
|
|
|
|
|
self.settingsManager = new window.MCPFeedback.SettingsManager({
|
|
|
|
|
onSettingsChange: function(settings) {
|
|
|
|
|
self.handleSettingsChange(settings);
|
|
|
|
|
},
|
|
|
|
|
onLanguageChange: function(language) {
|
|
|
|
|
self.handleLanguageChange(language);
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-06-07 04:34:54 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 2. 載入設定
|
|
|
|
|
self.settingsManager.loadSettings()
|
|
|
|
|
.then(function(settings) {
|
|
|
|
|
console.log('📋 設定載入完成:', settings);
|
|
|
|
|
|
|
|
|
|
// 3. 初始化 UI 管理器
|
|
|
|
|
self.uiManager = new window.MCPFeedback.UIManager({
|
|
|
|
|
currentTab: settings.activeTab,
|
|
|
|
|
layoutMode: settings.layoutMode,
|
|
|
|
|
onTabChange: function(tabName) {
|
|
|
|
|
self.handleTabChange(tabName);
|
|
|
|
|
},
|
|
|
|
|
onLayoutModeChange: function(layoutMode) {
|
|
|
|
|
self.handleLayoutModeChange(layoutMode);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 4. 初始化標籤頁管理器
|
|
|
|
|
self.tabManager = new window.MCPFeedback.TabManager();
|
|
|
|
|
|
2025-06-13 05:48:08 +08:00
|
|
|
|
// 5. 初始化連線監控器
|
|
|
|
|
self.connectionMonitor = new window.MCPFeedback.ConnectionMonitor({
|
|
|
|
|
onStatusChange: function(status, message) {
|
|
|
|
|
console.log('🔍 連線狀態變更:', status, message);
|
|
|
|
|
},
|
|
|
|
|
onQualityChange: function(quality, latency) {
|
|
|
|
|
console.log('🔍 連線品質變更:', quality, latency + 'ms');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 6. 初始化會話管理器
|
|
|
|
|
self.sessionManager = new window.MCPFeedback.SessionManager({
|
2025-06-13 05:50:27 +08:00
|
|
|
|
settingsManager: self.settingsManager,
|
2025-06-13 05:48:08 +08:00
|
|
|
|
onSessionChange: function(sessionData) {
|
|
|
|
|
console.log('📋 會話變更:', sessionData);
|
|
|
|
|
},
|
|
|
|
|
onSessionSelect: function(sessionId) {
|
|
|
|
|
console.log('📋 會話選擇:', sessionId);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 7. 初始化 WebSocket 管理器
|
2025-06-10 07:19:47 +08:00
|
|
|
|
self.webSocketManager = new window.MCPFeedback.WebSocketManager({
|
|
|
|
|
tabManager: self.tabManager,
|
2025-06-13 05:48:08 +08:00
|
|
|
|
connectionMonitor: self.connectionMonitor,
|
2025-06-10 07:19:47 +08:00
|
|
|
|
onOpen: function() {
|
|
|
|
|
self.handleWebSocketOpen();
|
|
|
|
|
},
|
|
|
|
|
onMessage: function(data) {
|
|
|
|
|
self.handleWebSocketMessage(data);
|
|
|
|
|
},
|
|
|
|
|
onClose: function(event) {
|
|
|
|
|
self.handleWebSocketClose(event);
|
|
|
|
|
},
|
|
|
|
|
onConnectionStatusChange: function(status, text) {
|
|
|
|
|
self.uiManager.updateConnectionStatus(status, text);
|
2025-06-13 05:48:08 +08:00
|
|
|
|
// 同時更新連線監控器
|
|
|
|
|
if (self.connectionMonitor) {
|
|
|
|
|
self.connectionMonitor.updateConnectionStatus(status, text);
|
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-06-13 05:48:08 +08:00
|
|
|
|
// 8. 初始化圖片處理器
|
2025-06-10 07:19:47 +08:00
|
|
|
|
self.imageHandler = new window.MCPFeedback.ImageHandler({
|
|
|
|
|
imageSizeLimit: settings.imageSizeLimit,
|
|
|
|
|
enableBase64Detail: settings.enableBase64Detail,
|
|
|
|
|
layoutMode: settings.layoutMode,
|
|
|
|
|
onSettingsChange: function() {
|
|
|
|
|
self.saveImageSettings();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-06-13 06:04:16 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
|
|
|
|
|
// 8. 應用設定到 UI
|
|
|
|
|
self.settingsManager.applyToUI();
|
|
|
|
|
|
2025-06-13 06:04:16 +08:00
|
|
|
|
// 8. 初始化各個管理器
|
2025-06-10 07:19:47 +08:00
|
|
|
|
self.uiManager.initTabs();
|
|
|
|
|
self.imageHandler.init();
|
|
|
|
|
|
2025-06-13 06:04:16 +08:00
|
|
|
|
// 9. 建立 WebSocket 連接
|
2025-06-10 07:19:47 +08:00
|
|
|
|
self.webSocketManager.connect();
|
|
|
|
|
|
|
|
|
|
resolve();
|
|
|
|
|
})
|
|
|
|
|
.catch(reject);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
reject(error);
|
2025-06-07 04:34:54 +08:00
|
|
|
|
}
|
|
|
|
|
});
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-06 22:11:18 +08:00
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 設置事件監聽器
|
2025-06-06 22:11:18 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.setupEventListeners = function() {
|
|
|
|
|
const self = this;
|
|
|
|
|
|
|
|
|
|
return new Promise(function(resolve) {
|
|
|
|
|
// 提交按鈕事件
|
|
|
|
|
const submitButtons = [
|
|
|
|
|
window.MCPFeedback.Utils.safeQuerySelector('#submitBtn'),
|
|
|
|
|
window.MCPFeedback.Utils.safeQuerySelector('#combinedSubmitBtn')
|
|
|
|
|
].filter(function(btn) { return btn !== null; });
|
|
|
|
|
|
|
|
|
|
submitButtons.forEach(function(button) {
|
|
|
|
|
button.addEventListener('click', function() {
|
|
|
|
|
self.submitFeedback();
|
|
|
|
|
});
|
2025-06-03 15:09:08 +08:00
|
|
|
|
});
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 取消按鈕事件
|
|
|
|
|
const cancelButtons = [
|
|
|
|
|
window.MCPFeedback.Utils.safeQuerySelector('#cancelBtn'),
|
|
|
|
|
window.MCPFeedback.Utils.safeQuerySelector('#combinedCancelBtn')
|
|
|
|
|
].filter(function(btn) { return btn !== null; });
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
cancelButtons.forEach(function(button) {
|
|
|
|
|
button.addEventListener('click', function() {
|
|
|
|
|
self.cancelFeedback();
|
2025-06-06 22:11:18 +08:00
|
|
|
|
});
|
2025-06-10 07:19:47 +08:00
|
|
|
|
});
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 命令執行事件
|
|
|
|
|
const runCommandBtn = window.MCPFeedback.Utils.safeQuerySelector('#runCommandBtn');
|
|
|
|
|
if (runCommandBtn) {
|
|
|
|
|
runCommandBtn.addEventListener('click', function() {
|
|
|
|
|
self.runCommand();
|
2025-06-06 22:11:18 +08:00
|
|
|
|
});
|
|
|
|
|
}
|
2025-06-05 01:59:56 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
const commandInput = window.MCPFeedback.Utils.safeQuerySelector('#commandInput');
|
|
|
|
|
if (commandInput) {
|
|
|
|
|
commandInput.addEventListener('keydown', function(e) {
|
|
|
|
|
if (e.key === 'Enter') {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
self.runCommand();
|
|
|
|
|
}
|
2025-06-06 22:11:18 +08:00
|
|
|
|
});
|
2025-06-10 07:19:47 +08:00
|
|
|
|
}
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 快捷鍵
|
|
|
|
|
document.addEventListener('keydown', function(e) {
|
|
|
|
|
// Ctrl+Enter 提交回饋
|
|
|
|
|
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
|
2025-06-06 22:11:18 +08:00
|
|
|
|
e.preventDefault();
|
2025-06-10 07:19:47 +08:00
|
|
|
|
self.submitFeedback();
|
|
|
|
|
}
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// Esc 取消
|
|
|
|
|
if (e.key === 'Escape') {
|
|
|
|
|
self.cancelFeedback();
|
|
|
|
|
}
|
2025-06-06 22:11:18 +08:00
|
|
|
|
});
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 設置設定管理器的事件監聽器
|
|
|
|
|
self.settingsManager.setupEventListeners();
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
console.log('✅ 事件監聽器設置完成');
|
|
|
|
|
resolve();
|
2025-06-06 22:11:18 +08:00
|
|
|
|
});
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 設置清理處理器
|
2025-06-06 16:44:24 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.setupCleanupHandlers = function() {
|
|
|
|
|
const self = this;
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
return new Promise(function(resolve) {
|
|
|
|
|
window.addEventListener('beforeunload', function() {
|
|
|
|
|
self.cleanup();
|
|
|
|
|
});
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
console.log('✅ 清理處理器設置完成');
|
|
|
|
|
resolve();
|
|
|
|
|
});
|
|
|
|
|
};
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 處理設定變更
|
2025-06-06 16:44:24 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.handleSettingsChange = function(settings) {
|
|
|
|
|
console.log('🔧 處理設定變更:', settings);
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 更新圖片處理器設定
|
|
|
|
|
if (this.imageHandler) {
|
|
|
|
|
this.imageHandler.updateSettings(settings);
|
2025-06-06 16:44:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-13 06:04:16 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 更新 UI 管理器佈局模式
|
|
|
|
|
if (this.uiManager && settings.layoutMode) {
|
|
|
|
|
this.uiManager.applyLayoutMode(settings.layoutMode);
|
2025-06-06 16:44:24 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 處理語言變更
|
2025-06-06 16:44:24 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.handleLanguageChange = function(language) {
|
|
|
|
|
console.log('🌐 處理語言變更:', language);
|
2025-06-06 21:09:45 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 更新 UI 顯示
|
|
|
|
|
if (this.uiManager) {
|
|
|
|
|
this.uiManager.updateStatusIndicator();
|
2025-06-06 16:44:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-13 06:04:16 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-06 21:09:45 +08:00
|
|
|
|
|
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 處理頁籤變更
|
2025-06-06 21:09:45 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.handleTabChange = function(tabName) {
|
|
|
|
|
console.log('📋 處理頁籤變更:', tabName);
|
2025-06-06 21:09:45 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 重新初始化圖片處理器(確保使用正確的佈局模式元素)
|
|
|
|
|
if (this.imageHandler) {
|
|
|
|
|
const layoutMode = this.settingsManager.get('layoutMode');
|
|
|
|
|
this.imageHandler.reinitialize(layoutMode);
|
2025-06-06 21:09:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 保存當前頁籤設定
|
|
|
|
|
this.settingsManager.set('activeTab', tabName);
|
|
|
|
|
};
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 處理佈局模式變更
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.handleLayoutModeChange = function(layoutMode) {
|
|
|
|
|
console.log('🎨 處理佈局模式變更:', layoutMode);
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 重新初始化圖片處理器
|
|
|
|
|
if (this.imageHandler) {
|
|
|
|
|
this.imageHandler.reinitialize(layoutMode);
|
2025-06-06 16:44:24 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 保存圖片設定
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.saveImageSettings = function() {
|
|
|
|
|
if (this.imageHandler && this.settingsManager) {
|
|
|
|
|
this.settingsManager.setMultiple({
|
|
|
|
|
imageSizeLimit: this.imageHandler.imageSizeLimit,
|
|
|
|
|
enableBase64Detail: this.imageHandler.enableBase64Detail
|
|
|
|
|
});
|
2025-06-06 16:44:24 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-13 06:04:16 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 處理 WebSocket 開啟
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.handleWebSocketOpen = function() {
|
|
|
|
|
console.log('🔗 WebSocket 連接已開啟');
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 如果有待處理的提交,處理它
|
|
|
|
|
if (this.pendingSubmission) {
|
|
|
|
|
console.log('🔄 處理待提交的回饋');
|
|
|
|
|
this.submitFeedbackInternal(this.pendingSubmission);
|
|
|
|
|
this.pendingSubmission = null;
|
2025-06-03 06:50:19 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 處理 WebSocket 訊息
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.handleWebSocketMessage = function(data) {
|
|
|
|
|
console.log('📨 處理 WebSocket 訊息:', data);
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-03 06:50:19 +08:00
|
|
|
|
switch (data.type) {
|
|
|
|
|
case 'command_output':
|
|
|
|
|
this.appendCommandOutput(data.output);
|
|
|
|
|
break;
|
|
|
|
|
case 'command_complete':
|
2025-06-10 07:19:47 +08:00
|
|
|
|
this.appendCommandOutput('\n[命令完成,退出碼: ' + data.exit_code + ']\n');
|
2025-06-03 06:50:19 +08:00
|
|
|
|
this.enableCommandInput();
|
|
|
|
|
break;
|
|
|
|
|
case 'command_error':
|
2025-06-10 07:19:47 +08:00
|
|
|
|
this.appendCommandOutput('\n[錯誤: ' + data.error + ']\n');
|
2025-06-03 06:50:19 +08:00
|
|
|
|
this.enableCommandInput();
|
|
|
|
|
break;
|
|
|
|
|
case 'feedback_received':
|
|
|
|
|
console.log('回饋已收到');
|
2025-06-06 16:44:24 +08:00
|
|
|
|
this.handleFeedbackReceived(data);
|
|
|
|
|
break;
|
|
|
|
|
case 'status_update':
|
|
|
|
|
console.log('狀態更新:', data.status_info);
|
|
|
|
|
this.handleStatusUpdate(data.status_info);
|
2025-06-03 06:50:19 +08:00
|
|
|
|
break;
|
2025-06-06 16:44:24 +08:00
|
|
|
|
case 'session_updated':
|
2025-06-10 07:19:47 +08:00
|
|
|
|
console.log('🔄 收到會話更新訊息:', data.session_info);
|
2025-06-06 16:44:24 +08:00
|
|
|
|
this.handleSessionUpdated(data);
|
2025-06-03 22:26:38 +08:00
|
|
|
|
break;
|
2025-06-03 06:50:19 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 處理 WebSocket 關閉
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.handleWebSocketClose = function(event) {
|
|
|
|
|
console.log('🔗 WebSocket 連接已關閉');
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 重置回饋狀態,避免卡在處理狀態
|
|
|
|
|
if (this.uiManager && this.uiManager.getFeedbackState() === window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_PROCESSING) {
|
|
|
|
|
console.log('🔄 WebSocket 斷開,重置處理狀態');
|
|
|
|
|
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 處理回饋接收
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.handleFeedbackReceived = function(data) {
|
|
|
|
|
// 使用 UI 管理器設置狀態
|
|
|
|
|
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_SUBMITTED);
|
|
|
|
|
this.uiManager.setLastSubmissionTime(Date.now());
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
|
|
|
|
// 顯示成功訊息
|
2025-06-10 07:19:47 +08:00
|
|
|
|
window.MCPFeedback.Utils.showMessage(data.message || '回饋提交成功!', window.MCPFeedback.Utils.CONSTANTS.MESSAGE_SUCCESS);
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
|
|
|
|
// 更新 AI 摘要區域顯示「已送出反饋」狀態
|
|
|
|
|
this.updateSummaryStatus('已送出反饋,等待下次 MCP 調用...');
|
|
|
|
|
|
|
|
|
|
console.log('反饋已提交,頁面保持開啟狀態');
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 處理會話更新
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.handleSessionUpdated = function(data) {
|
2025-06-06 16:44:24 +08:00
|
|
|
|
console.log('🔄 處理會話更新:', data.session_info);
|
2025-06-03 22:26:38 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 顯示更新通知
|
2025-06-10 07:19:47 +08:00
|
|
|
|
window.MCPFeedback.Utils.showMessage(data.message || '會話已更新,正在局部更新內容...', window.MCPFeedback.Utils.CONSTANTS.MESSAGE_SUCCESS);
|
2025-06-03 22:26:38 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 更新會話信息
|
|
|
|
|
if (data.session_info) {
|
2025-06-06 22:29:49 +08:00
|
|
|
|
const newSessionId = data.session_info.session_id;
|
2025-06-10 07:19:47 +08:00
|
|
|
|
console.log('📋 會話 ID 更新: ' + this.currentSessionId + ' -> ' + newSessionId);
|
2025-06-06 22:29:49 +08:00
|
|
|
|
|
2025-06-13 05:48:08 +08:00
|
|
|
|
// 保存舊會話到歷史記錄(在更新當前會話之前)
|
|
|
|
|
if (this.currentSessionId && this.sessionManager && this.currentSessionId !== newSessionId) {
|
|
|
|
|
console.log('📋 嘗試獲取當前會話數據...');
|
|
|
|
|
// 從 SessionManager 獲取當前會話的完整數據
|
|
|
|
|
const currentSessionData = this.sessionManager.getCurrentSessionData();
|
|
|
|
|
console.log('📋 從 currentSession 獲取數據:', this.currentSessionId);
|
|
|
|
|
|
|
|
|
|
if (currentSessionData) {
|
|
|
|
|
// 計算實際持續時間
|
|
|
|
|
const now = Date.now() / 1000;
|
|
|
|
|
let duration = 300; // 預設 5 分鐘
|
|
|
|
|
|
|
|
|
|
if (currentSessionData.created_at) {
|
|
|
|
|
let createdAt = currentSessionData.created_at;
|
|
|
|
|
// 處理時間戳格式
|
|
|
|
|
if (createdAt > 1e12) {
|
|
|
|
|
createdAt = createdAt / 1000;
|
|
|
|
|
}
|
|
|
|
|
duration = Math.max(1, Math.round(now - createdAt));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const oldSessionData = {
|
|
|
|
|
session_id: this.currentSessionId,
|
|
|
|
|
status: 'completed',
|
|
|
|
|
created_at: currentSessionData.created_at || (now - duration),
|
|
|
|
|
completed_at: now,
|
|
|
|
|
duration: duration,
|
|
|
|
|
project_directory: currentSessionData.project_directory,
|
|
|
|
|
summary: currentSessionData.summary
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
console.log('📋 準備將舊會話加入歷史記錄:', oldSessionData);
|
|
|
|
|
|
|
|
|
|
// 先更新當前會話 ID,再調用 addSessionToHistory
|
|
|
|
|
this.currentSessionId = newSessionId;
|
|
|
|
|
|
|
|
|
|
// 更新會話管理器的當前會話(這樣 addSessionToHistory 檢查時就不會認為是當前活躍會話)
|
|
|
|
|
if (this.sessionManager) {
|
|
|
|
|
this.sessionManager.updateCurrentSession(data.session_info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 現在可以安全地將舊會話加入歷史記錄
|
|
|
|
|
this.sessionManager.addSessionToHistory(oldSessionData);
|
|
|
|
|
} else {
|
|
|
|
|
console.log('⚠️ 無法獲取當前會話數據,跳過歷史記錄保存');
|
|
|
|
|
// 仍然需要更新當前會話 ID
|
|
|
|
|
this.currentSessionId = newSessionId;
|
|
|
|
|
// 更新會話管理器
|
|
|
|
|
if (this.sessionManager) {
|
|
|
|
|
this.sessionManager.updateCurrentSession(data.session_info);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 沒有舊會話或會話 ID 相同,直接更新
|
|
|
|
|
this.currentSessionId = newSessionId;
|
|
|
|
|
// 更新會話管理器
|
|
|
|
|
if (this.sessionManager) {
|
|
|
|
|
this.sessionManager.updateCurrentSession(data.session_info);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 重置回饋狀態為等待新回饋
|
|
|
|
|
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, newSessionId);
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-13 06:04:16 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 更新頁面標題
|
|
|
|
|
if (data.session_info.project_directory) {
|
|
|
|
|
const projectName = data.session_info.project_directory.split(/[/\\]/).pop();
|
2025-06-10 07:19:47 +08:00
|
|
|
|
document.title = 'MCP Feedback - ' + projectName;
|
2025-06-06 16:44:24 +08:00
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 使用局部更新替代整頁刷新
|
|
|
|
|
this.refreshPageContent();
|
2025-06-06 22:29:49 +08:00
|
|
|
|
} else {
|
|
|
|
|
console.log('⚠️ 會話更新沒有包含會話信息,僅重置狀態');
|
2025-06-10 07:19:47 +08:00
|
|
|
|
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING);
|
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
console.log('✅ 會話更新處理完成');
|
|
|
|
|
};
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 處理狀態更新
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.handleStatusUpdate = function(statusInfo) {
|
|
|
|
|
console.log('處理狀態更新:', statusInfo);
|
2025-06-03 17:19:52 +08:00
|
|
|
|
|
2025-06-13 05:48:08 +08:00
|
|
|
|
// 更新 SessionManager 的狀態資訊
|
|
|
|
|
if (this.sessionManager && this.sessionManager.updateStatusInfo) {
|
|
|
|
|
this.sessionManager.updateStatusInfo(statusInfo);
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 更新頁面標題顯示會話信息
|
|
|
|
|
if (statusInfo.project_directory) {
|
|
|
|
|
const projectName = statusInfo.project_directory.split(/[/\\]/).pop();
|
|
|
|
|
document.title = 'MCP Feedback - ' + projectName;
|
2025-06-03 15:09:08 +08:00
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 提取會話 ID
|
|
|
|
|
const sessionId = statusInfo.session_id || this.currentSessionId;
|
|
|
|
|
|
|
|
|
|
// 根據狀態更新 UI
|
|
|
|
|
switch (statusInfo.status) {
|
|
|
|
|
case 'feedback_submitted':
|
|
|
|
|
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_SUBMITTED, sessionId);
|
|
|
|
|
this.updateSummaryStatus('已送出反饋,等待下次 MCP 調用...');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'active':
|
|
|
|
|
case 'waiting':
|
|
|
|
|
// 檢查是否是新會話
|
|
|
|
|
if (sessionId && sessionId !== this.currentSessionId) {
|
|
|
|
|
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, sessionId);
|
|
|
|
|
} else if (this.uiManager.getFeedbackState() !== window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_SUBMITTED) {
|
|
|
|
|
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, sessionId);
|
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
if (statusInfo.status === 'waiting') {
|
|
|
|
|
this.updateSummaryStatus('等待用戶回饋...');
|
2025-06-06 16:44:24 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
break;
|
2025-06-03 06:50:19 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-04 21:34:45 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 提交回饋
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.submitFeedback = function() {
|
2025-06-06 22:29:49 +08:00
|
|
|
|
console.log('📤 嘗試提交回饋...');
|
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 檢查是否可以提交回饋
|
|
|
|
|
if (!this.canSubmitFeedback()) {
|
2025-06-10 07:19:47 +08:00
|
|
|
|
console.log('⚠️ 無法提交回饋');
|
|
|
|
|
this.handleSubmitError();
|
2025-06-03 06:50:19 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-08 00:52:30 +08:00
|
|
|
|
// 收集回饋數據並提交
|
|
|
|
|
const feedbackData = this.collectFeedbackData();
|
|
|
|
|
if (!feedbackData) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.submitFeedbackInternal(feedbackData);
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 檢查是否可以提交回饋
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.canSubmitFeedback = function() {
|
|
|
|
|
return this.webSocketManager &&
|
|
|
|
|
this.webSocketManager.isReady() &&
|
|
|
|
|
this.uiManager &&
|
|
|
|
|
this.uiManager.getFeedbackState() === window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 處理提交錯誤
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.handleSubmitError = function() {
|
|
|
|
|
const feedbackState = this.uiManager ? this.uiManager.getFeedbackState() : null;
|
|
|
|
|
|
|
|
|
|
if (feedbackState === window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_SUBMITTED) {
|
|
|
|
|
window.MCPFeedback.Utils.showMessage('回饋已提交,請等待下次 MCP 調用', window.MCPFeedback.Utils.CONSTANTS.MESSAGE_WARNING);
|
|
|
|
|
} else if (feedbackState === window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_PROCESSING) {
|
|
|
|
|
window.MCPFeedback.Utils.showMessage('正在處理中,請稍候', window.MCPFeedback.Utils.CONSTANTS.MESSAGE_WARNING);
|
|
|
|
|
} else if (!this.webSocketManager || !this.webSocketManager.isReady()) {
|
|
|
|
|
// 收集回饋數據,等待連接就緒後提交
|
|
|
|
|
const feedbackData = this.collectFeedbackData();
|
|
|
|
|
if (feedbackData) {
|
|
|
|
|
this.pendingSubmission = feedbackData;
|
|
|
|
|
window.MCPFeedback.Utils.showMessage('WebSocket 連接中,回饋將在連接就緒後自動提交...', window.MCPFeedback.Utils.CONSTANTS.MESSAGE_INFO);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
window.MCPFeedback.Utils.showMessage('當前狀態不允許提交: ' + feedbackState, window.MCPFeedback.Utils.CONSTANTS.MESSAGE_WARNING);
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-06-08 00:52:30 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 收集回饋數據
|
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.collectFeedbackData = function() {
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 根據當前佈局模式獲取回饋內容
|
|
|
|
|
let feedback = '';
|
2025-06-10 07:19:47 +08:00
|
|
|
|
const layoutMode = this.settingsManager ? this.settingsManager.get('layoutMode') : 'combined-vertical';
|
|
|
|
|
|
|
|
|
|
if (layoutMode.startsWith('combined')) {
|
|
|
|
|
const combinedFeedbackInput = window.MCPFeedback.Utils.safeQuerySelector('#combinedFeedbackText');
|
|
|
|
|
feedback = combinedFeedbackInput ? combinedFeedbackInput.value.trim() : '';
|
2025-06-03 06:50:19 +08:00
|
|
|
|
} else {
|
2025-06-10 07:19:47 +08:00
|
|
|
|
const feedbackInput = window.MCPFeedback.Utils.safeQuerySelector('#feedbackText');
|
|
|
|
|
feedback = feedbackInput ? feedbackInput.value.trim() : '';
|
2025-06-03 06:50:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
const images = this.imageHandler ? this.imageHandler.getImages() : [];
|
|
|
|
|
|
|
|
|
|
if (!feedback && images.length === 0) {
|
|
|
|
|
window.MCPFeedback.Utils.showMessage('請提供回饋文字或上傳圖片', window.MCPFeedback.Utils.CONSTANTS.MESSAGE_WARNING);
|
2025-06-08 00:52:30 +08:00
|
|
|
|
return null;
|
2025-06-03 06:50:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-08 00:52:30 +08:00
|
|
|
|
return {
|
|
|
|
|
feedback: feedback,
|
2025-06-10 07:19:47 +08:00
|
|
|
|
images: images,
|
2025-06-08 00:52:30 +08:00
|
|
|
|
settings: {
|
2025-06-10 07:19:47 +08:00
|
|
|
|
image_size_limit: this.imageHandler ? this.imageHandler.imageSizeLimit : 0,
|
|
|
|
|
enable_base64_detail: this.imageHandler ? this.imageHandler.enableBase64Detail : false
|
2025-06-08 00:52:30 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-08 00:52:30 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 內部提交回饋方法
|
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.submitFeedbackInternal = function(feedbackData) {
|
2025-06-08 00:52:30 +08:00
|
|
|
|
console.log('📤 內部提交回饋...');
|
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 設置處理狀態
|
2025-06-10 07:19:47 +08:00
|
|
|
|
if (this.uiManager) {
|
|
|
|
|
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_PROCESSING);
|
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
|
|
|
|
try {
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 發送回饋
|
2025-06-10 07:19:47 +08:00
|
|
|
|
const success = this.webSocketManager.send({
|
2025-06-06 16:44:24 +08:00
|
|
|
|
type: 'submit_feedback',
|
2025-06-08 00:52:30 +08:00
|
|
|
|
feedback: feedbackData.feedback,
|
|
|
|
|
images: feedbackData.images,
|
|
|
|
|
settings: feedbackData.settings
|
2025-06-10 07:19:47 +08:00
|
|
|
|
});
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
if (success) {
|
|
|
|
|
// 清空表單
|
|
|
|
|
this.clearFeedback();
|
|
|
|
|
console.log('📤 回饋已發送,等待服務器確認...');
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error('WebSocket 發送失敗');
|
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
|
|
|
|
} catch (error) {
|
2025-06-06 16:44:24 +08:00
|
|
|
|
console.error('❌ 發送回饋失敗:', error);
|
2025-06-10 07:19:47 +08:00
|
|
|
|
window.MCPFeedback.Utils.showMessage('發送失敗,請重試', window.MCPFeedback.Utils.CONSTANTS.MESSAGE_ERROR);
|
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 恢復到等待狀態
|
2025-06-10 07:19:47 +08:00
|
|
|
|
if (this.uiManager) {
|
|
|
|
|
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING);
|
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 清空回饋內容
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.clearFeedback = function() {
|
2025-06-06 22:11:18 +08:00
|
|
|
|
console.log('🧹 清空回饋內容...');
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 使用 UI 管理器重置表單
|
|
|
|
|
if (this.uiManager) {
|
|
|
|
|
this.uiManager.resetFeedbackForm();
|
|
|
|
|
}
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
|
|
|
|
// 清空圖片數據
|
2025-06-10 07:19:47 +08:00
|
|
|
|
if (this.imageHandler) {
|
|
|
|
|
this.imageHandler.clearImages();
|
|
|
|
|
}
|
2025-06-06 22:11:18 +08:00
|
|
|
|
|
|
|
|
|
console.log('✅ 回饋內容清空完成');
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 取消回饋
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.cancelFeedback = function() {
|
|
|
|
|
console.log('❌ 取消回饋');
|
|
|
|
|
this.clearFeedback();
|
|
|
|
|
};
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 執行命令
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.runCommand = function() {
|
|
|
|
|
const commandInput = window.MCPFeedback.Utils.safeQuerySelector('#commandInput');
|
|
|
|
|
const command = commandInput ? commandInput.value.trim() : '';
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
if (!command) {
|
|
|
|
|
this.appendCommandOutput('⚠️ 請輸入命令\n');
|
|
|
|
|
return;
|
2025-06-03 06:50:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
if (!this.webSocketManager || !this.webSocketManager.isConnected) {
|
2025-06-06 16:44:24 +08:00
|
|
|
|
this.appendCommandOutput('❌ WebSocket 未連接,無法執行命令\n');
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 顯示執行的命令
|
2025-06-10 07:19:47 +08:00
|
|
|
|
this.appendCommandOutput('$ ' + command + '\n');
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
// 發送命令
|
|
|
|
|
try {
|
2025-06-10 07:19:47 +08:00
|
|
|
|
const success = this.webSocketManager.send({
|
2025-06-06 16:44:24 +08:00
|
|
|
|
type: 'run_command',
|
|
|
|
|
command: command
|
2025-06-10 07:19:47 +08:00
|
|
|
|
});
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
if (success) {
|
|
|
|
|
// 清空輸入框
|
|
|
|
|
commandInput.value = '';
|
|
|
|
|
this.appendCommandOutput('[正在執行...]\n');
|
|
|
|
|
} else {
|
|
|
|
|
this.appendCommandOutput('❌ 發送命令失敗\n');
|
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
} catch (error) {
|
2025-06-10 07:19:47 +08:00
|
|
|
|
this.appendCommandOutput('❌ 發送命令失敗: ' + error.message + '\n');
|
2025-06-03 06:50:19 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 添加命令輸出
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.appendCommandOutput = function(output) {
|
|
|
|
|
const commandOutput = window.MCPFeedback.Utils.safeQuerySelector('#commandOutput');
|
2025-06-06 16:44:24 +08:00
|
|
|
|
if (commandOutput) {
|
|
|
|
|
commandOutput.textContent += output;
|
|
|
|
|
commandOutput.scrollTop = commandOutput.scrollHeight;
|
2025-06-03 06:50:19 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
/**
|
|
|
|
|
* 啟用命令輸入
|
|
|
|
|
*/
|
|
|
|
|
FeedbackApp.prototype.enableCommandInput = function() {
|
|
|
|
|
const commandInput = window.MCPFeedback.Utils.safeQuerySelector('#commandInput');
|
|
|
|
|
const runCommandBtn = window.MCPFeedback.Utils.safeQuerySelector('#runCommandBtn');
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
|
|
|
|
if (commandInput) commandInput.disabled = false;
|
|
|
|
|
if (runCommandBtn) {
|
|
|
|
|
runCommandBtn.disabled = false;
|
|
|
|
|
runCommandBtn.textContent = '▶️ 執行';
|
2025-06-03 15:09:08 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-07 04:22:24 +08:00
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 更新摘要狀態
|
2025-06-07 04:22:24 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.updateSummaryStatus = function(message) {
|
|
|
|
|
const summaryElements = document.querySelectorAll('.ai-summary-content');
|
|
|
|
|
summaryElements.forEach(function(element) {
|
|
|
|
|
element.innerHTML = '<div style="padding: 16px; background: var(--success-color); color: white; border-radius: 6px; text-align: center;">✅ ' + message + '</div>';
|
2025-06-07 04:22:24 +08:00
|
|
|
|
});
|
2025-06-10 07:19:47 +08:00
|
|
|
|
};
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 處理會話更新(來自自動刷新)
|
2025-06-07 04:22:24 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.handleSessionUpdate = function(sessionData) {
|
|
|
|
|
console.log('🔄 處理自動檢測到的會話更新:', sessionData);
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 更新當前會話 ID
|
|
|
|
|
this.currentSessionId = sessionData.session_id;
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 重置回饋狀態
|
|
|
|
|
if (this.uiManager) {
|
|
|
|
|
this.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, sessionData.session_id);
|
2025-06-07 04:22:24 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
|
|
|
|
|
// 局部更新頁面內容
|
|
|
|
|
this.refreshPageContent();
|
|
|
|
|
};
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 刷新頁面內容
|
2025-06-07 04:22:24 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.refreshPageContent = function() {
|
|
|
|
|
console.log('🔄 局部更新頁面內容...');
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
const self = this;
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
fetch('/api/current-session')
|
|
|
|
|
.then(function(response) {
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw new Error('API 請求失敗: ' + response.status);
|
|
|
|
|
}
|
|
|
|
|
return response.json();
|
|
|
|
|
})
|
|
|
|
|
.then(function(sessionData) {
|
|
|
|
|
console.log('📥 獲取到最新會話資料:', sessionData);
|
|
|
|
|
|
|
|
|
|
// 重置回饋狀態
|
|
|
|
|
if (sessionData.session_id && self.uiManager) {
|
|
|
|
|
self.uiManager.setFeedbackState(window.MCPFeedback.Utils.CONSTANTS.FEEDBACK_WAITING, sessionData.session_id);
|
|
|
|
|
}
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 更新 AI 摘要內容
|
|
|
|
|
if (self.uiManager) {
|
|
|
|
|
self.uiManager.updateAISummaryContent(sessionData.summary);
|
|
|
|
|
self.uiManager.resetFeedbackForm();
|
|
|
|
|
self.uiManager.updateStatusIndicator();
|
|
|
|
|
}
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 更新頁面標題
|
|
|
|
|
if (sessionData.project_directory) {
|
|
|
|
|
const projectName = sessionData.project_directory.split(/[/\\]/).pop();
|
|
|
|
|
document.title = 'MCP Feedback - ' + projectName;
|
2025-06-07 04:22:24 +08:00
|
|
|
|
}
|
2025-06-10 07:19:47 +08:00
|
|
|
|
|
|
|
|
|
console.log('✅ 局部更新完成');
|
|
|
|
|
})
|
|
|
|
|
.catch(function(error) {
|
|
|
|
|
console.error('❌ 局部更新失敗:', error);
|
|
|
|
|
window.MCPFeedback.Utils.showMessage('更新內容失敗,請手動刷新頁面以查看新的 AI 工作摘要', window.MCPFeedback.Utils.CONSTANTS.MESSAGE_WARNING);
|
|
|
|
|
});
|
|
|
|
|
};
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
|
|
|
|
/**
|
2025-06-10 07:19:47 +08:00
|
|
|
|
* 清理資源
|
2025-06-07 04:22:24 +08:00
|
|
|
|
*/
|
2025-06-10 07:19:47 +08:00
|
|
|
|
FeedbackApp.prototype.cleanup = function() {
|
|
|
|
|
console.log('🧹 清理應用程式資源...');
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
if (this.tabManager) {
|
|
|
|
|
this.tabManager.cleanup();
|
2025-06-07 04:22:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
if (this.webSocketManager) {
|
|
|
|
|
this.webSocketManager.close();
|
2025-06-07 04:22:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-13 05:48:08 +08:00
|
|
|
|
if (this.connectionMonitor) {
|
|
|
|
|
this.connectionMonitor.cleanup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.sessionManager) {
|
|
|
|
|
this.sessionManager.cleanup();
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
if (this.imageHandler) {
|
|
|
|
|
this.imageHandler.cleanup();
|
2025-06-07 04:22:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-13 06:04:16 +08:00
|
|
|
|
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
console.log('✅ 應用程式資源清理完成');
|
|
|
|
|
};
|
2025-06-07 04:22:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 將 FeedbackApp 加入命名空間
|
|
|
|
|
window.MCPFeedback.FeedbackApp = FeedbackApp;
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
console.log('✅ FeedbackApp 主模組載入完成');
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
})();
|