mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-09 00:49:41 +02:00
refactor(select): extract the deferred panel refresh into _refreshSessionPanels
The block selectSession runs in an idle callback once the terminal content is on screen (respawn banner and countdown, action log, task panel, Ralph state, CLI info, project insights, subagent window visibility, file browser) moves verbatim into its own method. The tile grid's focus change needs the same refresh without the rest of selectSession, and one copy keeps the two from drifting. No behavior change: the stale-generation guard moves with it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+85
-72
@@ -8513,78 +8513,7 @@ class CodemanApp {
|
|||||||
// Defer secondary panel updates so they don't block the main thread
|
// Defer secondary panel updates so they don't block the main thread
|
||||||
// after terminal content is already visible.
|
// after terminal content is already visible.
|
||||||
const idleCb = typeof requestIdleCallback === 'function' ? requestIdleCallback : (cb) => setTimeout(cb, 16);
|
const idleCb = typeof requestIdleCallback === 'function' ? requestIdleCallback : (cb) => setTimeout(cb, 16);
|
||||||
idleCb(() => {
|
idleCb(() => this._refreshSessionPanels(sessionId, selectGen));
|
||||||
// Guard against stale generation — user may have switched tabs again
|
|
||||||
if (selectGen !== this._selectGeneration) return;
|
|
||||||
|
|
||||||
// Update respawn banner
|
|
||||||
if (this.respawnStatus[sessionId]) {
|
|
||||||
this.showRespawnBanner();
|
|
||||||
this.updateRespawnBanner(this.respawnStatus[sessionId].state);
|
|
||||||
document.getElementById('respawnCycleCount').textContent = this.respawnStatus[sessionId].cycleCount || 0;
|
|
||||||
this.updateCountdownTimerDisplay();
|
|
||||||
this.updateActionLogDisplay();
|
|
||||||
if (Object.keys(this.respawnCountdownTimers[sessionId] || {}).length > 0) {
|
|
||||||
this.startCountdownInterval();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.hideRespawnBanner();
|
|
||||||
this.stopCountdownInterval();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update task panel if open
|
|
||||||
const taskPanel = document.getElementById('taskPanel');
|
|
||||||
if (taskPanel && taskPanel.classList.contains('open')) {
|
|
||||||
this.renderTaskPanel();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update ralph state panel for this session
|
|
||||||
const curSession = this.sessions.get(sessionId);
|
|
||||||
if (curSession && (curSession.ralphLoop || curSession.ralphTodos)) {
|
|
||||||
this.updateRalphState(sessionId, {
|
|
||||||
loop: curSession.ralphLoop,
|
|
||||||
todos: curSession.ralphTodos
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.renderRalphStatePanel();
|
|
||||||
|
|
||||||
// Update CLI info bar (mobile - shows Claude version/model)
|
|
||||||
this.updateCliInfoDisplay();
|
|
||||||
|
|
||||||
// Update project insights panel for this session
|
|
||||||
this.renderProjectInsightsPanel();
|
|
||||||
|
|
||||||
// Update subagent window visibility for active session
|
|
||||||
this.updateSubagentWindowVisibility();
|
|
||||||
|
|
||||||
// Load file browser if enabled
|
|
||||||
const settings = this.loadAppSettingsFromStorage();
|
|
||||||
if (settings.showFileBrowser) {
|
|
||||||
const fileBrowserPanel = this.$('fileBrowserPanel');
|
|
||||||
if (fileBrowserPanel) {
|
|
||||||
fileBrowserPanel.classList.add('visible');
|
|
||||||
this.loadFileBrowser(sessionId);
|
|
||||||
// Attach drag listeners if not already attached
|
|
||||||
if (!this.fileBrowserDragListeners) {
|
|
||||||
const header = fileBrowserPanel.querySelector('.file-browser-header');
|
|
||||||
if (header) {
|
|
||||||
const onFirstDrag = () => {
|
|
||||||
if (!fileBrowserPanel.style.left) {
|
|
||||||
const rect = fileBrowserPanel.getBoundingClientRect();
|
|
||||||
fileBrowserPanel.style.left = `${rect.left}px`;
|
|
||||||
fileBrowserPanel.style.top = `${rect.top}px`;
|
|
||||||
fileBrowserPanel.style.right = 'auto';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
header.addEventListener('mousedown', onFirstDrag);
|
|
||||||
header.addEventListener('touchstart', onFirstDrag, { passive: true });
|
|
||||||
this.fileBrowserDragListeners = this.makeWindowDraggable(fileBrowserPanel, header);
|
|
||||||
this.fileBrowserDragListeners._onFirstDrag = onFirstDrag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Open WebSocket for low-latency terminal I/O (after buffer load completes)
|
// Open WebSocket for low-latency terminal I/O (after buffer load completes)
|
||||||
this._connectWs(sessionId);
|
this._connectWs(sessionId);
|
||||||
@@ -8707,6 +8636,90 @@ class CodemanApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The panels that follow the active session (respawn banner and countdown,
|
||||||
|
* action log, task panel, Ralph state, CLI info, project insights, subagent
|
||||||
|
* window visibility, file browser). Run deferred, after the terminal content
|
||||||
|
* is on screen, by selectSession and by the tile grid's focus change
|
||||||
|
* (tile-grid.js _selectTiledSession), so both share one copy.
|
||||||
|
*
|
||||||
|
* @param {string} sessionId - the session that just became active
|
||||||
|
* @param {number} selectGen - the `_selectGeneration` of that selection; a
|
||||||
|
* newer one (the user switched again) makes this a no-op
|
||||||
|
*/
|
||||||
|
_refreshSessionPanels(sessionId, selectGen) {
|
||||||
|
// A newer selection won: the user switched tabs again.
|
||||||
|
if (selectGen !== this._selectGeneration) return;
|
||||||
|
|
||||||
|
// Update respawn banner
|
||||||
|
if (this.respawnStatus[sessionId]) {
|
||||||
|
this.showRespawnBanner();
|
||||||
|
this.updateRespawnBanner(this.respawnStatus[sessionId].state);
|
||||||
|
document.getElementById('respawnCycleCount').textContent = this.respawnStatus[sessionId].cycleCount || 0;
|
||||||
|
this.updateCountdownTimerDisplay();
|
||||||
|
this.updateActionLogDisplay();
|
||||||
|
if (Object.keys(this.respawnCountdownTimers[sessionId] || {}).length > 0) {
|
||||||
|
this.startCountdownInterval();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.hideRespawnBanner();
|
||||||
|
this.stopCountdownInterval();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update task panel if open
|
||||||
|
const taskPanel = document.getElementById('taskPanel');
|
||||||
|
if (taskPanel && taskPanel.classList.contains('open')) {
|
||||||
|
this.renderTaskPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update ralph state panel for this session
|
||||||
|
const curSession = this.sessions.get(sessionId);
|
||||||
|
if (curSession && (curSession.ralphLoop || curSession.ralphTodos)) {
|
||||||
|
this.updateRalphState(sessionId, {
|
||||||
|
loop: curSession.ralphLoop,
|
||||||
|
todos: curSession.ralphTodos
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.renderRalphStatePanel();
|
||||||
|
|
||||||
|
// Update CLI info bar (mobile - shows Claude version/model)
|
||||||
|
this.updateCliInfoDisplay();
|
||||||
|
|
||||||
|
// Update project insights panel for this session
|
||||||
|
this.renderProjectInsightsPanel();
|
||||||
|
|
||||||
|
// Update subagent window visibility for active session
|
||||||
|
this.updateSubagentWindowVisibility();
|
||||||
|
|
||||||
|
// Load file browser if enabled
|
||||||
|
const settings = this.loadAppSettingsFromStorage();
|
||||||
|
if (settings.showFileBrowser) {
|
||||||
|
const fileBrowserPanel = this.$('fileBrowserPanel');
|
||||||
|
if (fileBrowserPanel) {
|
||||||
|
fileBrowserPanel.classList.add('visible');
|
||||||
|
this.loadFileBrowser(sessionId);
|
||||||
|
// Attach drag listeners if not already attached
|
||||||
|
if (!this.fileBrowserDragListeners) {
|
||||||
|
const header = fileBrowserPanel.querySelector('.file-browser-header');
|
||||||
|
if (header) {
|
||||||
|
const onFirstDrag = () => {
|
||||||
|
if (!fileBrowserPanel.style.left) {
|
||||||
|
const rect = fileBrowserPanel.getBoundingClientRect();
|
||||||
|
fileBrowserPanel.style.left = `${rect.left}px`;
|
||||||
|
fileBrowserPanel.style.top = `${rect.top}px`;
|
||||||
|
fileBrowserPanel.style.right = 'auto';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
header.addEventListener('mousedown', onFirstDrag);
|
||||||
|
header.addEventListener('touchstart', onFirstDrag, { passive: true });
|
||||||
|
this.fileBrowserDragListeners = this.makeWindowDraggable(fileBrowserPanel, header);
|
||||||
|
this.fileBrowserDragListeners._onFirstDrag = onFirstDrag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Shared cleanup for all session data — called from both closeSession() and session:deleted handler
|
// Shared cleanup for all session data — called from both closeSession() and session:deleted handler
|
||||||
_cleanupSessionData(sessionId) {
|
_cleanupSessionData(sessionId) {
|
||||||
this.closeTabRailActionMenu?.();
|
this.closeTabRailActionMenu?.();
|
||||||
|
|||||||
Reference in New Issue
Block a user