Conversation
Signed-off-by: prxt6529 <prxt@6529.io>
📝 WalkthroughWalkthroughThreads per-wave unread and mute state through UI, API, contexts, hooks, and navigation; adds UnreadDivider context and mark‑as‑unread API/action; centralizes wave list logic in a new core hook; propagates firstUnreadDropSerialNo/serialNo through navigation and active‑wave APIs. Changes
Sequence Diagram(s)mermaid User->>UI: Click "Mark as unread" Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (4)**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (.cursorrules)
Files:
**/*.{tsx,jsx}📄 CodeRabbit inference engine (.cursorrules)
Files:
**/*.{js,jsx,ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (4)📚 Learning: 2025-12-03T14:52:34.271ZApplied to files:
📚 Learning: 2025-12-03T14:52:34.271ZApplied to files:
📚 Learning: 2025-12-03T14:52:34.271ZApplied to files:
📚 Learning: 2025-12-05T10:55:30.871ZApplied to files:
⏰ 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)
🔇 Additional comments (5)
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.
Actionable comments posted: 0
🧹 Nitpick comments (2)
contexts/wave/hooks/useEnhancedDmWavesList.ts (1)
9-39: Clarify/adjust interaction between local “cleared” state and server unread metricsThe
clearedUnreadWaveIds+ 1s timeout nicely model “wave has been viewed, treat existing unread as read” and the MinimalWave additions (unreadDropsCount,latestReadTimestamp) line up with the new API fields. One nuance:
- Once a wave ID is in
clearedUnreadWaveIds, you always returnunreadDropsCount: 0for that wave, even ifwave.metrics.your_unread_drops_countlater increases. In the happy path, new unread are surfaced via the WebSocket‑drivennewDropsCount, but if WS events are missed (offline, tab throttling, reconnect gaps), metrics could indicate new unread while the local “cleared” flag keeps them hidden.Consider either:
- clearing
clearedUnreadWaveIdsfor a wave whenwave.metrics.your_unread_drops_countjumps above zero again, or- explicitly documenting that, after first view, DM unread relies solely on the live WebSocket counter for the rest of the session.
This would make the behavior more robust in degraded network scenarios.
Also applies to: 40-65
contexts/wave/hooks/useEnhancedWavesList.ts (1)
35-53: Consider cleanup strategy for the cleared set.The
clearedUnreadWaveIdsSet grows indefinitely as users visit waves and is never pruned. While each entry is small and bounded by session activity, this is technically a memory leak.💡 Potential cleanup strategies
Option 1: Store only the current cleared wave
- const [clearedUnreadWaveIds, setClearedUnreadWaveIds] = useState<Set<string>>( - new Set() - ); + const [clearedUnreadWaveId, setClearedUnreadWaveId] = useState<string | null>(null); const resetWaveUnreadCount = useCallback((waveId: string) => { - setClearedUnreadWaveIds((prev) => { - const next = new Set(prev); - next.add(waveId); - return next; - }); + setClearedUnreadWaveId(waveId); }, []);Then update the
isClearedcheck inmapWave:- const isCleared = clearedUnreadWaveIds.has(wave.id); + const isCleared = clearedUnreadWaveId === wave.id;Option 2: Implement LRU eviction or size limit
If multiple waves need to stay cleared simultaneously, consider capping the Set size or evicting old entries.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
generated/models/ApiWaveMetrics.tsis excluded by!**/generated/**
📒 Files selected for processing (10)
components/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcomponents/user/user-page-header/UserPageHeaderClient.tsxcomponents/waves/create-dm/CreateDirectMessage.tsxcontexts/wave/hooks/useEnhancedDmWavesList.tscontexts/wave/hooks/useEnhancedWavesList.tscontexts/wave/hooks/useNewDropCounter.tshelpers/navigation.helpers.tshooks/useUnreadIndicator.tsopenapi.yaml
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version
**/*.{ts,tsx,js,jsx}: Replace<img>elements with<Image />fromnext/imageto satisfy@next/next/no-img-elementESLint rule
Use<Link href="/path">from Next.js for internal navigation instead of plain HTML links to satisfy@next/next/no-html-link-for-pagesESLint rule
Files:
helpers/navigation.helpers.tscontexts/wave/hooks/useNewDropCounter.tscomponents/user/user-page-header/UserPageHeaderClient.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcontexts/wave/hooks/useEnhancedWavesList.tscontexts/wave/hooks/useEnhancedDmWavesList.tscomponents/waves/create-dm/CreateDirectMessage.tsxhooks/useUnreadIndicator.tscomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use<Link>, images should usenext/image, and adopt Next's ESLint rules (Core Web Vitals)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Files:
helpers/navigation.helpers.tscontexts/wave/hooks/useNewDropCounter.tscomponents/user/user-page-header/UserPageHeaderClient.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcontexts/wave/hooks/useEnhancedWavesList.tscontexts/wave/hooks/useEnhancedDmWavesList.tscomponents/waves/create-dm/CreateDirectMessage.tsxhooks/useUnreadIndicator.tscomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Must passtsc --noEmittype checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") overReact.namespace usage (React.useMemo,React.useRef, etc.)
If thereact-hooks/exhaustive-depslint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic inuseEffectEvent
**/*.{ts,tsx}: Must passtsc --noEmitfor TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
UseuseEffectEventfor non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs:<Link>for internal links,next/imagefor images, adopt Next's ESLint rules
Use'use cache'directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace<img>elements with<Image />fromnext/image
Use<Link href="/path">for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with'use server'directive
Files:
helpers/navigation.helpers.tscontexts/wave/hooks/useNewDropCounter.tscomponents/user/user-page-header/UserPageHeaderClient.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcontexts/wave/hooks/useEnhancedWavesList.tscontexts/wave/hooks/useEnhancedDmWavesList.tscomponents/waves/create-dm/CreateDirectMessage.tsxhooks/useUnreadIndicator.tscomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always addreadonlybefore props in React components
Files:
components/user/user-page-header/UserPageHeaderClient.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcomponents/waves/create-dm/CreateDirectMessage.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx
🧠 Learnings (11)
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions
Applied to files:
contexts/wave/hooks/useNewDropCounter.tscomponents/user/user-page-header/UserPageHeaderClient.tsxcontexts/wave/hooks/useEnhancedDmWavesList.tscomponents/waves/create-dm/CreateDirectMessage.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Include all required imports and ensure proper naming of key components
Applied to files:
components/user/user-page-header/UserPageHeaderClient.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/*.{ts,tsx} : Prefer direct named imports for React hooks and types (`import { useMemo, useRef, FC, etc. } from "react"`) over `React.` namespace usage (`React.useMemo`, `React.useRef`, etc.)
Applied to files:
components/user/user-page-header/UserPageHeaderClient.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Prefer Server Components over Client Components; use Server Functions/Server Actions (`'use server'`) for mutations
Applied to files:
components/user/user-page-header/UserPageHeaderClient.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use react-query for data fetching
Applied to files:
components/user/user-page-header/UserPageHeaderClient.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks
Applied to files:
components/user/user-page-header/UserPageHeaderClient.tsxcontexts/wave/hooks/useEnhancedWavesList.ts
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: TypeScript + React functional components with hooks; follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Applied to files:
components/user/user-page-header/UserPageHeaderClient.tsxcontexts/wave/hooks/useEnhancedWavesList.tscomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/*.{ts,tsx} : If the `react-hooks/exhaustive-deps` lint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic in `useEffectEvent`
Applied to files:
contexts/wave/hooks/useEnhancedDmWavesList.ts
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Organize imports with one import per module in order: external → internal → types, with no duplicates
Applied to files:
components/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)
Applied to files:
components/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use framework APIs: `<Link>` for internal links, `next/image` for images, adopt Next's ESLint rules
Applied to files:
components/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx
🧬 Code graph analysis (3)
components/user/user-page-header/UserPageHeaderClient.tsx (2)
hooks/useDeviceInfo.ts (1)
useDeviceInfo(23-105)helpers/navigation.helpers.ts (1)
navigateToDirectMessage(73-92)
components/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsx (1)
components/waves/WavePicture.tsx (1)
WavePicture(63-122)
components/waves/create-dm/CreateDirectMessage.tsx (1)
helpers/navigation.helpers.ts (1)
navigateToDirectMessage(73-92)
⏰ 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: Analyze (javascript-typescript)
🔇 Additional comments (9)
openapi.yaml (1)
7967-7999: ApiWaveMetrics unread fields align with frontend usageAdding
your_latest_drop_timestamp,your_unread_drops_count, andyour_latest_read_timestampas required fields withnumber/int64matches how the frontend now consumeswave.metricsfor per-wave unread tracking. Just ensure the backend always populates non-null values for these fields to avoid runtime inconsistencies.components/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/CollapsedWave.tsx (1)
1-52: Collapsed wave styling/tooltip tweaks are safeSwitching to double-quoted class strings and a quoted
"data-tooltip-id"key is purely stylistic; the hover/active styling and tooltip behavior remain unchanged.contexts/wave/hooks/useNewDropCounter.ts (1)
167-181: Uncapped new-drop counter matches display-level badge capThe increment change to
count: currentCount + 1removes the previous logical cap and relies on UI (e.g.,WaveAvatar’s display cap) to clamp what’s shown. This keeps internal state accurate while preserving UX limits and does not introduce new race conditions given the existing functionalsetNewDropsCountsusage.hooks/useUnreadIndicator.ts (1)
39-48: Unread indicator now correctly uses both server and local unread sourcesUsing
(dm?.unreadDropsCount ?? 0) > 0 || (dm?.newDropsCount?.count ?? 0) > 0ensures the badge appears for both persisted unread drops (from metrics) and new, session-local drops tracked via WebSocket, while still null‑safe.helpers/navigation.helpers.ts (1)
73-92: Centralized DM navigation helper is consistent and reusable
navigateToDirectMessagecorrectly reusesgetWaveRoutewithisDirectMessage: trueand switches betweenrouter.replaceandrouter.pushbased onisApp, matching prior per-call logic and reducing duplication across callers.components/waves/create-dm/CreateDirectMessage.tsx (1)
3-20: Create DM flow now correctly delegates navigation to helperUsing
navigateToDirectMessage({ waveId: wave.id, router, isApp })aftercreateDirectMessageWavekeeps behavior the same while aligning with the new centralized navigation helper. Imports anduseStateusage are consistent with the rest of the file.Also applies to: 71-81
components/user/user-page-header/UserPageHeaderClient.tsx (1)
3-26: User header DM button correctly uses centralized navigation with app-awarenessWiring
isAppfromuseDeviceInfointohandleCreateDirectMessageand delegating tonavigateToDirectMessage({ waveId: wave.id, router, isApp })brings this entrypoint in line with the new DM navigation helper, while preserving loading state and error handling. The new imports and hook usages are consistent and type-safe.Also applies to: 40-53, 127-154, 178-188
components/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsx (1)
26-64: LGTM! Badge logic is clear and correct.The badge display logic appropriately prioritizes
unreadDropsCountovernewDropsCount.count, and the "99+" cap provides a clean UX for high counts. The conditional rendering and styling transitions are well-structured.contexts/wave/hooks/useEnhancedWavesList.ts (1)
75-76: API types are confirmed; clarify the intentionality of unread count caching behavior.The generated
ApiWaveMetricstype correctly includes bothyour_unread_drops_countandyour_latest_read_timestampfields, so the API contract is satisfied.The clearing behavior in the code is real: once a wave is added to
clearedUnreadWaveIds(after becoming active for 1000ms),unreadDropsCountreturns0and ignores subsequent API values until page refresh. This design appears intentional—the code delays the clear by 1000ms and stores the cleared state persistently. However, confirm with your team whether this caching behavior is the intended UX: new drops arriving during the session will not update the unread count until the next page load.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (9)
__tests__/components/drops/view/UnreadDivider.test.tsx (1)
15-19: Consider using a more resilient selector and add accessibility tests.The test uses class-based selectors (
.tw-h-0\\.5.tw-bg-rose-500) which are fragile and tightly coupled to Tailwind implementation details. If styling changes, this test will break even if functionality is correct.🔎 More resilient test approach
Consider using a test-specific attribute or role:
it('renders horizontal lines', () => { const { container } = render(<UnreadDivider />); - const lines = container.querySelectorAll('.tw-h-0\\.5.tw-bg-rose-500'); + const lines = container.querySelectorAll('[role="separator"]'); expect(lines.length).toBe(2); });Or query by semantic structure rather than styling classes.
Additionally, per coding guidelines for test files in
__tests__/**/components/**/*.test.{ts,tsx}, consider adding accessibility tests for keyboard navigation and screen reader compatibility.Based on learnings, accessibility testing should be included for component tests.
contexts/wave/hooks/useNewDropCounter.ts (1)
176-188: LGTM! Solid logic for tracking first unread serial number.The implementation correctly:
- Sets
firstUnreadSerialNotomessage.serial_nowhen null- Uses
Math.min()to maintain the earliest unread serial number- Increments count unbounded (removed MAX_COUNT cap)
The unbounded count increment means badges could display very large numbers. If this is intentional (e.g., with capping at display time), this is fine. Otherwise, consider whether a maximum threshold should be enforced here.
components/waves/specs/WaveNotificationSettings.tsx (1)
45-73: Consider removing optimistic state update for consistency.The implementation correctly handles mute/unmute with proper error handling and cache invalidation. However, line 53 performs an optimistic state update (
setIsMuted(!isMuted)) before cache invalidation completes.🔎 Recommended refactor to rely on query invalidation
Instead of optimistically updating state, let the
useEffectat lines 41-43 handle state synchronization when the query refetches:if (isMuted) { await commonApiDelete({ endpoint: `waves/${wave.id}/mute` }); } else { await commonApiPost({ endpoint: `waves/${wave.id}/mute`, body: {} }); } - setIsMuted(!isMuted); queryClient.invalidateQueries({ queryKey: [QueryKey.WAVE, { wave_id: wave.id }], }); queryClient.invalidateQueries({ queryKey: [QueryKey.WAVES_OVERVIEW], });This ensures the UI state is driven by the server response rather than optimistic assumptions, preventing potential race conditions.
Alternatively, if optimistic updates are desired, consider adding error rollback in the catch block.
__tests__/components/waves/drops/WaveDropActions.test.tsx (1)
17-17: Mock added for newWaveDropActionsMarkUnreadcomponent.The mock follows the established pattern. Consider adding a test case to verify the mark-unread button renders when
connectedProfileexists and is not the author.🔎 Suggested test case
it('renders mark-unread when user is not the author', () => { render(<WaveDropActions drop={baseDrop} activePartIndex={0} onReply={() => {}} onQuote={() => {}} />, { wrapper }); expect(screen.getByTestId('mark-unread')).toBeInTheDocument(); }); it('hides mark-unread when author is current profile', () => { render( <AuthContext.Provider value={{ connectedProfile: { handle: 'bob' } } as any}> <WaveDropActions drop={baseDrop} activePartIndex={0} onReply={() => {}} onQuote={() => {}} /> </AuthContext.Provider> ); expect(screen.queryByTestId('mark-unread')).toBeNull(); });__tests__/components/waves/header/options/mute/WaveMute.test.tsx (2)
1-1: Remove unused React import.React 19 does not require importing React for JSX. The import can be removed.
🔎 Proposed fix
-import React from 'react'; import { render, screen, waitFor } from '@testing-library/react';
99-111: Prefer data-testid over className selectors for spinner.Using
.querySelector('.spinner')couples tests to implementation details. Consider addingdata-testidto the Spinner component or using a more semantic query.Alternative approach
Instead of:
expect(screen.getByRole('menuitem').querySelector('.spinner')).toBeInTheDocument();Use semantic queries or test IDs:
expect(screen.getByRole('status')).toBeInTheDocument();This requires the Spinner component to have
role="status"or adata-testid.Also applies to: 113-125
__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx (1)
123-134: Prefer semantic queries over className selectors for spinner.Using
.querySelector('.spinner')couples tests to implementation details. Consider usinggetByRole('status')or a data-testid attribute on the Spinner component for more robust tests.Alternative approach
await waitFor(() => { expect(screen.getByRole('status')).toBeInTheDocument(); });This requires the Spinner component to have
role="status"for accessibility.Also applies to: 136-148
contexts/wave/UnreadDividerContext.tsx (1)
29-38: Simplify redundant conditional in setter.The
if/elsebranches are identical—setUnreadDividerSerialNoStatealready handles both function and value arguments natively. This wrapper can be simplified.🔎 Proposed simplification
const setUnreadDividerSerialNo: SetUnreadDividerSerialNo = useCallback( (serialNo) => { - if (typeof serialNo === "function") { - setUnreadDividerSerialNoState(serialNo); - } else { - setUnreadDividerSerialNoState(serialNo); - } + setUnreadDividerSerialNoState(serialNo); }, [] );contexts/wave/hooks/useEnhancedWavesListCore.ts (1)
181-211: Consider whetheroptions.supportsPinningshould trigger re-computation.The
options.supportsPinningis included in the finaluseMemodependencies but theoptionsobject reference from the hook parameter may change on each render if the caller doesn't memoize it. Since the default is provided inline at line 46, consider destructuringsupportsPinningat the top of the hook or documenting that callers should pass a stable options object.#!/bin/bash # Check how callers pass options to this hook rg -n "useEnhancedWavesListCore" --type=ts -A2 -B1
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
generated/models/ApiMarkDropUnreadResponse.tsis excluded by!**/generated/**generated/models/ApiWaveMetrics.tsis excluded by!**/generated/**generated/models/ObjectSerializer.tsis excluded by!**/generated/**
📒 Files selected for processing (41)
__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/helpers/navigation.helpers.test.ts__tests__/useWaveRealtimeUpdater.test.ts__tests__/utils/mockFactories.tscomponents/brain/left-sidebar/waves/BrainLeftSidebarWave.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/hooks/useWaveNavigation.tscomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/index.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcomponents/brain/my-stream/MyStreamWaveChat.tsxcomponents/common/icons/MailUnreadIcon.tsxcomponents/drops/view/DropsList.tsxcomponents/drops/view/UnreadDivider.tsxcomponents/waves/drops/WaveDropActions.tsxcomponents/waves/drops/WaveDropActionsMarkUnread.tsxcomponents/waves/drops/WaveDropActionsOptions.tsxcomponents/waves/drops/wave-drops-all/index.tsxcomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsContent.tsxcomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsMessageListSection.tsxcomponents/waves/header/options/WaveHeaderOptions.tsxcomponents/waves/header/options/mute/WaveMute.tsxcomponents/waves/specs/WaveNotificationSettings.tsxcontexts/wave/MyStreamContext.tsxcontexts/wave/UnreadDividerContext.tsxcontexts/wave/hooks/useActiveWaveManager.tscontexts/wave/hooks/useEnhancedDmWavesList.tscontexts/wave/hooks/useEnhancedWavesList.tscontexts/wave/hooks/useEnhancedWavesListCore.tscontexts/wave/hooks/useNewDropCounter.tscontexts/wave/hooks/useWaveRealtimeUpdater.tshooks/useWavesList.tsopenapi.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
- openapi.yaml
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version
**/*.{ts,tsx,js,jsx}: Replace<img>elements with<Image />fromnext/imageto satisfy@next/next/no-img-elementESLint rule
Use<Link href="/path">from Next.js for internal navigation instead of plain HTML links to satisfy@next/next/no-html-link-for-pagesESLint rule
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsxhooks/useWavesList.ts__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsxcontexts/wave/hooks/useWaveRealtimeUpdater.ts__tests__/components/drops/view/DropsList.test.tsxcontexts/wave/hooks/useNewDropCounter.ts__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/index.tsxcomponents/drops/view/DropsList.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsMessageListSection.tsxcomponents/waves/drops/WaveDropActionsMarkUnread.tsxcomponents/waves/header/options/mute/WaveMute.tsx__tests__/utils/mockFactories.ts__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsxcomponents/waves/drops/WaveDropActionsOptions.tsxcontexts/wave/UnreadDividerContext.tsxcomponents/waves/header/options/WaveHeaderOptions.tsx__tests__/useWaveRealtimeUpdater.test.tscontexts/wave/hooks/useEnhancedWavesList.tscomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/hooks/useWaveNavigation.tscomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsContent.tsxcomponents/drops/view/UnreadDivider.tsxcontexts/wave/hooks/useActiveWaveManager.tscomponents/common/icons/MailUnreadIcon.tsx__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsxcomponents/brain/my-stream/MyStreamWaveChat.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsxcontexts/wave/hooks/useEnhancedDmWavesList.tscomponents/waves/drops/WaveDropActions.tsxcontexts/wave/MyStreamContext.tsxcomponents/waves/specs/WaveNotificationSettings.tsxcontexts/wave/hooks/useEnhancedWavesListCore.tscomponents/waves/drops/wave-drops-all/index.tsxcomponents/brain/left-sidebar/waves/BrainLeftSidebarWave.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always addreadonlybefore props in React components
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/index.tsxcomponents/drops/view/DropsList.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsMessageListSection.tsxcomponents/waves/drops/WaveDropActionsMarkUnread.tsxcomponents/waves/header/options/mute/WaveMute.tsx__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsxcomponents/waves/drops/WaveDropActionsOptions.tsxcontexts/wave/UnreadDividerContext.tsxcomponents/waves/header/options/WaveHeaderOptions.tsxcomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsContent.tsxcomponents/drops/view/UnreadDivider.tsxcomponents/common/icons/MailUnreadIcon.tsx__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsxcomponents/brain/my-stream/MyStreamWaveChat.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsxcomponents/waves/drops/WaveDropActions.tsxcontexts/wave/MyStreamContext.tsxcomponents/waves/specs/WaveNotificationSettings.tsxcomponents/waves/drops/wave-drops-all/index.tsxcomponents/brain/left-sidebar/waves/BrainLeftSidebarWave.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use<Link>, images should usenext/image, and adopt Next's ESLint rules (Core Web Vitals)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsxhooks/useWavesList.ts__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsxcontexts/wave/hooks/useWaveRealtimeUpdater.ts__tests__/components/drops/view/DropsList.test.tsxcontexts/wave/hooks/useNewDropCounter.ts__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/index.tsxcomponents/drops/view/DropsList.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsMessageListSection.tsxcomponents/waves/drops/WaveDropActionsMarkUnread.tsxcomponents/waves/header/options/mute/WaveMute.tsx__tests__/utils/mockFactories.ts__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsxcomponents/waves/drops/WaveDropActionsOptions.tsxcontexts/wave/UnreadDividerContext.tsxcomponents/waves/header/options/WaveHeaderOptions.tsx__tests__/useWaveRealtimeUpdater.test.tscontexts/wave/hooks/useEnhancedWavesList.tscomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/hooks/useWaveNavigation.tscomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsContent.tsxcomponents/drops/view/UnreadDivider.tsxcontexts/wave/hooks/useActiveWaveManager.tscomponents/common/icons/MailUnreadIcon.tsx__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsxcomponents/brain/my-stream/MyStreamWaveChat.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsxcontexts/wave/hooks/useEnhancedDmWavesList.tscomponents/waves/drops/WaveDropActions.tsxcontexts/wave/MyStreamContext.tsxcomponents/waves/specs/WaveNotificationSettings.tsxcontexts/wave/hooks/useEnhancedWavesListCore.tscomponents/waves/drops/wave-drops-all/index.tsxcomponents/brain/left-sidebar/waves/BrainLeftSidebarWave.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Must passtsc --noEmittype checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") overReact.namespace usage (React.useMemo,React.useRef, etc.)
If thereact-hooks/exhaustive-depslint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic inuseEffectEvent
**/*.{ts,tsx}: Must passtsc --noEmitfor TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
UseuseEffectEventfor non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs:<Link>for internal links,next/imagefor images, adopt Next's ESLint rules
Use'use cache'directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace<img>elements with<Image />fromnext/image
Use<Link href="/path">for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with'use server'directive
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsxhooks/useWavesList.ts__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsxcontexts/wave/hooks/useWaveRealtimeUpdater.ts__tests__/components/drops/view/DropsList.test.tsxcontexts/wave/hooks/useNewDropCounter.ts__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/index.tsxcomponents/drops/view/DropsList.tsxcomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsMessageListSection.tsxcomponents/waves/drops/WaveDropActionsMarkUnread.tsxcomponents/waves/header/options/mute/WaveMute.tsx__tests__/utils/mockFactories.ts__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsxcomponents/waves/drops/WaveDropActionsOptions.tsxcontexts/wave/UnreadDividerContext.tsxcomponents/waves/header/options/WaveHeaderOptions.tsx__tests__/useWaveRealtimeUpdater.test.tscontexts/wave/hooks/useEnhancedWavesList.tscomponents/brain/left-sidebar/web/WebBrainLeftSidebarWave/hooks/useWaveNavigation.tscomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsContent.tsxcomponents/drops/view/UnreadDivider.tsxcontexts/wave/hooks/useActiveWaveManager.tscomponents/common/icons/MailUnreadIcon.tsx__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsxcomponents/brain/my-stream/MyStreamWaveChat.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsxcontexts/wave/hooks/useEnhancedDmWavesList.tscomponents/waves/drops/WaveDropActions.tsxcontexts/wave/MyStreamContext.tsxcomponents/waves/specs/WaveNotificationSettings.tsxcontexts/wave/hooks/useEnhancedWavesListCore.tscomponents/waves/drops/wave-drops-all/index.tsxcomponents/brain/left-sidebar/waves/BrainLeftSidebarWave.tsx
**/@(__tests__|*.test).{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Tests should live in
__tests__/orComponentName.test.tsx; mock external dependencies and APIs in tests
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/useWaveRealtimeUpdater.test.ts__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
**/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Place tests in
__tests__/directory or asComponentName.test.tsxalongside components
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/utils/mockFactories.ts__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/useWaveRealtimeUpdater.test.ts__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Mock external dependencies and APIs in tests
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/useWaveRealtimeUpdater.test.ts__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use Jest +
ts-jestfor TypeScript testing
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/useWaveRealtimeUpdater.test.ts__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/utils/mockFactories.ts__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/useWaveRealtimeUpdater.test.ts__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
__tests__/**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (tests/AGENTS.md)
__tests__/**/*.{ts,tsx,js}: Preferfor...ofloops overforEachas it allowsbreak/continueand works with async/await
Usearray.at(-1)andarray.at(-2)instead of index-based array access for negative indexing
UseString.prototype.replaceAll()instead ofreplace()for global string replacements
UseglobalThis.fetch()instead of directfetch()calls
Organize imports with one import per module in order: external → internal → types, with no duplicates
Useelement.remove()instead ofparent.removeChild(element)for DOM manipulation
Catch errors only when meaningful; no empty catch blocks; log errors with context
Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (?.)
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/utils/mockFactories.ts__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/useWaveRealtimeUpdater.test.ts__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
__tests__/**/{components,contexts,hooks}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use semantic HTML elements (
<label>,<output>) over ARIA attributes when possible; every form control must have a label
Files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
🧠 Learnings (25)
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.test.{ts,tsx} : Mock external dependencies and APIs in tests
Applied to files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/utils/mockFactories.ts__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/@(__tests__|*.test).{ts,tsx} : Tests should live in `__tests__/` or `ComponentName.test.tsx`; mock external dependencies and APIs in tests
Applied to files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Use testing-library/react + user-event for React component tests
Applied to files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)
Applied to files:
__tests__/components/waves/drops/WaveDropActions.test.tsx__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/useWaveRealtimeUpdater.test.ts__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Test high-risk areas including happy path workflows, invalid input errors, edge cases/boundaries, component & API interactions, and performance/security when relevant
Applied to files:
__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Test accessibility with keyboard navigation and screen reader compatibility
Applied to files:
__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/__tests__/**/*.{ts,tsx} : Place tests in `__tests__/` directory or as `ComponentName.test.tsx` alongside components
Applied to files:
__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : All tests must live in `__tests__`, mirroring source folders (`components`, `contexts`, `hooks`, `utils`)
Applied to files:
__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/{components,contexts,hooks}/**/*.{ts,tsx} : Use semantic HTML elements (`<label>`, `<output>`) over ARIA attributes when possible; every form control must have a label
Applied to files:
__tests__/components/waves/header/options/mute/WaveMute.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Write tests following Arrange – Act – Assert pattern with one behaviour per test and clear, descriptive names
Applied to files:
__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Keep tests independent, deterministic, and fast with production-like data
Applied to files:
__tests__/components/drops/view/DropsList.test.tsx__tests__/components/waves/drops/WaveDropActionsMarkUnread.test.tsx__tests__/utils/mockFactories.ts__tests__/components/waves/drops/WaveDropsAll.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx__tests__/helpers/navigation.helpers.test.ts
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use FontAwesome for icons in React components
Applied to files:
components/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsxcomponents/common/icons/MailUnreadIcon.tsxcomponents/brain/left-sidebar/waves/BrainLeftSidebarWave.tsx
📚 Learning: 2025-11-25T08:37:21.058Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-11-25T08:37:21.058Z
Learning: Applies to __mocks__/**/__mocks__/** : Document expected behaviour in the mock file when it is not obvious
Applied to files:
__tests__/utils/mockFactories.ts__tests__/components/waves/drops/WaveDropsAll.test.tsx
📚 Learning: 2025-11-25T08:37:21.058Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __mocks__/AGENTS.md:0-0
Timestamp: 2025-11-25T08:37:21.058Z
Learning: Applies to __mocks__/**/__mocks__/** : Keep mock implementations minimal – enough to satisfy test scenarios
Applied to files:
__tests__/utils/mockFactories.ts
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Use `element.remove()` instead of `parent.removeChild(element)` for DOM manipulation
Applied to files:
__tests__/components/waves/drops/WaveDropsAll.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions
Applied to files:
contexts/wave/UnreadDividerContext.tsx__tests__/components/waves/specs/WaveNotificationSettings.test.tsxcontexts/wave/MyStreamContext.tsxcomponents/brain/left-sidebar/waves/BrainLeftSidebarWave.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Always add `readonly` before props in React components
Applied to files:
components/common/icons/MailUnreadIcon.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx} : Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic
Applied to files:
__tests__/helpers/navigation.helpers.test.ts__tests__/components/brain/left-sidebar/waves/BrainLeftSidebarWave.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/app/api/**/__tests__/**/*.test.{ts,tsx,js} : API integration tests should be located in `app/api`
Applied to files:
__tests__/helpers/navigation.helpers.test.ts
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Organize imports with one import per module in order: external → internal → types, with no duplicates
Applied to files:
__tests__/helpers/navigation.helpers.test.ts
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to app/**/page.{ts,tsx} : Export `generateMetadata` in App Router routes using the `getAppMetadata` helper from '@/components/providers/metadata'
Applied to files:
__tests__/helpers/navigation.helpers.test.ts
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Remove unnecessary Effects; if Effect only derives state, compute during render instead
Applied to files:
components/brain/my-stream/MyStreamWaveChat.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use react-query for data fetching
Applied to files:
__tests__/components/waves/specs/WaveNotificationSettings.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/*.{ts,tsx} : Prefer direct named imports for React hooks and types (`import { useMemo, useRef, FC, etc. } from "react"`) over `React.` namespace usage (`React.useMemo`, `React.useRef`, etc.)
Applied to files:
contexts/wave/MyStreamContext.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks
Applied to files:
contexts/wave/MyStreamContext.tsx
🧬 Code graph analysis (16)
__tests__/contexts/wave/hooks/useActiveWaveManager.test.tsx (1)
contexts/wave/hooks/useActiveWaveManager.ts (1)
useActiveWaveManager(37-82)
__tests__/contexts/wave/UnreadDividerContext.test.tsx (1)
contexts/wave/UnreadDividerContext.tsx (3)
useUnreadDivider(55-61)UnreadDividerProvider(21-53)useUnreadDividerOptional(63-65)
components/drops/view/DropsList.tsx (1)
components/waves/drops/VirtualScrollWrapper.tsx (1)
VirtualScrollWrapper(56-181)
components/brain/left-sidebar/web/WebBrainLeftSidebarWave/subcomponents/WaveAvatar.tsx (1)
components/waves/WavePicture.tsx (1)
WavePicture(63-122)
components/waves/drops/WaveDropActionsMarkUnread.tsx (5)
generated/models/ApiDrop.ts (1)
ApiDrop(28-229)components/auth/Auth.tsx (1)
useAuth(95-97)contexts/wave/UnreadDividerContext.tsx (1)
useUnreadDividerOptional(63-65)contexts/wave/MyStreamContext.tsx (1)
useMyStream(263-269)generated/models/ApiMarkDropUnreadResponse.ts (1)
ApiMarkDropUnreadResponse(15-43)
components/waves/header/options/mute/WaveMute.tsx (2)
generated/models/ApiWave.ts (1)
ApiWave(27-179)components/auth/Auth.tsx (1)
useAuth(95-97)
components/waves/header/options/WaveHeaderOptions.tsx (1)
components/waves/header/options/mute/WaveMute.tsx (1)
WaveMute(11-68)
__tests__/useWaveRealtimeUpdater.test.ts (1)
contexts/wave/hooks/useWaveRealtimeUpdater.ts (1)
useWaveRealtimeUpdater(38-324)
components/waves/drops/wave-drops-all/subcomponents/WaveDropsContent.tsx (1)
contexts/wave/UnreadDividerContext.tsx (1)
useUnreadDivider(55-61)
contexts/wave/hooks/useActiveWaveManager.ts (1)
helpers/navigation.helpers.ts (1)
getWaveRoute(19-59)
__tests__/helpers/navigation.helpers.test.ts (1)
helpers/navigation.helpers.ts (2)
getWaveRoute(19-59)getWaveHomeRoute(61-71)
__tests__/components/waves/specs/WaveNotificationSettings.test.tsx (1)
generated/models/ApiWave.ts (1)
ApiWave(27-179)
components/waves/drops/WaveDropActions.tsx (1)
components/waves/drops/WaveDropActionsMarkUnread.tsx (1)
WaveDropActionsMarkUnread(20-103)
components/waves/specs/WaveNotificationSettings.tsx (2)
generated/models/ApiWave.ts (1)
ApiWave(27-179)contexts/SeizeSettingsContext.tsx (1)
useSeizeSettings(118-126)
contexts/wave/hooks/useEnhancedWavesListCore.ts (2)
contexts/wave/hooks/useNewDropCounter.ts (2)
MinimalWaveNewDropsCount(12-16)getNewestTimestamp(18-35)generated/models/ApiWave.ts (1)
ApiWave(27-179)
components/brain/left-sidebar/waves/BrainLeftSidebarWave.tsx (1)
helpers/navigation.helpers.ts (1)
getWaveRoute(19-59)
⏰ 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: Analyze (javascript-typescript)
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
__tests__/components/drops/view/UnreadDivider.test.tsx (2)
15-19: Consider testing structure semantically rather than via Tailwind classes.Querying by specific Tailwind CSS classes (
.tw-h-0\.5.tw-bg-rose-500) makes the test brittle—if styling changes but the visual divider remains, the test breaks. Consider using a more semantic approach:
- Add
data-testid="divider-line"to each line element in the component, then query by test ID- Verify the component's semantic structure (e.g., check for role or container elements) instead of implementation details
🔎 Proposed refactor using data-testid
it('renders horizontal lines', () => { - const { container } = render(<UnreadDivider />); - const lines = container.querySelectorAll(String.raw`.tw-h-0\.5.tw-bg-rose-500`); + render(<UnreadDivider />); + const lines = screen.getAllByTestId('divider-line'); expect(lines.length).toBe(2); });Then update the component to add
data-testid="divider-line"to each horizontal line element.
4-20: Add accessibility tests for keyboard navigation and screen reader compatibility.The component should verify that the divider doesn't break keyboard navigation and is appropriately exposed (or hidden) to assistive technologies. Consider adding tests for:
- Proper ARIA role or landmark (e.g.,
separatorrole if semantically a divider)- Ensure the divider doesn't trap focus or interfere with tab order
- Verify screen reader announcement (if applicable) or that decorative elements are properly hidden from accessibility tree
Based on learnings, as per coding guidelines for
__tests__/**/components/**/*.test.{ts,tsx}.🔎 Example accessibility test
it('is accessible and does not interfere with keyboard navigation', () => { render(<UnreadDivider />); const separator = screen.getByRole('separator', { hidden: true }); expect(separator).toBeInTheDocument(); });Adjust the role query based on the actual semantic structure of the UnreadDivider component.
__tests__/components/waves/header/WaveHeaderOptions.test.tsx (1)
22-22: Consider adding explicit type for better type safety.The wave fixture uses
as anywhich bypasses type checking. While acceptable in tests, an explicit interface or type would catch potential mismatches with the actual Wave type.🔎 Example type-safe alternative
+type TestWave = Pick<Wave, 'id' | 'metrics'>; + -const wave = { id: 'w1', metrics: { muted: false } } as any; +const wave: TestWave = { id: 'w1', metrics: { muted: false } };components/waves/specs/WaveNotificationSettings.tsx (1)
16-18: Rename props interface to match component purpose.The interface
WaveRatingPropsdoesn't match the component nameWaveNotificationSettings. This naming mismatch could confuse future developers.🔎 Proposed fix
-interface WaveRatingProps { +interface WaveNotificationSettingsProps { readonly wave: ApiWave; } -export default function WaveNotificationSettings({ wave }: WaveRatingProps) { +export default function WaveNotificationSettings({ wave }: WaveNotificationSettingsProps) {
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
__tests__/components/drops/view/UnreadDivider.test.tsx__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsxcomponents/waves/header/options/mute/WaveMute.tsxcomponents/waves/specs/WaveNotificationSettings.tsxcontexts/wave/UnreadDividerContext.tsxcontexts/wave/hooks/useEnhancedWavesListCore.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- tests/contexts/wave/UnreadDividerContext.test.tsx
- components/waves/header/options/mute/WaveMute.tsx
- contexts/wave/UnreadDividerContext.tsx
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version
**/*.{ts,tsx,js,jsx}: Replace<img>elements with<Image />fromnext/imageto satisfy@next/next/no-img-elementESLint rule
Use<Link href="/path">from Next.js for internal navigation instead of plain HTML links to satisfy@next/next/no-html-link-for-pagesESLint rule
Files:
components/waves/specs/WaveNotificationSettings.tsx__tests__/components/waves/header/WaveHeaderOptions.test.tsxcontexts/wave/hooks/useEnhancedWavesListCore.ts__tests__/components/drops/view/UnreadDivider.test.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always addreadonlybefore props in React components
Files:
components/waves/specs/WaveNotificationSettings.tsx__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use<Link>, images should usenext/image, and adopt Next's ESLint rules (Core Web Vitals)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Files:
components/waves/specs/WaveNotificationSettings.tsx__tests__/components/waves/header/WaveHeaderOptions.test.tsxcontexts/wave/hooks/useEnhancedWavesListCore.ts__tests__/components/drops/view/UnreadDivider.test.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Must passtsc --noEmittype checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") overReact.namespace usage (React.useMemo,React.useRef, etc.)
If thereact-hooks/exhaustive-depslint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic inuseEffectEvent
**/*.{ts,tsx}: Must passtsc --noEmitfor TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
UseuseEffectEventfor non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs:<Link>for internal links,next/imagefor images, adopt Next's ESLint rules
Use'use cache'directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace<img>elements with<Image />fromnext/image
Use<Link href="/path">for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with'use server'directive
Files:
components/waves/specs/WaveNotificationSettings.tsx__tests__/components/waves/header/WaveHeaderOptions.test.tsxcontexts/wave/hooks/useEnhancedWavesListCore.ts__tests__/components/drops/view/UnreadDivider.test.tsx
**/@(__tests__|*.test).{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Tests should live in
__tests__/orComponentName.test.tsx; mock external dependencies and APIs in tests
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
**/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Place tests in
__tests__/directory or asComponentName.test.tsxalongside components
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Mock external dependencies and APIs in tests
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use Jest +
ts-jestfor TypeScript testing
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
__tests__/**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (tests/AGENTS.md)
__tests__/**/*.{ts,tsx,js}: Preferfor...ofloops overforEachas it allowsbreak/continueand works with async/await
Usearray.at(-1)andarray.at(-2)instead of index-based array access for negative indexing
UseString.prototype.replaceAll()instead ofreplace()for global string replacements
UseglobalThis.fetch()instead of directfetch()calls
Organize imports with one import per module in order: external → internal → types, with no duplicates
Useelement.remove()instead ofparent.removeChild(element)for DOM manipulation
Catch errors only when meaningful; no empty catch blocks; log errors with context
Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (?.)
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
__tests__/**/{components,contexts,hooks}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use semantic HTML elements (
<label>,<output>) over ARIA attributes when possible; every form control must have a label
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
🧠 Learnings (13)
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.test.{ts,tsx} : Mock external dependencies and APIs in tests
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Use testing-library/react + user-event for React component tests
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/@(__tests__|*.test).{ts,tsx} : Tests should live in `__tests__/` or `ComponentName.test.tsx`; mock external dependencies and APIs in tests
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use react-query for data fetching
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks
Applied to files:
contexts/wave/hooks/useEnhancedWavesListCore.ts
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/{components,contexts,hooks}/**/*.{ts,tsx} : Use semantic HTML elements (`<label>`, `<output>`) over ARIA attributes when possible; every form control must have a label
Applied to files:
__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Test high-risk areas including happy path workflows, invalid input errors, edge cases/boundaries, component & API interactions, and performance/security when relevant
Applied to files:
__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/__tests__/**/*.{ts,tsx} : Place tests in `__tests__/` directory or as `ComponentName.test.tsx` alongside components
Applied to files:
__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Test accessibility with keyboard navigation and screen reader compatibility
Applied to files:
__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx} : Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic
Applied to files:
__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Write tests following Arrange – Act – Assert pattern with one behaviour per test and clear, descriptive names
Applied to files:
__tests__/components/drops/view/UnreadDivider.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : All tests must live in `__tests__`, mirroring source folders (`components`, `contexts`, `hooks`, `utils`)
Applied to files:
__tests__/components/drops/view/UnreadDivider.test.tsx
🧬 Code graph analysis (2)
components/waves/specs/WaveNotificationSettings.tsx (2)
generated/models/ApiWave.ts (1)
ApiWave(27-179)contexts/SeizeSettingsContext.tsx (1)
useSeizeSettings(118-126)
contexts/wave/hooks/useEnhancedWavesListCore.ts (4)
contexts/wave/hooks/useEnhancedDmWavesList.ts (1)
MinimalWave(6-6)contexts/wave/hooks/useEnhancedWavesList.ts (1)
MinimalWave(6-6)contexts/wave/hooks/useNewDropCounter.ts (2)
MinimalWaveNewDropsCount(12-16)getNewestTimestamp(18-35)generated/models/ApiWave.ts (1)
ApiWave(27-179)
⏰ 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: Analyze (javascript-typescript)
🔇 Additional comments (8)
__tests__/components/waves/header/WaveHeaderOptions.test.tsx (4)
4-4: LGTM!The React Query imports are correctly added to provide the necessary context for components that use react-query hooks.
18-20: Consistent mock pattern for test isolation.The WaveMute mock follows the same pattern as WaveDelete, enabling proper test isolation and prop verification.
24-31: LGTM!The
createWrapperhelper follows React Query testing best practices by creating a fresh QueryClient with retry disabled for each test, preventing test pollution and ensuring deterministic behavior.
35-39: LGTM!The test correctly uses the wrapper to provide React Query context and adds an appropriate assertion to verify the new mute option appears alongside the delete option.
contexts/wave/hooks/useEnhancedWavesListCore.ts (2)
176-184: LGTM!Sorting by latest drop timestamp descending correctly surfaces recently active waves. The memo dependencies are correct.
186-216: LGTM!The return memo properly includes all dependencies and exposes a stable API. The conditional pinning wiring based on
supportsPinningis clean.components/waves/specs/WaveNotificationSettings.tsx (2)
29-30: LGTM! State management correctly handles mute synchronization.The combination of local state (lines 29-30) and sync effect (lines 41-43) provides a good balance between immediate UI feedback and server consistency. The optimistic update pattern ensures responsive UX while staying synchronized with backend state.
Also applies to: 41-43
45-72: LGTM! Mute functionality is well-implemented.The implementation demonstrates solid patterns:
- Error handling (lines 60-68): Contextual error messages differentiate mute vs unmute failures
- Query invalidation (lines 54-59): Correctly targets both specific wave and overview caches
- Loading states (line 30, 46, 70): Prevents race conditions from concurrent clicks
- Accessibility (line 179): Proper aria-label for screen readers
- Dependencies (line 72): All callback dependencies are correctly specified
The conditional rendering (lines 165-196) provides clear UX when a wave is muted.
Also applies to: 161-196
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
contexts/wave/hooks/useEnhancedWavesListCore.ts (1)
156-156: TheisPinnedproperty access is now correct.This addresses the previous review comment about using
wave.pinnedinstead of the non-existentwave.isPinned.
🧹 Nitpick comments (2)
components/waves/header/options/mute/WaveMute.tsx (1)
23-50: Consider usingPromise.allfor cache invalidations.The two
invalidateQueriescalls are independent and can run in parallel.🔎 Proposed refactor
- queryClient.invalidateQueries({ - queryKey: [QueryKey.WAVE, { wave_id: wave.id }], - }); - queryClient.invalidateQueries({ - queryKey: [QueryKey.WAVES_OVERVIEW], - }); + await Promise.all([ + queryClient.invalidateQueries({ + queryKey: [QueryKey.WAVE, { wave_id: wave.id }], + }), + queryClient.invalidateQueries({ + queryKey: [QueryKey.WAVES_OVERVIEW], + }), + ]);contexts/wave/hooks/useEnhancedWavesListCore.ts (1)
110-111: Simplify redundant type annotation.The type
ApiWave & { pinned?: boolean }is redundant sinceApiWavealready haspinned: boolean. The intersection with an optional version doesn't change the effective type.🔎 Proposed fix
const mapWave = useCallback( - (wave: ApiWave & { pinned?: boolean }): MinimalWave => { + (wave: ApiWave): MinimalWave => {
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
__tests__/components/waves/header/WaveHeaderOptions.test.tsx__tests__/contexts/wave/UnreadDividerContext.test.tsxcomponents/brain/my-stream/MyStreamWaveChat.tsxcomponents/waves/drops/WaveDropActionsMarkUnread.tsxcomponents/waves/header/options/mute/WaveMute.tsxcontexts/wave/MyStreamContext.tsxcontexts/wave/hooks/useActiveWaveManager.tscontexts/wave/hooks/useEnhancedWavesListCore.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- components/waves/drops/WaveDropActionsMarkUnread.tsx
- components/brain/my-stream/MyStreamWaveChat.tsx
- tests/contexts/wave/UnreadDividerContext.test.tsx
- contexts/wave/hooks/useActiveWaveManager.ts
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version
**/*.{ts,tsx,js,jsx}: Replace<img>elements with<Image />fromnext/imageto satisfy@next/next/no-img-elementESLint rule
Use<Link href="/path">from Next.js for internal navigation instead of plain HTML links to satisfy@next/next/no-html-link-for-pagesESLint rule
Files:
contexts/wave/MyStreamContext.tsxcomponents/waves/header/options/mute/WaveMute.tsx__tests__/components/waves/header/WaveHeaderOptions.test.tsxcontexts/wave/hooks/useEnhancedWavesListCore.ts
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always addreadonlybefore props in React components
Files:
contexts/wave/MyStreamContext.tsxcomponents/waves/header/options/mute/WaveMute.tsx__tests__/components/waves/header/WaveHeaderOptions.test.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use<Link>, images should usenext/image, and adopt Next's ESLint rules (Core Web Vitals)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Files:
contexts/wave/MyStreamContext.tsxcomponents/waves/header/options/mute/WaveMute.tsx__tests__/components/waves/header/WaveHeaderOptions.test.tsxcontexts/wave/hooks/useEnhancedWavesListCore.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Must passtsc --noEmittype checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") overReact.namespace usage (React.useMemo,React.useRef, etc.)
If thereact-hooks/exhaustive-depslint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic inuseEffectEvent
**/*.{ts,tsx}: Must passtsc --noEmitfor TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
UseuseEffectEventfor non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs:<Link>for internal links,next/imagefor images, adopt Next's ESLint rules
Use'use cache'directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace<img>elements with<Image />fromnext/image
Use<Link href="/path">for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with'use server'directive
Files:
contexts/wave/MyStreamContext.tsxcomponents/waves/header/options/mute/WaveMute.tsx__tests__/components/waves/header/WaveHeaderOptions.test.tsxcontexts/wave/hooks/useEnhancedWavesListCore.ts
**/@(__tests__|*.test).{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Tests should live in
__tests__/orComponentName.test.tsx; mock external dependencies and APIs in tests
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
**/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Place tests in
__tests__/directory or asComponentName.test.tsxalongside components
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Mock external dependencies and APIs in tests
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use Jest +
ts-jestfor TypeScript testing
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
__tests__/**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (tests/AGENTS.md)
__tests__/**/*.{ts,tsx,js}: Preferfor...ofloops overforEachas it allowsbreak/continueand works with async/await
Usearray.at(-1)andarray.at(-2)instead of index-based array access for negative indexing
UseString.prototype.replaceAll()instead ofreplace()for global string replacements
UseglobalThis.fetch()instead of directfetch()calls
Organize imports with one import per module in order: external → internal → types, with no duplicates
Useelement.remove()instead ofparent.removeChild(element)for DOM manipulation
Catch errors only when meaningful; no empty catch blocks; log errors with context
Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (?.)
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
__tests__/**/{components,contexts,hooks}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use semantic HTML elements (
<label>,<output>) over ARIA attributes when possible; every form control must have a label
Files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
🧠 Learnings (10)
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/*.{ts,tsx} : Prefer direct named imports for React hooks and types (`import { useMemo, useRef, FC, etc. } from "react"`) over `React.` namespace usage (`React.useMemo`, `React.useRef`, etc.)
Applied to files:
contexts/wave/MyStreamContext.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions
Applied to files:
contexts/wave/MyStreamContext.tsx__tests__/components/waves/header/WaveHeaderOptions.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks
Applied to files:
contexts/wave/MyStreamContext.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.test.{ts,tsx} : Mock external dependencies and APIs in tests
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Use testing-library/react + user-event for React component tests
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Test accessibility with keyboard navigation and screen reader compatibility
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Do not include any comments in the code; it should be self-explanatory
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx} : Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{tsx,jsx} : Use react-query for data fetching
Applied to files:
__tests__/components/waves/header/WaveHeaderOptions.test.tsx
🧬 Code graph analysis (2)
components/waves/header/options/mute/WaveMute.tsx (2)
generated/models/ApiWave.ts (1)
ApiWave(27-179)components/auth/Auth.tsx (1)
useAuth(95-97)
contexts/wave/hooks/useEnhancedWavesListCore.ts (3)
contexts/wave/hooks/useEnhancedDmWavesList.ts (2)
MinimalWave(6-6)useEnhancedDmWavesList(9-68)contexts/wave/hooks/useNewDropCounter.ts (2)
MinimalWaveNewDropsCount(12-16)getNewestTimestamp(18-35)generated/models/ApiWave.ts (1)
ApiWave(27-179)
⏰ 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: Analyze (javascript-typescript)
🔇 Additional comments (14)
components/waves/header/options/mute/WaveMute.tsx (3)
1-10: LGTM!Imports are well-organized with proper separation between external and internal modules.
11-21: LGTM!Props correctly use
readonlyas per coding guidelines, and the component setup is clean.
52-67: LGTM!The button correctly handles loading states, uses proper accessibility attributes (
role="menuitem"), and prevents event propagation.__tests__/components/waves/header/WaveHeaderOptions.test.tsx (2)
24-31: LGTM!The
createWrapperhelper follows best practices by creating a freshQueryClientper test invocation withretry: falseto prevent flaky tests.
33-47: LGTM!Test correctly verifies that both mute and delete options are rendered when the menu opens, and that the menu closes on click-away and escape key press.
contexts/wave/MyStreamContext.tsx (4)
120-131: LGTM!The refs pattern is correctly used to avoid stale closures in
isWaveMuted. The callback has no dependencies since it reads from refs that are always current.
44-44: LGTM!The interface extension adds the new
restoreWaveUnreadCountcapability to the waves context.
49-56: LGTM!The updated
setsignature uses an options object pattern which is extensible and maintains backward compatibility since the options parameter is optional.
184-260: LGTM!The context value construction and memoization dependencies are comprehensive and correctly include the new
restoreWaveUnreadCountproperties for both waves and direct messages.contexts/wave/hooks/useEnhancedWavesListCore.ts (5)
13-25: LGTM!The
MinimalWaveinterface is well-defined with all necessary fields for UI rendering including the new unread/muted state properties.
58-77: LGTM!State management for cleared and forced unread counts is correctly implemented. The
resetWaveUnreadCountproperly clears both the cleared set and any forced count for the wave.
97-108: LGTM!The debounced clearing of unread indicators with proper cleanup prevents flickering when navigating between waves and ensures the timeout is cancelled if the active wave changes before the delay completes.
122-145: LGTM!The unread count calculation logic correctly handles the priority of states: cleared > forced > websocket new drops > API count. The
firstUnreadDropSerialNocomputation properly takes the minimum between API and websocket values when both exist.
186-216: LGTM!The return value is properly memoized with all necessary dependencies, and the conditional pinning support correctly returns no-op functions when pinning is disabled.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
contexts/wave/hooks/useEnhancedWavesListCore.ts (1)
110-161: Fix conflicting type annotation for wave parameter.Line 111 declares
wave: ApiWave & { pinned?: boolean }, which creates a type conflict becauseApiWavealready definespinned: boolean(non-optional). The intersection type with{ pinned?: boolean }(optional) is contradictory and unnecessary.🔎 Proposed fix
const mapWave = useCallback( - (wave: ApiWave & { pinned?: boolean }): MinimalWave => { + (wave: ApiWave): MinimalWave => { const wsData = newDropsCounts[wave.id];
🧹 Nitpick comments (4)
hooks/useWaveWebSocket.ts (2)
45-48: Remove placeholder fallback URL and fail fast instead.The fallback to
"wss://default-fallback-url"violates the coding guideline: "fail fast if base origin is unavailable; do not fall back to placeholder origins". This placeholder could mask configuration issues.🔎 Proposed fix to fail fast
- const url = - publicEnv.WS_ENDPOINT ?? - publicEnv.API_ENDPOINT?.replace("https://api", "wss://ws") ?? - "wss://default-fallback-url"; + const url = + publicEnv.WS_ENDPOINT ?? + publicEnv.API_ENDPOINT?.replace("https://api", "wss://ws"); + + if (!url) { + console.error("WebSocket endpoint not configured"); + setReadyState(WebSocket.CLOSED); + return; + }As per coding guidelines, URLs should fail fast when the base origin is unavailable.
34-98: Consider removing inline comments per style guidelines.The coding guidelines specify: "Do not include any comments in the code; it should be self-explanatory". While the comments aid understanding, consider whether the code can be made self-documenting through better naming or structure.
As per coding guidelines, code should be self-explanatory without comments.
hooks/useWaveIsTyping.ts (1)
11-136: Consider removing inline comments per style guidelines.The coding guidelines specify: "Do not include any comments in the code; it should be self-explanatory". While the section dividers and inline comments aid understanding, consider whether clearer naming or structure could replace them.
As per coding guidelines, code should be self-explanatory without comments.
components/waves/drops/wave-drops-all/index.tsx (1)
58-58: Prefer direct import ofFCtype.The coding guidelines recommend importing React types directly rather than using the
React.namespace.🔎 Suggested refactor
Update the import statement:
-import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState, FC } from "react";Then update the component declarations:
-const WaveDropsAllInner: React.FC<WaveDropsAllInnerProps> = ({ +const WaveDropsAllInner: FC<WaveDropsAllInnerProps> = ({-const WaveDropsAll: React.FC<WaveDropsAllProps> = ({ +const WaveDropsAll: FC<WaveDropsAllProps> = ({As per coding guidelines: "Prefer direct named imports for React hooks and types (
import { useMemo, useRef, FC, etc. } from "react") overReact.namespace usage."Also applies to: 334-334
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
__tests__/contexts/wave/UnreadDividerContext.test.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsxcomponents/brain/my-stream/MyStreamWaveChat.tsxcomponents/waves/drop/SingleWaveDropChat.tsxcomponents/waves/drops/wave-drops-all/index.tsxcontexts/wave/hooks/useEnhancedWavesListCore.tscontexts/wave/hooks/useNewDropCounter.tshooks/useWaveIsTyping.tshooks/useWaveWebSocket.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- components/brain/my-stream/MyStreamWaveChat.tsx
- tests/contexts/wave/UnreadDividerContext.test.tsx
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version
**/*.{ts,tsx,js,jsx}: Replace<img>elements with<Image />fromnext/imageto satisfy@next/next/no-img-elementESLint rule
Use<Link href="/path">from Next.js for internal navigation instead of plain HTML links to satisfy@next/next/no-html-link-for-pagesESLint rule
Files:
components/waves/drop/SingleWaveDropChat.tsxhooks/useWaveIsTyping.tscontexts/wave/hooks/useNewDropCounter.tscontexts/wave/hooks/useEnhancedWavesListCore.ts__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsxhooks/useWaveWebSocket.tscomponents/waves/drops/wave-drops-all/index.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always addreadonlybefore props in React components
Files:
components/waves/drop/SingleWaveDropChat.tsx__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsxcomponents/waves/drops/wave-drops-all/index.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use<Link>, images should usenext/image, and adopt Next's ESLint rules (Core Web Vitals)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Files:
components/waves/drop/SingleWaveDropChat.tsxhooks/useWaveIsTyping.tscontexts/wave/hooks/useNewDropCounter.tscontexts/wave/hooks/useEnhancedWavesListCore.ts__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsxhooks/useWaveWebSocket.tscomponents/waves/drops/wave-drops-all/index.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Must passtsc --noEmittype checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") overReact.namespace usage (React.useMemo,React.useRef, etc.)
If thereact-hooks/exhaustive-depslint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic inuseEffectEvent
**/*.{ts,tsx}: Must passtsc --noEmitfor TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
UseuseEffectEventfor non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs:<Link>for internal links,next/imagefor images, adopt Next's ESLint rules
Use'use cache'directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace<img>elements with<Image />fromnext/image
Use<Link href="/path">for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with'use server'directive
Files:
components/waves/drop/SingleWaveDropChat.tsxhooks/useWaveIsTyping.tscontexts/wave/hooks/useNewDropCounter.tscontexts/wave/hooks/useEnhancedWavesListCore.ts__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsxhooks/useWaveWebSocket.tscomponents/waves/drops/wave-drops-all/index.tsx
**/@(__tests__|*.test).{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Tests should live in
__tests__/orComponentName.test.tsx; mock external dependencies and APIs in tests
Files:
__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx
**/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Place tests in
__tests__/directory or asComponentName.test.tsxalongside components
Files:
__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Mock external dependencies and APIs in tests
Files:
__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx
__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use Jest +
ts-jestfor TypeScript testing
Files:
__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx
__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic
Files:
__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx
__tests__/**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (tests/AGENTS.md)
__tests__/**/*.{ts,tsx,js}: Preferfor...ofloops overforEachas it allowsbreak/continueand works with async/await
Usearray.at(-1)andarray.at(-2)instead of index-based array access for negative indexing
UseString.prototype.replaceAll()instead ofreplace()for global string replacements
UseglobalThis.fetch()instead of directfetch()calls
Organize imports with one import per module in order: external → internal → types, with no duplicates
Useelement.remove()instead ofparent.removeChild(element)for DOM manipulation
Catch errors only when meaningful; no empty catch blocks; log errors with context
Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (?.)
Files:
__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx
__tests__/**/{components,contexts,hooks}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use semantic HTML elements (
<label>,<output>) over ARIA attributes when possible; every form control must have a label
Files:
__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx
🧠 Learnings (2)
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)
Applied to files:
__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Keep tests independent, deterministic, and fast with production-like data
Applied to files:
__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx
🧬 Code graph analysis (3)
hooks/useWaveIsTyping.ts (1)
hooks/useWaveWebSocket.ts (1)
useWaveWebSocket(27-119)
contexts/wave/hooks/useEnhancedWavesListCore.ts (2)
contexts/wave/hooks/useNewDropCounter.ts (2)
MinimalWaveNewDropsCount(12-16)getNewestTimestamp(18-35)generated/models/ApiWave.ts (1)
ApiWave(27-179)
components/waves/drops/wave-drops-all/index.tsx (2)
hooks/useVirtualizedWaveDrops.ts (1)
useVirtualizedWaveDrops(17-91)contexts/wave/UnreadDividerContext.tsx (2)
useUnreadDivider(46-54)UnreadDividerProvider(23-44)
⏰ 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: Analyze (javascript-typescript)
🔇 Additional comments (24)
hooks/useWaveWebSocket.ts (2)
19-26: LGTM! Clear documentation of hook behavior.The JSDoc accurately describes the subscription message behavior and the new waveId parameter semantics, including the disable-by-empty-string pattern.
35-42: LGTM! Proper lifecycle management for disabled state.The empty waveId guard correctly tears down any existing connection and prevents new connections when the hook should be disabled. The cleanup logic properly closes the socket and updates state.
hooks/useWaveIsTyping.ts (2)
56-68: LGTM! Clean disabled flag implementation.The new
disabledparameter is well-documented and correctly implemented:
- Backwards compatible with default value
false- Properly leverages the empty waveId handling in
useWaveWebSocket- Clear JSDoc explains the purpose (e.g., for muted waves)
74-77: LGTM! Correct dependency array.The addition of
disabledto the dependency array is correct. The effect should reset the typing state when either the wave changes or the disabled flag toggles.__tests__/contexts/wave/hooks/useEnhancedWavesList.test.tsx (4)
21-79: LGTM! Test fixtures properly updated.The test fixtures now include the unread-related fields (
your_unread_drops_count,your_latest_read_timestamp,first_unread_drop_serial_no,muted), and the change fromisPinnedtopinnedcorrectly aligns with theApiWavemodel structure.
81-118: LGTM! Comprehensive test coverage for unread state mapping.The test validates that
unreadDropsCount,latestReadTimestamp, andfirstUnreadDropSerialNoare correctly mapped from wave metrics, ensuring the core hook properly exposes unread state to consumers.
120-155: LGTM! Muted state mapping validated.The test confirms that
isMutedis correctly derived fromwave.metrics.muted, which is essential for proper UI behavior of muted waves.
157-191: LGTM! Null handling for firstUnreadDropSerialNo verified.The test ensures that when
first_unread_drop_serial_nois undefined in metrics, the mapped field correctly becomesnull, maintaining type safety and avoiding undefined values in the UI.contexts/wave/hooks/useNewDropCounter.ts (3)
12-16: LGTM! Interface extended with firstUnreadSerialNo.The
firstUnreadSerialNofield correctly tracks the earliest unread drop, enabling precise navigation to the first unread message in the UI.
58-91: LGTM! Reset logic properly initializes firstUnreadSerialNo.Both
resetWaveNewDropsCountandresetAllWavesNewDropsCountcorrectly setfirstUnreadSerialNotonullwhen clearing unread state, maintaining consistency across reset operations.
116-196: LGTM! WebSocket handling correctly maintains firstUnreadSerialNo.The logic properly:
- Returns early and refetches when wave is not found (Line 128)
- Skips processing for muted waves (Line 131)
- Preserves
firstUnreadSerialNofor owner messages and active visible waves (Lines 149, 168)- Computes the minimum serial number for new unread drops (Lines 187-190), ensuring the field always points to the earliest unread message
contexts/wave/hooks/useEnhancedWavesListCore.ts (5)
13-25: LGTM! MinimalWave interface properly defines enriched wave structure.The interface includes all necessary fields for UI rendering, including the new unread state fields (
unreadDropsCount,latestReadTimestamp,firstUnreadDropSerialNo,isMuted), enabling comprehensive wave state management.
66-95: LGTM! Unread state management utilities.
resetWaveUnreadCountandrestoreWaveUnreadCountprovide fine-grained control over per-wave unread state, supporting both clearing and restoring with optional forced counts.
97-108: LGTM! Debounced unread clearing on active wave change.The 1-second delay before clearing unread state for the active wave provides a better UX by allowing brief navigation away without losing unread indicators.
122-145: LGTM! Comprehensive unread count computation.The logic correctly handles multiple scenarios:
- Cleared state: unreadDropsCount = 0
- Forced count: adds WebSocket drops to forced baseline
- New WebSocket drops: adds to API unread count
- Default: uses API unread count
This provides flexible unread state management across different use cases.
176-188: LGTM! Sorting respects muted state.Waves are sorted with muted waves pushed to the bottom, then by latest drop timestamp. This ensures important conversations remain visible while de-emphasizing muted content.
components/waves/drop/SingleWaveDropChat.tsx (4)
19-22: LGTM: Interface follows guidelines.The props interface correctly uses
readonlymodifiers as required by the coding guidelines for React components.
24-77: LGTM: Clean component logic and state management.The hook usage, memoization, and state management follow React best practices. Dependencies are correctly specified and the logic is well-structured.
79-149: LGTM: Well-structured responsive layout.The JSX structure properly handles responsive design with TailwindCSS, includes mobile-specific considerations (keyboard adjustments, safe area insets), and maintains clean component composition.
120-120: Property access is type-safe and guaranteed.The
metrics.mutedproperty is a required (non-optional) field in bothApiWaveandApiWaveMetrics, so accessingwave.metrics.mutedwithout optional chaining is correct and will always be present. TypeScript compilation will enforce this safety.components/waves/drops/wave-drops-all/index.tsx (4)
29-56: LGTM! Well-structured interface definitions.The addition of
isMutedprop and the newWaveDropsAllInnerPropsinterface are well-designed. UsingReturnTypeto extract types fromuseVirtualizedWaveDropsis a good pattern that ensures type consistency between the hook and component props.
58-93: LGTM! Proper context integration.The component correctly consumes the
UnreadDividerProvidercontext viauseUnreadDivider, and theisMutedprop is properly passed through touseWaveIsTyping.
113-154: LGTM! Solid unread divider state management.The unread divider logic is well-implemented with proper state transitions:
- Tracks when new drops arrive while user is scrolled up
- Preserves the divider position at the first unread drop
- Clears the divider when user scrolls back to bottom
- Properly resets on wave or initialDrop changes
The use of refs (
prevLatestSerialNoRef,wasNotAtBottomRef) and functional state updates prevents race conditions, and all effect dependencies are correct.
334-366: LGTM! Clean component composition pattern.The outer wrapper correctly:
- Extracts hook state from
useVirtualizedWaveDrops- Wraps the inner component with
UnreadDividerProvider- Uses a keyed provider (
unread-divider-${waveId}) to ensure clean remounting on wave changes- Delegates all props and hook results to the inner component
This architecture enables proper context isolation and makes the component more testable.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx (1)
4-126: LGTM! Mock enhancements and test coverage are solid.The ES module mock structure (
__esModule: true) correctly handles default exports for Jest. The extendedwindow.matchMediamock withaddEventListener,removeEventListener, anddispatchEventimproves API compatibility. Test cases are independent, deterministic, and properly verify component behavior including reply/reset actions and keyboard-driven padding adjustments.Optional: Consider stronger typing for test data.
While
anytypes are common in tests, you could improve type safety with more specific types or utility types likePick<Wave, 'id'>for test fixtures. This remains a minor, deferrable refinement.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
__tests__/components/waves/drop/SingleWaveDropChat.test.tsxcomponents/brain/my-stream/MyStreamWaveChat.tsxcomponents/waves/drop/SingleWaveDropChat.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- components/waves/drop/SingleWaveDropChat.tsx
- components/brain/my-stream/MyStreamWaveChat.tsx
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version
**/*.{ts,tsx,js,jsx}: Replace<img>elements with<Image />fromnext/imageto satisfy@next/next/no-img-elementESLint rule
Use<Link href="/path">from Next.js for internal navigation instead of plain HTML links to satisfy@next/next/no-html-link-for-pagesESLint rule
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always addreadonlybefore props in React components
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use<Link>, images should usenext/image, and adopt Next's ESLint rules (Core Web Vitals)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Must passtsc --noEmittype checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") overReact.namespace usage (React.useMemo,React.useRef, etc.)
If thereact-hooks/exhaustive-depslint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic inuseEffectEvent
**/*.{ts,tsx}: Must passtsc --noEmitfor TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
UseuseEffectEventfor non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs:<Link>for internal links,next/imagefor images, adopt Next's ESLint rules
Use'use cache'directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace<img>elements with<Image />fromnext/image
Use<Link href="/path">for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with'use server'directive
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/@(__tests__|*.test).{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Tests should live in
__tests__/orComponentName.test.tsx; mock external dependencies and APIs in tests
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Place tests in
__tests__/directory or asComponentName.test.tsxalongside components
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Mock external dependencies and APIs in tests
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use Jest +
ts-jestfor TypeScript testing
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
__tests__/**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (tests/AGENTS.md)
__tests__/**/*.{ts,tsx,js}: Preferfor...ofloops overforEachas it allowsbreak/continueand works with async/await
Usearray.at(-1)andarray.at(-2)instead of index-based array access for negative indexing
UseString.prototype.replaceAll()instead ofreplace()for global string replacements
UseglobalThis.fetch()instead of directfetch()calls
Organize imports with one import per module in order: external → internal → types, with no duplicates
Useelement.remove()instead ofparent.removeChild(element)for DOM manipulation
Catch errors only when meaningful; no empty catch blocks; log errors with context
Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (?.)
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
__tests__/**/{components,contexts,hooks}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use semantic HTML elements (
<label>,<output>) over ARIA attributes when possible; every form control must have a label
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
🧠 Learnings (13)
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/@(__tests__|*.test).{ts,tsx} : Tests should live in `__tests__/` or `ComponentName.test.tsx`; mock external dependencies and APIs in tests
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Organize imports with one import per module in order: external → internal → types, with no duplicates
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.test.{ts,tsx} : Mock external dependencies and APIs in tests
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Test high-risk areas including happy path workflows, invalid input errors, edge cases/boundaries, component & API interactions, and performance/security when relevant
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Use testing-library/react + user-event for React component tests
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/{components,contexts,hooks}/**/*.{ts,tsx} : Use semantic HTML elements (`<label>`, `<output>`) over ARIA attributes when possible; every form control must have a label
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Keep tests independent, deterministic, and fast with production-like data
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Use `String.prototype.replaceAll()` instead of `replace()` for global string replacements
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: TypeScript + React functional components with hooks; follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Test accessibility with keyboard navigation and screen reader compatibility
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
🧬 Code graph analysis (1)
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx (1)
components/waves/drop/SingleWaveDropChat.tsx (1)
SingleWaveDropChat(24-150)
⏰ 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: Analyze (javascript-typescript)
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx (1)
1-2: Reorder imports: external libraries before internal modules.The import order violates the coding guideline. External library imports should precede internal module imports.
Based on learnings, organize imports with one import per module in order: external → internal → types.
🧹 Nitpick comments (4)
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx (4)
11-11: Consider removing the comment for self-explanatory code.The variable names
mockKeyboardVisibleandmockGetContainerStyleclearly indicate the mock's purpose.As per coding guidelines, code should be self-explanatory without comments.
🔎 Proposed change
- -// Mock useAndroidKeyboard with configurable values let mockKeyboardVisible = false;
58-58: Consider removing the comment for self-explanatory code.The mock setup for
globalThis.matchMediais clear from the implementation itself.As per coding guidelines, code should be self-explanatory without comments.
🔎 Proposed change
- -// Mock globalThis.matchMedia for useDeviceInfo hook Object.defineProperty(globalThis, "matchMedia", {
102-102: Consider removing the redundant comment.The test description and assertion already clearly convey that
getContainerStyleshould be called withpaddingBottom: "0px".As per coding guidelines, code should be self-explanatory without comments.
🔎 Proposed change
- // getContainerStyle should have been called with paddingBottom: "0px" expect(mockGetContainerStyle).toHaveBeenCalledWith(
118-118: Consider removing the redundant comment.The test description and assertion already clearly convey that
getContainerStyleshould be called with safe-area-inset-bottom padding.As per coding guidelines, code should be self-explanatory without comments.
🔎 Proposed change
- // getContainerStyle should have been called with paddingBottom: safe-area-inset-bottom expect(mockGetContainerStyle).toHaveBeenCalledWith(
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version
**/*.{ts,tsx,js,jsx}: Replace<img>elements with<Image />fromnext/imageto satisfy@next/next/no-img-elementESLint rule
Use<Link href="/path">from Next.js for internal navigation instead of plain HTML links to satisfy@next/next/no-html-link-for-pagesESLint rule
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always addreadonlybefore props in React components
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use<Link>, images should usenext/image, and adopt Next's ESLint rules (Core Web Vitals)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Must passtsc --noEmittype checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") overReact.namespace usage (React.useMemo,React.useRef, etc.)
If thereact-hooks/exhaustive-depslint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic inuseEffectEvent
**/*.{ts,tsx}: Must passtsc --noEmitfor TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
UseuseEffectEventfor non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs:<Link>for internal links,next/imagefor images, adopt Next's ESLint rules
Use'use cache'directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace<img>elements with<Image />fromnext/image
Use<Link href="/path">for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with'use server'directive
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/@(__tests__|*.test).{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Tests should live in
__tests__/orComponentName.test.tsx; mock external dependencies and APIs in tests
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Place tests in
__tests__/directory or asComponentName.test.tsxalongside components
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Mock external dependencies and APIs in tests
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
__tests__/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use Jest +
ts-jestfor TypeScript testing
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
__tests__/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
__tests__/**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (tests/AGENTS.md)
__tests__/**/*.{ts,tsx,js}: Preferfor...ofloops overforEachas it allowsbreak/continueand works with async/await
Usearray.at(-1)andarray.at(-2)instead of index-based array access for negative indexing
UseString.prototype.replaceAll()instead ofreplace()for global string replacements
UseglobalThis.fetch()instead of directfetch()calls
Organize imports with one import per module in order: external → internal → types, with no duplicates
Useelement.remove()instead ofparent.removeChild(element)for DOM manipulation
Catch errors only when meaningful; no empty catch blocks; log errors with context
Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (?.)
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
__tests__/**/{components,contexts,hooks}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (tests/AGENTS.md)
Use semantic HTML elements (
<label>,<output>) over ARIA attributes when possible; every form control must have a label
Files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
🧠 Learnings (16)
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Avoid double negatives in code; prefer explicit logic and remove redundant annotations; use optional chaining (`?.`)
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Organize imports with one import per module in order: external → internal → types, with no duplicates
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/@(__tests__|*.test).{ts,tsx} : Tests should live in `__tests__/` or `ComponentName.test.tsx`; mock external dependencies and APIs in tests
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/{components,contexts,hooks}/**/*.{ts,tsx} : Use semantic HTML elements (`<label>`, `<output>`) over ARIA attributes when possible; every form control must have a label
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : Test high-risk areas including happy path workflows, invalid input errors, edge cases/boundaries, component & API interactions, and performance/security when relevant
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.test.{ts,tsx} : Mock external dependencies and APIs in tests
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Use testing-library/react + user-event for React component tests
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx,js} : Use `String.prototype.replaceAll()` instead of `replace()` for global string replacements
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/components/**/*.test.{ts,tsx} : Test accessibility with keyboard navigation and screen reader compatibility
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-11-25T08:35:58.729Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T08:35:58.729Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Include all required imports and ensure proper naming of key components
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Applies to **/*.{ts,tsx} : Prefer direct named imports for React hooks and types (`import { useMemo, useRef, FC, etc. } from "react"`) over `React.` namespace usage (`React.useMemo`, `React.useRef`, etc.)
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: TypeScript + React functional components with hooks; follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/*.{ts,tsx} : Functions must have ≤ 15 cognitive complexity; extract deep ternaries (>3 levels) and break down complex logic
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:43.476Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: __tests__/AGENTS.md:0-0
Timestamp: 2025-12-05T10:55:43.476Z
Learning: Applies to __tests__/**/__tests__/**/*.test.{ts,tsx,js} : All tests must live in `__tests__`, mirroring source folders (`components`, `contexts`, `hooks`, `utils`)
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks
Applied to files:
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx
🧬 Code graph analysis (1)
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx (1)
components/waves/drop/SingleWaveDropChat.tsx (1)
SingleWaveDropChat(24-150)
⏰ 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: Analyze (javascript-typescript)
🔇 Additional comments (10)
__tests__/components/waves/drop/SingleWaveDropChat.test.tsx (10)
4-9: LGTM!The mock setup for
useCapacitorandLayoutContextis clean and correctly structured.
15-22: LGTM!The
useAndroidKeyboardmock correctly implements all required properties with configurable test values.
24-32: LGTM!The
wave-drops-allmock correctly uses ES module format and captures props for test inspection.
34-39: LGTM!The
CreateDropWaveWrappermock correctly exports both the component and context with appropriate test structure.
41-56: LGTM!The
PrivilegedDropCreatormock properly uses ES module format and exposes props through data attributes for test verification.
59-71: LGTM!The
globalThis.matchMediamock comprehensively implements the MediaQueryList interface with all necessary methods.
73-79: LGTM!The test setup properly resets mock state in
beforeEachto ensure test isolation.
80-93: LGTM!The test correctly verifies reply and reset actions using captured props and data attribute assertions.
95-109: LGTM!The test correctly verifies that keyboard visibility applies zero padding to the container.
111-125: LGTM!The test correctly verifies that when the keyboard is hidden, safe-area-inset-bottom padding is applied.
Signed-off-by: prxt6529 <prxt@6529.io>
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
__tests__/components/waves/drop/SingleWaveDropChat.test.tsxcomponents/waves/drop/SingleWaveDropChat.tsxcomponents/waves/drops/WaveDropActions.tsxcomponents/waves/drops/WaveDropActionsOptions.tsxcomponents/waves/drops/WaveDropMobileMenu.tsxcomponents/waves/drops/wave-drops-all/index.tsxcomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsContent.tsxcomponents/waves/drops/wave-drops-all/subcomponents/WaveDropsMessageListSection.tsx
🚧 Files skipped from review as they are similar to previous changes (5)
- components/waves/drops/WaveDropActionsOptions.tsx
- components/waves/drops/wave-drops-all/subcomponents/WaveDropsMessageListSection.tsx
- tests/components/waves/drop/SingleWaveDropChat.test.tsx
- components/waves/drops/WaveDropActions.tsx
- components/waves/drops/wave-drops-all/subcomponents/WaveDropsContent.tsx
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx,js,jsx}: Do not include any comments in the code; it should be self-explanatory
Write correct, up-to-date, bug-free, fully componentized, secure, and efficient code
Include all required imports and ensure proper naming of key components
Use NextJS features that match the current version
**/*.{ts,tsx,js,jsx}: Replace<img>elements with<Image />fromnext/imageto satisfy@next/next/no-img-elementESLint rule
Use<Link href="/path">from Next.js for internal navigation instead of plain HTML links to satisfy@next/next/no-html-link-for-pagesESLint rule
Files:
components/waves/drops/WaveDropMobileMenu.tsxcomponents/waves/drops/wave-drops-all/index.tsxcomponents/waves/drop/SingleWaveDropChat.tsx
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{tsx,jsx}: Use FontAwesome for icons in React components
Use TailwindCSS for styling in React components
Use react-query for data fetching
Always addreadonlybefore props in React components
Files:
components/waves/drops/WaveDropMobileMenu.tsxcomponents/waves/drops/wave-drops-all/index.tsxcomponents/waves/drop/SingleWaveDropChat.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks)
Use framework APIs: internal links should use<Link>, images should usenext/image, and adopt Next's ESLint rules (Core Web Vitals)
**/*.{js,jsx,ts,tsx}: Code must satisfy ESLint (Next's Core Web Vitals + React Hooks rules)
Follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Files:
components/waves/drops/WaveDropMobileMenu.tsxcomponents/waves/drops/wave-drops-all/index.tsxcomponents/waves/drop/SingleWaveDropChat.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Must passtsc --noEmittype checking
Prefer direct named imports for React hooks and types (import { useMemo, useRef, FC, etc. } from "react") overReact.namespace usage (React.useMemo,React.useRef, etc.)
If thereact-hooks/exhaustive-depslint rule is triggered: if the Effect only derives state, remove the Effect and compute during render; if listening to an external system and needing fresh props/state, wrap non-reactive logic inuseEffectEvent
**/*.{ts,tsx}: Must passtsc --noEmitfor TypeScript type checking
Prefer Server Components over Client Components; use Server Functions/Server Actions ('use server') for mutations
Remove unnecessary Effects; if Effect only derives state, compute during render instead
UseuseEffectEventfor non-reactive logic inside Effects to avoid unnecessary re-runs
Use framework APIs:<Link>for internal links,next/imagefor images, adopt Next's ESLint rules
Use'use cache'directive and Cache Components features for explicit opt-in caching in Next.js 16
Use TypeScript and React functional components with hooks
When parsing Seize URLs or similar, fail fast if base origin is unavailable; do not fall back to placeholder origins
Replace<img>elements with<Image />fromnext/image
Use<Link href="/path">for internal navigation instead of plain HTML links
Move data fetches to Server Components; handle mutations through Server Functions/Server Actions with'use server'directive
Files:
components/waves/drops/WaveDropMobileMenu.tsxcomponents/waves/drops/wave-drops-all/index.tsxcomponents/waves/drop/SingleWaveDropChat.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: Fix with modernization (no `// eslint-disable` unless explicitly instructed); prefer refactors aligned with React 19.2, React Compiler, and Next.js 16 conventions
Applied to files:
components/waves/drops/WaveDropMobileMenu.tsxcomponents/waves/drops/wave-drops-all/index.tsx
📚 Learning: 2025-12-05T10:55:30.871Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-05T10:55:30.871Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript and React functional components with hooks
Applied to files:
components/waves/drops/WaveDropMobileMenu.tsxcomponents/waves/drops/wave-drops-all/index.tsx
📚 Learning: 2025-12-03T14:52:34.271Z
Learnt from: CR
Repo: 6529-Collections/6529seize-frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-03T14:52:34.271Z
Learning: TypeScript + React functional components with hooks; follow existing code style and naming conventions; maintain clean code standards (measured by SonarQube)
Applied to files:
components/waves/drops/WaveDropMobileMenu.tsxcomponents/waves/drops/wave-drops-all/index.tsx
🧬 Code graph analysis (2)
components/waves/drops/WaveDropMobileMenu.tsx (1)
components/waves/drops/WaveDropActionsMarkUnread.tsx (1)
WaveDropActionsMarkUnread(22-151)
components/waves/drops/wave-drops-all/index.tsx (6)
hooks/useVirtualizedWaveDrops.ts (1)
useVirtualizedWaveDrops(17-91)__mocks__/react-use.js (1)
React(2-2)contexts/wave/UnreadDividerContext.tsx (2)
useUnreadDivider(46-54)UnreadDividerProvider(23-44)hooks/useWaveIsTyping.ts (1)
useWaveIsTyping(63-139)components/waves/drops/wave-drops-all/hooks/useWaveDropsSerialScroll.ts (1)
useWaveDropsSerialScroll(38-287)helpers/waves/wave.helpers.ts (1)
isWaveDirectMessage(15-25)
⏰ 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: Analyze (javascript-typescript)
🔇 Additional comments (4)
components/waves/drops/WaveDropMobileMenu.tsx (2)
3-4: LGTM! Import organization is clean.The import statements are properly organized and all imports are utilized within the component. The addition of
WaveDropActionsMarkUnreadsupports the new mark-as-unread functionality.Also applies to: 8-8, 10-11, 13-13
249-253: LGTM! Mark-as-unread integration is correct.The
WaveDropActionsMarkUnreadcomponent is properly integrated with the correct props:
dropprovides the necessary drop dataisMobile={true}matches the mobile menu contextonMarkUnread={closeMenu}ensures the menu closes after the action completesThe component handles its own visibility logic (returning null for authors or when no profile is connected), so no parent-level conditional is needed.
components/waves/drop/SingleWaveDropChat.tsx (1)
101-101: LGTM! Correct mute state propagation.The addition correctly passes the wave's mute state to WaveDropsAll using safe navigation and an appropriate fallback.
components/waves/drops/wave-drops-all/index.tsx (1)
124-163: LGTM! Well-structured unread divider state management.The logic correctly handles:
- Resetting state when wave or initial drop changes
- Setting the divider when new messages arrive while scrolled up
- Clearing the divider when the user scrolls back to the bottom
The use of refs to track previous state and scroll position is appropriate.
|



Summary by CodeRabbit
New Features
Improvements
API
Tests
✏️ Tip: You can customize this high-level summary in your review settings.