Fix tab persistence in Claude IDE - persist closed tabs to localStorage
Implement localStorage persistence for closed session and project tabs. When users close tabs, they now remain closed after page refresh. Changes: - session-tabs.js: Add closedSessions tracking with localStorage - project-manager.js: Add closedProjects tracking with localStorage - Filter out closed tabs on load - Persist state whenever tabs are closed Fixes issue where closed tabs would reappear on page refresh. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,8 @@ class ProjectManager {
|
|||||||
this.activeProjectId = null;
|
this.activeProjectId = null;
|
||||||
this.activeSessionId = null;
|
this.activeSessionId = null;
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
|
this.closedProjects = new Set(); // Track closed project IDs
|
||||||
|
this.STORAGE_KEY = 'claude_ide_closed_projects';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,6 +33,7 @@ class ProjectManager {
|
|||||||
if (this.initialized) return;
|
if (this.initialized) return;
|
||||||
|
|
||||||
console.log('[ProjectManager] Initializing...');
|
console.log('[ProjectManager] Initializing...');
|
||||||
|
this.loadClosedProjects();
|
||||||
await this.loadProjects();
|
await this.loadProjects();
|
||||||
this.renderProjectTabs();
|
this.renderProjectTabs();
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
@@ -44,6 +47,36 @@ class ProjectManager {
|
|||||||
console.log('[ProjectManager] Initialized with', this.projects.size, 'projects');
|
console.log('[ProjectManager] Initialized with', this.projects.size, 'projects');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load closed projects from localStorage
|
||||||
|
*/
|
||||||
|
loadClosedProjects() {
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem(this.STORAGE_KEY);
|
||||||
|
if (stored) {
|
||||||
|
const closedIds = JSON.parse(stored);
|
||||||
|
this.closedProjects = new Set(closedIds);
|
||||||
|
console.log('[ProjectManager] Loaded', this.closedProjects.size, 'closed projects from storage');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[ProjectManager] Error loading closed projects:', error);
|
||||||
|
this.closedProjects = new Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save closed projects to localStorage
|
||||||
|
*/
|
||||||
|
saveClosedProjects() {
|
||||||
|
try {
|
||||||
|
const closedIds = Array.from(this.closedProjects);
|
||||||
|
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(closedIds));
|
||||||
|
console.log('[ProjectManager] Saved', closedIds.length, 'closed projects to storage');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[ProjectManager] Error saving closed projects:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load all sessions and organize them by project
|
* Load all sessions and organize them by project
|
||||||
*/
|
*/
|
||||||
@@ -97,8 +130,16 @@ class ProjectManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.projects = grouped;
|
// Filter out closed projects
|
||||||
console.log('[ProjectManager] Loaded', this.projects.size, 'projects');
|
const filtered = new Map();
|
||||||
|
grouped.forEach((project, key) => {
|
||||||
|
if (!this.closedProjects.has(project.id)) {
|
||||||
|
filtered.set(key, project);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.projects = filtered;
|
||||||
|
console.log('[ProjectManager] Loaded', this.projects.size, 'projects (filtered out', grouped.size - this.projects.size, 'closed)');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[ProjectManager] Error loading projects:', error);
|
console.error('[ProjectManager] Error loading projects:', error);
|
||||||
@@ -434,6 +475,10 @@ class ProjectManager {
|
|||||||
|
|
||||||
console.log('[ProjectManager] Closing project:', projectId);
|
console.log('[ProjectManager] Closing project:', projectId);
|
||||||
|
|
||||||
|
// Add to closed projects set and persist
|
||||||
|
this.closedProjects.add(projectId);
|
||||||
|
this.saveClosedProjects();
|
||||||
|
|
||||||
// Remove project from map
|
// Remove project from map
|
||||||
this.projects.delete(projectKey);
|
this.projects.delete(projectKey);
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ class SessionTabs {
|
|||||||
this.sessions = [];
|
this.sessions = [];
|
||||||
this.activeSessionId = null;
|
this.activeSessionId = null;
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
|
this.closedSessions = new Set(); // Track closed session IDs
|
||||||
|
this.STORAGE_KEY = 'claude_ide_closed_sessions';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,16 +32,48 @@ class SessionTabs {
|
|||||||
if (this.initialized) return;
|
if (this.initialized) return;
|
||||||
|
|
||||||
console.log('[SessionTabs] Initializing...');
|
console.log('[SessionTabs] Initializing...');
|
||||||
|
this.loadClosedSessions();
|
||||||
this.render();
|
this.render();
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load closed sessions from localStorage
|
||||||
|
*/
|
||||||
|
loadClosedSessions() {
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem(this.STORAGE_KEY);
|
||||||
|
if (stored) {
|
||||||
|
const closedIds = JSON.parse(stored);
|
||||||
|
this.closedSessions = new Set(closedIds);
|
||||||
|
console.log('[SessionTabs] Loaded', this.closedSessions.size, 'closed sessions from storage');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[SessionTabs] Error loading closed sessions:', error);
|
||||||
|
this.closedSessions = new Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save closed sessions to localStorage
|
||||||
|
*/
|
||||||
|
saveClosedSessions() {
|
||||||
|
try {
|
||||||
|
const closedIds = Array.from(this.closedSessions);
|
||||||
|
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(closedIds));
|
||||||
|
console.log('[SessionTabs] Saved', closedIds.length, 'closed sessions to storage');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[SessionTabs] Error saving closed sessions:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set sessions for current project
|
* Set sessions for current project
|
||||||
*/
|
*/
|
||||||
setSessions(sessions) {
|
setSessions(sessions) {
|
||||||
this.sessions = sessions || [];
|
// Filter out closed sessions
|
||||||
console.log('[SessionTabs] Set', this.sessions.length, 'sessions');
|
this.sessions = (sessions || []).filter(s => !this.closedSessions.has(s.id));
|
||||||
|
console.log('[SessionTabs] Set', this.sessions.length, 'sessions (filtered out', (sessions || []).length - this.sessions.length, 'closed)');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -191,6 +225,10 @@ class SessionTabs {
|
|||||||
|
|
||||||
console.log('[SessionTabs] Closing session:', sessionId);
|
console.log('[SessionTabs] Closing session:', sessionId);
|
||||||
|
|
||||||
|
// Add to closed sessions set and persist
|
||||||
|
this.closedSessions.add(sessionId);
|
||||||
|
this.saveClosedSessions();
|
||||||
|
|
||||||
// Note: This just removes the tab from view
|
// Note: This just removes the tab from view
|
||||||
// The session still exists on the server
|
// The session still exists on the server
|
||||||
this.sessions = this.sessions.filter(s => s.id !== sessionId);
|
this.sessions = this.sessions.filter(s => s.id !== sessionId);
|
||||||
|
|||||||
Reference in New Issue
Block a user