fix: corrected tab handling over projects
This commit is contained in:
@@ -1,8 +1,22 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { ActivityBar, Sidebar, Editor, StatusBar, Panel, TabBar, ToastContainer, showToast } from './components';
|
import { ActivityBar, Sidebar, Editor, StatusBar, Panel, TabBar, ToastContainer, showToast } from './components';
|
||||||
import { useAppStore, PostData, MediaData, TaskProgress } from './store';
|
import { useAppStore, PostData, MediaData, TaskProgress, TabState } from './store';
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
|
||||||
|
// Helper to load tabs for a project from localStorage
|
||||||
|
const TAB_STATE_PREFIX = 'bds-tabs-';
|
||||||
|
const loadTabsForProject = (projectId: string): TabState | null => {
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem(`${TAB_STATE_PREFIX}${projectId}`);
|
||||||
|
if (stored) {
|
||||||
|
return JSON.parse(stored) as TabState;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to load tab state:', error);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const {
|
const {
|
||||||
setPosts,
|
setPosts,
|
||||||
@@ -24,6 +38,7 @@ const App: React.FC = () => {
|
|||||||
setActiveView,
|
setActiveView,
|
||||||
setSelectedPost,
|
setSelectedPost,
|
||||||
openTab,
|
openTab,
|
||||||
|
restoreTabState,
|
||||||
} = useAppStore();
|
} = useAppStore();
|
||||||
|
|
||||||
// Load initial data
|
// Load initial data
|
||||||
@@ -32,7 +47,7 @@ const App: React.FC = () => {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
// First, get active project to set the correct context in backend engines
|
// First, get active project to set the correct context in backend engines
|
||||||
await window.electronAPI?.projects.getActive();
|
const activeProject = await window.electronAPI?.projects.getActive();
|
||||||
|
|
||||||
// Load posts (now with correct project context, limited to 500)
|
// Load posts (now with correct project context, limited to 500)
|
||||||
const postsResult = await window.electronAPI?.posts.getAll({ limit: 500, offset: 0 });
|
const postsResult = await window.electronAPI?.posts.getAll({ limit: 500, offset: 0 });
|
||||||
@@ -46,6 +61,14 @@ const App: React.FC = () => {
|
|||||||
if (media) {
|
if (media) {
|
||||||
setMedia(media as MediaData[]);
|
setMedia(media as MediaData[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore tabs for the active project
|
||||||
|
if (activeProject && (activeProject as { id: string }).id) {
|
||||||
|
const savedTabState = loadTabsForProject((activeProject as { id: string }).id);
|
||||||
|
if (savedTabState) {
|
||||||
|
restoreTabState(savedTabState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Re-configure Dropbox sync from saved credentials
|
// Re-configure Dropbox sync from saved credentials
|
||||||
const savedCreds = localStorage.getItem('bds-credentials');
|
const savedCreds = localStorage.getItem('bds-credentials');
|
||||||
@@ -89,6 +112,25 @@ const App: React.FC = () => {
|
|||||||
loadData();
|
loadData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Save tabs when window closes
|
||||||
|
useEffect(() => {
|
||||||
|
const saveTabsOnUnload = () => {
|
||||||
|
const state = useAppStore.getState();
|
||||||
|
const projectId = state.activeProject?.id;
|
||||||
|
if (projectId) {
|
||||||
|
const tabState = state.getTabState();
|
||||||
|
try {
|
||||||
|
localStorage.setItem(`${TAB_STATE_PREFIX}${projectId}`, JSON.stringify(tabState));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to save tab state on unload:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('beforeunload', saveTabsOnUnload);
|
||||||
|
return () => window.removeEventListener('beforeunload', saveTabsOnUnload);
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Set up event listeners for real-time updates
|
// Set up event listeners for real-time updates
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubscribers: Array<() => void> = [];
|
const unsubscribers: Array<() => void> = [];
|
||||||
|
|||||||
@@ -1,10 +1,33 @@
|
|||||||
import React, { useState, useRef, useEffect } from 'react';
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
import { useAppStore, ProjectData, PostData, MediaData } from '../../store';
|
import { useAppStore, ProjectData, PostData, MediaData, TabState } from '../../store';
|
||||||
import { showToast } from '../Toast';
|
import { showToast } from '../Toast';
|
||||||
import './ProjectSelector.css';
|
import './ProjectSelector.css';
|
||||||
|
|
||||||
|
// Helper functions for project-specific tab persistence
|
||||||
|
const TAB_STATE_PREFIX = 'bds-tabs-';
|
||||||
|
|
||||||
|
const saveTabsForProject = (projectId: string, tabState: TabState): void => {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(`${TAB_STATE_PREFIX}${projectId}`, JSON.stringify(tabState));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to save tab state:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadTabsForProject = (projectId: string): TabState | null => {
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem(`${TAB_STATE_PREFIX}${projectId}`);
|
||||||
|
if (stored) {
|
||||||
|
return JSON.parse(stored) as TabState;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to load tab state:', error);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
export const ProjectSelector: React.FC = () => {
|
export const ProjectSelector: React.FC = () => {
|
||||||
const { projects, activeProject, setProjects, setActiveProject, setPosts, setMedia, setSelectedPost, setSelectedMedia, removeProject } = useAppStore();
|
const { projects, activeProject, setProjects, setActiveProject, setPosts, setMedia, setSelectedPost, setSelectedMedia, removeProject, getTabState, restoreTabState, clearTabs } = useAppStore();
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [showCreateModal, setShowCreateModal] = useState(false);
|
const [showCreateModal, setShowCreateModal] = useState(false);
|
||||||
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||||
@@ -51,6 +74,15 @@ export const ProjectSelector: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Save current project's tab state before switching
|
||||||
|
if (activeProject) {
|
||||||
|
const currentTabState = getTabState();
|
||||||
|
saveTabsForProject(activeProject.id, currentTabState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear tabs for the transition
|
||||||
|
clearTabs();
|
||||||
|
|
||||||
const updatedProject = await window.electronAPI?.projects.setActive(project.id);
|
const updatedProject = await window.electronAPI?.projects.setActive(project.id);
|
||||||
if (updatedProject) {
|
if (updatedProject) {
|
||||||
setActiveProject(updatedProject as ProjectData);
|
setActiveProject(updatedProject as ProjectData);
|
||||||
@@ -70,6 +102,12 @@ export const ProjectSelector: React.FC = () => {
|
|||||||
}
|
}
|
||||||
if (mediaResult) setMedia(mediaResult as MediaData[]);
|
if (mediaResult) setMedia(mediaResult as MediaData[]);
|
||||||
|
|
||||||
|
// Restore tabs for the new project
|
||||||
|
const savedTabState = loadTabsForProject(project.id);
|
||||||
|
if (savedTabState) {
|
||||||
|
restoreTabState(savedTabState);
|
||||||
|
}
|
||||||
|
|
||||||
showToast.success(`Switched to ${project.name}`);
|
showToast.success(`Switched to ${project.name}`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user