Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
15 changes: 13 additions & 2 deletions src/components/foregroundNotification/foregroundNotification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface RemoteMessage {
permlink2: string;
permlink3: string;
amount?: string;
type: 'mention' | 'reply' | 'transfer' | 'delegations';
type: 'mention' | 'reply' | 'transfer' | 'delegations' | 'scheduled_published';
};
notification: {
body: string;
Expand Down Expand Up @@ -50,7 +50,11 @@ const ForegroundNotification = ({ remoteMessage }: Props) => {
const { source, target, type, id, amount } = remoteMessage.data;
if (
activeId !== id &&
(type === 'reply' || type === 'mention' || type === 'transfer' || type === 'delegations')
(type === 'reply' ||
type === 'mention' ||
type === 'transfer' ||
type === 'delegations' ||
type === 'scheduled_published')
) {
let titleText = '';
let bodyText = '';
Expand Down Expand Up @@ -82,6 +86,13 @@ const ForegroundNotification = ({ remoteMessage }: Props) => {
defaultMessage: 'Amount unavailable',
});
break;
case 'scheduled_published':
titleText = intl.formatMessage({ id: 'notification.scheduled_published_title' });
// the delivered payload body carries the post title; keep it when present
bodyText =
remoteMessage.notification?.body ||
intl.formatMessage({ id: 'notification.scheduled_published_body' });
break;
Comment thread
greptile-apps[bot] marked this conversation as resolved.
}

setActiveId(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ const NotificationLineView = ({
notification.type === 'favorites' ||
notification.type === 'checkin' ||
notification.type === 'monthly_posts' ||
notification.type === 'scheduled_published' ||
(notification.type === 'mention' && notification.post)
) {
_moreinfo = notification.title || notification.permlink;
Expand Down
6 changes: 5 additions & 1 deletion src/config/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,10 @@
"account_update_active_authority": "{accounts} was granted active authority on your account. If you did not authorize this, revoke it.",
"account_update_posting_authority": "{accounts} can now post and vote on your behalf. If you did not authorize this, revoke it.",
"weekly_earnings": "You earned ${amount} this week{breakdown}",
"payouts": "Payout received: ${amount}"
"payouts": "Payout received: ${amount}",
"scheduled_published": "published a scheduled post",
"scheduled_published_title": "Scheduled post published",
"scheduled_published_body": "Your scheduled post is now live, tap to view it"
},
"recurrent": {
"delete_failed": "Failed to delete recurrent transfer, {error}",
Expand Down Expand Up @@ -1548,6 +1551,7 @@
"transfers": "Transfers",
"vote": "Vote",
"follow": "Follow",
"scheduled_published": "Scheduled post published",
"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
7 changes: 7 additions & 0 deletions src/redux/actions/applicationActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
CHANGE_BOOKMARK_NOTIFICATION,
CHANGE_REBLOG_NOTIFICATION,
CHANGE_TRANSFERS_NOTIFICATION,
CHANGE_SCHEDULED_PUBLISHED_NOTIFICATION,
CHANGE_ALL_NOTIFICATION_SETTINGS,
CHANGE_VOTE_NOTIFICATION,
IS_CONNECTED,
Expand Down Expand Up @@ -133,6 +134,12 @@ export const changeNotificationSettings = (payload) => {
type: CHANGE_TRANSFERS_NOTIFICATION,
};

case 'notification.scheduledPublished':
return {
payload: payload.action,
type: CHANGE_SCHEDULED_PUBLISHED_NOTIFICATION,
};

case 'notification':
return {
payload: payload.action,
Expand Down
1 change: 1 addition & 0 deletions src/redux/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const CHANGE_FAVORITE_NOTIFICATION = 'CHANGE_FAVORITE_NOTIFICATION';
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_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
19 changes: 19 additions & 0 deletions src/redux/reducers/applicationReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
CHANGE_BOOKMARK_NOTIFICATION,
CHANGE_REBLOG_NOTIFICATION,
CHANGE_TRANSFERS_NOTIFICATION,
CHANGE_SCHEDULED_PUBLISHED_NOTIFICATION,
CHANGE_VOTE_NOTIFICATION,
CHANGE_ALL_NOTIFICATION_SETTINGS,
IS_CONNECTED,
Expand Down Expand Up @@ -70,9 +71,11 @@ interface State {
followNotification: boolean;
mentionNotification: boolean;
favoriteNotification: boolean;
bookmarkNotification: boolean;
reblogNotification: boolean;
transfersNotification: boolean;
voteNotification: boolean;
scheduledPublishedNotification: boolean;
};
postUpvotePercent: number;
commentUpvotePercent: number;
Expand Down Expand Up @@ -114,9 +117,11 @@ const initialState: State = {
followNotification: true,
mentionNotification: true,
favoriteNotification: true,
bookmarkNotification: true,
reblogNotification: true,
transfersNotification: true,
voteNotification: true,
scheduledPublishedNotification: true,
},
postUpvotePercent: 1,
commentUpvotePercent: 1,
Expand Down Expand Up @@ -226,6 +231,13 @@ const applicationReducer = (state = initialState, action): State => {
transfersNotification: action.payload,
},
});
case CHANGE_SCHEDULED_PUBLISHED_NOTIFICATION:
return Object.assign({}, state, {
notificationDetails: {
...state.notificationDetails,
scheduledPublishedNotification: action.payload,
},
});
case CHANGE_VOTE_NOTIFICATION:
return Object.assign({}, state, {
notificationDetails: {
Expand All @@ -240,11 +252,18 @@ const applicationReducer = (state = initialState, action): State => {
...state.notificationDetails,
mentionNotification: action.payload.mentionNotification,
favoriteNotification: action.payload.favoriteNotification,
// bookmark and scheduledPublished may be missing from legacy settings
// payloads (realm migration predates them), keep current value then
bookmarkNotification:
action.payload.bookmarkNotification ?? state.notificationDetails.bookmarkNotification,
reblogNotification: action.payload.reblogNotification,
transfersNotification: action.payload.transfersNotification,
voteNotification: action.payload.voteNotification,
followNotification: action.payload.followNotification,
commentNotification: action.payload.commentNotification,
scheduledPublishedNotification:
action.payload.scheduledPublishedNotification ??
state.notificationDetails.scheduledPublishedNotification,
},
});
case IS_DARK_THEME:
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: 19, // v19: Purge persisted SPK/LARYNX/LP assets (SPK support removed)
version: 20, // v20: Default scheduledPublished notification ON, backfill bookmark setting
// // Blacklist (Don't Save Specific Reducers)
blacklist: ['communities', 'user', 'ui'],
transforms: [transformCacheVoteMap, transformWalkthroughMap],
Expand Down
18 changes: 15 additions & 3 deletions src/screens/application/container/applicationContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,13 @@ class ApplicationContainer extends Component {
firebaseOnMessageListener = getMessaging().onMessage((remoteMessage) => {
console.log('Notification Received: foreground', remoteMessage);

const notificationTypes = ['mention', 'reply', 'transfer', 'delegations'];
const notificationTypes = [
'mention',
'reply',
'transfer',
'delegations',
'scheduled_published',
];
const messageType = remoteMessage?.data?.type;
if (notificationTypes.includes(messageType)) {
// FCM and the enotify websocket can both deliver the same event, so a
Expand Down Expand Up @@ -883,7 +889,8 @@ class ApplicationContainer extends Component {
(wsData.type === 'mention' ||
wsData.type === 'reply' ||
wsData.type === 'transfer' ||
wsData.type === 'delegations')
wsData.type === 'delegations' ||
wsData.type === 'scheduled_published')
) {
// Re-fetch the authoritative unread count rather than a local +1:
// FCM may deliver the same event, and a local increment in both
Expand Down Expand Up @@ -914,12 +921,16 @@ class ApplicationContainer extends Component {
? `@${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 || ''
: '',
},
};
Expand Down Expand Up @@ -1067,6 +1078,7 @@ class ApplicationContainer extends Component {
transfersNotification: 6,
favoriteNotification: 13,
bookmarkNotification: 15,
scheduledPublishedNotification: 22,
};

Object.keys(settings).forEach((item) => {
Expand All @@ -1075,7 +1087,7 @@ class ApplicationContainer extends Component {
}
});
} else {
notify_types = [1, 2, 3, 4, 5, 6, 13, 15];
notify_types = [1, 2, 3, 4, 5, 6, 13, 15, 22];
}

try {
Expand Down
9 changes: 9 additions & 0 deletions src/screens/application/hook/useInitApplication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,15 @@ export const useInitApplication = () => {
routeName = ROUTES.SCREENS.POST;
break;

case 'scheduled_published':
params = {
author: get(push, 'source', ''),
permlink: fullPermlink,
};
Comment thread
greptile-apps[bot] marked this conversation as resolved.
key = fullPermlink;
routeName = ROUTES.SCREENS.POST;
break;

case 'favorite':
case 'bookmark':
case 'reply':
Expand Down
1 change: 1 addition & 0 deletions src/screens/login/container/loginContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ class LoginContainer extends PureComponent {
transfers: 6,
favorite: 13,
bookmark: 15,
scheduledPublished: 22,
};
const notifyTypes = [];

Expand Down
8 changes: 8 additions & 0 deletions src/screens/notification/container/notificationContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ const NotificationContainer = ({ navigation }) => {
author,
permlink,
};
} else if (type === 'scheduled_published' && permlink) {
// source is the author of the published scheduled post
routeName = ROUTES.SCREENS.POST;
key = permlink;
params = {
author: get(data, 'source'),
permlink,
};
} else if (type === 'follow') {
routeName = ROUTES.SCREENS.PROFILE;
key = get(data, 'follower');
Expand Down
3 changes: 3 additions & 0 deletions src/screens/settings/container/settingsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ class SettingsContainer extends Component {
case 'notification.bookmark':
case 'notification.reblog':
case 'notification.transfers':
case 'notification.scheduledPublished':
this._handleNotification(action, actionType);
break;

Expand Down Expand Up @@ -325,6 +326,7 @@ class SettingsContainer extends Component {
transfers: 6,
favorite: 13,
bookmark: 15,
scheduledPublished: 22,
};
const notifyTypes = [];

Expand Down Expand Up @@ -672,6 +674,7 @@ const mapStateToProps = (state) => {
reblogNotification: notificationDetails.reblogNotification,
transfersNotification: notificationDetails.transfersNotification,
voteNotification: notificationDetails.voteNotification,
scheduledPublishedNotification: notificationDetails.scheduledPublishedNotification,
selectedApi: selectApi(state),
selectedCurrency: selectCurrency(state),
selectedLanguage: selectLanguage(state),
Expand Down
10 changes: 10 additions & 0 deletions src/screens/settings/screen/settingsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const SettingsScreen = ({
reblogNotification,
transfersNotification,
voteNotification,
scheduledPublishedNotification,
handleOnButtonPress,
isLoading,
isHideImages,
Expand Down Expand Up @@ -327,6 +328,15 @@ const SettingsScreen = ({
isOn={transfersNotification}
handleOnChange={handleOnChange}
/>
<SettingsItem
title={intl.formatMessage({
id: 'settings.notification.scheduled_published',

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 Add fallbacks for scheduled notification copy

When the app locale is anything other than en-US, IntlProvider is initialized with only that locale's messages (src/index.tsx), and this commit adds the new scheduled-published strings only to en-US.json. This formatMessage call will therefore render the raw id for every other supported language; the foreground title/body ids added in this commit have the same issue. Please add the new keys to the other locale files, or provide defaultMessage fallbacks at each call site.

Useful? React with 👍 / 👎.

})}
type="toggle"
actionType="notification.scheduledPublished"
isOn={scheduledPublishedNotification}
handleOnChange={handleOnChange}
/>
</CollapsibleCard>
{isFCMAvailable === false && (
<View
Expand Down
27 changes: 27 additions & 0 deletions src/utils/migrationHelpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,33 @@ describe('reduxMigrations', () => {
});
});

describe('v20: scheduledPublished + bookmark notification defaults', () => {
it('defaults scheduledPublished and bookmark notification settings ON when missing', () => {
const state = { application: { notificationDetails: { voteNotification: false } } } as any;
const result = reduxMigrations[20](state);
expect(result.application.notificationDetails.scheduledPublishedNotification).toBe(true);
expect(result.application.notificationDetails.bookmarkNotification).toBe(true);
// existing settings are untouched
expect(result.application.notificationDetails.voteNotification).toBe(false);
});

it('preserves an explicit false for bookmarkNotification', () => {
const state = {
application: { notificationDetails: { bookmarkNotification: false } },
} as any;
const result = reduxMigrations[20](state);
expect(result.application.notificationDetails.bookmarkNotification).toBe(false);
expect(result.application.notificationDetails.scheduledPublishedNotification).toBe(true);
});

it('is a no-op when notificationDetails is absent', () => {
const state = { application: {}, account: { keep: 'me' } } as any;
const result = reduxMigrations[20](state);
expect(result.application.notificationDetails).toBeUndefined();
expect(result.account.keep).toBe('me');
});
});

describe('failure isolation', () => {
it('rolls back a throwing migration and preserves the rest of the state', () => {
// v1 writes state.application.notificationDetails.favoriteNotification; with
Expand Down
13 changes: 13 additions & 0 deletions src/utils/migrationHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,19 @@ const reduxMigrations = {
}
return state;
},
20: (state) => {
// Default the scheduled-post-published notification setting ON for existing
// installs; autoMergeLevel1 keeps the persisted notificationDetails as-is on
// rehydration, so the new key is never defaulted from initialState (see 17).
// Also backfill bookmarkNotification: migration 2 covered upgrades, but fresh
// installs since then started from an initialState that lacked the key.
if (state.application?.notificationDetails) {
const details = state.application.notificationDetails;
details.bookmarkNotification = details.bookmarkNotification ?? true;
details.scheduledPublishedNotification = details.scheduledPublishedNotification ?? true;
}
return state;
},
};

// Wrap every migration so a throw degrades to "skip this migration" and keep the
Expand Down
Loading