Show local notification when replying to PN fails (#2142)
This commit is contained in:
parent
1d37f9bbec
commit
46b6687d1f
7 changed files with 62 additions and 29 deletions
|
|
@ -149,7 +149,7 @@ public class CustomPushNotification extends PushNotification {
|
|||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
|
||||
CHANNEL_NAME,
|
||||
NotificationManager.IMPORTANCE_DEFAULT);
|
||||
NotificationManager.IMPORTANCE_HIGH);
|
||||
final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
notification.setChannelId(CHANNEL_ID);
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ export function purgeOfflineStore() {
|
|||
// A non-optimistic version of the createPost action in mattermost-redux with the file handling
|
||||
// removed since it's not needed.
|
||||
export function createPostForNotificationReply(post) {
|
||||
return (dispatch, getState) => {
|
||||
return async (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const currentUserId = state.entities.users.currentUserId;
|
||||
|
||||
|
|
@ -119,18 +119,23 @@ export function createPostForNotificationReply(post) {
|
|||
update_at: timestamp,
|
||||
};
|
||||
|
||||
return Client4.createPost({...newPost, create_at: 0}).then((payload) => {
|
||||
try {
|
||||
const data = await Client4.createPost({...newPost, create_at: 0});
|
||||
dispatch({
|
||||
type: PostTypes.RECEIVED_POSTS,
|
||||
data: {
|
||||
order: [],
|
||||
posts: {
|
||||
[payload.id]: payload,
|
||||
[data.id]: data,
|
||||
},
|
||||
},
|
||||
channelId: payload.channel_id,
|
||||
channelId: data.channel_id,
|
||||
});
|
||||
});
|
||||
|
||||
return {data};
|
||||
} catch (error) {
|
||||
return {error};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,3 +89,9 @@ export function getTranslations(locale) {
|
|||
}
|
||||
return TRANSLATIONS[locale] || TRANSLATIONS[DEFAULT_LOCALE];
|
||||
}
|
||||
|
||||
export function getLocalizedMessage(locale, id) {
|
||||
const translations = getTranslations(locale);
|
||||
|
||||
return translations[id] || TRANSLATIONS[DEFAULT_LOCALE][id];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import {AppRegistry, AppState} from 'react-native';
|
|||
import {NotificationsAndroid, PendingNotifications} from 'react-native-notifications';
|
||||
import Notification from 'react-native-notifications/notification.android';
|
||||
|
||||
import {emptyFunction} from 'app/utils/general';
|
||||
|
||||
class PushNotification {
|
||||
constructor() {
|
||||
this.onRegister = null;
|
||||
|
|
@ -37,15 +39,16 @@ class PushNotification {
|
|||
AppRegistry.registerHeadlessTask('notificationReplied', () => async (deviceNotification) => {
|
||||
const notification = new Notification(deviceNotification);
|
||||
const data = notification.getData();
|
||||
const completed = emptyFunction;
|
||||
|
||||
if (this.onReply) {
|
||||
this.onReply(data, data.text, parseInt(data.badge, 10) - parseInt(data.msg_count, 10));
|
||||
this.onReply(data, data.text, parseInt(data.badge, 10) - parseInt(data.msg_count, 10), completed);
|
||||
} else {
|
||||
this.deviceNotification = {
|
||||
data,
|
||||
text: data.text,
|
||||
badge: parseInt(data.badge, 10) - parseInt(data.msg_count, 10),
|
||||
completed: true, // used to identify that the notification belongs to a reply
|
||||
completed, // used to identify that the notification belongs to a reply
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -122,6 +122,16 @@ class PushNotification {
|
|||
}
|
||||
}
|
||||
|
||||
localNotification(notification) {
|
||||
const deviceNotification = {
|
||||
alertBody: notification.message,
|
||||
alertAction: '',
|
||||
userInfo: notification.userInfo,
|
||||
};
|
||||
|
||||
NotificationsIOS.localNotification(deviceNotification);
|
||||
}
|
||||
|
||||
cancelAllLocalNotifications() {
|
||||
NotificationsIOS.cancelAllLocalNotifications();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,28 +2,28 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Platform} from 'react-native';
|
||||
|
||||
import PushNotifications from 'app/push_notifications';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
|
||||
import {markChannelAsRead} from 'mattermost-redux/actions/channels';
|
||||
import {setDeviceToken} from 'mattermost-redux/actions/general';
|
||||
import {getPosts} from 'mattermost-redux/actions/posts';
|
||||
import {Client4} from 'mattermost-redux/client';
|
||||
import {General} from 'mattermost-redux/constants';
|
||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||
import EventEmitter from 'mattermost-redux/utils/event_emitter';
|
||||
|
||||
import {ViewTypes} from 'app/constants';
|
||||
import {retryGetPostsAction} from 'app/actions/views/channel';
|
||||
import {
|
||||
createPostForNotificationReply,
|
||||
loadFromPushNotification,
|
||||
} from 'app/actions/views/root';
|
||||
|
||||
import {ViewTypes} from 'app/constants';
|
||||
import {DEFAULT_LOCALE, getLocalizedMessage} from 'app/i18n';
|
||||
import {
|
||||
app,
|
||||
store,
|
||||
} from 'app/mattermost';
|
||||
import PushNotifications from 'app/push_notifications';
|
||||
|
||||
const onRegisterDevice = (data) => {
|
||||
app.setIsNotificationsConfigured(true);
|
||||
|
|
@ -105,14 +105,14 @@ const onPushNotification = async (deviceNotification) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const onPushNotificationReply = (data, text, badge, completed) => {
|
||||
export const onPushNotificationReply = async (data, text, badge, completed) => {
|
||||
const {dispatch, getState} = store;
|
||||
const state = getState();
|
||||
const {currentUserId: reduxCurrentUserId} = state.entities.users;
|
||||
const reduxCurrentUser = getCurrentUser(state);
|
||||
const reduxCredentialsUrl = state.entities.general.credentials.url;
|
||||
const reduxCredentialsToken = state.entities.general.credentials.token;
|
||||
|
||||
const currentUserId = reduxCurrentUserId || app.currentUserId;
|
||||
const currentUserId = reduxCurrentUser ? reduxCurrentUser.id : app.currentUserId;
|
||||
const url = reduxCredentialsUrl || app.url;
|
||||
const token = reduxCredentialsToken || app.token;
|
||||
|
||||
|
|
@ -138,20 +138,28 @@ export const onPushNotificationReply = (data, text, badge, completed) => {
|
|||
}
|
||||
|
||||
retryGetPostsAction(getPosts(data.channel_id), dispatch, getState);
|
||||
dispatch(createPostForNotificationReply(post)).
|
||||
then(() => {
|
||||
dispatch(markChannelAsRead(data.channel_id));
|
||||
|
||||
if (badge >= 0) {
|
||||
PushNotifications.setApplicationIconBadgeNumber(badge);
|
||||
}
|
||||
|
||||
app.setReplyNotificationData(null);
|
||||
}).
|
||||
then(completed).
|
||||
catch((e) => {
|
||||
console.warn('Failed to send reply to push notification', e); // eslint-disable-line no-console
|
||||
const result = await dispatch(createPostForNotificationReply(post));
|
||||
if (result.error) {
|
||||
const locale = reduxCurrentUser ? reduxCurrentUser.locale : DEFAULT_LOCALE;
|
||||
PushNotifications.localNotification({
|
||||
message: getLocalizedMessage(locale, 'mobile.reply_post.failed'),
|
||||
userInfo: {
|
||||
localNotification: true,
|
||||
localTest: true,
|
||||
},
|
||||
});
|
||||
console.warn('Failed to send reply to push notification', result.error); // eslint-disable-line no-console
|
||||
completed();
|
||||
return;
|
||||
}
|
||||
|
||||
if (badge >= 0) {
|
||||
PushNotifications.setApplicationIconBadgeNumber(badge);
|
||||
}
|
||||
|
||||
dispatch(markChannelAsRead(data.channel_id));
|
||||
app.setReplyNotificationData(null);
|
||||
completed();
|
||||
} else {
|
||||
app.setReplyNotificationData({
|
||||
data,
|
||||
|
|
|
|||
|
|
@ -2579,6 +2579,7 @@
|
|||
"mobile.rename_channel.name_maxLength": "URL must be less than {maxLength, number} characters",
|
||||
"mobile.rename_channel.name_minLength": "URL must be {minLength, number} or more characters",
|
||||
"mobile.rename_channel.name_required": "URL is required",
|
||||
"mobile.reply_post.failed": "Message failed to send.",
|
||||
"mobile.request.invalid_response": "Received invalid response from the server.",
|
||||
"mobile.reset_status.alert_cancel": "Cancel",
|
||||
"mobile.reset_status.alert_ok": "Ok",
|
||||
|
|
|
|||
Loading…
Reference in a new issue