feat: add MCP session visibility toggle and rebuild release

This commit is contained in:
shiyue
2026-08-26 17:12:45 +08:00
parent f15bc92d1e
commit e62a545569
13 changed files with 564 additions and 7 deletions

View File

@@ -12,6 +12,7 @@
const CCWEB_PROMPT_VIEW_MODE_STORAGE_KEY = 'cc-web-ccweb-prompt-view-mode';
const PROJECT_COLLAPSE_STORAGE_KEY = 'cc-web-collapsed-projects';
const SIDEBAR_COLLAPSE_STORAGE_KEY = 'cc-web-sidebar-collapsed';
const MCP_SESSION_VISIBILITY_STORAGE_KEY = 'cc-web-mcp-session-visibility';
const SIDEBAR_DRAWER_MEDIA_QUERY = '(max-width: 768px)';
const SIDEBAR_DESKTOP_COLLAPSE_MEDIA_QUERY = '(width > 768px)';
const SIDEBAR_HOVER_PREVIEW_MEDIA_QUERY = '(width > 768px) and (hover: hover) and (pointer: fine)';
@@ -272,6 +273,7 @@
let isReloadingMcp = false;
const mcpStartupToastKeys = new Map();
let sessionSearchQuery = '';
let showMcpSessions = readMcpSessionVisibilityPreference();
const advancedSessionSearchState = {
open: false,
query: '',
@@ -365,6 +367,7 @@
const importSessionBtn = $('#import-session-btn');
const sessionSearchInput = $('#session-search-input');
const sessionSearchClear = $('#session-search-clear');
const mcpSessionVisibilityToggle = $('#mcp-session-visibility-toggle');
const advancedSearchOpen = $('#advanced-search-open');
const advancedSearchPanel = $('#advanced-search-panel');
const advancedSearchClose = $('#advanced-search-close');
@@ -4521,6 +4524,39 @@
}
}
function readMcpSessionVisibilityPreference() {
try {
return localStorage.getItem(MCP_SESSION_VISIBILITY_STORAGE_KEY) !== 'false';
} catch {
return true;
}
}
function persistMcpSessionVisibilityPreference(visible) {
try {
localStorage.setItem(MCP_SESSION_VISIBILITY_STORAGE_KEY, visible ? 'true' : 'false');
} catch {
// 存储不可用时仍保留当前页面内的筛选状态。
}
}
function sessionPassesMcpVisibilityFilter(session, normalizedSearchQuery = '') {
if (normalizedSearchQuery) return true;
if (showMcpSessions) return true;
const isMcpCreated = String(session?.createdFromKind || '').toLowerCase() === 'mcp';
if (!isMcpCreated) return true;
return session.id === currentSessionId || !!session.isRunning;
}
function syncMcpSessionVisibilityToggle() {
if (!mcpSessionVisibilityToggle) return;
const isHidingMcpSessions = !showMcpSessions;
const actionLabel = isHidingMcpSessions ? '显示 MCP 会话' : '隐藏 MCP 会话';
mcpSessionVisibilityToggle.setAttribute('aria-pressed', String(isHidingMcpSessions));
mcpSessionVisibilityToggle.title = actionLabel;
mcpSessionVisibilityToggle.setAttribute('aria-label', actionLabel);
}
function getSessionSearchText(session) {
const cwd = getSessionEffectiveCwd(session);
return [
@@ -10856,6 +10892,7 @@
return JSON.stringify({
agent: currentAgent,
currentSessionId,
showMcpSessions,
search: model.normalizedSearchQuery,
allEmpty: model.allVisibleSessions.length === 0,
visibleEmpty: model.visibleSessions.length === 0,
@@ -10890,12 +10927,16 @@
function renderSessionList() {
syncSessionSearchUi();
syncMcpSessionVisibilityToggle();
const allVisibleSessions = getVisibleSessions();
const normalizedSearchQuery = normalizeSessionSearchQuery(sessionSearchQuery);
const isSearchingSessions = !!normalizedSearchQuery;
const mcpVisibilityFilteredSessions = allVisibleSessions.filter((session) => (
sessionPassesMcpVisibilityFilter(session, normalizedSearchQuery)
));
const visibleSessions = isSearchingSessions
? allVisibleSessions.filter((session) => sessionMatchesSearch(session, normalizedSearchQuery))
: allVisibleSessions;
? mcpVisibilityFilteredSessions.filter((session) => sessionMatchesSearch(session, normalizedSearchQuery))
: mcpVisibilityFilteredSessions;
const { pinnedSessions, regularSessions } = splitPinnedSessions(visibleSessions);
const { groups: projectGroups, ungroupedSessions } = groupSessionsByProject(regularSessions);
const renderGroups = projectGroups.map((group, groupIndex) => {
@@ -10951,7 +10992,7 @@
if (visibleSessions.length === 0) {
const empty = document.createElement('div');
empty.className = 'session-list-empty';
empty.textContent = '没有匹配的会话或项目。';
empty.textContent = isSearchingSessions ? '没有匹配的会话或项目。' : 'MCP 会话已隐藏。';
sessionList.appendChild(empty);
lastSessionListStructureSignature = structureSignature;
return;
@@ -11821,6 +11862,14 @@
});
}
if (mcpSessionVisibilityToggle) {
mcpSessionVisibilityToggle.addEventListener('click', () => {
showMcpSessions = !showMcpSessions;
persistMcpSessionVisibilityPreference(showMcpSessions);
renderSessionList();
});
}
if (advancedSearchOpen && advancedSearchPanel) {
advancedSearchOpen.addEventListener('click', openAdvancedSessionSearch);
advancedSearchClose?.addEventListener('click', () => closeAdvancedSessionSearch());