| author | |
| committer | |
| log | 0527ddf06defc88169c245a0fe53635d41d66469 |
| tree | 78065c97c8f2c63fd9aa08b5bb2bda4cd2e45b57 |
| parent | 0882431e0fc0fabe950743dd44b674a07a584bc9 |
| signature | Signed by PGP key B5690EEEBB952194 |
6 files changed, 26 insertions(+), 23 deletions(-)
apps/mobile/src/features/threads/thread-list-items.tsx+2-2| ... | ... | @@ -44,11 +44,11 @@ export const THREAD_LIST_COMPACT_INSET = HOME_HORIZONTAL_INSET; |
| 44 | 44 | const SIDEBAR_ROW_RADIUS = 12; |
| 45 | 45 | |
| 46 | 46 | function pullRequestTintColor( |
| 47 | pr: Pick<ThreadPrPresentation, "state" | "isDraft">, | |
| 47 | pr: Pick<ThreadPrPresentation, "state" | "isDraft" | "others">, | |
| 48 | 48 | colorScheme: "light" | "dark", |
| 49 | 49 | ) { |
| 50 | 50 | const dark = colorScheme === "dark"; |
| 51 | if (pr.state === "open" && pr.isDraft === true) { | |
| 51 | if (pr.others > 0 || (pr.state === "open" && pr.isDraft === true)) { | |
| 52 | 52 | return dark ? "#a1a1aa" : "#71717a"; |
| 53 | 53 | } |
| 54 | 54 | switch (pr.state) { |
apps/mobile/src/features/threads/thread-list-v2-items.tsx+1-7| ... | ... | @@ -880,13 +880,7 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: { |
| 880 | 880 | ? materialYouStyleLayoutActive |
| 881 | 881 | ? "accent-thread-selected-foreground" |
| 882 | 882 | : "accent-user-bubble-foreground" |
| 883 | : pr.kind === "stack" || pr.isDraft || pr.state === null | |
| 884 | ? "accent-foreground-muted" | |
| 885 | : pr.state === "open" | |
| 886 | ? "accent-adaptive-emerald-600-400" | |
| 887 | : pr.state === "merged" | |
| 888 | ? "accent-adaptive-violet-600-400" | |
| 889 | : "accent-foreground-muted" | |
| 883 | : "accent-foreground-muted" | |
| 890 | 884 | } |
| 891 | 885 | /> |
| 892 | 886 | ) : null} |
apps/mobile/src/state/thread-pr-presentation.ts+7-3| ... | ... | @@ -65,11 +65,12 @@ export function presentThreadLinkedPullRequests( |
| 65 | 65 | const snapshot = link.snapshot; |
| 66 | 66 | const state = badge.kind === "stack" ? badge.state : (snapshot?.state ?? null); |
| 67 | 67 | const isDraft = snapshot?.isDraft === true && state === "open"; |
| 68 | const linkedCount = badge.kind === "pull-request" && badge.others > 0 ? badge.others + 1 : null; | |
| 68 | 69 | const label = |
| 69 | 70 | badge.kind === "stack" |
| 70 | 71 | ? String(badge.layers) |
| 71 | : badge.others > 0 | |
| 72 | ? `+${badge.others}` | |
| 72 | : linkedCount !== null | |
| 73 | ? `+${linkedCount}` | |
| 73 | 74 | : String(link.number); |
| 74 | 75 | return { |
| 75 | 76 | kind: badge.kind, |
| ... | ... | @@ -84,7 +85,10 @@ export function presentThreadLinkedPullRequests( |
| 84 | 85 | badge.kind === "stack" |
| 85 | 86 | ? `${badge.layers} pull requests in stack, ${state ?? "status pending"}` |
| 86 | 87 | : `#${link.number} pull request ${state === null ? "status pending" : isDraft ? "draft" : state}${badge.others > 0 ? `, ${badge.others} more linked` : ""}`, |
| 87 | textClassName: state === null || isDraft ? "text-foreground-muted" : PR_STATE_TEXT_CLASS[state], | |
| 88 | textClassName: | |
| 89 | linkedCount !== null || state === null || isDraft | |
| 90 | ? "text-foreground-muted" | |
| 91 | : PR_STATE_TEXT_CLASS[state], | |
| 88 | 92 | }; |
| 89 | 93 | } |
| 90 | 94 |
apps/mobile/src/state/use-thread-pr.test.ts+3-1| ... | ... | @@ -87,7 +87,9 @@ describe("presentThreadLinkedPullRequests", () => { |
| 87 | 87 | it("counts unrelated links without labelling them a stack", () => { |
| 88 | 88 | expect(presentThreadLinkedPullRequests([linkedPr(1), linkedPr(2)])).toMatchObject({ |
| 89 | 89 | kind: "pull-request", |
| 90 | label: "+1", | |
| 90 | label: "+2", | |
| 91 | others: 1, | |
| 92 | textClassName: "text-foreground-muted", | |
| 91 | 93 | }); |
| 92 | 94 | }); |
| 93 | 95 |
apps/web/src/components/Sidebar.tsx+6-4| ... | ... | @@ -1387,6 +1387,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1387 | 1387 | // content; surface is reserved for interaction (hover, multi-select, route). |
| 1388 | 1388 | const rowSurfaceClassName = cn( |
| 1389 | 1389 | "group/sidebar-row relative w-full cursor-pointer overflow-hidden rounded-md text-left outline-none select-none", |
| 1390 | variantAction === "unsettle" && "[&:not(:hover):not(:focus-within)_*]:text-secondary-label/70", | |
| 1390 | 1391 | props.isActive |
| 1391 | 1392 | ? "bg-sidebar-row-active text-sidebar-foreground" |
| 1392 | 1393 | : isSelected |
| ... | ... | @@ -1469,7 +1470,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1469 | 1470 | : "text-foreground/90", |
| 1470 | 1471 | ) |
| 1471 | 1472 | : cn( |
| 1472 | "truncate group-hover/sidebar-row:text-foreground", | |
| 1473 | "truncate group-focus-within/sidebar-row:text-foreground group-hover/sidebar-row:text-foreground", | |
| 1473 | 1474 | shouldRecede |
| 1474 | 1475 | ? "text-secondary-label/70" |
| 1475 | 1476 | : props.isActive || isWoke |
| ... | ... | @@ -1485,7 +1486,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1485 | 1486 | </span> |
| 1486 | 1487 | ); |
| 1487 | 1488 | |
| 1488 | // Stacks show their layer count; unrelated links show only the remainder count. | |
| 1489 | // Stacks show their layer count; multiple unrelated links show their total count. | |
| 1489 | 1490 | // Plain clicks open T3; individual PR links also support opening the host in a new tab. |
| 1490 | 1491 | const prBadgeShape = supportsMultiplePullRequests |
| 1491 | 1492 | ? resolveThreadPullRequestBadge(thread.pullRequests) |
| ... | ... | @@ -1597,8 +1598,8 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1597 | 1598 | <span |
| 1598 | 1599 | className={cn( |
| 1599 | 1600 | "shrink-0 transition-opacity", |
| 1600 | !props.isActive && | |
| 1601 | "opacity-40 grayscale group-hover/sidebar-row:opacity-100 group-hover/sidebar-row:grayscale-0", | |
| 1601 | (!props.isActive || variantAction === "unsettle") && | |
| 1602 | "opacity-40 grayscale group-focus-within/sidebar-row:opacity-100 group-focus-within/sidebar-row:grayscale-0 group-hover/sidebar-row:opacity-100 group-hover/sidebar-row:grayscale-0", | |
| 1602 | 1603 | )} |
| 1603 | 1604 | > |
| 1604 | 1605 | {props.project ? <ProjectFavicon project={props.project} className="size-4" /> : null} |
| ... | ... | @@ -1617,6 +1618,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1617 | 1618 | the time/jump label yields to the settle affordance. */} |
| 1618 | 1619 | {prBadge} |
| 1619 | 1620 | {prBadge && |
| 1621 | variantAction !== "unsettle" && | |
| 1620 | 1622 | pr && |
| 1621 | 1623 | (supportsMultiplePullRequests |
| 1622 | 1624 | ? visibleThreadPullRequests(thread.pullRequests).length === 0 |
apps/web/src/components/ThreadStatusIndicators.tsx+7-6| ... | ... | @@ -154,6 +154,7 @@ export function ThreadPullRequestBadgeControl({ |
| 154 | 154 | onOpenPullRequest: (event: MouseEvent<HTMLAnchorElement>) => void; |
| 155 | 155 | }) { |
| 156 | 156 | const isStack = badge?.kind === "stack"; |
| 157 | const linkedCount = badge?.kind === "pull-request" && badge.others > 0 ? badge.others + 1 : null; | |
| 157 | 158 | if (!isStack && (number === undefined || url === undefined)) return null; |
| 158 | 159 | const label = isStack |
| 159 | 160 | ? `Stack of ${badge.layers} pull requests, ${badge.state}` |
| ... | ... | @@ -169,16 +170,16 @@ export function ThreadPullRequestBadgeControl({ |
| 169 | 170 | "text-xs tabular-nums", |
| 170 | 171 | variant === "ghost" && |
| 171 | 172 | "font-normal text-xs! active:scale-100 [--control-icon-color:currentColor]", |
| 172 | isStack ? PR_STATE_COLOR_CLASS[badge.state] : (status?.colorClass ?? "text-muted-foreground"), | |
| 173 | linkedCount !== null | |
| 174 | ? "text-secondary-label" | |
| 175 | : isStack | |
| 176 | ? PR_STATE_COLOR_CLASS[badge.state] | |
| 177 | : (status?.colorClass ?? "text-muted-foreground"), | |
| 173 | 178 | ); |
| 174 | 179 | const content = ( |
| 175 | 180 | <> |
| 176 | 181 | <ThreadPullRequestBadgeIcon icon={badge?.kind ?? "pull-request"} /> |
| 177 | {isStack | |
| 178 | ? badge.layers | |
| 179 | : badge?.kind === "pull-request" && badge.others > 0 | |
| 180 | ? `+${badge.others}` | |
| 181 | : number} | |
| 182 | {isStack ? badge.layers : linkedCount !== null ? `+${linkedCount}` : number} | |
| 182 | 183 | </> |
| 183 | 184 | ); |
| 184 | 185 | return ( |