Skip to content

feat: Add projectFolder to user preferences#669

Open
paulohenriquesg wants to merge 4 commits into
siddharthvaddem:mainfrom
paulohenriquesg:feat/remember-last-project-folder
Open

feat: Add projectFolder to user preferences#669
paulohenriquesg wants to merge 4 commits into
siddharthvaddem:mainfrom
paulohenriquesg:feat/remember-last-project-folder

Conversation

@paulohenriquesg
Copy link
Copy Markdown

@paulohenriquesg paulohenriquesg commented May 29, 2026

Description

Adds projectFolder as a key to user preferences, stores the location of the most recently opened project, and prefills it in the next File → Open action.

Direct mirror of the pattern introduced by #512 for the export dialog. Reuses the existing parentDirectoryOf helper (which already handles POSIX and Windows roots after the codex-bot / coderabbit feedback on #512) and the same localStorage-backed preferences module.

Type of Change

  • New Feature

Related Issue(s)

Closes #668. Inspired by #503 / #512.

What changed

  • src/lib/userPreferences.ts — added projectFolder: string \| null to UserPreferences and DEFAULT_PREFS, hydrate in loadUserPreferences, added getProjectFolder() helper.
  • src/lib/userPreferences.test.ts — round-trip tests for the new field, default / invalid / empty hydration, independence from exportFolder. Tests use an in-memory localStorage stub since the jsdom global isn't exposed in this vitest setup.
  • electron/ipc/handlers.tsloadProjectFile now accepts projectFolder?: string, stats it, falls back to RECORDINGS_DIR with a warn log if it's gone or unreadable. Mirrors the save-exported-video path validation pattern from feat: Add exportFolder to user preferences #512.
  • electron/preload.ts + electron/electron-env.d.ts — thread projectFolder?: string through the bridge.
  • electron/ipc/nativeBridge.ts + electron/native-bridge/services/projectService.ts — extend the bridge dispatch + service signature to forward the param.
  • src/native/contracts.ts + src/native/client.ts — payload on the loadProjectFile action carries projectFolder?: string.
  • src/components/video-editor/VideoEditor.tsx and src/components/launch/LaunchWindow.tsx — both open-project entry points read getProjectFolder() before calling the bridge, and on success persist parentDirectoryOf(result.path) back to preferences.

Testing

  1. Build and launch the app.
  2. File → Open; navigate to a folder other than the default (RECORDINGS_DIR) and open an .openscreen project.
  3. File → Open again — the open dialog should default to the folder chosen in step 2.
  4. Quit and relaunch the app, then File → Open — the dialog should still open in that folder (preference is persisted via localStorage).
  5. Rename or delete that folder on disk, then File → Open again — the dialog should fall back to RECORDINGS_DIR without erroring (warning logged to the main-process console).
  6. Repeat steps 2–3 starting from the launch window's "Open" action — both entry points share the same preference.

Unit tests (src/lib/userPreferences.test.ts) cover the load/save round-trip, default fallback, invalid-type rejection, empty-string rejection, and independence from exportFolder.

Checklist

  • I have performed a self-review of my code.
  • I have linked related issue(s).
  • npm test, npx tsc --noEmit, and npx biome check . all pass locally.

Summary by CodeRabbit

  • New Features

    • App remembers the last opened project folder and pre-fills the Open dialog, streamlining project loading from Launch and Editor screens.
    • Opening or importing a project updates and persists the remembered project folder for future use.
  • Tests

    • Added tests validating project-folder preference storage, defaults, fallback behavior, and edge-case handling.

Adds `projectFolder` as a key to user preferences, stores the location of
the most recently opened project, and prefills it in the next File → Open
action. Mirrors the pattern from siddharthvaddem#512 (`exportFolder`).

Closes siddharthvaddem#668
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4db525b7-5ea4-47f3-bcb5-528d4d441812

📥 Commits

Reviewing files that changed from the base of the PR and between c01c88b and f5ad566.

📒 Files selected for processing (1)
  • src/components/video-editor/EditorEmptyState.tsx

📝 Walkthrough

Walkthrough

Threads an optional projectFolder from UI through preload, IPC, native bridge, and ProjectService; validates it for dialog prefill, and persists the parent folder in user preferences for future dialog defaults.

Changes

Remember Last Project Folder

Layer / File(s) Summary
User preferences contract and tests
src/lib/userPreferences.ts, src/lib/userPreferences.test.ts
UserPreferences gains projectFolder: string | null (DEFAULT_PREFS.projectFolder = null). loadUserPreferences() validates persisted projectFolder (non-empty string only). getProjectFolder() helper added. Tests cover defaults, round-trip persistence, validation, and independence from other prefs.
Native bridge request contract & client
src/native/contracts.ts, src/native/client.ts
project/loadProjectFile payload changes from EmptyPayload to { projectFolder?: string }. nativeBridgeClient.project.loadProjectFile(projectFolder?) forwards { projectFolder }.
Preload API and type definitions
electron/preload.ts, electron/electron-env.d.ts
electronAPI.loadProjectFile(projectFolder?: string) added and forwards to the load-project-file IPC channel; type declaration updated.
Electron IPC handler (dialog prefill)
electron/ipc/handlers.ts
ipcMain.handle("load-project-file") accepts optional projectFolder, validates it via fs.stat, sets the open-dialog defaultPath to the remembered folder when it's a directory, and falls back to RECORDINGS_DIR on error.
NativeBridge wiring and ProjectService
electron/ipc/nativeBridge.ts, electron/native-bridge/services/projectService.ts
NativeBridgeContext and the "project"/"loadProjectFile" action forward request.payload?.projectFolder to projectService.loadProjectFile(projectFolder?). ProjectService API updated to accept and forward the optional param.
UI components with project folder memory
src/components/launch/LaunchWindow.tsx, src/components/video-editor/VideoEditor.tsx, src/components/video-editor/EditorEmptyState.tsx
Components call loadProjectFile(getProjectFolder()) to prefill the dialog; on successful load they compute the parent directory and persist it via saveUserPreferences({ projectFolder }).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • siddharthvaddem
  • FabLrc

"lowkey humble little patch"
threads a folder like a breadcrumb trail 🥖
remembers where you left off, even after sleep
prefs whisper "next time" in the background
tiny plumbing, big QoL win — nice and not cursed

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly summarizes the main change: adding projectFolder to user preferences to remember and prefill the last opened project directory.
Description check ✅ Passed Description covers all required sections: clear purpose, motivation addressing issue #668, type of change marked, related issues linked, detailed testing instructions, and completion checklist.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@paulohenriquesg paulohenriquesg marked this pull request as ready for review May 29, 2026 08:40
Resolves conflicts in userPreferences.ts and userPreferences.test.ts by
combining the projectFolder feature with upstream's trayLayout addition.
Resolved conflicts:
- LaunchWindow.tsx: kept upstream's removal of openVideoFile/openProjectFile (moved to Studio Dashboard)
- VideoEditor.tsx: used upstream's doLoadProject rename while preserving getProjectFolder() arg
The Studio Dashboard's Load Project button was calling loadProjectFile()
without the remembered folder, always defaulting to RECORDINGS_DIR.
Also save projectFolder preference after a successful load from this path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Remember last opened project folder

1 participant