Skip to content

fix(folder-picker): show loading state to fix dead clicks on repo selector#2473

Open
adboio wants to merge 1 commit into
mainfrom
posthog-code/fix-dead-clicks-on-repo-selector
Open

fix(folder-picker): show loading state to fix dead clicks on repo selector#2473
adboio wants to merge 1 commit into
mainfrom
posthog-code/fix-dead-clicks-on-repo-selector

Conversation

@adboio
Copy link
Copy Markdown
Contributor

@adboio adboio commented Jun 3, 2026

Problem

Clicking the folder/repo selector opens a native directory picker dialog, but the UI gave no synchronous feedback while the dialog was open. Because no DOM mutation occurred on click, PostHog logged these as "dead clicks." Users also had no indication that the picker was opening.

Changes

  • Add an isOpening state to FolderPicker that is set synchronously when the picker is triggered and cleared in a finally block once the native dialog resolves or errors.
  • While opening:
    • Display "Opening..." text in both the field and compact variants.
    • Swap the CaretDown icon for an animated CircleNotch spinner.
    • Disable the trigger and set aria-busy to prevent re-clicks and improve accessibility.
  • Guard handleOpenFilePicker to ignore re-clicks while a dialog is already open.
  • Add FolderPicker.test.tsx covering:
    • Synchronous "Opening..." feedback and disabled state while the dialog is open, followed by committing the selected path.
    • Ignoring re-clicks while a dialog is already in flight.

The synchronous state change both reassures the user and gives PostHog a DOM mutation so the open native dialog is no longer recorded as a dead click.

How did you test this?

  • Added unit tests with Vitest / Testing Library verifying the loading state, path commit, and re-click guard behavior.

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Created with PostHog Code

Generated-By: PostHog Code
Task-Id: e6034585-4d15-44f5-acdb-20fc8c001a07
@adboio adboio marked this pull request as ready for review June 3, 2026 14:52
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 3, 2026

Comments Outside Diff (1)

  1. apps/code/src/renderer/features/folder-picker/components/FolderPicker.tsx, line 137-185 (link)

    P2 isOpening protection incomplete for the dropdown path

    When recentFolders.length > 0 the component renders a DropdownMenu. The DropdownMenuTrigger (lines 139–151) and the "Open folder..." DropdownMenuItem (line 179) neither receive disabled={isOpening} nor aria-busy={isOpening}. While the if (isOpening) return guard prevents a second dialog from opening, the dropdown itself is still openable mid-flight, so a user can click the trigger, see the dropdown appear, and attempt the "Open folder..." item — at which point nothing happens silently. The visual loading state (spinner, "Opening..." text) is present in the trigger content, but the button is not actually disabled, making the accessibility and UX fix described in the PR incomplete for this branch.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/code/src/renderer/features/folder-picker/components/FolderPicker.tsx
    Line: 137-185
    
    Comment:
    **`isOpening` protection incomplete for the dropdown path**
    
    When `recentFolders.length > 0` the component renders a `DropdownMenu`. The `DropdownMenuTrigger` (lines 139–151) and the "Open folder..." `DropdownMenuItem` (line 179) neither receive `disabled={isOpening}` nor `aria-busy={isOpening}`. While the `if (isOpening) return` guard prevents a second dialog from opening, the dropdown itself is still openable mid-flight, so a user can click the trigger, see the dropdown appear, and attempt the "Open folder..." item — at which point nothing happens silently. The visual loading state (spinner, "Opening..." text) is present in the trigger content, but the button is not actually disabled, making the accessibility and UX fix described in the PR incomplete for this branch.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/code/src/renderer/features/folder-picker/components/FolderPicker.tsx:137-185
**`isOpening` protection incomplete for the dropdown path**

When `recentFolders.length > 0` the component renders a `DropdownMenu`. The `DropdownMenuTrigger` (lines 139–151) and the "Open folder..." `DropdownMenuItem` (line 179) neither receive `disabled={isOpening}` nor `aria-busy={isOpening}`. While the `if (isOpening) return` guard prevents a second dialog from opening, the dropdown itself is still openable mid-flight, so a user can click the trigger, see the dropdown appear, and attempt the "Open folder..." item — at which point nothing happens silently. The visual loading state (spinner, "Opening..." text) is present in the trigger content, but the button is not actually disabled, making the accessibility and UX fix described in the PR incomplete for this branch.

### Issue 2 of 2
apps/code/src/renderer/features/folder-picker/components/FolderPicker.tsx:53-55
The string `"Opening..."` is spelled out twice — once in `fieldContent` and once in `compactContent` — violating the OnceAndOnlyOnce simplicity rule. Extracting it to a constant makes any future copy change a single edit.

```suggestion
  const [isOpening, setIsOpening] = useState(false);
  const openingLabel = "Opening...";

  const handleSelect = (path: string) => {
```

Reviews (1): Last reviewed commit: "feat(folder-picker): show loading state ..." | Re-trigger Greptile

Comment on lines +53 to 55
const [isOpening, setIsOpening] = useState(false);

const handleSelect = (path: string) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The string "Opening..." is spelled out twice — once in fieldContent and once in compactContent — violating the OnceAndOnlyOnce simplicity rule. Extracting it to a constant makes any future copy change a single edit.

Suggested change
const [isOpening, setIsOpening] = useState(false);
const handleSelect = (path: string) => {
const [isOpening, setIsOpening] = useState(false);
const openingLabel = "Opening...";
const handleSelect = (path: string) => {
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/code/src/renderer/features/folder-picker/components/FolderPicker.tsx
Line: 53-55

Comment:
The string `"Opening..."` is spelled out twice — once in `fieldContent` and once in `compactContent` — violating the OnceAndOnlyOnce simplicity rule. Extracting it to a constant makes any future copy change a single edit.

```suggestion
  const [isOpening, setIsOpening] = useState(false);
  const openingLabel = "Opening...";

  const handleSelect = (path: string) => {
```

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@adboio adboio added the Stamphog This will request an autostamp by stamphog on small changes label Jun 3, 2026 — with Graphite App
Copy link
Copy Markdown

@stamphog stamphog Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review agent failed after 3 attempts — needs human review.

@stamphog stamphog Bot removed the Stamphog This will request an autostamp by stamphog on small changes label Jun 3, 2026
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.

1 participant