From 1dc9d1114e9df7b6f322672bfc6557b3bef7fc6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Forment?= Date: Wed, 15 Oct 2025 11:39:22 +0200 Subject: [PATCH] Keeping last project open --- src/App.svelte | 47 ++++++++++++++----- src/lib/components/editor/Editor.svelte | 11 ++++- .../components/editor/EditorWithLogs.svelte | 5 +- src/lib/project-system/persistence.ts | 17 +++++++ src/lib/stores/projectEditor.svelte.ts | 4 ++ 5 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 src/lib/project-system/persistence.ts diff --git a/src/App.svelte b/src/App.svelte index f7b718f..17acd60 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -21,6 +21,7 @@ templateRegistry, type CsoundTemplate, } from "./lib/templates/template-registry"; + import { loadLastProjectId } from "./lib/project-system/persistence"; import { createAppContext, setAppContext } from "./lib/contexts/app-context"; import type { ProjectMode } from "./lib/project-system/types"; import { @@ -53,20 +54,43 @@ onMount(async () => { await projectManager.init(); - const result = await projectManager.getAllProjects(); - if (result.success && result.data.length === 0) { - const classicTemplate = templateRegistry.getById("classic"); - if (classicTemplate) { - await projectManager.createProject({ - title: "Welcome", - author: "System", - content: classicTemplate.content, - tags: [], - mode: classicTemplate.mode, - }); + const lastProjectId = loadLastProjectId(); + let projectToLoad: CsoundProject | null = null; + + if (lastProjectId) { + const result = await projectManager.getProject(lastProjectId); + if (result.success) { + projectToLoad = result.data; } } + if (!projectToLoad) { + const allProjectsResult = await projectManager.getAllProjects(); + if (allProjectsResult.success) { + if (allProjectsResult.data.length > 0) { + projectToLoad = allProjectsResult.data[0]; + } else { + const classicTemplate = templateRegistry.getById("classic"); + if (classicTemplate) { + const createResult = await projectManager.createProject({ + title: "Welcome", + author: "System", + content: classicTemplate.content, + tags: [], + mode: classicTemplate.mode, + }); + if (createResult.success) { + projectToLoad = createResult.data; + } + } + } + } + } + + if (projectToLoad) { + projectEditor.loadProject(projectToLoad); + } + logsUnsubscribe = csoundDerived.logs.subscribe((logs) => { interpreterLogs = logs; }); @@ -344,6 +368,7 @@ onExecute={handleExecute} logs={interpreterLogs} {editorSettings} + mode={projectEditor.currentProject?.mode || 'composition'} /> diff --git a/src/lib/components/editor/Editor.svelte b/src/lib/components/editor/Editor.svelte index d6f5cad..0cd1240 100644 --- a/src/lib/components/editor/Editor.svelte +++ b/src/lib/components/editor/Editor.svelte @@ -25,13 +25,15 @@ onChange?: (value: string) => void; onExecute?: (code: string, source: 'selection' | 'block' | 'document') => void; editorSettings: EditorSettingsStore; + mode: 'composition' | 'livecoding'; } let { value = '', onChange, onExecute, - editorSettings + editorSettings, + mode = 'composition' }: Props = $props(); let editorContainer: HTMLDivElement; @@ -44,6 +46,13 @@ function handleExecute() { if (!editorView) return; + if (mode === 'composition') { + const doc = getDocument(editorView.state); + flash(editorView, doc.from, doc.to); + onExecute?.(doc.text, 'document'); + return; + } + const selection = getSelection(editorView.state); if (selection.text) { flash(editorView, selection.from, selection.to); diff --git a/src/lib/components/editor/EditorWithLogs.svelte b/src/lib/components/editor/EditorWithLogs.svelte index afd1547..76c29f9 100644 --- a/src/lib/components/editor/EditorWithLogs.svelte +++ b/src/lib/components/editor/EditorWithLogs.svelte @@ -10,6 +10,7 @@ onExecute?: (code: string, source: 'selection' | 'block' | 'document') => void; logs?: string[]; editorSettings: EditorSettingsStore; + mode: 'composition' | 'livecoding'; } let { @@ -17,7 +18,8 @@ onChange, onExecute, logs = [], - editorSettings + editorSettings, + mode = 'composition' }: Props = $props(); let logPanelRef: LogPanel; @@ -84,6 +86,7 @@ {onChange} {onExecute} {editorSettings} + {mode} /> diff --git a/src/lib/project-system/persistence.ts b/src/lib/project-system/persistence.ts new file mode 100644 index 0000000..e168694 --- /dev/null +++ b/src/lib/project-system/persistence.ts @@ -0,0 +1,17 @@ +const LAST_PROJECT_KEY = 'oldboy:lastProjectId'; + +export function saveLastProjectId(projectId: string | null): void { + if (projectId === null) { + localStorage.removeItem(LAST_PROJECT_KEY); + } else { + localStorage.setItem(LAST_PROJECT_KEY, projectId); + } +} + +export function loadLastProjectId(): string | null { + return localStorage.getItem(LAST_PROJECT_KEY); +} + +export function clearLastProjectId(): void { + localStorage.removeItem(LAST_PROJECT_KEY); +} diff --git a/src/lib/stores/projectEditor.svelte.ts b/src/lib/stores/projectEditor.svelte.ts index 25ce9a1..42fd1c0 100644 --- a/src/lib/stores/projectEditor.svelte.ts +++ b/src/lib/stores/projectEditor.svelte.ts @@ -1,4 +1,5 @@ import type { CsoundProject, ProjectManager } from '../project-system'; +import { saveLastProjectId } from '../project-system/persistence'; interface ProjectEditorState { currentProject: CsoundProject | null; @@ -54,6 +55,7 @@ export class ProjectEditor { this.state.content = project.content; this.state.hasUnsavedChanges = false; this.state.isNewUnsavedBuffer = false; + saveLastProjectId(project.id); } createNew(template: string) { @@ -61,6 +63,7 @@ export class ProjectEditor { this.state.content = template; this.state.hasUnsavedChanges = false; this.state.isNewUnsavedBuffer = true; + saveLastProjectId(null); } async save(): Promise { @@ -105,6 +108,7 @@ export class ProjectEditor { this.state.currentProject = result.data; this.state.hasUnsavedChanges = false; this.state.isNewUnsavedBuffer = false; + saveLastProjectId(result.data.id); return true; }