authorgravatar for maria@kuuro.netmaria <maria@kuuro.net> 2026-09-10 15:24:25-03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-10 15:24:25-03:00
loge784975bbec7c54ed75fc6da3d4ffd4038fae041
treed8f788e936be6aa2f666768d56bc3e34ebc57b26
parent3836890e4484406813997259efc69065b25ce698
signature Signed by PGP key B5690EEEBB952194

fix(ui): simplify multiple linked pull request badges (#11104)


5 files changed, 24 insertions(+), 12 deletions(-)

apps/mobile/src/features/threads/thread-list-v2-items.tsx+10-4
......@@ -871,16 +871,22 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: {
871871 )}
872872 {pr ? (
873873 <View className="flex-row items-center gap-1" accessibilityLabel={pr.accessibilityLabel}>
874 {pr.kind === "stack" ? (
874 {pr.kind === "stack" || pr.others > 0 ? (
875875 <SymbolView
876 name="square.3.layers.3d"
876 name={pr.kind === "stack" ? "square.3.layers.3d" : "arrow.triangle.pull"}
877877 size={12}
878878 tintColorClassName={
879879 selected
880880 ? materialYouStyleLayoutActive
881881 ? "accent-thread-selected-foreground"
882882 : "accent-user-bubble-foreground"
883 : "accent-foreground-muted"
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"
884890 }
885891 />
886892 ) : null}
......@@ -896,7 +902,7 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: {
896902 )}
897903 style={{ fontFamily: MONO_FONT }}
898904 >
899 {pr.kind === "stack" ? pr.label : `#${pr.label}`}
905 {pr.kind === "stack" || pr.others > 0 ? pr.label : `#${pr.label}`}
900906 </Text>
901907 </View>
902908 ) : null}
apps/mobile/src/state/thread-pr-presentation.ts+7-2
......@@ -17,11 +17,12 @@ export interface ThreadPrPresentation {
1717 readonly number: number;
1818 readonly state: ThreadPr["state"] | null;
1919 readonly kind: "pull-request" | "stack";
20 readonly others: number;
2021 readonly isDraft: boolean;
2122 /** Provider-side last activity, bounding when a terminal state landed. */
2223 readonly updatedAt: string | null;
2324 readonly url: string;
24 /** Compact pull request number label, e.g. "3774". */
25 /** Compact pull request number or linked count, e.g. "3774" or "+2". */
2526 readonly label: string;
2627 /** Full, provider-aware label for assistive technologies. */
2728 readonly accessibilityLabel: string;
......@@ -42,6 +43,7 @@ export function presentThreadPr(
4243 const isDraft = pr.state === "open" && pr.isDraft === true;
4344 return {
4445 kind: "pull-request",
46 others: 0,
4547 number: pr.number,
4648 state: pr.state,
4749 isDraft,
......@@ -66,9 +68,12 @@ export function presentThreadLinkedPullRequests(
6668 const label =
6769 badge.kind === "stack"
6870 ? String(badge.layers)
69 : `${link.number}${badge.others > 0 ? ` +${badge.others}` : ""}`;
71 : badge.others > 0
72 ? `+${badge.others}`
73 : String(link.number);
7074 return {
7175 kind: badge.kind,
76 others: badge.kind === "pull-request" ? badge.others : 0,
7277 number: link.number,
7378 state,
7479 isDraft,
apps/mobile/src/state/use-thread-pr.test.ts+1-1
......@@ -87,7 +87,7 @@ describe("presentThreadLinkedPullRequests", () => {
8787 it("counts unrelated links without labelling them a stack", () => {
8888 expect(presentThreadLinkedPullRequests([linkedPr(1), linkedPr(2)])).toMatchObject({
8989 kind: "pull-request",
90 label: "1 +1",
90 label: "+1",
9191 });
9292 });
9393
apps/web/src/components/Sidebar.tsx+1-1
......@@ -1485,7 +1485,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: {
14851485 </span>
14861486 );
14871487
1488 // Stacks show their layer count; unrelated links show the current PR and a remainder count.
1488 // Stacks show their layer count; unrelated links show only the remainder count.
14891489 // Plain clicks open T3; individual PR links also support opening the host in a new tab.
14901490 const prBadgeShape = supportsMultiplePullRequests
14911491 ? resolveThreadPullRequestBadge(thread.pullRequests)
apps/web/src/components/ThreadStatusIndicators.tsx+5-4
......@@ -174,10 +174,11 @@ export function ThreadPullRequestBadgeControl({
174174 const content = (
175175 <>
176176 <ThreadPullRequestBadgeIcon icon={badge?.kind ?? "pull-request"} />
177 {isStack ? badge.layers : number}
178 {badge?.kind === "pull-request" && badge.others > 0 ? (
179 <span className="opacity-70">+{badge.others}</span>
180 ) : null}
177 {isStack
178 ? badge.layers
179 : badge?.kind === "pull-request" && badge.others > 0
180 ? `+${badge.others}`
181 : number}
181182 </>
182183 );
183184 return (