Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughAdds curation-wave awareness across brain UI and tests, implements curation-based NFT preview selection and MIME inference for My Votes, consolidates ProfileRatersParams into ReactQueryWrapper, and removes the Profile Raters table suite and several small UI helper components/types. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
components/brain/my-stream/votes/MyStreamWaveMyVote.tsx (1)
257-270:⚠️ Potential issue | 🟡 MinorAuthor link text is empty when
handleis null.Line 258/263 correctly falls back to
primary_addressfor thehrefandwindow.open, but Line 269 renders only{drop.author.handle}— which would be empty/invisible if the author has no handle.🔧 Suggested fix
- {drop.author.handle} + {drop.author.handle ?? drop.author.primary_address}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/brain/my-stream/votes/MyStreamWaveMyVote.tsx` around lines 257 - 270, The link text currently renders only drop.author.handle which will be empty when handle is null; update the JSX in MyStreamWaveMyVote so the displayed text uses the same fallback as the href/window.open (e.g., replace the rendered expression drop.author.handle with drop.author.handle ?? drop.author.primary_address) so the primary address is shown when handle is absent; keep the existing Link href and window.open logic and class names unchanged.
🧹 Nitpick comments (3)
components/react-query-wrapper/ReactQueryWrapper.tsx (1)
800-803: Prefer simpler null guard;oldData.pagesitself is unguarded.
typeof oldData?.pages.length !== "number"only short-circuits onoldDatabeing nullish (via?.). IfoldDatais defined butoldData.pagesis somehowundefined/nullat runtime, accessing.lengthon it would still throw aTypeError— the optional chain doesn't protect that step.Additionally,
Array.prototype.lengthalways returns anumber, so thetypeofcheck adds no practical coverage over a simple!oldData, making the condition more verbose without extra safety.♻️ Suggested simplification
- if ( - typeof oldData?.pages.length !== "number" || - oldData.pages.length === 0 - ) { + if (!oldData?.pages?.length) {Or equivalently, for explicit clarity:
- if ( - typeof oldData?.pages.length !== "number" || - oldData.pages.length === 0 - ) { + if (!oldData || oldData.pages.length === 0) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/react-query-wrapper/ReactQueryWrapper.tsx` around lines 800 - 803, The condition in ReactQueryWrapper.tsx that reads `typeof oldData?.pages.length !== "number" || oldData.pages.length === 0` is unsafe because it can access `.length` on an undefined `oldData.pages` and the typeof check is redundant; change the guard to directly ensure pages is an array (or at least defined) before checking length — e.g., replace the condition with a simple explicit guard like `!oldData?.pages || oldData.pages.length === 0` or use `!Array.isArray(oldData?.pages) || oldData.pages.length === 0` so `oldData.pages` is safely checked before accessing `.length`.components/brain/mobile/BrainMobileTabs.tsx (1)
102-104: Pre-existing typo:otucomeButtonTextClassesshould beoutcomeButtonTextClasses.Not introduced in this PR, but worth noting if you're touching this area.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/brain/mobile/BrainMobileTabs.tsx` around lines 102 - 104, Fix the misspelled variable name otucomeButtonTextClasses by renaming it to outcomeButtonTextClasses wherever it’s declared and referenced (e.g., in BrainMobileTabs.tsx where the const is defined and any JSX or helper functions that consume it), ensuring imports/exports and any related props or state names are updated to match the new spelling so no references break.components/brain/my-stream/MyStreamWaveDesktopTabs.tsx (1)
188-196: Minor: contradictory optional chain + non-null assertion.Line 194 uses
options[0]?.key!— the?.and!contradict each other. Sinceoptions.length > 0is already checked,options[0].keysuffices.🔧 Suggested simplification
- setActiveTab(options[0]?.key!); + setActiveTab(options[0].key);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/brain/my-stream/MyStreamWaveDesktopTabs.tsx` around lines 188 - 196, The conditional uses a contradictory optional chain and non-null assertion in the useEffect when calling setActiveTab with options[0]?.key! — since you already check options.length > 0, replace the expression with the non-optional property access (options[0].key) to remove the unnecessary ?. and !; update the useEffect block that defines isMyVotesHidden/isFaqHidden and calls setActiveTab to use options[0].key instead.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@__tests__/components/brain/my-stream/votes/MyStreamWaveMyVote.test.tsx`:
- Around line 46-56: The test fixture `drop` used in MyStreamWaveMyVote.test.tsx
is missing the top_raters property which causes MyStreamWaveMyVote.tsx (which
calls drop.top_raters.slice(0, 3)) to throw; fix by adding a top_raters array to
the `drop` object in the test (e.g., top_raters: [] or an array of the same
rater objects the component expects) so slice can be called safely, or
alternatively adjust the fixture to include the expected rater shape used by
MyStreamWaveMyVote.
In `@components/brain/my-stream/votes/MyStreamWaveMyVote.tsx`:
- Around line 284-286: The React key for the top-raters list uses
voter.profile.handle which can be null and the tooltip also renders
voter.profile.handle without a fallback; update the map key in
MyStreamWaveMyVote (the slice/map that iterates drop.top_raters) to use a
guaranteed unique identifier such as voter.profile.id or
voter.profile.primary_address (e.g., key={voter.profile.id ||
voter.profile.primary_address}) and change the tooltip/label rendering (where
{voter.profile.handle} is used) to provide a safe fallback like
voter.profile.handle || voter.profile.primary_address || 'Unknown user' so
null/undefined handles don’t produce duplicate keys or show "null".
- Around line 144-150: The curation check can fail due to case differences:
update the isCurationWave call in the curationPreviewMedia useMemo to pass a
normalized ID (e.g., call isCurationWave(drop.wave.id.toLowerCase())) and update
the dependency array accordingly (use drop.wave.id and/or its lowercased form)
so the memo and resolveCurationPreviewMedia logic use a case-insensitive
comparison; alternatively ensure isCurationWave itself normalizes its input, but
in this file adjust the isCurationWave invocation to use .toLowerCase() to match
other usages.
---
Outside diff comments:
In `@components/brain/my-stream/votes/MyStreamWaveMyVote.tsx`:
- Around line 257-270: The link text currently renders only drop.author.handle
which will be empty when handle is null; update the JSX in MyStreamWaveMyVote so
the displayed text uses the same fallback as the href/window.open (e.g., replace
the rendered expression drop.author.handle with drop.author.handle ??
drop.author.primary_address) so the primary address is shown when handle is
absent; keep the existing Link href and window.open logic and class names
unchanged.
---
Nitpick comments:
In `@components/brain/mobile/BrainMobileTabs.tsx`:
- Around line 102-104: Fix the misspelled variable name otucomeButtonTextClasses
by renaming it to outcomeButtonTextClasses wherever it’s declared and referenced
(e.g., in BrainMobileTabs.tsx where the const is defined and any JSX or helper
functions that consume it), ensuring imports/exports and any related props or
state names are updated to match the new spelling so no references break.
In `@components/brain/my-stream/MyStreamWaveDesktopTabs.tsx`:
- Around line 188-196: The conditional uses a contradictory optional chain and
non-null assertion in the useEffect when calling setActiveTab with
options[0]?.key! — since you already check options.length > 0, replace the
expression with the non-optional property access (options[0].key) to remove the
unnecessary ?. and !; update the useEffect block that defines
isMyVotesHidden/isFaqHidden and calls setActiveTab to use options[0].key
instead.
In `@components/react-query-wrapper/ReactQueryWrapper.tsx`:
- Around line 800-803: The condition in ReactQueryWrapper.tsx that reads `typeof
oldData?.pages.length !== "number" || oldData.pages.length === 0` is unsafe
because it can access `.length` on an undefined `oldData.pages` and the typeof
check is redundant; change the guard to directly ensure pages is an array (or at
least defined) before checking length — e.g., replace the condition with a
simple explicit guard like `!oldData?.pages || oldData.pages.length === 0` or
use `!Array.isArray(oldData?.pages) || oldData.pages.length === 0` so
`oldData.pages` is safely checked before accessing `.length`.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
__tests__/components/brain/BrainMobile.test.tsx__tests__/components/brain/mobile/BrainMobileTabs.test.tsx__tests__/components/brain/my-stream/MyStreamWaveDesktopTabs.test.tsx__tests__/components/brain/my-stream/votes/MyStreamWaveMyVote.test.tsxcomponents/brain/BrainMobile.tsxcomponents/brain/mobile/BrainMobileTabs.tsxcomponents/brain/my-stream/MyStreamWaveDesktopTabs.tsxcomponents/brain/my-stream/votes/MyStreamWaveMyVote.tsxcomponents/profile-activity/ProfileName.tsxcomponents/react-query-wrapper/ReactQueryWrapper.tsxcomponents/user/rep/new-rep/UserPageRepNewRepSearchHeader.tsxcomponents/user/utils/UserTableHeaderWrapper.tsxcomponents/user/utils/raters-table/ProfileRatersTable.tsxcomponents/user/utils/raters-table/ProfileRatersTableBody.tsxcomponents/user/utils/raters-table/ProfileRatersTableHeader.tsxcomponents/user/utils/raters-table/ProfileRatersTableHeaderSortableCell.tsxcomponents/user/utils/raters-table/ProfileRatersTableItem.tsxcomponents/user/utils/raters-table/wrapper/ProfileRatersTableWrapper.tsxcomponents/user/utils/raters-table/wrapper/ProfileRatersTableWrapperHeader.tsxcomponents/utils/CommonFilterTargetSelect.tsxcomponents/utils/table/CommonTableWrapper.tsxhelpers/server.helpers.tstypes/enums.ts
💤 Files with no reviewable changes (14)
- types/enums.ts
- helpers/server.helpers.ts
- components/user/utils/raters-table/ProfileRatersTableHeaderSortableCell.tsx
- components/utils/CommonFilterTargetSelect.tsx
- components/user/utils/raters-table/wrapper/ProfileRatersTableWrapperHeader.tsx
- components/profile-activity/ProfileName.tsx
- components/user/utils/raters-table/ProfileRatersTableBody.tsx
- components/user/utils/raters-table/ProfileRatersTableItem.tsx
- components/user/utils/raters-table/ProfileRatersTable.tsx
- components/user/utils/raters-table/ProfileRatersTableHeader.tsx
- components/user/utils/UserTableHeaderWrapper.tsx
- components/user/utils/raters-table/wrapper/ProfileRatersTableWrapper.tsx
- components/utils/table/CommonTableWrapper.tsx
- components/user/rep/new-rep/UserPageRepNewRepSearchHeader.tsx
|

Summary by CodeRabbit
New Features
Improvements
Removals