Add loading spinner to MCP add button during polling

- Send mcp-polling-started event from main process before each poll
- Show spinner on add button when polling starts
- Restore + button when mcp-servers-updated event received
- Spinner shows on initial load and every 60s refresh
This commit is contained in:
Amrit Subramanian 2025-10-05 16:13:23 -04:00
parent 639ec0ab08
commit 9405824d7b
2 changed files with 28 additions and 14 deletions

View file

@ -158,6 +158,11 @@ function spawnMcpPoller(sessionId: string, projectDir: string) {
console.log(`[MCP Poller ${sessionId}] Starting polling loop`); console.log(`[MCP Poller ${sessionId}] Starting polling loop`);
const pollMcp = () => { const pollMcp = () => {
if (mcpPollerPtyProcesses.has(sessionId)) { if (mcpPollerPtyProcesses.has(sessionId)) {
// Notify renderer that polling is starting
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.webContents.send("mcp-polling-started", sessionId);
}
const command = `claude mcp list`; const command = `claude mcp list`;
console.log(`[MCP Poller ${sessionId}] Running command: ${command}`); console.log(`[MCP Poller ${sessionId}] Running command: ${command}`);
ptyProcess.write(command + "\r"); ptyProcess.write(command + "\r");

View file

@ -225,6 +225,7 @@ const DEFAULT_SETTINGS: TerminalSettings = {
const sessions = new Map<string, Session>(); const sessions = new Map<string, Session>();
let activeSessionId: string | null = null; let activeSessionId: string | null = null;
let mcpServers: McpServer[] = []; let mcpServers: McpServer[] = [];
let mcpPollerActive = false;
let terminalSettings: TerminalSettings = { ...DEFAULT_SETTINGS }; let terminalSettings: TerminalSettings = { ...DEFAULT_SETTINGS };
function createTerminalUI(sessionId: string) { function createTerminalUI(sessionId: string) {
@ -962,25 +963,11 @@ async function loadMcpServers() {
return; return;
} }
const addMcpServerBtn = document.getElementById("add-mcp-server");
// Show loading spinner
if (addMcpServerBtn) {
addMcpServerBtn.innerHTML = '<span class="loading-spinner"></span>';
addMcpServerBtn.classList.add("pointer-events-none");
}
try { try {
await ipcRenderer.invoke("list-mcp-servers", activeSessionId); await ipcRenderer.invoke("list-mcp-servers", activeSessionId);
// Results will come via mcp-servers-updated event // Results will come via mcp-servers-updated event
} catch (error) { } catch (error) {
console.error("Failed to load MCP servers:", error); console.error("Failed to load MCP servers:", error);
} finally {
// Restore button
if (addMcpServerBtn) {
addMcpServerBtn.innerHTML = '+';
addMcpServerBtn.classList.remove("pointer-events-none");
}
} }
} }
@ -1243,12 +1230,34 @@ removeMcpDetailsBtn?.addEventListener("click", async () => {
} }
}); });
// Listen for MCP polling started event
ipcRenderer.on("mcp-polling-started", (_event, sessionId: string) => {
console.log(`[MCP UI] Polling started for session ${sessionId}, active: ${activeSessionId}`);
if (sessionId === activeSessionId) {
const addMcpServerBtn = document.getElementById("add-mcp-server");
if (addMcpServerBtn) {
console.log("[MCP UI] Setting add button to loading state");
addMcpServerBtn.innerHTML = '<span class="loading-spinner"></span>';
addMcpServerBtn.classList.add("pointer-events-none");
}
}
});
// Listen for MCP server updates from main process // Listen for MCP server updates from main process
ipcRenderer.on("mcp-servers-updated", (_event, sessionId: string, servers: McpServer[]) => { ipcRenderer.on("mcp-servers-updated", (_event, sessionId: string, servers: McpServer[]) => {
console.log(`[MCP UI] Received update for session ${sessionId}, active: ${activeSessionId}`);
// Only update if this is for the active session // Only update if this is for the active session
if (sessionId === activeSessionId) { if (sessionId === activeSessionId) {
mcpServers = servers; mcpServers = servers;
renderMcpServers(); renderMcpServers();
// Restore add button
console.log("[MCP UI] Restoring add button from loading state");
const addMcpServerBtn = document.getElementById("add-mcp-server");
if (addMcpServerBtn) {
addMcpServerBtn.innerHTML = '+';
addMcpServerBtn.classList.remove("pointer-events-none");
}
} }
}); });