From 473731479b1168c4591a293cc578badcbee2d6cc Mon Sep 17 00:00:00 2001 From: T3 Code PR Stack <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 11:05:06 +0200 Subject: [PATCH 1/2] feat(identity): merge participation into count badge --- .../features/identity/ParticipantStack.tsx | 28 +++++++++---------- .../identity/participantStackSurface.test.ts | 5 +++- .../components/identity/ParticipantStack.tsx | 21 ++++++-------- apps/web/src/forkSurfaceExistence.test.ts | 5 +++- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/apps/mobile/src/features/identity/ParticipantStack.tsx b/apps/mobile/src/features/identity/ParticipantStack.tsx index eda60df41f6..6dd6ca208b3 100644 --- a/apps/mobile/src/features/identity/ParticipantStack.tsx +++ b/apps/mobile/src/features/identity/ParticipantStack.tsx @@ -56,25 +56,25 @@ export function ParticipantStack(props: { /> {extras.length > 0 ? ( - + +{extras.length} ) : null} - {youParticipated ? ( - - - - ) : null} ); } diff --git a/apps/mobile/src/features/identity/participantStackSurface.test.ts b/apps/mobile/src/features/identity/participantStackSurface.test.ts index ef64d87a877..a5b69d389f2 100644 --- a/apps/mobile/src/features/identity/participantStackSurface.test.ts +++ b/apps/mobile/src/features/identity/participantStackSurface.test.ts @@ -13,7 +13,10 @@ describe("mobile participation indicator surface", () => { const listV2 = readSource("../threads/thread-list-v2-items.tsx"); const board = readSource("../board/BoardScreen.tsx"); - expect(stack).toContain('testID="you-participated-indicator"'); + expect(stack).toContain('testID={youParticipated ? "you-participated-indicator"'); + expect(stack).toContain("+{extras.length}"); + expect(stack).toContain('"border border-primary bg-primary/15"'); + expect(stack).not.toContain(">✓"); expect(stack).toContain("isClaimedNonStarterParticipant"); expect(stack).toContain("You participated"); expect(listV1).toContain("environmentId={thread.environmentId}"); diff --git a/apps/web/src/components/identity/ParticipantStack.tsx b/apps/web/src/components/identity/ParticipantStack.tsx index 760fa81b147..edfcb097c64 100644 --- a/apps/web/src/components/identity/ParticipantStack.tsx +++ b/apps/web/src/components/identity/ParticipantStack.tsx @@ -4,7 +4,6 @@ import { isClaimedNonStarterParticipant, } from "@t3tools/client-runtime/state/identity"; import type { ThreadParticipantSummary } from "@t3tools/contracts"; -import { CheckIcon } from "lucide-react"; import { identityClaimPersonIdByEnvironmentAtom } from "../../state/identity"; import { IdentityAvatar } from "./IdentityAvatar"; import { participantDisplayLabel } from "./ParticipantStack.logic"; @@ -56,21 +55,19 @@ export function ParticipantStack(props: { /> {extras.length > 0 ? ( +{extras.length} ) : null} - {youParticipated ? ( - - - - ) : null} ); diff --git a/apps/web/src/forkSurfaceExistence.test.ts b/apps/web/src/forkSurfaceExistence.test.ts index 22dbe806de8..0cc80ea0deb 100644 --- a/apps/web/src/forkSurfaceExistence.test.ts +++ b/apps/web/src/forkSurfaceExistence.test.ts @@ -137,7 +137,10 @@ describe("fork surface existence (anti stack-drop)", () => { expect(stack).toContain(" Date: Fri, 31 Jul 2026 11:24:42 +0200 Subject: [PATCH 2/2] feat(identity): highlight claimed user avatar --- .../src/features/identity/IdentityAvatar.tsx | 15 ++++++++++++--- .../src/features/identity/ParticipantStack.tsx | 1 + .../identity/participantStackSurface.test.ts | 3 +++ .../src/components/identity/IdentityAvatar.tsx | 6 +++++- .../src/components/identity/ParticipantStack.tsx | 2 ++ apps/web/src/forkSurfaceExistence.test.ts | 3 +++ 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/apps/mobile/src/features/identity/IdentityAvatar.tsx b/apps/mobile/src/features/identity/IdentityAvatar.tsx index 3e3ab28d65d..d640c03a80f 100644 --- a/apps/mobile/src/features/identity/IdentityAvatar.tsx +++ b/apps/mobile/src/features/identity/IdentityAvatar.tsx @@ -13,6 +13,7 @@ export function IdentityAvatar(props: { readonly name?: string | null | undefined; readonly size?: "micro" | "sm" | "md"; readonly className?: string; + readonly highlighted?: boolean; }) { const model = identityAvatar({ personId: props.personId, @@ -26,10 +27,18 @@ export function IdentityAvatar(props: { return ( - + {model.initials} diff --git a/apps/mobile/src/features/identity/ParticipantStack.tsx b/apps/mobile/src/features/identity/ParticipantStack.tsx index 6dd6ca208b3..b53956727cb 100644 --- a/apps/mobile/src/features/identity/ParticipantStack.tsx +++ b/apps/mobile/src/features/identity/ParticipantStack.tsx @@ -53,6 +53,7 @@ export function ParticipantStack(props: { username={lead.username} name={lead.name} size="micro" + highlighted={lead.personId === claimPersonId} /> {extras.length > 0 ? ( { expect(stack).toContain("+{extras.length}"); expect(stack).toContain('"border border-primary bg-primary/15"'); expect(stack).not.toContain(">✓"); + expect(stack).toContain("highlighted={lead.personId === claimPersonId}"); + const avatar = readSource("./IdentityAvatar.tsx"); + expect(avatar).toContain('props.highlighted && "bg-primary"'); expect(stack).toContain("isClaimedNonStarterParticipant"); expect(stack).toContain("You participated"); expect(listV1).toContain("environmentId={thread.environmentId}"); diff --git a/apps/web/src/components/identity/IdentityAvatar.tsx b/apps/web/src/components/identity/IdentityAvatar.tsx index d41462c5b9b..cee49d7b440 100644 --- a/apps/web/src/components/identity/IdentityAvatar.tsx +++ b/apps/web/src/components/identity/IdentityAvatar.tsx @@ -7,6 +7,7 @@ export function IdentityAvatar(props: { readonly name?: string | null | undefined; readonly size?: "micro" | "sm" | "md"; readonly className?: string; + readonly highlighted?: boolean; /** `null` suppresses the native title when a parent owns richer tooltip content. */ readonly title?: string | null; }) { @@ -33,7 +34,10 @@ export function IdentityAvatar(props: { sizeClass, props.className, )} - style={{ backgroundColor: model.backgroundColor, color: model.color }} + style={{ + backgroundColor: props.highlighted ? "var(--primary)" : model.backgroundColor, + color: props.highlighted ? "var(--primary-foreground)" : model.color, + }} > {model.initials} diff --git a/apps/web/src/components/identity/ParticipantStack.tsx b/apps/web/src/components/identity/ParticipantStack.tsx index edfcb097c64..979e6a2d4c1 100644 --- a/apps/web/src/components/identity/ParticipantStack.tsx +++ b/apps/web/src/components/identity/ParticipantStack.tsx @@ -52,6 +52,7 @@ export function ParticipantStack(props: { name={lead.name} size="micro" title={null} + highlighted={lead.personId === claimPersonId} /> {extras.length > 0 ? ( {participantDisplayLabel(person)} diff --git a/apps/web/src/forkSurfaceExistence.test.ts b/apps/web/src/forkSurfaceExistence.test.ts index 0cc80ea0deb..7eb0383d37c 100644 --- a/apps/web/src/forkSurfaceExistence.test.ts +++ b/apps/web/src/forkSurfaceExistence.test.ts @@ -141,6 +141,9 @@ describe("fork surface existence (anti stack-drop)", () => { expect(stack).toContain("+{extras.length}"); expect(stack).toContain('"bg-primary/15 text-primary ring-1 ring-primary/35"'); expect(stack).not.toContain("