Skip to content

fix(client): support server-side pinning on participant join#2190

Merged
oliverlaz merged 3 commits intomainfrom
feat/client-server-side-pinning
Apr 9, 2026
Merged

fix(client): support server-side pinning on participant join#2190
oliverlaz merged 3 commits intomainfrom
feat/client-server-side-pinning

Conversation

@oliverlaz
Copy link
Copy Markdown
Member

@oliverlaz oliverlaz commented Apr 7, 2026

💡 Overview

Support server-side pinning when a participant joins a call. When the SFU signals isPinned: true on a ParticipantJoined event, the participant is automatically pinned with isLocalPin: false.

📝 Implementation notes

  • Updated watchParticipantJoined to apply a server-side pin ({ isLocalPin: false, pinnedAt: Date.now() }) when e.isPinned is truthy
  • Added two unit tests: one verifying the pin is set when isPinned: true, another verifying no pin is set when isPinned: false

Ref: GetStream/protocol#1772

Summary by CodeRabbit

  • New Features

    • Participants now include pin metadata when joining while pinned, tracking pin status and timestamp information.
  • Tests

    • Added comprehensive unit tests to validate participant pin behavior during join events, ensuring correct handling for both pinned and unpinned participants.

Apply a server-side pin when a participant joins with isPinned flag set
by the SFU. Updated SFU protobuf types to include the new isPinned field
on ParticipantJoined, SendMetrics RPC, and negotiationId on SendAnswerRequest.
@oliverlaz oliverlaz changed the title feat(client): support server-side pinning on participant join fix(client): support server-side pinning on participant join Apr 7, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 7, 2026

⚠️ No Changeset found

Latest commit: e85a6b2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@oliverlaz oliverlaz requested a review from jdimovska April 7, 2026 14:00
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

Added server-side pin state management for participants upon join events. When a participant joins with isPinned: true, a pin object is created with isLocalPin: false and a pinnedAt timestamp. Includes corresponding test coverage for both pinned and unpinned scenarios.

Changes

Cohort / File(s) Summary
Participant Pin State Management
packages/client/src/events/participant.ts
Added conditional pin metadata (isLocalPin: false, pinnedAt timestamp) to participant join event handling when isPinned flag is present.
Pin Behavior Tests
packages/client/src/events/__tests__/participant.test.ts
Added two unit tests validating pin state: one confirming pin object creation with isPinned: true, another verifying pin is undefined when isPinned: false.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A pin upon the stage so bright,
When participants join into our sight,
With timestamps marked and flags held true,
The server knows just what they do! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding support for server-side pinning when participants join calls.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The pull request description matches the template structure and includes all required sections with comprehensive implementation details.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/client-server-side-pinning

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@oliverlaz oliverlaz requested a review from brunoribc April 7, 2026 14:03
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/client/src/events/__tests__/participant.test.ts (1)

78-98: Add regression coverage for join-pin → server-pin reconciliation

These tests verify isPinned on join, but they don’t cover the follow-up case where server pin state is reconciled (e.g., via setServerSidePins). Please add a regression test that joins with isPinned: true, then applies server pins, and asserts the participant keeps a server-side pin with server-authoritative ordering semantics.

Based on learnings: "Add regression tests for bug fixes".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/client/src/events/__tests__/participant.test.ts` around lines 78 -
98, Add a regression test that uses CallState and watchParticipantJoined to
simulate a join with isPinned: true, then call the state method that applies
server pins (e.g., setServerSidePins) with a server-authoritative pin list for
that participant's userId/sessionId, and assert that findParticipantBySessionId
still shows a pin that is server-side (pin.isLocalPin === false) and that the
pin's timestamp/ordering reflects the server-provided value (e.g., pinnedAt
equals or is derived from the server pin entry) to validate server-pin
reconciliation keeps server-authoritative ordering.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/client/src/events/participant.ts`:
- Line 41: The join-time pin currently sets pin.pinnedAt = Date.now() which
blocks later server-authoritative updates; change the participant join logic
(the spread creating pin in participant.ts) to avoid seeding a numeric pinnedAt
(omit or set to undefined) for non-local pins, and update
CallState.setServerSidePins to accept and overwrite pins when the incoming
server timestamp is newer or when the existing pinnedAt is "unset" (undefined)
while still preserving isLocalPin precedence (do not overwrite if
existing.isLocalPin === true). Also implement the timestamp/instance-id
comparison guard in setServerSidePins so server updates win only when
serverTimestamp > existingTimestamp (or existing is unset) to prevent race
conditions.

---

Nitpick comments:
In `@packages/client/src/events/__tests__/participant.test.ts`:
- Around line 78-98: Add a regression test that uses CallState and
watchParticipantJoined to simulate a join with isPinned: true, then call the
state method that applies server pins (e.g., setServerSidePins) with a
server-authoritative pin list for that participant's userId/sessionId, and
assert that findParticipantBySessionId still shows a pin that is server-side
(pin.isLocalPin === false) and that the pin's timestamp/ordering reflects the
server-provided value (e.g., pinnedAt equals or is derived from the server pin
entry) to validate server-pin reconciliation keeps server-authoritative
ordering.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 106dd125-b547-44a4-bbd4-f26995e0d80f

📥 Commits

Reviewing files that changed from the base of the PR and between 649aea2 and 890593d.

⛔ Files ignored due to path filters (2)
  • packages/client/src/gen/video/sfu/event/events.ts is excluded by !**/gen/**
  • packages/client/src/gen/video/sfu/signal_rpc/signal.ts is excluded by !**/gen/**
📒 Files selected for processing (2)
  • packages/client/src/events/__tests__/participant.test.ts
  • packages/client/src/events/participant.ts

@oliverlaz oliverlaz merged commit 2c354a4 into main Apr 9, 2026
21 checks passed
@oliverlaz oliverlaz deleted the feat/client-server-side-pinning branch April 9, 2026 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants