Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"@babel/preset-typescript": "^7.26.0",
"@babel/runtime": "^7.26.7",
"@ecency/render-helper": "^2.5.22",
"@ecency/sdk": "^2.3.57",
"@ecency/sdk": "^2.3.61",
"@esteemapp/react-native-autocomplete-input": "^4.2.1",
"@esteemapp/react-native-multi-slider": "^1.1.0",
"@native-html/iframe-plugin": "^2.6.1",
Expand Down
18 changes: 15 additions & 3 deletions src/components/notification/view/notificationView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,26 @@ import { selectIsDarkTheme } from '../../../redux/selectors';
import styles from './notificationStyles';

// Each `key` must match a NotificationFilters enum value (passed straight to the
// notifications query) and have a `notification.<key>` locale string, which is
// also the displayed label — so the key is the single source for both.
// notifications query) and have a `notification.filters.<key>` locale string.
// Labels live under their own `filters` namespace rather than reusing
// `notification.<key>`: several of those are notification BODY strings
// (`payouts` is "Payout received: ${amount}", `delegations` is "delegated"), so
// using them as labels renders template text in the dropdown.
const FILTERS = [
{ key: 'activities' },
{ key: 'replies' },
{ key: 'mentions' },
{ key: 'rvotes' },
{ key: 'follows' },
{ key: 'reblogs' },
{ key: 'transfers' },
{ key: 'delegations' },
{ key: 'nfavorites' },
{ key: 'nbookmarks' },
{ key: 'payouts' },
{ key: 'scheduled_published' },
{ key: 'account_updates' },
{ key: 'weekly_earnings' },
];

interface Props {
Expand Down Expand Up @@ -113,7 +125,7 @@ const NotificationView = ({
<FilterBar
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

)}
defaultText="ALL"
onDropdownSelect={_handleOnDropdownSelect}
Expand Down
19 changes: 19 additions & 0 deletions src/config/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,22 @@
"selected": "Selected {postfix}"
},
"notification": {
"filters": {
"activities": "All",
"replies": "Replies",
"mentions": "Mentions",
"rvotes": "Votes",
"follows": "Follows",
"reblogs": "Reblogs",
"transfers": "Transfers",
"delegations": "Delegations",
"nfavorites": "Favorites",
"nbookmarks": "Bookmarks",
"payouts": "Payouts",
"scheduled_published": "Scheduled posts",
"account_updates": "Account updates",
"weekly_earnings": "Weekly earnings"
},
"this_week": "This Week",
"reblog": "reblogged",
"unfollow": "unfollowed you",
Expand Down Expand Up @@ -1581,6 +1597,9 @@
"vote": "Vote",
"follow": "Follow",
"scheduled_published": "Scheduled post published",
"payouts": "Payouts",
"account_update": "Account updates",
"weekly_earnings": "Weekly earnings",
"fcm_unavailable": "Push notifications are not supported on this device. You will receive notifications only while the app is open."
},
"keys_warning": "Sensitive account information!\nEcency must be secured with PIN code before viewing private keys.",
Expand Down
6 changes: 6 additions & 0 deletions src/providers/ecency/ecency.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ export enum NotificationFilters {
DELEGATIONS = 'delegations',
FAVOURITES = 'nfavorites',
BOOKMARKS = 'nbookmarks',
PAYOUTS = 'payouts',
SCHEDULED_PUBLISHED = 'scheduled_published',
// Filter path is plural while the notification `type` string is singular
// (`account_update`) — enotify routes on the plural form.
ACCOUNT_UPDATES = 'account_updates',
WEEKLY_EARNINGS = 'weekly_earnings',
}

export enum PointActivityIds {
Expand Down
28 changes: 28 additions & 0 deletions src/redux/actions/applicationActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import {
CHANGE_REBLOG_NOTIFICATION,
CHANGE_TRANSFERS_NOTIFICATION,
CHANGE_SCHEDULED_PUBLISHED_NOTIFICATION,
CHANGE_DELEGATIONS_NOTIFICATION,
CHANGE_PAYOUTS_NOTIFICATION,
CHANGE_ACCOUNT_UPDATE_NOTIFICATION,
CHANGE_WEEKLY_EARNINGS_NOTIFICATION,
CHANGE_ALL_NOTIFICATION_SETTINGS,
CHANGE_VOTE_NOTIFICATION,
IS_CONNECTED,
Expand Down Expand Up @@ -140,6 +144,30 @@ export const changeNotificationSettings = (payload) => {
type: CHANGE_SCHEDULED_PUBLISHED_NOTIFICATION,
};

case 'notification.delegations':
return {
payload: payload.action,
type: CHANGE_DELEGATIONS_NOTIFICATION,
};

case 'notification.payouts':
return {
payload: payload.action,
type: CHANGE_PAYOUTS_NOTIFICATION,
};

case 'notification.accountUpdate':
return {
payload: payload.action,
type: CHANGE_ACCOUNT_UPDATE_NOTIFICATION,
};

case 'notification.weeklyEarnings':
return {
payload: payload.action,
type: CHANGE_WEEKLY_EARNINGS_NOTIFICATION,
};

case 'notification':
return {
payload: payload.action,
Expand Down
4 changes: 4 additions & 0 deletions src/redux/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export const CHANGE_BOOKMARK_NOTIFICATION = 'CHANGE_BOOKMARK_NOTIFICATION';
export const CHANGE_REBLOG_NOTIFICATION = 'CHANGE_REBLOG_NOTIFICATION';
export const CHANGE_TRANSFERS_NOTIFICATION = 'CHANGE_TRANSFERS_NOTIFICATION';
export const CHANGE_SCHEDULED_PUBLISHED_NOTIFICATION = 'CHANGE_SCHEDULED_PUBLISHED_NOTIFICATION';
export const CHANGE_DELEGATIONS_NOTIFICATION = 'CHANGE_DELEGATIONS_NOTIFICATION';
export const CHANGE_PAYOUTS_NOTIFICATION = 'CHANGE_PAYOUTS_NOTIFICATION';
export const CHANGE_ACCOUNT_UPDATE_NOTIFICATION = 'CHANGE_ACCOUNT_UPDATE_NOTIFICATION';
export const CHANGE_WEEKLY_EARNINGS_NOTIFICATION = 'CHANGE_WEEKLY_EARNINGS_NOTIFICATION';
export const CHANGE_ALL_NOTIFICATION_SETTINGS = 'CHANGE_ALL_NOTIFICATION_SETTINGS';
export const SET_LAST_APP_VERSION = 'SET_LAST_APP_VERSION';
export const SET_COLOR_THEME = 'SET_COLOR_THEME';
Expand Down
40 changes: 40 additions & 0 deletions src/redux/reducers/applicationReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import {
CHANGE_REBLOG_NOTIFICATION,
CHANGE_TRANSFERS_NOTIFICATION,
CHANGE_SCHEDULED_PUBLISHED_NOTIFICATION,
CHANGE_DELEGATIONS_NOTIFICATION,
CHANGE_PAYOUTS_NOTIFICATION,
CHANGE_ACCOUNT_UPDATE_NOTIFICATION,
CHANGE_WEEKLY_EARNINGS_NOTIFICATION,
CHANGE_VOTE_NOTIFICATION,
CHANGE_ALL_NOTIFICATION_SETTINGS,
IS_CONNECTED,
Expand Down Expand Up @@ -76,6 +80,10 @@ interface State {
transfersNotification: boolean;
voteNotification: boolean;
scheduledPublishedNotification: boolean;
delegationsNotification: boolean;
payoutsNotification: boolean;
accountUpdateNotification: boolean;
weeklyEarningsNotification: boolean;
Comment on lines +83 to +86

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.

};
postUpvotePercent: number;
commentUpvotePercent: number;
Expand Down Expand Up @@ -122,6 +130,10 @@ const initialState: State = {
transfersNotification: true,
voteNotification: true,
scheduledPublishedNotification: true,
delegationsNotification: true,
payoutsNotification: true,
accountUpdateNotification: true,
weeklyEarningsNotification: true,
},
postUpvotePercent: 1,
commentUpvotePercent: 1,
Expand Down Expand Up @@ -238,6 +250,34 @@ const applicationReducer = (state = initialState, action): State => {
scheduledPublishedNotification: action.payload,
},
});
case CHANGE_DELEGATIONS_NOTIFICATION:
return Object.assign({}, state, {
notificationDetails: {
...state.notificationDetails,
delegationsNotification: action.payload,
},
});
case CHANGE_PAYOUTS_NOTIFICATION:
return Object.assign({}, state, {
notificationDetails: {
...state.notificationDetails,
payoutsNotification: action.payload,
},
});
case CHANGE_ACCOUNT_UPDATE_NOTIFICATION:
return Object.assign({}, state, {
notificationDetails: {
...state.notificationDetails,
accountUpdateNotification: action.payload,
},
});
case CHANGE_WEEKLY_EARNINGS_NOTIFICATION:
return Object.assign({}, state, {
notificationDetails: {
...state.notificationDetails,
weeklyEarningsNotification: action.payload,
},
});
case CHANGE_VOTE_NOTIFICATION:
return Object.assign({}, state, {
notificationDetails: {
Expand Down
2 changes: 1 addition & 1 deletion src/redux/store/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const persistConfig = {
key: 'root',
// Storage Method (React Native)
storage: AsyncStorage,
version: 20, // v20: Default scheduledPublished notification ON, backfill bookmark setting
version: 21, // v21: Default delegations/payouts/accountUpdate/weeklyEarnings notifications ON
// // Blacklist (Don't Save Specific Reducers)
blacklist: ['communities', 'user', 'ui'],
transforms: [transformCacheVoteMap, transformWalkthroughMap],
Expand Down
74 changes: 55 additions & 19 deletions src/screens/application/container/applicationContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,9 @@ class ApplicationContainer extends Component {
'transfer',
'delegations',
'scheduled_published',
'payouts',
'account_update',
'weekly_earnings',
];
const messageType = remoteMessage?.data?.type;
if (notificationTypes.includes(messageType)) {
Expand Down Expand Up @@ -890,14 +893,59 @@ class ApplicationContainer extends Component {
wsData.type === 'reply' ||
wsData.type === 'transfer' ||
wsData.type === 'delegations' ||
wsData.type === 'scheduled_published')
wsData.type === 'scheduled_published' ||
wsData.type === 'payouts' ||
wsData.type === 'account_update' ||
wsData.type === 'weekly_earnings')
) {
// Re-fetch the authoritative unread count rather than a local +1:
// FCM may deliver the same event, and a local increment in both
// paths double-counted (daily-spin POINT transfers showed 2 not 1).
this._refreshUnreadActivityCount();
const { type, source, target, extra } = wsData;

// Title/body per type. A ternary chain here previously ended in a
// delegation fallback, so any unhandled type announced itself as a
// delegation — every type in the allowlist above needs a case.
let notifTitle = '';
let notifBody = '';
switch (type) {
case 'mention':
notifTitle = `@${source} mentioned @${target}`;
break;
case 'reply':
notifTitle = `@${source} replied to @${target}`;
notifBody = extra?.body ? extra.body.substring(0, 100) : '';
break;
case 'transfer':
notifTitle = `@${source} transferred to @${target}`;
notifBody = extra?.amount || '';
break;
case 'delegations':
notifTitle = `@${source} delegated to @${target}`;
notifBody = extra?.amount || '';
break;
case 'scheduled_published':
notifTitle = 'Scheduled post published';
notifBody = extra?.title || '';
break;
case 'payouts':
notifTitle = 'Rewards received';
notifBody = extra?.amount || '';
break;
case 'account_update':
notifTitle = 'Account updated';
notifBody = 'Your account details were updated';
break;
case 'weekly_earnings':
notifTitle = 'Weekly earnings';
notifBody = extra?.total_usd ? `$${extra.total_usd}` : '';
break;
default:
notifTitle = `@${source}`;
break;
}

// Build FCM-compatible notification object
const fcmFormat = {
data: {
Expand All @@ -914,24 +962,8 @@ class ApplicationContainer extends Component {
amount: extra?.amount || '',
},
notification: {
title:
type === 'mention'
? `@${source} mentioned @${target}`
: type === 'reply'
? `@${source} replied to @${target}`
: type === 'transfer'
? `@${source} transferred to @${target}`
: type === 'scheduled_published'
? 'Scheduled post published'
: `@${source} delegated to @${target}`,
body:
type === 'reply' && extra?.body
? extra.body.substring(0, 100)
: type === 'transfer' || type === 'delegations'
? extra?.amount || ''
: type === 'scheduled_published'
? extra?.title || ''
: '',
title: notifTitle,
body: notifBody,
},
};

Expand Down Expand Up @@ -1078,6 +1110,10 @@ class ApplicationContainer extends Component {
transfersNotification: 6,
favoriteNotification: 13,
bookmarkNotification: 15,
delegationsNotification: 10,
payoutsNotification: 19,
accountUpdateNotification: 20,
weeklyEarningsNotification: 21,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
scheduledPublishedNotification: 22,
};

Expand Down
4 changes: 4 additions & 0 deletions src/screens/login/container/loginContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ class LoginContainer extends PureComponent {
transfers: 6,
favorite: 13,
bookmark: 15,
delegations: 10,
payouts: 19,
accountUpdate: 20,
weeklyEarnings: 21,
scheduledPublished: 22,
};
const notifyTypes = [];
Expand Down
12 changes: 12 additions & 0 deletions src/screens/settings/container/settingsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,10 @@ class SettingsContainer extends Component {
case 'notification.reblog':
case 'notification.transfers':
case 'notification.scheduledPublished':
case 'notification.delegations':
case 'notification.payouts':
case 'notification.accountUpdate':
case 'notification.weeklyEarnings':
this._handleNotification(action, actionType);
break;

Expand Down Expand Up @@ -538,6 +542,10 @@ class SettingsContainer extends Component {
transfers: 6,
favorite: 13,
bookmark: 15,
delegations: 10,
payouts: 19,
accountUpdate: 20,
weeklyEarnings: 21,
scheduledPublished: 22,
};
const notifyTypes = [];
Expand Down Expand Up @@ -888,6 +896,10 @@ const mapStateToProps = (state) => {
transfersNotification: notificationDetails.transfersNotification,
voteNotification: notificationDetails.voteNotification,
scheduledPublishedNotification: notificationDetails.scheduledPublishedNotification,
delegationsNotification: notificationDetails.delegationsNotification,
payoutsNotification: notificationDetails.payoutsNotification,
accountUpdateNotification: notificationDetails.accountUpdateNotification,
weeklyEarningsNotification: notificationDetails.weeklyEarningsNotification,
selectedApi: selectApi(state),
selectedCurrency: selectCurrency(state),
selectedLanguage: selectLanguage(state),
Expand Down
Loading
Loading