fix: show loading spinner instead of hanging in open project dialog when user click open button
This commit is contained in:
@@ -29,6 +29,7 @@ import { KEY_SIGNATURE_MAP } from '../constants/coreConstants';
|
||||
import { KGOfflineRenderer } from '../core/audio-interface/KGOfflineRenderer';
|
||||
import KGDropdown from './common/KGDropdown';
|
||||
import FileImportModal from './common/FileImportModal';
|
||||
import LoadingOverlay from './common/LoadingOverlay';
|
||||
import OpenProjectModal from './common/OpenProjectModal';
|
||||
import { clearChatHistoryAndUI } from '../util/chatUtil';
|
||||
import PianoIcon from './common/icons/PianoIcon';
|
||||
@@ -77,6 +78,7 @@ const Toolbar: React.FC = () => {
|
||||
|
||||
// State for open project modal
|
||||
const [showOpenProject, setShowOpenProject] = React.useState(false);
|
||||
const [isOpeningProject, setIsOpeningProject] = React.useState(false);
|
||||
|
||||
// Close zoom slider on click outside
|
||||
React.useEffect(() => {
|
||||
@@ -205,12 +207,7 @@ const Toolbar: React.FC = () => {
|
||||
};
|
||||
|
||||
const handleOpenProjectSelect = async (projectNameToLoad: string) => {
|
||||
const confirmed = await showConfirm(
|
||||
'Open this project? Any unsaved changes in the current project will be lost.'
|
||||
);
|
||||
if (!confirmed) {
|
||||
return false;
|
||||
}
|
||||
setIsOpeningProject(true);
|
||||
|
||||
try {
|
||||
const storage = KGProjectStorage.getInstance();
|
||||
@@ -218,18 +215,25 @@ const Toolbar: React.FC = () => {
|
||||
|
||||
if (!loadedProject) {
|
||||
await showAlert(`Project "${projectNameToLoad}" not found.`);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
await loadProjectFromData(loadedProject, `Project "${projectNameToLoad}"`, projectNameToLoad);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error("Error loading project:", error);
|
||||
await showAlert(`An error occurred while loading the project: ${error}`);
|
||||
return false;
|
||||
} finally {
|
||||
setIsOpeningProject(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleConfirmOpenProject = async (_projectNameToLoad: string) => {
|
||||
const confirmed = await showConfirm(
|
||||
'Open this project? Any unsaved changes in the current project will be lost.'
|
||||
);
|
||||
return confirmed;
|
||||
};
|
||||
|
||||
const handleSaveProject = async () => {
|
||||
if (DEBUG_MODE.TOOLBAR) {
|
||||
console.log("user clicked save button");
|
||||
@@ -1207,9 +1211,15 @@ const Toolbar: React.FC = () => {
|
||||
description="Drag and drop your project file here"
|
||||
/>
|
||||
|
||||
<LoadingOverlay
|
||||
visible={isOpeningProject}
|
||||
message="Opening project..."
|
||||
/>
|
||||
|
||||
{showOpenProject && (
|
||||
<OpenProjectModal
|
||||
onClose={() => setShowOpenProject(false)}
|
||||
onConfirmOpenProject={handleConfirmOpenProject}
|
||||
onOpenProject={handleOpenProjectSelect}
|
||||
currentProjectName={savedProjectName}
|
||||
onCreateNewProject={createNewProject}
|
||||
|
||||
@@ -7,7 +7,8 @@ import { showAlert, showConfirm, showPrompt } from '../../util/dialogUtil';
|
||||
|
||||
interface OpenProjectModalProps {
|
||||
onClose: () => void;
|
||||
onOpenProject: (projectName: string) => Promise<boolean>;
|
||||
onConfirmOpenProject: (projectName: string) => Promise<boolean>;
|
||||
onOpenProject: (projectName: string) => Promise<void>;
|
||||
currentProjectName: string | null;
|
||||
onCreateNewProject: () => void;
|
||||
}
|
||||
@@ -44,12 +45,19 @@ const formatDate = (timestamp: number): string => {
|
||||
});
|
||||
};
|
||||
|
||||
const OpenProjectModal: React.FC<OpenProjectModalProps> = ({ onClose, onOpenProject, currentProjectName, onCreateNewProject }) => {
|
||||
const OpenProjectModal: React.FC<OpenProjectModalProps> = ({
|
||||
onClose,
|
||||
onConfirmOpenProject,
|
||||
onOpenProject,
|
||||
currentProjectName,
|
||||
onCreateNewProject
|
||||
}) => {
|
||||
const [projects, setProjects] = useState<ProjectMeta[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [filter, setFilter] = useState('');
|
||||
const [isClosing, setIsClosing] = useState(false);
|
||||
const mouseDownOnOverlay = useRef(false);
|
||||
const pendingOpenProjectName = useRef<string | null>(null);
|
||||
|
||||
const [sortField, setSortField] = useState<SortField>('updatedAt');
|
||||
const [sortDirection, setSortDirection] = useState<SortDirection>('desc');
|
||||
@@ -61,9 +69,16 @@ const OpenProjectModal: React.FC<OpenProjectModalProps> = ({ onClose, onOpenProj
|
||||
const handleAnimationEnd = useCallback((e: React.AnimationEvent) => {
|
||||
if (e.target !== e.currentTarget) return;
|
||||
if (!isClosing) return;
|
||||
|
||||
const projectNameToOpen = pendingOpenProjectName.current;
|
||||
pendingOpenProjectName.current = null;
|
||||
setIsClosing(false);
|
||||
onClose();
|
||||
}, [isClosing, onClose]);
|
||||
|
||||
if (projectNameToOpen) {
|
||||
void onOpenProject(projectNameToOpen);
|
||||
}
|
||||
}, [isClosing, onClose, onOpenProject]);
|
||||
|
||||
const fetchProjects = useCallback(async (mode: ViewMode) => {
|
||||
setIsLoading(true);
|
||||
@@ -121,10 +136,11 @@ const OpenProjectModal: React.FC<OpenProjectModalProps> = ({ onClose, onOpenProj
|
||||
}, [projects, filter, sortField, sortDirection]);
|
||||
|
||||
const handleOpen = async (projectName: string) => {
|
||||
const opened = await onOpenProject(projectName);
|
||||
if (opened) {
|
||||
startClose();
|
||||
}
|
||||
const confirmed = await onConfirmOpenProject(projectName);
|
||||
if (!confirmed) return;
|
||||
|
||||
pendingOpenProjectName.current = projectName;
|
||||
startClose();
|
||||
};
|
||||
|
||||
const handleDuplicate = async (e: React.MouseEvent, projectName: string) => {
|
||||
@@ -141,11 +157,12 @@ const OpenProjectModal: React.FC<OpenProjectModalProps> = ({ onClose, onOpenProj
|
||||
try {
|
||||
const storage = KGProjectStorage.getInstance();
|
||||
const finalName = await storage.resolveUniqueName(trimmed);
|
||||
const confirmed = await onConfirmOpenProject(finalName);
|
||||
if (!confirmed) return;
|
||||
|
||||
await storage.duplicate(projectName, finalName);
|
||||
const opened = await onOpenProject(finalName);
|
||||
if (opened) {
|
||||
startClose();
|
||||
}
|
||||
pendingOpenProjectName.current = finalName;
|
||||
startClose();
|
||||
} catch (error) {
|
||||
console.error('Error duplicating project:', error);
|
||||
await showAlert(`Failed to duplicate project: ${error}`);
|
||||
|
||||
Reference in New Issue
Block a user