Skip to content

Boosted notification#1740

Merged
simo6529 merged 3 commits intomainfrom
boosted-notification
Jan 14, 2026
Merged

Boosted notification#1740
simo6529 merged 3 commits intomainfrom
boosted-notification

Conversation

@simo6529
Copy link
Copy Markdown
Collaborator

@simo6529 simo6529 commented Jan 14, 2026

Summary by CodeRabbit

  • New Features

    • Boosted drop notifications now appear in your notification feed with a distinctive visual indicator and timestamp for easy identification.
    • Added a new "boosted drops" filter option to help you customize which notification types you see.
  • Refactor

    • Optimized the notifications interface for improved performance and responsive UI behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
Signed-off-by: Simo <simo@6529.io>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

This pull request adds support for a new "DropBoosted" notification type across the notification system. Changes include adding the new cause to the API schema and enum, creating corresponding TypeScript type definitions, wiring it through notification components (NotificationItem, NotificationItems, NotificationDropReacted), updating filter options, and refactoring NotificationsCauseFilter to use direct DOM manipulation for highlight positioning with ResizeObserver support.

Changes

Cohort / File(s) Summary
Notification Type Definitions
types/feed.types.ts, openapi.yaml
Added new INotificationDropBoosted type with id, cause, created_at, read_at, related_identity, related_drops, and additional_context fields. Extended TypedNotification union and added new ApiMintMetrics and ApiMintMetricsPage schemas to OpenAPI spec. Added DROP_BOOSTED to ApiNotificationCause enum.
Notification Component Wiring
components/brain/notifications/NotificationItem.tsx, NotificationItems.tsx
Added case handling for ApiNotificationCause.DropBoosted in NotificationItem switch, mapping to NotificationDropReacted component. Updated imports in NotificationItems to include DropInteractionParams and ExtendedDrop types with import reordering.
Notification Drop Reacted Display
components/brain/notifications/drop-reacted/NotificationDropReacted.tsx
Extended NotificationUnion type to include INotificationDropBoosted. Replaced previous type-guard logic with cause-based checks using ApiNotificationCause. Added new boosted branch rendering "🔥 boosted 🔥" indicator with timestamp. Simplified vote data access and adjusted CSS class ordering.
Notification Cause Filter & Priority
components/brain/notifications/NotificationsCauseFilter.tsx, index.tsx
Added DropBoosted to Reactions filter. Refactored highlight tracking from React state to direct DOM updates using highlightRef and activeIndexRef with ResizeObserver for layout changes. Added hover-based prefetching gated by authentication context. Reworked priority mapping: DropBoosted:5, DropReacted:6, WaveCreated:7, AllDrops:8, PriorityAlert:9.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • ragnep
  • prxt6529
  • GelatoGenesis

Poem

🐰 A boost for our drops, flames dancing bright,
New notifications flutter into sight,
With filters refined and priorities set,
The notifications system's better yet! 🔥

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title "Boosted notification" directly corresponds to the main changes in the PR, which add support for a new DropBoosted notification type throughout the codebase.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

❤️ Share

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

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@openapi.yaml`:
- Around line 7425-7455: The ApiMintMetrics schema uses invalid OpenAPI types
(type: number with format: int64) for integer fields; update each property in
ApiMintMetrics (card, mint_time, subscriptions, mints) to use type: integer and
keep format: int64 (or remove format if you prefer plain integers), ensuring
ApiMintMetricsPage continues to reference ApiMintMetrics unchanged; this will
make the schema OpenAPI-compliant and compatible with strict validators and
codegen.
🧹 Nitpick comments (3)
types/feed.types.ts (1)

77-85: Avoid Record<string, any> for additional_context; prefer unknown (or a typed shape).

If the payload is truly opaque, Record<string, unknown> is safer; otherwise define explicit fields (even if optional) so UI handling can stay type-safe.

Proposed fix
 export type INotificationDropBoosted = {
   readonly id: number;
   readonly cause: ApiNotificationCause.DropBoosted;
   readonly created_at: number;
   readonly read_at: number | null;
   readonly related_identity: ApiProfileMin;
   readonly related_drops: Array<ApiDrop>;
-  readonly additional_context: Record<string, any>;
+  readonly additional_context: Record<string, unknown>;
 };
components/brain/notifications/drop-reacted/NotificationDropReacted.tsx (1)

54-61: Type narrowing relies on correct conditional guards.

The cause-based checks using ApiNotificationCause enum values are cleaner than string-based checks. TypeScript should narrow the notification type within each branch, allowing safe access to additional_context.vote when isVoted is true.

However, since isVoted, isReacted, and isBoosted are separate boolean variables rather than inline checks, TypeScript may not narrow the union type automatically. Consider using inline checks or type guards for stronger type safety:

💡 Optional: Use inline checks for better type narrowing
-  const isVoted = notification.cause === ApiNotificationCause.DropVoted;
-  const isReacted = notification.cause === ApiNotificationCause.DropReacted;
-  const isBoosted = notification.cause === ApiNotificationCause.DropBoosted;
-
   let actionElement: React.ReactNode = null;
 
-  if (isVoted) {
-    const voteValue = notification.additional_context.vote;
+  if (notification.cause === ApiNotificationCause.DropVoted) {
+    const voteValue = notification.additional_context.vote;
     // ... rest of voted branch
-  } else if (isBoosted) {
+  } else if (notification.cause === ApiNotificationCause.DropBoosted) {
     // ... boosted branch
-  } else if (isReacted) {
-    const rawId = notification.additional_context.reaction.replaceAll(":", "");
+  } else if (notification.cause === ApiNotificationCause.DropReacted) {
+    const rawId = notification.additional_context.reaction.replaceAll(":", "");
     // ... rest of reacted branch
components/brain/notifications/NotificationsCauseFilter.tsx (1)

148-150: Avoid non-null assertion on ref callback.

The el! non-null assertion is unsafe because React passes null to ref callbacks when elements unmount. While this may work in practice because the array isn't accessed after unmount, it's cleaner to guard against null:

💡 Suggested fix
-            buttonRef={(el) => (buttonRefs.current[index] = el!)}
+            buttonRef={(el) => {
+              if (el) buttonRefs.current[index] = el;
+            }}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db5f95c and bb8eb91.

⛔ Files ignored due to path filters (1)
  • generated/models/ApiNotificationCause.ts is excluded by !**/generated/**
📒 Files selected for processing (7)
  • components/brain/notifications/NotificationItem.tsx
  • components/brain/notifications/NotificationItems.tsx
  • components/brain/notifications/NotificationsCauseFilter.tsx
  • components/brain/notifications/drop-reacted/NotificationDropReacted.tsx
  • components/brain/notifications/index.tsx
  • openapi.yaml
  • types/feed.types.ts
🧰 Additional context used
🧬 Code graph analysis (2)
types/feed.types.ts (3)
generated/models/ApiProfileMin.ts (1)
  • ApiProfileMin (17-150)
generated/models/ApiDrop.ts (1)
  • ApiDrop (29-244)
generated/models/ApiNotificationsResponse.ts (1)
  • ApiNotificationsResponse (17-45)
components/brain/notifications/drop-reacted/NotificationDropReacted.tsx (3)
types/feed.types.ts (3)
  • INotificationDropVoted (53-63)
  • INotificationDropReacted (65-75)
  • INotificationDropBoosted (77-85)
helpers/Helpers.ts (1)
  • numberWithCommas (114-131)
components/brain/notifications/subcomponents/NotificationTimestamp.tsx (1)
  • NotificationTimestamp (7-18)
⏰ 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 (12)
openapi.yaml (1)

7701-7713: ApiNotificationCause + DROP_BOOSTED looks consistent with existing enum style.

types/feed.types.ts (2)

149-159: Nice: TypedNotification now covers INotificationDropBoosted.

This keeps downstream switch rendering strongly typed.


161-166: TypedNotificationsResponse wrapper is a clean way to re-type notifications.

components/brain/notifications/NotificationItem.tsx (1)

53-56: DropBoosted routing via NotificationDropReacted is correct with full prop-type coverage.

The NotificationDropReacted component imports INotificationDropBoosted, includes it in the NotificationUnion type, and explicitly handles the boosted case (line 56: const isBoosted = notification.cause === ApiNotificationCause.DropBoosted;). All DropBoosted enum usage is consistent across the codebase.

components/brain/notifications/NotificationItems.tsx (1)

1-6: LGTM!

The import reordering places type imports before runtime imports, which is a good practice for code organization. No functional changes to the component logic.

components/brain/notifications/index.tsx (2)

16-27: LGTM!

The priority mapping correctly integrates DropBoosted with a sensible priority value (5) between DropVoted (4) and DropReacted (6). All enum values are accounted for with consecutive priorities.


74-89: LGTM!

The structural and styling updates improve the layout consistency. The WebkitOverflowScrolling: "touch" style is a good addition for smoother scrolling on iOS devices.

components/brain/notifications/drop-reacted/NotificationDropReacted.tsx (2)

79-87: LGTM!

The boosted notification UI follows the established pattern of other notification types, with a descriptive label and timestamp. The "🔥 boosted 🔥" visual indicator is clear and consistent with the notification styling.


30-33: LGTM!

The NotificationUnion type correctly includes INotificationDropBoosted alongside the existing voted and reacted types, ensuring type safety for the component's props.

components/brain/notifications/NotificationsCauseFilter.tsx (3)

25-29: LGTM!

Adding DropBoosted to the Reactions filter alongside DropVoted and DropReacted is semantically appropriate, as boosting is a form of positive reaction to content.


80-100: LGTM with a minor observation.

The useLayoutEffect with ResizeObserver is well-implemented for handling layout shifts during resize, font loading, etc. The cleanup properly disconnects the observer.

Note: The effect has activeFilter in its dependency array but also references updateHighlightPosition which closes over buttonRefs and highlightRef. Since these are stable refs, this is fine, but if updateHighlightPosition were to change, it would need to be added to dependencies.


59-78: Direct DOM manipulation is appropriate here.

The switch from React state to direct DOM manipulation for the highlight animation is a valid optimization—it avoids re-renders during animation transitions. The edge-case adjustments for first/last buttons (lines 66-72) handle the border spacing correctly.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread openapi.yaml
@simo6529 simo6529 merged commit 2e21ea1 into main Jan 14, 2026
7 checks passed
@simo6529 simo6529 deleted the boosted-notification branch January 14, 2026 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants