Skip to content

feat(notifications): sync filter tabs and push toggles across all types#3363

Merged
feruzm merged 4 commits into
developmentfrom
feature/notification-types-sync
Jul 22, 2026
Merged

feat(notifications): sync filter tabs and push toggles across all types#3363
feruzm merged 4 commits into
developmentfrom
feature/notification-types-sync

Conversation

@feruzm

@feruzm feruzm commented Jul 22, 2026

Copy link
Copy Markdown
Member

Companion to ecency/vision-next#1229, which does the same for web.

Notification types were exposed inconsistently on mobile:

Type Renders Filter tab Push toggle
replies, mentions, rvotes, follows yes yes yes
reblogs, transfers, nfavorites, nbookmarks yes no yes
scheduled_published yes no yes
delegations yes no (enum only) no
payouts, account_update, weekly_earnings yes no no

The filter bar offered 5 of the 10 enum values. This adds the missing filter entries and push toggles so every type the feed renders can also be filtered and muted.

Notes

  • notifyTypesConst values are enotify's ACTIVITY_MAIN_TYPE_* ints, validated server-side at device registration. Payouts is 19 — 16 is commented out upstream and must not be reused. The map is duplicated across loginContainer, settingsContainer and applicationContainer, so all three are updated together (note applicationContainer keys on the full *Notification name while the other two use the short name).
  • The account_updates filter path is plural while the notification type string is account_update (singular). enotify routes on the plural.

Filter labels moved to their own namespace

Labels previously came from notification.<key>, which for the newer types holds the notification body string — payouts is "Payout received: ${amount}" and delegations is "delegated". Reusing those would have rendered template text in the dropdown, so labels now live under notification.filters.*.

Defaults

Follows the existing convention rather than leaving the new toggles off: initialState: true plus a v21 migration backfilling the four keys, exactly as v20 did for scheduledPublished. autoMergeLevel1 keeps persisted notificationDetails as-is on rehydration, so a new key is never defaulted from initialState without a migration.

This means existing users start receiving delegation, payout, account-update and weekly-earnings pushes after upgrading. That is deliberate and matches how every other mobile notification type behaves, but it is the reviewable decision in this PR.

Verification

  • eslint on all touched paths: 0 errors
  • Full suite: 43 suites / 663 tests pass, including 3 new v21 migration tests (defaults ON when missing, preserves explicit false, no-op when notificationDetails absent)
  • Both new filter paths return live data end to end: /api/weekly_earnings/<user>type: weekly_earnings, /api/account_updates/<user>type: account_update

The api-proxy allowlist entries these filters depend on were added separately; without them the new tabs would return empty.

Summary by CodeRabbit

  • New Features
    • Added new notification filters and settings for delegations, payouts, scheduled posts, account updates, and weekly earnings.
    • Added corresponding push notification toggles on the settings screen.
  • Bug Fixes
    • Updated notification filter display text to use the correct localized labels.
    • Improved foreground notification handling for the new notification types to ensure consistent unread-activity updates and titles/bodies.
  • Chores
    • Extended persisted notification preferences with a new default migration (new toggles default to enabled when missing) and added test coverage.

Notification types were exposed inconsistently: the filter bar offered 5
of the 10 enum values, and push toggles covered 9 types while delegations,
payouts, account_update and weekly_earnings had none.

Add the missing filter entries and push toggles so every type that the
notifications feed renders can also be filtered and muted.

notifyTypesConst values are enotify's ACTIVITY_MAIN_TYPE_* ints, validated
server-side at device registration; payouts is 19 (16 is retired upstream
and must not be reused). The map is duplicated in three containers, so all
three are updated together.

Filter labels move to their own notification.filters.* namespace. They
previously reused notification.<key>, which for the newer types holds the
notification BODY string - payouts is "Payout received: ${amount}" and
delegations is "delegated", so reusing them would render template text in
the dropdown.

Defaults follow the existing mobile convention: initialState true plus a
v21 migration backfilling the four keys for existing installs, exactly as
v20 did for scheduledPublished. autoMergeLevel1 keeps persisted
notificationDetails as-is, so a new key is never defaulted from
initialState without a migration.
@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown

Greptile Summary

This PR makes notification filters and push settings consistent across supported notification types. The main changes are:

  • Adds missing filter tabs and dedicated English filter labels.
  • Adds push toggles, Redux state, and registration mappings for four notification types.
  • Adds a persistence migration that enables the new preferences when absent.
  • Extends foreground notification handling and unread-count updates.
  • Updates the Ecency SDK dependency.

Confidence Score: 5/5

This looks safe to merge.

  • The new toggle actions now follow the complete settings, Redux, and registration path.
  • The migration preserves explicit disabled preferences.
  • No distinct blocking issue remains in the updated code.

Important Files Changed

Filename Overview
src/components/notification/view/notificationView.tsx Adds the missing filters and reads their labels from the dedicated filter namespace.
src/screens/settings/screen/settingsScreen.tsx Adds toggles for delegation, payout, account-update, and weekly-earnings notifications.
src/screens/settings/container/settingsContainer.tsx Routes the new toggle actions through notification updates and device registration.
src/redux/reducers/applicationReducer.ts Adds defaults and reducer handling for the four new notification preferences.
src/utils/migrationHelpers.ts Backfills missing notification preferences while preserving explicit disabled values.
src/screens/application/container/applicationContainer.tsx Handles the new foreground notification types and includes them in device registration.

Reviews (4): Last reviewed commit: "chore(deps): bump @ecency/sdk to 2.3.61" | Re-trigger Greptile

title={intl.formatMessage({
id: 'settings.notification.delegations',
})}
type="toggle"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 New Toggles Skip Update Path

When a user changes any of the four new toggles, its action type reaches _handleToggleChanged, which has no matching case and falls through to default. _handleNotification never runs, so Redux and device registration remain unchanged and the toggle snaps back.

Fix in Claude Code

dropdownIconName="arrow-drop-down"
options={FILTERS.map((item) =>
intl.formatMessage({ id: `notification.${item.key}` }).toUpperCase(),
intl.formatMessage({ id: `notification.filters.${item.key}` }).toUpperCase(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Translated Labels Lose Their Fallback

This lookup moves every filter label to notification.filters.*, but only the English locale defines that namespace. With another supported locale selected, these calls have no defaultMessage, so the filter bar can display uppercased message IDs such as NOTIFICATION.FILTERS.REPLIES instead of readable labels.

Fix in Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6a2984323a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

id: 'settings.notification.delegations',
})}
type="toggle"
actionType="notification.delegations"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Wire new notification toggles through the settings handler

When a user changes this new toggle (and the three new toggles that follow), SettingsItem passes the actionType to handleOnChange, but SettingsContainer._handleToggleChanged only forwards notification action types through notification.scheduledPublished; notification.delegations, notification.payouts, notification.accountUpdate, and notification.weeklyEarnings all fall through the default case. In that scenario no Redux action is dispatched and _setPushToken is never called, so users cannot actually mute these newly added push types from Settings.

Useful? React with 👍 / 👎.

_handleToggleChanged switches on actionType and only forwarded the
pre-existing notification.* cases, so the four new toggles fell through to
default: no Redux action dispatched, _setPushToken never called, and the
switch snapped back with nothing persisted.

Add the four action types to the notification case group.
@feruzm

feruzm commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

Triaged both P1s.

Toggles skip the update path — confirmed and fixed in da42a52. _handleToggleChanged switches on actionType and only forwarded the pre-existing notification.* cases, so all four new toggles hit default: no Redux dispatch, _setPushToken never called, switch snaps back. Added them to the case group.

Translated labels lose their fallback — not reproducible, declining. src/index.tsx:30 builds the message table as an en-US underlay:

messages={{ ...flattenMessages(messages['en-US']), ...flattenMessages(messages[locale]) }}

flattenMessages flattens to dot-notation keys, so notification.filters.* resolves from the en-US layer for every locale that has not translated it yet. Labels render in English rather than as NOTIFICATION.FILTERS.REPLIES. That underlay is deliberate and documented in the comment directly above the line. Same mechanism already covers settings.notification.scheduled_published, which is also en-US only today.

Crowdin picks the new keys up from en-US on the next sync, as with any other added string.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@feruzm, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b29ffd44-f1fe-414b-9514-c1415867a943

📥 Commits

Reviewing files that changed from the base of the PR and between c144c4a and 047e678.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (1)
  • package.json
📝 Walkthrough

Walkthrough

Four notification categories are added to filters, localized labels, Redux state, settings toggles, persistence migration, and push notification handling. Filter dropdown labels now use the notification.filters locale namespace.

Changes

Notification settings expansion

Layer / File(s) Summary
Filter contracts and localization
src/providers/ecency/ecency.types.ts, src/components/notification/view/notificationView.tsx, src/config/locales/en-US.json
Filter keys, enum values, and localized filter and settings labels are expanded.
Redux state and persistence migration
src/redux/constants/constants.ts, src/redux/actions/applicationActions.ts, src/redux/reducers/applicationReducer.ts, src/redux/store/store.ts, src/utils/migrationHelpers.ts, src/utils/migrationHelpers.test.ts
Redux actions, boolean state fields, defaults, version 21 persistence, and migration tests support the new settings.
Settings controls and Redux wiring
src/screens/settings/container/settingsContainer.tsx, src/screens/settings/screen/settingsScreen.tsx
Four notification toggles are exposed, localized, state-bound, and connected to matching actions and notification type IDs.
Push notification synchronization
src/screens/application/container/applicationContainer.tsx, src/screens/login/container/loginContainer.tsx
Foreground and WebSocket handling accepts the new types, and push settings include IDs 10, 19, 20, and 21.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SettingsScreen
  participant Redux
  participant ApplicationContainer
  participant PushSettings
  SettingsScreen->>Redux: toggle notification category
  Redux-->>SettingsScreen: update notificationDetails
  SettingsScreen->>ApplicationContainer: enable notification settings
  ApplicationContainer->>PushSettings: save notify_types
  PushSettings-->>ApplicationContainer: notification settings updated
Loading

Possibly related PRs

Poem

A bunny hops through filters bright,
Four new toggles join the night.
Payouts and earnings, labels new,
Redux keeps their settings true.
Pushes now know which paths to choose—
Hop, hop, notification news!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: aligning notification filter tabs and push toggles across multiple notification types.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/notification-types-sync

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/redux/reducers/applicationReducer.ts`:
- Around line 83-86: Update the CHANGE_ALL_NOTIFICATION_SETTINGS reducer case to
include delegationsNotification, payoutsNotification, accountUpdateNotification,
and weeklyEarningsNotification in the bulk update. Use explicit false-preserving
payload handling so legacy payloads that provide false remain false while
unspecified fields retain their existing behavior.

In `@src/screens/application/container/applicationContainer.tsx`:
- Around line 1081-1084: Update the foreground and WebSocket notification
allowlists in the relevant handlers to include the server event names for
payout, account-update, and weekly-earnings notifications, alongside the
existing event types. Ensure both conversion/surfacing and unread-count refresh
paths recognize these new events consistently.

In `@src/screens/settings/screen/settingsScreen.tsx`:
- Around line 354-389: Update SettingsContainer._handleToggleChanged to handle
notification.delegations, notification.payouts, notification.accountUpdate, and
notification.weeklyEarnings emitted by the four SettingsItem controls,
dispatching the corresponding Redux and push-token setting updates instead of
falling through default. Preserve existing toggle handling for all other action
types.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b490bdb8-05ef-4cc8-bedf-80ff957708ab

📥 Commits

Reviewing files that changed from the base of the PR and between e3d7e9a and 6a29843.

📒 Files selected for processing (13)
  • src/components/notification/view/notificationView.tsx
  • src/config/locales/en-US.json
  • src/providers/ecency/ecency.types.ts
  • src/redux/actions/applicationActions.ts
  • src/redux/constants/constants.ts
  • src/redux/reducers/applicationReducer.ts
  • src/redux/store/store.ts
  • src/screens/application/container/applicationContainer.tsx
  • src/screens/login/container/loginContainer.tsx
  • src/screens/settings/container/settingsContainer.tsx
  • src/screens/settings/screen/settingsScreen.tsx
  • src/utils/migrationHelpers.test.ts
  • src/utils/migrationHelpers.ts

Comment on lines +83 to +86
delegationsNotification: boolean;
payoutsNotification: boolean;
accountUpdateNotification: boolean;
weeklyEarningsNotification: boolean;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Include the new fields in the bulk notification-settings reducer.

CHANGE_ALL_NOTIFICATION_SETTINGS at Lines 289-308 does not update these four fields. Any “enable/disable all notifications” action will leave delegations, payouts, account updates, and weekly earnings unchanged. Preserve explicit false values for legacy payloads.

Suggested fix
         notificationDetails: {
           ...state.notificationDetails,
+          delegationsNotification:
+            action.payload.delegationsNotification ??
+            state.notificationDetails.delegationsNotification,
+          payoutsNotification:
+            action.payload.payoutsNotification ??
+            state.notificationDetails.payoutsNotification,
+          accountUpdateNotification:
+            action.payload.accountUpdateNotification ??
+            state.notificationDetails.accountUpdateNotification,
+          weeklyEarningsNotification:
+            action.payload.weeklyEarningsNotification ??
+            state.notificationDetails.weeklyEarningsNotification,
           mentionNotification: action.payload.mentionNotification,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/redux/reducers/applicationReducer.ts` around lines 83 - 86, Update the
CHANGE_ALL_NOTIFICATION_SETTINGS reducer case to include
delegationsNotification, payoutsNotification, accountUpdateNotification, and
weeklyEarningsNotification in the bulk update. Use explicit false-preserving
payload handling so legacy payloads that provide false remain false while
unspecified fields retain their existing behavior.

Comment thread src/screens/application/container/applicationContainer.tsx
Comment on lines +354 to +389
<SettingsItem
title={intl.formatMessage({
id: 'settings.notification.delegations',
})}
type="toggle"
actionType="notification.delegations"
isOn={delegationsNotification}
handleOnChange={handleOnChange}
/>
<SettingsItem
title={intl.formatMessage({
id: 'settings.notification.payouts',
})}
type="toggle"
actionType="notification.payouts"
isOn={payoutsNotification}
handleOnChange={handleOnChange}
/>
<SettingsItem
title={intl.formatMessage({
id: 'settings.notification.account_update',
})}
type="toggle"
actionType="notification.accountUpdate"
isOn={accountUpdateNotification}
handleOnChange={handleOnChange}
/>
<SettingsItem
title={intl.formatMessage({
id: 'settings.notification.weekly_earnings',
})}
type="toggle"
actionType="notification.weeklyEarnings"
isOn={weeklyEarningsNotification}
handleOnChange={handleOnChange}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Route the four new notification toggle actions.

These controls emit action types that SettingsContainer._handleToggleChanged does not handle (Line 472-483), so toggling them falls through default; Redux state and push-token settings are never updated.

Suggested handler addition
       case 'notification.scheduledPublished':
+      case 'notification.delegations':
+      case 'notification.payouts':
+      case 'notification.accountUpdate':
+      case 'notification.weeklyEarnings':
         this._handleNotification(action, actionType);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/screens/settings/screen/settingsScreen.tsx` around lines 354 - 389,
Update SettingsContainer._handleToggleChanged to handle
notification.delegations, notification.payouts, notification.accountUpdate, and
notification.weeklyEarnings emitted by the four SettingsItem controls,
dispatching the corresponding Redux and push-token setting updates instead of
falling through default. Preserve existing toggle handling for all other action
types.

… paths

Both the FCM foreground handler and the websocket handler allowlist event
types explicitly, and payouts, account_update and weekly_earnings were in
neither. They produced no foreground notification and no unread-count
refresh, so the toggles added here looked functional but delivered nothing
while the app was open.

Adding them to the allowlist alone would have been worse than leaving them
out: the websocket->FCM title was a ternary chain ending in a delegation
fallback, so every newly-allowed type would have announced itself as a
delegation. Replace that chain with a switch that handles each allowlisted
type explicitly and falls back to the bare source handle.
@feruzm

feruzm commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

Triaged the CodeRabbit findings. Two of three actionable, one declined.

Foreground + websocket allowlists — confirmed and fixed in c144c4a. payouts, account_update and weekly_earnings were in neither allowlist, so they produced no foreground notification and no unread-count refresh.

Worth flagging that the suggested fix alone would have made things worse: the websocket→FCM title was a ternary chain ending in `@${source} delegated to @${target}`, so every newly-allowed type would have announced itself as a delegation. Replaced the chain with a switch that handles each allowlisted type explicitly, so an unhandled type can no longer inherit another type's wording.

Route the four new toggle actions — already fixed in da42a52, before this review landed.

Bulk notification-settings reducer — declining. CHANGE_ALL_NOTIFICATION_SETTINGS has exactly one dispatcher: the one-time legacy realm→redux settings migration in migrationHelpers.ts:95, gated by setSettingsMigrated. It is not an "enable/disable all" control — that path is changeNotificationSettings({ type: 'notification' }), which calls _setPushToken with the full notifyTypes list built from notificationDetails, and that list does include the four new keys.

The suggested diff is also behaviourally identical to the current code. Legacy realm payloads predate these fields, so action.payload.X is always undefined; with the ?? guard it resolves to state.notificationDetails.X, which is exactly what the existing ...state.notificationDetails spread already yields. Adding the four lines changes no observable behaviour.

Picks up the notification enum additions released from vision-next#1229
(NotificationFilter.ACCOUNT_UPDATES/WEEKLY_EARNINGS and the NotifyTypes
ints for delegations/payouts/account_update/weekly_earnings), keeping the
shared definitions aligned with the filter and toggle work in this PR.

2.3.57 -> 2.3.61 changes no dependencies, so the lockfile edit is limited
to the one entry; verified with yarn install --frozen-lockfile against an
isolated modules folder.
@feruzm
feruzm merged commit 7f0264c into development Jul 22, 2026
13 checks passed
@feruzm
feruzm deleted the feature/notification-types-sync branch July 22, 2026 20:36
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.

1 participant