• Will Chen's avatar
    Support browser-like tabs for better multi-chat experience (#2619) · 9b2146f3
    Will Chen 提交于
    <!-- devin-review-badge-begin -->
    
    ---
    
    <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2619"
    target="_blank">
      <picture>
    <source media="(prefers-color-scheme: dark)"
    srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1">
    <img
    src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1"
    alt="Open with Devin">
      </picture>
    </a>
    <!-- devin-review-badge-end -->
    
    <!-- CURSOR_SUMMARY -->
    ---
    
    > [!NOTE]
    > **Medium Risk**
    > Introduces new cross-cutting chat navigation UI and new tab-state
    atoms that affect chat selection/creation/deletion flows; risk is mainly
    UX/state regressions and e2e flakiness rather than security.
    > 
    > **Overview**
    > **Adds browser-like chat tabs in the title bar.** Introduces
    `ChatTabs` with draggable visible tabs, an overflow menu, per-tab close
    (incl. middle-click), streaming-in-progress indicator, and “new
    activity” dot, plus i18n strings for accessible labels.
    > 
    > **Persists and coordinates tab state across navigation.** Adds
    `recentViewedChatIds`/`closedChatIds` atoms and helpers to keep MRU
    ordering, prevent explicitly closed tabs from reappearing, prune stale
    IDs, and choose an adjacent fallback chat when closing the active tab
    (navigating home if none).
    > 
    > **Updates chat creation/selection flows and tests.** Refactors
    `useSelectChat` to optionally preserve tab order; updates
    Home/CreateApp/ChatHeader/ChatList to use it and invalidate chat queries
    so new chats appear in tabs immediately; adds stable `new-chat-button`
    test IDs, new unit tests for tab helpers/atoms, and new Playwright e2e
    coverage for tab render/switch/close behavior.
    > 
    > **Build tooling/doc tweaks.** Bumps Node engine requirement to `>=24`
    and updates `rules/git-workflow.md` guidance for engine conflict
    resolution and stash handling.
    > 
    > <sup>Written by [Cursor
    Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
    982cef98ff0d3c1552097a91f59196fd07d47602. This will update automatically
    on new commits. Configure
    [here](https://cursor.com/dashboard?tab=bugbot).</sup>
    <!-- /CURSOR_SUMMARY -->
    
    <!-- This is an auto-generated description by cubic. -->
    ---
    ## Summary by cubic
    Adds browser-like tabs to the chat title bar for fast multi-chat
    navigation. Refines tab behavior, accessibility, and creation/deletion
    flows so tabs stay accurate, responsive, and preserve tab order.
    
    - **New Features**
    - ChatTabs in TitleBar: MRU ordering; drag-to-reorder (visible tabs);
    overflow dropdown with live count; streaming spinner; post-stream
    notification dot; middle-click close; WCAG 24x24 close targets;
    tooltips; accessible labels and focus-visible rings; i18n labels for
    “Chat in progress” and “New activity” (en, pt-BR, zh-CN); unit + e2e
    tests (incl. closed-tab state).
    - Persistent tab state via Jotai: recentViewedChatIds (cap 100) and
    closedChatIds so explicitly closed tabs don’t reappear;
    ensureRecentViewedChatId to keep tab order on route changes; Node engine
    bumped to >=24.
    
    - **Bug Fixes**
    - Close/selection: adjacent-tab fallback; closing the last tab navigates
    home; selecting a closed tab re-opens it; clear notifications on close;
    guard unknown/stale IDs; resolve selection loop; prune stale closed IDs;
    deleting the selected chat also navigates home.
    - Flows/accessibility: new-chat in ChatHeader uses correct
    invalidate/select order so tabs render immediately; route changes use
    ensureRecentViewedChatId to preserve order; overflow ARIA label uses
    actual overflow count; ResizeObserver attaches with async loads; title
    truncation respects max length; stable e2e selectors via
    new-chat-button; fixed CI npm sync via encoding; updated git workflow
    docs on stash review and engine conflicts; internal refactor with
    removeFromClosedSet helper to reduce duplication.
    
    <sup>Written for commit 982cef98ff0d3c1552097a91f59196fd07d47602.
    Summary will update on new commits.</sup>
    
    <!-- End of auto-generated description by cubic. -->
    
    ---------
    Co-authored-by: 's avatarClaude Opus 4.5 <noreply@anthropic.com>
    Co-authored-by: 's avatarclaude[bot] <41898282+claude[bot]@users.noreply.github.com>
    9b2146f3
home.tsx 13.2 KB