| ... | ... | @@ -129,10 +129,6 @@ const SidebarV2Row = memo(function SidebarV2Row(props: { |
| 129 | 129 | // False on environments whose server predates thread.settle/unsettle: |
| 130 | 130 | // the lifecycle affordances hide entirely rather than fail on click. |
| 131 | 131 | settlementSupported: boolean; |
| 132 | | // Marks where active work transitions into history: a quiet labeled |
| 133 | | // rule above the first settled row, so the tail reads as a named zone |
| 134 | | // rather than an unexplained gap. |
| 135 | | showSettledGap?: boolean; |
| 136 | 132 | isActive: boolean; |
| 137 | 133 | jumpLabel: string | null; |
| 138 | 134 | currentEnvironmentId: string | null; |
| ... | ... | @@ -398,12 +394,6 @@ const SidebarV2Row = memo(function SidebarV2Row(props: { |
| 398 | 394 | data-thread-item |
| 399 | 395 | className="list-none [content-visibility:auto] [contain-intrinsic-size:auto_34px]" |
| 400 | 396 | > |
| 401 | | {props.showSettledGap ? ( |
| 402 | | <div aria-hidden className="mb-1 mt-3 flex items-center gap-2 px-2.5"> |
| 403 | | <span className="text-[10px] font-medium text-muted-foreground/50">Settled</span> |
| 404 | | <span className="h-px flex-1 bg-border/60" /> |
| 405 | | </div> |
| 406 | | ) : null} |
| 407 | 397 | <div |
| 408 | 398 | role="button" |
| 409 | 399 | tabIndex={0} |
| ... | ... | @@ -1529,7 +1519,7 @@ export default function SidebarV2() { |
| 1529 | 1519 | ) : null} |
| 1530 | 1520 | <SidebarGroup className="min-h-0 flex-1 overflow-y-auto px-2 py-1"> |
| 1531 | 1521 | <ul ref={attachListAutoAnimateRef} className="flex flex-col gap-px"> |
| 1532 | | {orderedThreads.map((thread, threadIndex) => { |
| 1522 | {orderedThreads.flatMap((thread, threadIndex) => { |
| 1533 | 1523 | const threadKey = scopedThreadKey(scopeThreadRef(thread.environmentId, thread.id)); |
| 1534 | 1524 | const isSettledRow = settledThreadKeys.has(threadKey); |
| 1535 | 1525 | // Settled is the ONLY thing that collapses a row: every |
| ... | ... | @@ -1544,10 +1534,14 @@ export default function SidebarV2() { |
| 1544 | 1534 | scopedThreadKey(scopeThreadRef(previousThread.environmentId, previousThread.id)), |
| 1545 | 1535 | ); |
| 1546 | 1536 | const showSettledGap = !isCard && previousWasCard; |
| 1547 | | return ( |
| 1537 | const row = ( |
| 1548 | 1538 | <SidebarV2Row |
| 1549 | | showSettledGap={showSettledGap} |
| 1550 | | key={threadKey} |
| 1539 | // Keyed per variant on purpose: when a thread settles, the |
| 1540 | // card fades out in place and the slim row fades in at its |
| 1541 | // settled position instead of one element FLIP-sliding |
| 1542 | // through every row in between (rows here are translucent, |
| 1543 | // so a crossing row reads as text painted over text). |
| 1544 | key={`${threadKey}:${isCard ? "card" : "slim"}`} |
| 1551 | 1545 | thread={thread} |
| 1552 | 1546 | variant={isCard ? "card" : "slim"} |
| 1553 | 1547 | // Every settled row can un-settle: explicit settles clear |
| ... | ... | @@ -1582,6 +1576,28 @@ export default function SidebarV2() { |
| 1582 | 1576 | onChangeRequestState={handleChangeRequestState} |
| 1583 | 1577 | /> |
| 1584 | 1578 | ); |
| 1579 | if (!showSettledGap) return [row]; |
| 1580 | // The divider is its own keyed list item (not part of the first |
| 1581 | // settled row): it keeps one stable DOM node at the boundary, |
| 1582 | // so settling a thread slides it instead of teleporting it |
| 1583 | // along with whichever row happens to be first in the tail — |
| 1584 | // and row heights stay independent of neighbor classification. |
| 1585 | return [ |
| 1586 | <li |
| 1587 | key="settled-divider" |
| 1588 | aria-hidden |
| 1589 | data-thread-selection-safe |
| 1590 | className="list-none" |
| 1591 | > |
| 1592 | <div className="mb-1 mt-3 flex items-center gap-2 px-2.5"> |
| 1593 | <span className="text-[10px] font-medium text-muted-foreground/50"> |
| 1594 | Settled |
| 1595 | </span> |
| 1596 | <span className="h-px flex-1 bg-border/60" /> |
| 1597 | </div> |
| 1598 | </li>, |
| 1599 | row, |
| 1600 | ]; |
| 1585 | 1601 | })} |
| 1586 | 1602 | {hiddenSettledCount > 0 ? ( |
| 1587 | 1603 | <li className="list-none"> |