-
Notifications
You must be signed in to change notification settings - Fork 0
feat: own_followings hook, add restrict_replies to sample app #208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📝 WalkthroughWalkthroughAdds a restrict-replies feature: activity creation includes a restrict_replies field, feeds can be enriched with own_followings, a new useOwnFollowings hook exposes that data, and UI components gate reply controls based on activity.restrict_replies and follow relationships. Tests added for restrict_replies and own_followings enrichment. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant UI as NewActivity / Comment UI
participant Client as Feeds Client
participant Server as API / Feed Backend
participant FeedState as Feed State / useOwnFollowings
User->>UI: create activity (restrict_replies)
UI->>Client: post activity payload (includes restrict_replies)
Client->>Server: create activity
Server-->>Client: activity created
Client->>FeedState: addActivitiesToState / enrich (enrich_own_followings)
FeedState-->>Client: feed state includes own_followings
UI->>FeedState: useOwnFollowings(currentFeed)
FeedState-->>UI: own_followings
UI->>UI: compute canComment based on user id, restrict_replies, own_followings
UI-->>User: show/hide reply UI and Post comment form
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (1 warning, 2 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts:
- Line 163: A local const named "feed" inside the test shadows the outer-scope
"feed" variable and triggers a lint error; rename the inner variable returned by
client.feed(...) (e.g., to "localFeed" or "testFeed") and update all subsequent
references in the test to that new name so the outer "feed" remains unshadowed;
locate the client.feed(...) call and any uses of "feed" in that test and perform
the rename consistently.
- Around line 167-169: Move the log/assert after awaiting enrichment: call await
feed.getOrCreate({ enrichment_options: { enrich_own_followings: true } }) so
enrichment completes, then inspect feed.currentState.own_followings (or assert
its expected contents) instead of logging it before calling getOrCreate; ensure
the test uses await on feed.getOrCreate to wait for enrichment to finish and
then verifies the feature.
In
@sample-apps/react-sample-app/app/components/comments/ActivityCommentSection.tsx:
- Around line 46-63: canComment's logic wrongly grants reply rights when the
activity author follows anyone because the 'people_i_follow' case checks
ownFollowings.length > 0; update the 'people_i_follow' branch in the canComment
useMemo to instead verify that the current user's id is present in ownFollowings
(e.g., use Array.prototype.some on ownFollowings comparing each
following.target_feed.id to currentUser?.id) and fall back to false if
ownFollowings or currentUser is null/undefined.
🧹 Nitpick comments (4)
packages/feeds-client/__integration-tests__/docs-snippets/activities.test.ts (1)
71-77: Consider adding an assertion to validate the feature.While this docs snippet appropriately demonstrates the API, adding a simple assertion would make the test more robust and verify the feature works as expected.
✅ Suggested enhancement
it(`restrict replies`, async () => { - await feed.addActivity({ + const response = await feed.addActivity({ type: 'post', text: 'apple stock will go up', restrict_replies: 'people_i_follow', // Options: "everyone", "people_i_follow", "nobody" }); + + expect(response.activity?.restrict_replies).toBe('people_i_follow'); });sample-apps/react-sample-app/app/components/NewActivity.tsx (1)
97-115: Consider extracting the type assertion to improve readability.The type assertion on line 106 works correctly but could be improved for maintainability.
♻️ Suggested refactor
+ const restrictRepliesOptions = [ + { value: 'everyone' as const, label: 'Everyone' }, + { value: 'people_i_follow' as const, label: 'People I follow' }, + { value: 'nobody' as const, label: 'Nobody' }, + ] as const; + <div className="w-full flex items-center gap-2"> <label htmlFor="restrict-replies" className="text-sm text-gray-700"> Who can reply: </label> <select id="restrict-replies" value={restrictReplies} onChange={(e) => - setRestrictReplies( - e.target.value as 'everyone' | 'people_i_follow' | 'nobody', - ) + setRestrictReplies(e.target.value as typeof restrictReplies) } className="px-3 py-1 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" > - <option value="everyone">Everyone</option> - <option value="people_i_follow">People I follow</option> - <option value="nobody">Nobody</option> + {restrictRepliesOptions.map(opt => ( + <option key={opt.value} value={opt.value}>{opt.label}</option> + ))} </select> </div>sample-apps/react-sample-app/app/activity/[id]/page.tsx (1)
84-88: Consider simplifying the negated equality check.The condition
!(_feed?.id === user.id)is functionally correct but could be more readable.♻️ Suggested refactor
- if ( - !(_feed?.id === user.id) && - !_feed?.currentState.watch && - !_feed?.currentState.is_loading - ) { + if ( + _feed?.id !== user.id && + !_feed?.currentState.watch && + !_feed?.currentState.is_loading + ) {sample-apps/react-sample-app/app/components/comments/ActivityCommentSection.tsx (1)
142-187: LGTM: Conditional rendering properly implements access control.The comment form and reply UI are correctly gated by
canComment, and the "Replying to" block with Cancel action provides good UX. The form structure is accessible with proper labels.Optional: Consider showing a message when commenting is restricted.
Currently, when
canCommentis false, the form is hidden without explanation. You might improve UX by showing a brief message indicating why commenting is disabled (e.g., "The author has restricted replies to this activity").♻️ Optional enhancement
+ {!canComment && ( + <div className="mb-6 p-4 bg-gray-50 rounded-lg border border-gray-200"> + <p className="text-sm text-gray-600"> + The author has restricted replies to this activity. + </p> + </div> + )} + {canComment && (
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (11)
packages/feeds-client/__integration-tests__/docs-snippets/activities.test.tspackages/feeds-client/__integration-tests__/docs-snippets/comments.test.tspackages/feeds-client/src/activity-with-state-updates/activity-with-state-updates.tspackages/feeds-client/src/bindings/react/hooks/feed-state-hooks/index.tspackages/feeds-client/src/bindings/react/hooks/feed-state-hooks/useOwnFollowings.tssample-apps/react-sample-app/app/activity/[id]/page.tsxsample-apps/react-sample-app/app/components/NewActivity.tsxsample-apps/react-sample-app/app/components/Search/SearchResults/SearchResultItem.tsxsample-apps/react-sample-app/app/components/comments/ActivityCommentSection.tsxsample-apps/react-sample-app/app/components/comments/Comment.tsxsample-apps/react-sample-app/app/own-feeds-context.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript for all code in this repository
Files:
packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/index.tssample-apps/react-sample-app/app/components/NewActivity.tsxpackages/feeds-client/__integration-tests__/docs-snippets/comments.test.tspackages/feeds-client/src/bindings/react/hooks/feed-state-hooks/useOwnFollowings.tspackages/feeds-client/__integration-tests__/docs-snippets/activities.test.tssample-apps/react-sample-app/app/own-feeds-context.tsxpackages/feeds-client/src/activity-with-state-updates/activity-with-state-updates.tssample-apps/react-sample-app/app/components/comments/Comment.tsxsample-apps/react-sample-app/app/components/Search/SearchResults/SearchResultItem.tsxsample-apps/react-sample-app/app/activity/[id]/page.tsxsample-apps/react-sample-app/app/components/comments/ActivityCommentSection.tsx
**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
Add and extend tests with .test.ts suffix, covering FeedsClient, Feed classes, event handlers, state management, React hooks, contexts, utility functions, generated API clients, and integration tests in integration-tests/ directories
Files:
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.tspackages/feeds-client/__integration-tests__/docs-snippets/activities.test.ts
🧠 Learnings (4)
📚 Learning: 2025-12-17T11:01:52.854Z
Learnt from: CR
Repo: GetStream/stream-feeds-js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T11:01:52.854Z
Learning: Applies to packages/react-bindings/**/*.{ts,tsx} : Use React hooks and contexts from react-bindings for React SDK integrations
Applied to files:
packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/index.tssample-apps/react-sample-app/app/components/NewActivity.tsxpackages/feeds-client/src/bindings/react/hooks/feed-state-hooks/useOwnFollowings.tssample-apps/react-sample-app/app/components/Search/SearchResults/SearchResultItem.tsxsample-apps/react-sample-app/app/activity/[id]/page.tsxsample-apps/react-sample-app/app/components/comments/ActivityCommentSection.tsx
📚 Learning: 2025-12-17T11:01:52.854Z
Learnt from: CR
Repo: GetStream/stream-feeds-js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T11:01:52.854Z
Learning: Applies to **/*.test.ts : Add and extend tests with .test.ts suffix, covering FeedsClient, Feed classes, event handlers, state management, React hooks, contexts, utility functions, generated API clients, and integration tests in __integration-tests__/ directories
Applied to files:
packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/index.tspackages/feeds-client/__integration-tests__/docs-snippets/comments.test.tspackages/feeds-client/src/bindings/react/hooks/feed-state-hooks/useOwnFollowings.tspackages/feeds-client/__integration-tests__/docs-snippets/activities.test.tssample-apps/react-sample-app/app/own-feeds-context.tsxpackages/feeds-client/src/activity-with-state-updates/activity-with-state-updates.tssample-apps/react-sample-app/app/components/Search/SearchResults/SearchResultItem.tsxsample-apps/react-sample-app/app/activity/[id]/page.tsxsample-apps/react-sample-app/app/components/comments/ActivityCommentSection.tsx
📚 Learning: 2025-12-17T11:01:52.854Z
Learnt from: CR
Repo: GetStream/stream-feeds-js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T11:01:52.854Z
Learning: Applies to packages/react-bindings/**/*.{ts,tsx} : Support React 18+ and React Native 0.73+ in respective SDKs (react-sdk/ and react-native-sdk/)
Applied to files:
packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/index.ts
📚 Learning: 2025-12-17T11:01:52.854Z
Learnt from: CR
Repo: GetStream/stream-feeds-js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T11:01:52.854Z
Learning: Prioritize backwards compatibility, API stability, and high test coverage when changing code in this TypeScript Feeds SDK repository
Applied to files:
packages/feeds-client/__integration-tests__/docs-snippets/activities.test.ts
🧬 Code graph analysis (6)
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts (3)
packages/feeds-client/src/feed/feed.ts (1)
feed(270-272)sample-apps/react-sample-app/setup-env.js (1)
client(16-16)sample-apps/react-sample-app/create-posts.js (1)
client(22-22)
packages/feeds-client/src/activity-with-state-updates/activity-with-state-updates.ts (1)
packages/feeds-client/src/feed/event-handlers/activity/handle-activity-added.ts (1)
addActivitiesToState(5-43)
sample-apps/react-sample-app/app/components/comments/Comment.tsx (1)
sample-apps/react-native/ExpoTikTokApp/store/comment-input-state-store.ts (1)
setParent(19-20)
sample-apps/react-sample-app/app/components/Search/SearchResults/SearchResultItem.tsx (1)
sample-apps/react-sample-app/app/own-feeds-context.tsx (1)
useOwnFeedsContext(69-69)
sample-apps/react-sample-app/app/activity/[id]/page.tsx (1)
packages/feeds-client/src/bindings/react/hooks/client-state-hooks/useClientConnectedUser.ts (1)
useClientConnectedUser(9-15)
sample-apps/react-sample-app/app/components/comments/ActivityCommentSection.tsx (3)
packages/feeds-client/src/bindings/react/hooks/client-state-hooks/useClientConnectedUser.ts (1)
useClientConnectedUser(9-15)packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/useOwnFollowings.ts (1)
useOwnFollowings(9-14)sample-apps/react-sample-app/app/components/comments/Comment.tsx (1)
Comment(21-192)
🪛 GitHub Actions: Lint and test
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts
[error] 163-163: ESLint: 'feed' is already declared in the upper scope. (no-shadow)
🪛 GitHub Check: lint-and-test (22.x)
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts
[failure] 163-163:
'feed' is already declared in the upper scope on line 18 column 7
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: lint-and-test (22.x)
🔇 Additional comments (18)
sample-apps/react-sample-app/app/own-feeds-context.tsx (1)
46-48: LGTM!The enrichment option correctly enables
own_followingsdata for the timeline feed, which is necessary for the restrict replies feature to function properly.packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/useOwnFollowings.ts (1)
1-18: LGTM!The hook implementation is clean, follows established patterns in the codebase, and provides the necessary functionality for components to access
own_followingsdata reactively.packages/feeds-client/src/activity-with-state-updates/activity-with-state-updates.ts (1)
167-173: Verify that side effects fromnewActivitiesAddedare intentional during initialization.The refactor now uses
addActivitiesToState, which callsthis.newActivitiesAdded()on line 37 of handle-activity-added.ts. This function performs side effects includinghydratePollCache()andgetOrCreateFeeds().When initializing an activity with
addActivitiesToState.bind(this.feed)([initialState], [], 'start'), these side effects will be triggered, whereas the previous code (activities: [initialState]) would have only updated state directly. Confirm this behavioral change is intentional and doesn't cause unintended feed creation or cache pollution during initialization. If these side effects should be deferred, consider callingaddActivitiesToStatewithout triggeringnewActivitiesAdded, or add an initialization-specific flag.packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/index.ts (1)
13-13: LGTM!The new export follows the established pattern and correctly exposes the
useOwnFollowingshook for downstream consumption.sample-apps/react-sample-app/app/components/NewActivity.tsx (2)
21-23: LGTM!The state variable is properly typed with the union of allowed values and initialized with a sensible default.
57-57: Therestrict_repliesfield is supported by the API.The field is properly defined in the API models (
packages/feeds-client/src/gen/models/index.ts) with the correct allowed values:'everyone' | 'people_i_follow' | 'nobody'. Integration tests and the FeedsApi client confirm proper usage of this field. The implementation at line 57 is correct.sample-apps/react-sample-app/app/components/Search/SearchResults/SearchResultItem.tsx (2)
23-27: LGTM!The selector correctly extracts
own_followingsfrom the feed state with an appropriate fallback to an empty array.
31-55: LGTM! Clean implementation of the "follows you" indicator.The destructuring and conditional rendering are correct. The UI appropriately shows the "follows you" indicator when the feed has entries in
own_followings.sample-apps/react-sample-app/app/components/comments/Comment.tsx (3)
22-29: LGTM!The
canReplyprop is correctly added to the component signature with proper TypeScript typing.
134-144: LGTM! Proper access control for reply functionality.The Reply button is now appropriately gated behind the
canReplyprop, ensuring only authorized users can reply to comments.
175-175: LGTM!The
canReplyprop is correctly propagated to nested Comment components, ensuring consistent reply restrictions throughout the comment thread hierarchy.sample-apps/react-sample-app/app/activity/[id]/page.tsx (4)
12-12: LGTM!The import of
useClientConnectedUseris correctly added to support user-aware feed logic.
45-45: LGTM!The hook is correctly invoked to obtain the current authenticated user for downstream logic.
71-73: LGTM!The guard correctly prevents progression when the user is not authenticated, ensuring the subsequent logic has a valid user context.
112-112: LGTM!The dependency array correctly includes
user?.idto ensure the effect re-runs when the authenticated user changes.sample-apps/react-sample-app/app/components/comments/ActivityCommentSection.tsx (3)
1-16: LGTM: Imports are clean and appropriate.All newly imported hooks and types are used correctly throughout the component to implement the restrict reply feature.
30-44: LGTM: Hook setup and memoization are well-structured.The
currentFeedderivation properly guards against missing data, and theuseOwnFollowingsdestructuring handles undefined values safely with appropriate defaults.
195-195: LGTM: Consistent access control propagated to child comments.Passing
canCommentascanReplyensures that reply restrictions apply consistently throughout the comment tree, which aligns with the expected behavior.
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts
Outdated
Show resolved
Hide resolved
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts
Outdated
Show resolved
Hide resolved
sample-apps/react-sample-app/app/components/comments/ActivityCommentSection.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts:
- Around line 163-166: The code dangerously assumes activity.current_feed exists
by using non-null assertions on activity.current_feed?.group_id! and
activity.current_feed?.id! when constructing currentFeed via client.feed;
instead, guard against a missing current_feed (e.g., check if
activity.current_feed is truthy before calling client.feed, or branch to a
fallback behavior or fail the test with a clear message) so you don't
dereference undefined — update the currentFeed creation to first test
activity.current_feed and only call client.feed with
activity.current_feed.group_id and activity.current_feed.id when present.
🧹 Nitpick comments (1)
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts (1)
167-167: Remove console.log from test code.Console statements should not be left in production test code. Use proper assertions instead to verify the behavior.
♻️ Proposed refactor
- console.log(currentFeed.currentState.own_followings); + expect(currentFeed.currentState.own_followings).toBeDefined();
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript for all code in this repository
Files:
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts
**/*.test.ts
📄 CodeRabbit inference engine (AGENTS.md)
Add and extend tests with .test.ts suffix, covering FeedsClient, Feed classes, event handlers, state management, React hooks, contexts, utility functions, generated API clients, and integration tests in integration-tests/ directories
Files:
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts
🧠 Learnings (1)
📚 Learning: 2025-12-17T11:01:52.854Z
Learnt from: CR
Repo: GetStream/stream-feeds-js PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T11:01:52.854Z
Learning: Applies to **/*.test.ts : Add and extend tests with .test.ts suffix, covering FeedsClient, Feed classes, event handlers, state management, React hooks, contexts, utility functions, generated API clients, and integration tests in __integration-tests__/ directories
Applied to files:
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts
🧬 Code graph analysis (1)
packages/feeds-client/__integration-tests__/docs-snippets/comments.test.ts (3)
sample-apps/react-sample-app/setup-env.js (1)
client(16-16)sample-apps/react-sample-app/create-posts.js (1)
client(22-22)packages/feeds-client/src/feed/feed.ts (1)
feed(270-272)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: lint-and-test (22.x)
🎫 Ticket: https://linear.app/stream/issue/REACT-736/integrate-restrict-reply-feature
📑 Docs: https://github.com/GetStream/docs-content/pull/895/files
💡 Overview
📝 Implementation notes
Summary by CodeRabbit
New Features
UI
Tests
✏️ Tip: You can customize this high-level summary in your review settings.