Show local notification when replying to PN fails (#2142)

This commit is contained in:
Elias Nahum 2018-09-20 13:58:21 -03:00 committed by Saturnino Abril
parent 1d37f9bbec
commit 46b6687d1f
7 changed files with 62 additions and 29 deletions

View file

@ -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);

View file

@ -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};
}
};
}

View file

@ -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];
}

View file

@ -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
};
}
});

View file

@ -122,6 +122,16 @@ class PushNotification {
}
}
localNotification(notification) {
const deviceNotification = {
alertBody: notification.message,
alertAction: '',
userInfo: notification.userInfo,
};
NotificationsIOS.localNotification(deviceNotification);
}
cancelAllLocalNotifications() {
NotificationsIOS.cancelAllLocalNotifications();
}

View file

@ -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,

View file

@ -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",