Start-Sequenz ergänzt: Splash-Screen, dann Startbildschirm mit Neues Projekt/Projekt öffnen/Zuletzt geöffnet.

Zuletzt-geöffnet-Liste (state/recentProjects.ts) trägt sich beim Öffnen und
beim Speichern automatisch ein, inkl. Öffnen über einen bekannten Pfad ohne
Dialog (verwaiste Einträge fliegen raus, wenn die Datei fehlt). Der Splash
wartet bewusst nicht auf den Update-Check — der läuft unabhängig im
Hintergrund weiter, damit ein langsames Netz den Start nie verzögert.
This commit is contained in:
2026-07-31 17:40:35 +02:00
parent fc31ef9f44
commit 06c0143d32
11 changed files with 407 additions and 8 deletions
+35
View File
@@ -210,6 +210,9 @@ import {
// Seiteneffekt: registriert die zwei dockbaren Kern-Panels in der Registry.
import { BUILTIN_PANEL_IDS } from "./panels/builtinPanels";
import { deriveDrawings } from "./DrawingTabs";
import { SplashScreen } from "./ui/SplashScreen";
import { StartScreen } from "./ui/StartScreen";
import { emptyProject } from "./model/sampleProject";
/**
* Offenes Kontextmenü — genau eine Quelle. `x/y` sind Viewport-Pixel (clientX/Y).
@@ -266,6 +269,13 @@ export default function App() {
// umgeschaltet wird (alle Kinder lesen denselben modulweiten Zustand über t).
useT();
// ── Boot-Sequenz: Splash → Startbildschirm (Neu/Öffnen/Zuletzt) → Editor ──
// Wie bei den meisten CAD-Programmen (s. ui/SplashScreen.tsx/StartScreen.tsx).
// Läuft NUR einmal pro Fensterstart; sobald "editor" erreicht ist, bleibt der
// volle Editor bestehen (auch bei späteren File>Neu/Öffnen-Aktionen, die
// weiterhin über das normale Menü laufen).
const [bootPhase, setBootPhase] = useState<"splash" | "start" | "editor">("splash");
// ── Globaler Zustand aus dem Store (Slices: project/selection/view/layout) ─
// Pro useStore-Aufruf EIN Feld selektieren (Referenz-Gleichheit, sonst
// Endlosschleife). Actions leben ebenfalls im Zustand und sind referenzstabil.
@@ -2158,6 +2168,7 @@ export default function App() {
onExportObj,
onExportStl,
onOpenProject,
openProjectAtPath,
onProjectFileChosen,
runImport,
} = useProjectFileActions(
@@ -4457,6 +4468,30 @@ export default function App() {
if (f) openImportForFile(f);
};
if (bootPhase === "splash") {
return <SplashScreen onDone={() => setBootPhase("start")} />;
}
if (bootPhase === "start") {
return (
<StartScreen
onNewProject={() => {
setProject(emptyProject);
setBootPhase("editor");
}}
onOpenProject={() => {
onOpenProject();
setBootPhase("editor");
}}
onOpenRecent={(path) => {
void openProjectAtPath(path).then((found) => {
if (!found) notify(t("start.recentMissing"), "error");
});
setBootPhase("editor");
}}
/>
);
}
return (
<div
className="app"