Skip to content

fix: respect create-list dialog dismissal - #292

Merged
brianorwhatever merged 1 commit into
mainfrom
dot/respect-create-list-dismissal
Oct 11, 2026
Merged

brianorwhatever merged 1 commit into
mainfrom
dot/respect-create-list-dismissal

Conversation

@brianorwhatever

@brianorwhatever brianorwhatever commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Keep create-list dismissal final

Summary

  • Invalidate pending create work when dismissal begins, not only after unmount.
  • Prevent stale callbacks, success/error feedback and navigation; guard repeated submissions and identity changes.
  • Make pending Close honest about an already-submitted save, and keep successful-dialog dismissal separate from explicit list navigation.
  • Cancel/deduplicate Panel close timers and cover controlled close/reopen.

Verification

56 new rendered regression cases pass, plus 9 independent adversarial Panel checks.
The actual Home callback path is exercised. Seven targeted regressions fail on
unchanged main. Independent review found and verified the repair of one initial
Panel regression; no remaining blocker was reported.

Focused TypeScript with service type stubs passes. CreateListModal lint passes;
Panel retains the existing set-state-in-effect lint failure. Full repository
build, aggregate checks, real browser/native behavior and live backend verification
still need a complete checkout.

Draft for review against main 8bfcdb78f14925c4e4e164a5f19187d9606c0fb8. No merge or deployment. Existing PRs #289/#290 are preserved.

Note

Fix create-list dialog to respect dismissal during async list creation

  • Reworks CreateListModal so any dismissal (Escape, backdrop, header, footer, swipe) during sign-in or saving invalidates the in-flight attempt. Late success or failure results, feedback, analytics, and navigation are suppressed after dismissal or unmount.
  • Moves the dialog implementation into a keyed CreateListDialog that remounts when the current identity changes, so one account's pending request cannot affect another account's draft.
  • Adds one-shot close lifecycle to Panel in Panel.tsx: the first dismissal starts the animation, calls onCloseStart immediately, and fires onClose once after the 200ms delay. Timers are cancelled on unmount or reopen.
  • Closes the modal with a working Close action while a save is pending, showing an in-flight status message instead of the Cancel button. Explicit Go to list and Share with people buttons on the success view still navigate.
  • Behavioral Change: closing the success view no longer implicitly opens the created list; only explicit success actions navigate. Dismissal during a save may let the save complete on the backend while the UI ignores the result.
  • Adds test suites in create-list-modal-ui.test.mjs and create-list-home-ui.test.mjs covering dismissal matrices, remount/identity-change cases, rapid submissions, and Panel timer behavior.

Macroscope summarized c6290e0.

@railway-app
railway-app Bot temporarily deployed to Friends / boop-pr-292 October 11, 2026 19:15 Destroyed
@railway-app

railway-app Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the boop-pr-292 environment in Friends

Service Status Web Updated
boop ✅ Success (View Logs) Web Oct 11, 2026 at 7:20 pm UTC

@brianorwhatever
brianorwhatever marked this pull request as ready for review October 11, 2026 19:29
@brianorwhatever
brianorwhatever merged commit 0b9f189 into main Oct 11, 2026
9 checks passed

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ℹ️ No critical issues. One minor suggestion inline.

Reviewed changes

I reviewed the single commit that makes create-list dismissal final, along with the Panel timer and dedupe changes it depends on. Both new suites pass under node --test and bun test (56/56), and npx tsc -b --force is clean.

  • Dismissal invalidates in-flight work: CreateListDialog checks mountedRef and dismissedRef after each await. A sign/save that resolves or rejects after Close, Escape, backdrop or swipe no longer fires onListCreated, haptics, analytics, errors or navigation.
  • Identity isolation: CreateListModal renders CreateListDialog key={did}. When the account changes, the dialog remounts and the old account's pending work is orphaned.
  • Double-submit guard: pendingRef and completedRef block a second submit in the same event turn and any resubmit after success. The plan-limit banner is cleared on retry.
  • Success dismissal no longer navigates: X, Escape, backdrop and swipe now just close the success view. Only "Go to list" and "Share with people" navigate, and both are blocked once a dismissal has started.
  • Honest pending Close: the footer button stays enabled while creating and its label becomes "Close". A role="status" note warns that a save already in flight may still complete.
  • Panel close lifecycle: adds the onCloseStart callback and removes isAnimating, so !isOpen renders nothing. Repeated dismissals are deduped, and the close timer is cleared on unmount or when isOpen changes. Every current consumer passes isOpen={true} and unmounts in onClose, so the dedupe latch, which only resets when isOpen changes, is safe today.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

setIsCreating(false);
onListCreated?.(listId, trimmedName);
} catch (err) {
if (!mountedRef.current || dismissedRef.current) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Returning before console.error means a sign or save that fails after the user dismisses the dialog leaves no trace. That is exactly the case where someone will later ask whether the list was created. Suppressing the user-facing feedback is right, but keeping the log would help debugging. The dismissal tests will then print the expected rejections to stderr; they still pass.

Suggested change
if (!mountedRef.current || dismissedRef.current) return;
console.error("Failed to create list:", err);
if (!mountedRef.current || dismissedRef.current) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Correction: this suggestion replaces only line 116, so applying it as-is would duplicate the log line. Move the guard below the existing console.error on line 117 by hand instead.

Pullfrog  | View workflow run | via Pullfrog | Using claude-opus-5-5 | 𝕏

This branch was successfully deployed

No deployments
Friends / boop-pr-292 — c6290e04 Deployed Oct 11, 2026 by railway-app[bot]
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