624 lines
20 KiB
JavaScript
Raw Normal View History

2025-06-13 05:48:08 +08:00
/**
* MCP Feedback Enhanced - 會話管理模組重構版
* =============================================
*
* 整合會話數據管理UI 渲染和面板控制功能
* 使用模組化架構提升可維護性
*/
(function() {
'use strict';
// 確保命名空間和依賴存在
window.MCPFeedback = window.MCPFeedback || {};
// 獲取 DOMUtils 的安全方法
function getDOMUtils() {
return window.MCPFeedback && window.MCPFeedback.Utils && window.MCPFeedback.Utils.DOM;
}
/**
* 會話管理器建構函數重構版
*/
function SessionManager(options) {
options = options || {};
// 子模組實例
this.dataManager = null;
this.uiRenderer = null;
this.detailsModal = null;
// UI 狀態
this.isPanelVisible = true;
this.isLoading = false;
// UI 元素
this.panel = null;
this.edgeToggleBtn = null;
this.collapsedToggleBtn = null;
this.mainContent = null;
2025-06-13 05:50:27 +08:00
// 設定管理器引用
this.settingsManager = options.settingsManager || null;
2025-06-13 05:48:08 +08:00
// 回調函數
this.onSessionChange = options.onSessionChange || null;
this.onSessionSelect = options.onSessionSelect || null;
this.initializeModules(options);
this.initializeUI();
2025-06-13 05:50:27 +08:00
this.loadPanelState();
2025-06-13 05:48:08 +08:00
console.log('📋 SessionManager (重構版) 初始化完成');
}
/**
* 初始化子模組
*/
SessionManager.prototype.initializeModules = function(options) {
const self = this;
2025-06-13 19:11:08 +08:00
// 先初始化 UI 渲染器(避免數據管理器回調時 UI 組件尚未準備好)
2025-06-13 05:48:08 +08:00
this.uiRenderer = new window.MCPFeedback.Session.UIRenderer({
showFullSessionId: options.showFullSessionId || false,
enableAnimations: options.enableAnimations !== false
});
// 初始化詳情彈窗
this.detailsModal = new window.MCPFeedback.Session.DetailsModal({
enableEscapeClose: options.enableEscapeClose !== false,
enableBackdropClose: options.enableBackdropClose !== false,
showFullSessionId: options.showFullSessionId || false
});
2025-06-13 19:11:08 +08:00
// 最後初始化數據管理器(確保 UI 組件已準備好接收回調)
this.dataManager = new window.MCPFeedback.Session.DataManager({
onSessionChange: function(sessionData) {
self.handleSessionChange(sessionData);
},
onHistoryChange: function(history) {
self.handleHistoryChange(history);
},
onStatsChange: function(stats) {
self.handleStatsChange(stats);
}
});
2025-06-13 05:48:08 +08:00
};
/**
* 初始化 UI 元素
*/
SessionManager.prototype.initializeUI = function() {
const DOMUtils = getDOMUtils();
if (!DOMUtils) {
console.warn('📋 DOMUtils 尚未載入,使用原生 DOM 方法');
// 使用原生 DOM 方法作為後備
this.panel = document.querySelector('.session-management-panel');
this.edgeToggleBtn = document.querySelector('#edgeToggleBtn');
this.collapsedToggleBtn = document.querySelector('#collapsedToggleBtn');
this.mainContent = document.querySelector('.main-content');
} else {
// 使用 DOMUtils
this.panel = DOMUtils.safeQuerySelector('.session-management-panel');
this.edgeToggleBtn = DOMUtils.safeQuerySelector('#edgeToggleBtn');
this.collapsedToggleBtn = DOMUtils.safeQuerySelector('#collapsedToggleBtn');
this.mainContent = DOMUtils.safeQuerySelector('.main-content');
}
// 設置事件監聽器
this.setupEventListeners();
// 初始化顯示
this.updateDisplay();
};
/**
* 處理會話變更
*/
SessionManager.prototype.handleSessionChange = function(sessionData) {
console.log('📋 處理會話變更:', sessionData);
// 更新 UI 渲染
this.uiRenderer.renderCurrentSession(sessionData);
// 調用外部回調
if (this.onSessionChange) {
this.onSessionChange(sessionData);
}
};
/**
* 處理歷史記錄變更
*/
SessionManager.prototype.handleHistoryChange = function(history) {
console.log('📋 處理歷史記錄變更:', history.length, '個會話');
// 更新 UI 渲染
this.uiRenderer.renderSessionHistory(history);
};
/**
* 處理統計資訊變更
*/
SessionManager.prototype.handleStatsChange = function(stats) {
console.log('📋 處理統計資訊變更:', stats);
// 更新 UI 渲染
this.uiRenderer.renderStats(stats);
};
/**
* 設置事件監聽器
*/
SessionManager.prototype.setupEventListeners = function() {
const self = this;
const DOMUtils = getDOMUtils();
// 邊緣收合按鈕
if (this.edgeToggleBtn) {
this.edgeToggleBtn.addEventListener('click', function() {
self.togglePanel();
});
}
// 收合狀態下的展開按鈕
if (this.collapsedToggleBtn) {
this.collapsedToggleBtn.addEventListener('click', function() {
self.togglePanel();
});
}
// 刷新按鈕
const refreshButton = DOMUtils ?
DOMUtils.safeQuerySelector('#refreshSessions') :
document.querySelector('#refreshSessions');
if (refreshButton) {
refreshButton.addEventListener('click', function() {
self.refreshSessionData();
});
}
// 詳細資訊按鈕
const detailsButton = DOMUtils ?
DOMUtils.safeQuerySelector('#viewSessionDetails') :
document.querySelector('#viewSessionDetails');
if (detailsButton) {
detailsButton.addEventListener('click', function() {
self.showSessionDetails();
});
}
};
/**
* 更新當前會話委託給數據管理器
*/
SessionManager.prototype.updateCurrentSession = function(sessionData) {
return this.dataManager.updateCurrentSession(sessionData);
};
/**
* 更新狀態資訊委託給數據管理器
*/
SessionManager.prototype.updateStatusInfo = function(statusInfo) {
return this.dataManager.updateStatusInfo(statusInfo);
};
/**
* 切換面板顯示
*/
SessionManager.prototype.togglePanel = function() {
if (!this.panel) return;
const DOMUtils = getDOMUtils();
this.isPanelVisible = !this.isPanelVisible;
if (this.isPanelVisible) {
// 展開面板
this.panel.classList.remove('collapsed');
if (this.mainContent) {
this.mainContent.classList.remove('panel-collapsed');
}
// 隱藏收合狀態下的展開按鈕
const collapsedToggle = DOMUtils ?
DOMUtils.safeQuerySelector('#collapsedPanelToggle') :
document.querySelector('#collapsedPanelToggle');
if (collapsedToggle) {
collapsedToggle.style.display = 'none';
}
// 更新邊緣按鈕圖示和提示
this.updateToggleButton('◀', '收合面板');
} else {
// 收合面板
this.panel.classList.add('collapsed');
if (this.mainContent) {
this.mainContent.classList.add('panel-collapsed');
}
// 顯示收合狀態下的展開按鈕
const collapsedToggle = DOMUtils ?
DOMUtils.safeQuerySelector('#collapsedPanelToggle') :
document.querySelector('#collapsedPanelToggle');
if (collapsedToggle) {
collapsedToggle.style.display = 'block';
}
// 更新邊緣按鈕圖示和提示
this.updateToggleButton('▶', '展開面板');
}
2025-06-13 05:50:27 +08:00
// 保存面板狀態到設定
this.savePanelState();
2025-06-13 05:48:08 +08:00
console.log('📋 會話面板', this.isPanelVisible ? '顯示' : '隱藏');
};
/**
* 更新切換按鈕
*/
SessionManager.prototype.updateToggleButton = function(iconText, title) {
if (this.edgeToggleBtn) {
const icon = this.edgeToggleBtn.querySelector('.toggle-icon');
if (icon) {
icon.textContent = iconText;
}
this.edgeToggleBtn.setAttribute('title', title);
}
};
/**
* 刷新會話數據
*/
SessionManager.prototype.refreshSessionData = function() {
if (this.isLoading) return;
console.log('📋 刷新會話數據');
this.isLoading = true;
const self = this;
// 這裡可以發送 WebSocket 請求獲取最新數據
setTimeout(function() {
self.isLoading = false;
console.log('📋 會話數據刷新完成');
}, 1000);
};
/**
* 顯示當前會話詳情
*/
SessionManager.prototype.showSessionDetails = function() {
const currentSession = this.dataManager.getCurrentSession();
if (!currentSession) {
this.showMessage('目前沒有活躍的會話數據', 'warning');
return;
}
this.detailsModal.showSessionDetails(currentSession);
};
/**
* 查看會話詳情通過會話ID
*/
SessionManager.prototype.viewSessionDetails = function(sessionId) {
console.log('📋 查看會話詳情:', sessionId);
const sessionData = this.dataManager.findSessionById(sessionId);
if (sessionData) {
this.detailsModal.showSessionDetails(sessionData);
} else {
this.showMessage('找不到會話資料', 'error');
}
};
/**
* 獲取當前會話便利方法
*/
SessionManager.prototype.getCurrentSession = function() {
return this.dataManager.getCurrentSession();
};
/**
* 獲取會話歷史便利方法
*/
SessionManager.prototype.getSessionHistory = function() {
return this.dataManager.getSessionHistory();
};
/**
* 獲取統計資訊便利方法
*/
SessionManager.prototype.getStats = function() {
return this.dataManager.getStats();
};
/**
* 獲取當前會話數據相容性方法
*/
SessionManager.prototype.getCurrentSessionData = function() {
console.log('📋 嘗試獲取當前會話數據...');
const currentSession = this.dataManager.getCurrentSession();
if (currentSession && currentSession.session_id) {
console.log('📋 從 dataManager 獲取數據:', currentSession.session_id);
return currentSession;
}
// 嘗試從 app 的 WebSocketManager 獲取
if (window.feedbackApp && window.feedbackApp.webSocketManager) {
const wsManager = window.feedbackApp.webSocketManager;
if (wsManager.sessionId) {
console.log('📋 從 WebSocketManager 獲取數據:', wsManager.sessionId);
return {
session_id: wsManager.sessionId,
status: this.getCurrentSessionStatus(),
created_at: this.getSessionCreatedTime(),
project_directory: this.getProjectDirectory(),
summary: this.getAISummary()
};
}
}
// 嘗試從 app 的 currentSessionId 獲取
if (window.feedbackApp && window.feedbackApp.currentSessionId) {
console.log('📋 從 app.currentSessionId 獲取數據:', window.feedbackApp.currentSessionId);
return {
session_id: window.feedbackApp.currentSessionId,
status: this.getCurrentSessionStatus(),
created_at: this.getSessionCreatedTime(),
project_directory: this.getProjectDirectory(),
summary: this.getAISummary()
};
}
console.log('📋 無法獲取會話數據');
return null;
};
/**
* 獲取會話建立時間
*/
SessionManager.prototype.getSessionCreatedTime = function() {
// 嘗試從 WebSocketManager 的連線開始時間獲取
if (window.feedbackApp && window.feedbackApp.webSocketManager) {
const wsManager = window.feedbackApp.webSocketManager;
if (wsManager.connectionStartTime) {
return wsManager.connectionStartTime / 1000;
}
}
// 嘗試從最後收到的狀態更新中獲取
if (this.dataManager && this.dataManager.lastStatusUpdate && this.dataManager.lastStatusUpdate.created_at) {
return this.dataManager.lastStatusUpdate.created_at;
}
// 如果都沒有,返回 null
return null;
};
/**
* 獲取當前會話狀態
*/
SessionManager.prototype.getCurrentSessionStatus = function() {
// 嘗試從 UIManager 獲取當前狀態
if (window.feedbackApp && window.feedbackApp.uiManager) {
const currentState = window.feedbackApp.uiManager.getFeedbackState();
if (currentState) {
// 將內部狀態轉換為會話狀態
const stateMap = {
'waiting_for_feedback': 'waiting',
'processing': 'active',
'feedback_submitted': 'feedback_submitted'
};
return stateMap[currentState] || currentState;
}
}
// 嘗試從最後收到的狀態更新中獲取
if (this.dataManager && this.dataManager.lastStatusUpdate && this.dataManager.lastStatusUpdate.status) {
return this.dataManager.lastStatusUpdate.status;
}
// 預設狀態
return 'waiting';
};
/**
* 獲取專案目錄
*/
SessionManager.prototype.getProjectDirectory = function() {
const projectElement = document.querySelector('.session-project');
if (projectElement) {
return projectElement.textContent.replace('專案: ', '');
}
// 從頂部狀態列獲取
const topProjectInfo = document.querySelector('.project-info');
if (topProjectInfo) {
return topProjectInfo.textContent.replace('專案目錄: ', '');
}
return '未知';
};
/**
* 獲取 AI 摘要
*/
SessionManager.prototype.getAISummary = function() {
const summaryElement = document.querySelector('.session-summary');
if (summaryElement && summaryElement.textContent !== 'AI 摘要: 載入中...') {
return summaryElement.textContent.replace('AI 摘要: ', '');
}
// 嘗試從主要內容區域獲取
const mainSummary = document.querySelector('#combinedSummaryContent');
if (mainSummary && mainSummary.textContent.trim()) {
return mainSummary.textContent.trim();
}
return '暫無摘要';
};
2025-06-13 05:50:27 +08:00
/**
* 載入面板狀態
*/
SessionManager.prototype.loadPanelState = function() {
if (!this.settingsManager) {
console.log('📋 沒有設定管理器,使用預設面板狀態');
return;
}
const isCollapsed = this.settingsManager.get('sessionPanelCollapsed', false);
this.isPanelVisible = !isCollapsed;
console.log('📋 載入面板狀態:', this.isPanelVisible ? '顯示' : '隱藏');
// 應用面板狀態
this.applyPanelState();
};
/**
* 保存面板狀態
*/
SessionManager.prototype.savePanelState = function() {
if (!this.settingsManager) {
console.log('📋 沒有設定管理器,無法保存面板狀態');
return;
}
const isCollapsed = !this.isPanelVisible;
this.settingsManager.set('sessionPanelCollapsed', isCollapsed);
console.log('📋 保存面板狀態:', isCollapsed ? '收合' : '展開');
};
/**
* 應用面板狀態
*/
SessionManager.prototype.applyPanelState = function() {
if (!this.panel) return;
const DOMUtils = getDOMUtils();
if (this.isPanelVisible) {
// 展開面板
this.panel.classList.remove('collapsed');
if (this.mainContent) {
this.mainContent.classList.remove('panel-collapsed');
}
// 隱藏收合狀態下的展開按鈕
const collapsedToggle = DOMUtils ?
DOMUtils.safeQuerySelector('#collapsedPanelToggle') :
document.querySelector('#collapsedPanelToggle');
if (collapsedToggle) {
collapsedToggle.style.display = 'none';
}
// 更新邊緣按鈕圖示和提示
this.updateToggleButton('◀', '收合面板');
} else {
// 收合面板
this.panel.classList.add('collapsed');
if (this.mainContent) {
this.mainContent.classList.add('panel-collapsed');
}
// 顯示收合狀態下的展開按鈕
const collapsedToggle = DOMUtils ?
DOMUtils.safeQuerySelector('#collapsedPanelToggle') :
document.querySelector('#collapsedPanelToggle');
if (collapsedToggle) {
collapsedToggle.style.display = 'block';
}
// 更新邊緣按鈕圖示和提示
this.updateToggleButton('▶', '展開面板');
}
};
2025-06-13 05:48:08 +08:00
/**
* 更新顯示
*/
SessionManager.prototype.updateDisplay = function() {
const currentSession = this.dataManager.getCurrentSession();
const history = this.dataManager.getSessionHistory();
const stats = this.dataManager.getStats();
this.uiRenderer.renderCurrentSession(currentSession);
this.uiRenderer.renderSessionHistory(history);
this.uiRenderer.renderStats(stats);
};
/**
* 清理資源
*/
SessionManager.prototype.cleanup = function() {
// 清理子模組
if (this.dataManager) {
this.dataManager.cleanup();
this.dataManager = null;
}
if (this.uiRenderer) {
this.uiRenderer.cleanup();
this.uiRenderer = null;
}
if (this.detailsModal) {
this.detailsModal.cleanup();
this.detailsModal = null;
}
// 清理 UI 引用
this.panel = null;
this.edgeToggleBtn = null;
this.collapsedToggleBtn = null;
this.mainContent = null;
console.log('📋 SessionManager (重構版) 清理完成');
};
// 將 SessionManager 加入命名空間
window.MCPFeedback.SessionManager = SessionManager;
// 全域方法供 HTML 調用
window.MCPFeedback.SessionManager.viewSessionDetails = function(sessionId) {
console.log('📋 全域查看會話詳情:', sessionId);
// 找到當前的 SessionManager 實例
if (window.MCPFeedback && window.MCPFeedback.app && window.MCPFeedback.app.sessionManager) {
const sessionManager = window.MCPFeedback.app.sessionManager;
sessionManager.viewSessionDetails(sessionId);
} else {
// 如果找不到實例,顯示錯誤訊息
console.warn('找不到 SessionManager 實例');
if (window.MCPFeedback && window.MCPFeedback.Utils && window.MCPFeedback.Utils.showMessage) {
window.MCPFeedback.Utils.showMessage('會話管理器未初始化', 'error');
}
}
};
console.log('✅ SessionManager (重構版) 模組載入完成');
})();