| author | |
| committer | |
| log | e784975bbec7c54ed75fc6da3d4ffd4038fae041 |
| tree | d8f788e936be6aa2f666768d56bc3e34ebc57b26 |
| parent | 3836890e4484406813997259efc69065b25ce698 |
| signature | Signed by PGP key B5690EEEBB952194 |
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: { | ... | @@ -871,16 +871,22 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: { |
| 871 | )} | 871 | )} |
| 872 | {pr ? ( | 872 | {pr ? ( |
| 873 | <View className="flex-row items-center gap-1" accessibilityLabel={pr.accessibilityLabel}> | 873 | <View className="flex-row items-center gap-1" accessibilityLabel={pr.accessibilityLabel}> |
| 874 | {pr.kind === "stack" ? ( | 874 | {pr.kind === "stack" || pr.others > 0 ? ( |
| 875 | <SymbolView | 875 | <SymbolView |
| 876 | name="square.3.layers.3d" | 876 | name={pr.kind === "stack" ? "square.3.layers.3d" : "arrow.triangle.pull"} |
| 877 | size={12} | 877 | size={12} |
| 878 | tintColorClassName={ | 878 | tintColorClassName={ |
| 879 | selected | 879 | selected |
| 880 | ? materialYouStyleLayoutActive | 880 | ? materialYouStyleLayoutActive |
| 881 | ? "accent-thread-selected-foreground" | 881 | ? "accent-thread-selected-foreground" |
| 882 | : "accent-user-bubble-foreground" | 882 | : "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" | ||
| 884 | } | 890 | } |
| 885 | /> | 891 | /> |
| 886 | ) : null} | 892 | ) : null} |
| ... | @@ -896,7 +902,7 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: { | ... | @@ -896,7 +902,7 @@ export const ThreadListV2Row = memo(function ThreadListV2Row(props: { |
| 896 | )} | 902 | )} |
| 897 | style={{ fontFamily: MONO_FONT }} | 903 | style={{ fontFamily: MONO_FONT }} |
| 898 | > | 904 | > |
| 899 | {pr.kind === "stack" ? pr.label : `#${pr.label}`} | 905 | {pr.kind === "stack" || pr.others > 0 ? pr.label : `#${pr.label}`} |
| 900 | </Text> | 906 | </Text> |
| 901 | </View> | 907 | </View> |
| 902 | ) : null} | 908 | ) : null} |
apps/mobile/src/state/thread-pr-presentation.ts+7-2| ... | @@ -17,11 +17,12 @@ export interface ThreadPrPresentation { | ... | @@ -17,11 +17,12 @@ export interface ThreadPrPresentation { |
| 17 | readonly number: number; | 17 | readonly number: number; |
| 18 | readonly state: ThreadPr["state"] | null; | 18 | readonly state: ThreadPr["state"] | null; |
| 19 | readonly kind: "pull-request" | "stack"; | 19 | readonly kind: "pull-request" | "stack"; |
| 20 | readonly others: number; | ||
| 20 | readonly isDraft: boolean; | 21 | readonly isDraft: boolean; |
| 21 | /** Provider-side last activity, bounding when a terminal state landed. */ | 22 | /** Provider-side last activity, bounding when a terminal state landed. */ |
| 22 | readonly updatedAt: string | null; | 23 | readonly updatedAt: string | null; |
| 23 | readonly url: string; | 24 | 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". */ |
| 25 | readonly label: string; | 26 | readonly label: string; |
| 26 | /** Full, provider-aware label for assistive technologies. */ | 27 | /** Full, provider-aware label for assistive technologies. */ |
| 27 | readonly accessibilityLabel: string; | 28 | readonly accessibilityLabel: string; |
| ... | @@ -42,6 +43,7 @@ export function presentThreadPr( | ... | @@ -42,6 +43,7 @@ export function presentThreadPr( |
| 42 | const isDraft = pr.state === "open" && pr.isDraft === true; | 43 | const isDraft = pr.state === "open" && pr.isDraft === true; |
| 43 | return { | 44 | return { |
| 44 | kind: "pull-request", | 45 | kind: "pull-request", |
| 46 | others: 0, | ||
| 45 | number: pr.number, | 47 | number: pr.number, |
| 46 | state: pr.state, | 48 | state: pr.state, |
| 47 | isDraft, | 49 | isDraft, |
| ... | @@ -66,9 +68,12 @@ export function presentThreadLinkedPullRequests( | ... | @@ -66,9 +68,12 @@ export function presentThreadLinkedPullRequests( |
| 66 | const label = | 68 | const label = |
| 67 | badge.kind === "stack" | 69 | badge.kind === "stack" |
| 68 | ? String(badge.layers) | 70 | ? String(badge.layers) |
| 69 | : `${link.number}${badge.others > 0 ? ` +${badge.others}` : ""}`; | 71 | : badge.others > 0 |
| 72 | ? `+${badge.others}` | ||
| 73 | : String(link.number); | ||
| 70 | return { | 74 | return { |
| 71 | kind: badge.kind, | 75 | kind: badge.kind, |
| 76 | others: badge.kind === "pull-request" ? badge.others : 0, | ||
| 72 | number: link.number, | 77 | number: link.number, |
| 73 | state, | 78 | state, |
| 74 | isDraft, | 79 | isDraft, |
apps/mobile/src/state/use-thread-pr.test.ts+1-1| ... | @@ -87,7 +87,7 @@ describe("presentThreadLinkedPullRequests", () => { | ... | @@ -87,7 +87,7 @@ describe("presentThreadLinkedPullRequests", () => { |
| 87 | it("counts unrelated links without labelling them a stack", () => { | 87 | it("counts unrelated links without labelling them a stack", () => { |
| 88 | expect(presentThreadLinkedPullRequests([linkedPr(1), linkedPr(2)])).toMatchObject({ | 88 | expect(presentThreadLinkedPullRequests([linkedPr(1), linkedPr(2)])).toMatchObject({ |
| 89 | kind: "pull-request", | 89 | kind: "pull-request", |
| 90 | label: "1 +1", | 90 | label: "+1", |
| 91 | }); | 91 | }); |
| 92 | }); | 92 | }); |
| 93 | 93 |
apps/web/src/components/Sidebar.tsx+1-1| ... | @@ -1485,7 +1485,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { | ... | @@ -1485,7 +1485,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: { |
| 1485 | </span> | 1485 | </span> |
| 1486 | ); | 1486 | ); |
| 1487 | 1487 | ||
| 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. |
| 1489 | // Plain clicks open T3; individual PR links also support opening the host in a new tab. | 1489 | // Plain clicks open T3; individual PR links also support opening the host in a new tab. |
| 1490 | const prBadgeShape = supportsMultiplePullRequests | 1490 | const prBadgeShape = supportsMultiplePullRequests |
| 1491 | ? resolveThreadPullRequestBadge(thread.pullRequests) | 1491 | ? resolveThreadPullRequestBadge(thread.pullRequests) |
apps/web/src/components/ThreadStatusIndicators.tsx+5-4| ... | @@ -174,10 +174,11 @@ export function ThreadPullRequestBadgeControl({ | ... | @@ -174,10 +174,11 @@ export function ThreadPullRequestBadgeControl({ |
| 174 | const content = ( | 174 | const content = ( |
| 175 | <> | 175 | <> |
| 176 | <ThreadPullRequestBadgeIcon icon={badge?.kind ?? "pull-request"} /> | 176 | <ThreadPullRequestBadgeIcon icon={badge?.kind ?? "pull-request"} /> |
| 177 | {isStack ? badge.layers : number} | 177 | {isStack |
| 178 | {badge?.kind === "pull-request" && badge.others > 0 ? ( | 178 | ? badge.layers |
| 179 | <span className="opacity-70">+{badge.others}</span> | 179 | : badge?.kind === "pull-request" && badge.others > 0 |
| 180 | ) : null} | 180 | ? `+${badge.others}` |
| 181 | : number} | ||
| 181 | </> | 182 | </> |
| 182 | ); | 183 | ); |
| 183 | return ( | 184 | return ( |