Skip to content

feat: drag-and-drop a folder to open it as a project - #51

Open
franktheglock wants to merge 3 commits into
FaqFirebase:Devfrom
franktheglock:feat/drag-drop-folder
Open

feat: drag-and-drop a folder to open it as a project#51
franktheglock wants to merge 3 commits into
FaqFirebase:Devfrom
franktheglock:feat/drag-drop-folder

Conversation

@franktheglock

Copy link
Copy Markdown
Contributor

Summary

  • Drag a folder onto the Pi Desktop window to open it as a project (create workspace if needed, switch into it, show Chat)
  • Same path as File → Open Project via shared openFolderAsWorkspace
  • Overlay only while dragging — dismisses immediately on drop so create/switch is not blocked by blur
  • Non-folder file drops are ignored (leaves room for future attachment drops)
  • Directory verified in main (system:path-kind); path from drop via preload webUtils.getPathForFile

Test plan

  • Drag a project folder from Explorer onto the window → workspace created/switched, Chat opens
  • Overlay appears while dragging and disappears on drop (not held until Pi starts)
  • Drop the same folder again → reuses existing workspace (no duplicate)
  • Drop a file (not folder) → ignored
  • File → Open Project still works (same code path)
  • While Pi is streaming, drop a folder → still-working confirm still gates switch
  • npm run typecheck && npm run lint && npx tsx --test src/shared/folder-drop.test.ts

Drop a directory onto the window to create/switch a workspace at that path
(same flow as File → Open Project). Overlay feedback while dragging; non-folder
drops are ignored. Path resolved via webUtils in preload; directory check in main.
@PikkonMG

PikkonMG commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

I'll take a look here later.

@PikkonMG

PikkonMG commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Typecheck, lint, and the full test suite all pass on my end. I did hit one state bug while poking at it though.

If you drop a folder that already has a workspace while a different workspace is active, the app ends up in a stale state. Here's the chain:

  1. Main's createWorkspace sees the duplicate path and calls setActiveWorkspace on the existing one right away.
  2. Back in the renderer, openFolderAsWorkspace reloads workspaces, sees the target is now active, and takes the "already active" shortcut.
  3. That shortcut skips switchWorkspace, so the chat keeps showing the old workspace's messages, piStatus is still the old workspace's status (which can stop the new workspace's Pi from ever starting, since startPi bails when it thinks Pi is running), and the still-working confirm never fires.

File > Open Project is affected too now that it shares this code path. It used to always go through switchWorkspace, which cleared messages and resynced status.

The fix is small: check whether the dropped path was already the active workspace before calling createWorkspace, and only take the shortcut in that case. Something like:

const active = get().activeWorkspace
const wasAlreadyActive = active ? pathsEqual(active.path, trimmed) : false
await get().createWorkspace(name, trimmed)
const ws = get().workspaces.find((w) => pathsEqual(w.path, trimmed))
if (!ws) return false
if (wasAlreadyActive) {
  get().setCurrentView('chat')
  if (get().piStatus !== 'running') await get().startPi()
  return true
}
const switched = await get().switchWorkspace(ws.id)
if (switched) get().setCurrentView('chat')
return switched

The first-workspace case then flows through switchWorkspace as well, which is actually better since it does the proper status sync and session load.

A store test for the "existing workspace, different one active" drop would be worth adding, since the current test plan only covers re-dropping the folder of the workspace you're already in.

…active shortcut

Main activates a duplicate path inside createWorkspace, so checking
activeWorkspace after create wrongly skipped switchWorkspace. Snapshot whether
the path was already active before create. Add regression tests.
@franktheglock

Copy link
Copy Markdown
Contributor Author

Addressed the stale-state bug on opening an existing workspace that is not currently active:

  • Snapshot wasAlreadyActive from activeWorkspace.path before createWorkspace (main may activate the target on duplicate path, which made the old "already active" shortcut fire incorrectly)
  • Only skip switchWorkspace when the dropped folder was already the active project
  • First-workspace and cross-workspace opens always go through switchWorkspace (clear messages, resync Pi status, still-working confirm)
  • Regression tests for "existing other workspace" and "already active" paths

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.

2 participants