Local push notification when session expires (#551)

This commit is contained in:
enahum 2017-05-18 08:55:49 -04:00 committed by GitHub
parent dbafd2f45c
commit 04d63a3e93
7 changed files with 92 additions and 37 deletions

View file

@ -1,9 +1,9 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import {GeneralTypes} from 'mattermost-redux/action_types';
import {Client4} from 'mattermost-redux/client';
import {ViewTypes} from 'app/constants';
import {Client4} from 'mattermost-redux/client';
export function handleLoginIdChanged(loginId) {
return async (dispatch, getState) => {
@ -24,14 +24,25 @@ export function handlePasswordChanged(password) {
}
export function handleSuccessfulLogin() {
return async (dispatch) => {
return async (dispatch, getState) => {
const {currentUserId} = getState().entities.users;
const token = Client4.getToken();
const session = await Client4.getSessions(currentUserId, token);
dispatch({
type: GeneralTypes.RECEIVED_APP_CREDENTIALS,
data: {
url: Client4.getUrl(),
token: Client4.getToken()
token
}
});
if (Array.isArray(session) && session[0]) {
const s = session[0];
return s.expires_at;
}
return false;
};
}

View file

@ -5,7 +5,7 @@ import 'babel-polyfill';
import Orientation from 'react-native-orientation';
import {Provider} from 'react-redux';
import {Navigation} from 'react-native-navigation';
import DeviceNotification from 'react-native-push-notification';
import PushNotification from 'react-native-push-notification';
import {
Alert,
AppState,
@ -71,6 +71,7 @@ export default class Mattermost {
handleReset = () => {
Client4.serverVersion = '';
PushNotification.cancelAllLocalNotifications();
this.startApp('fade');
};
@ -100,7 +101,7 @@ export default class Mattermost {
};
configurePushNotifications = () => {
DeviceNotification.configure({
PushNotification.configure({
onRegister: this.onRegisterDevice,
onNotification: this.onPushNotification,
senderID: Config.GooglePlaySenderId,
@ -117,7 +118,7 @@ export default class Mattermost {
};
onPushNotification = (deviceNotification) => {
const {foreground, userInteraction, data, message} = deviceNotification;
const {data, foreground, message, userInfo, userInteraction} = deviceNotification;
let notification;
if (Platform.OS === 'android') {
@ -135,19 +136,25 @@ export default class Mattermost {
};
}
if (userInfo) {
notification.localNotification = userInfo.localNotification;
}
if (foreground) {
EventEmitter.emit(ViewTypes.NOTIFICATION_IN_APP, notification);
} else if (userInteraction) {
const {dispatch, getState} = store;
const state = getState();
if (!state.views.root.appInitializing) {
// go to notification if the app is initialized
goToNotification(notification)(dispatch, getState);
EventEmitter.emit(ViewTypes.NOTIFICATION_TAPPED);
} else if (state.entities.general.credentials.token) {
// queue notification if app is not initialized but we are logged in
queueNotification(notification)(dispatch, getState);
if (!notification.localNotification) {
if (!state.views.root.appInitializing) {
// go to notification if the app is initialized
goToNotification(notification)(dispatch, getState);
EventEmitter.emit(ViewTypes.NOTIFICATION_TAPPED);
} else if (state.entities.general.credentials.token) {
// queue notification if app is not initialized but we are logged in
queueNotification(notification)(dispatch, getState);
}
}
}
};

View file

@ -18,6 +18,7 @@ import {
View
} from 'react-native';
import Button from 'react-native-button';
import PushNotification from 'react-native-push-notification';
import ErrorText from 'app/components/error_text';
import FormattedText from 'app/components/formatted_text';
@ -73,8 +74,23 @@ class Login extends PureComponent {
}
}
goToLoadTeam = () => {
const {navigator, theme} = this.props;
goToLoadTeam = (expiresAt) => {
const {intl, navigator, theme} = this.props;
if (expiresAt) {
PushNotification.localNotificationSchedule({
alertAction: null,
date: new Date(expiresAt),
message: intl.formatMessage({
id: 'mobile.session_expired',
defaultMessage: 'Session Expired: Please log in to continue receiving notifications.'
}),
userInfo: {
localNotification: true
}
});
}
navigator.resetTo({
screen: 'LoadTeam',
title: '',

View file

@ -31,17 +31,19 @@ export default class Notification extends PureComponent {
const {actions, navigator, notification, theme} = this.props;
navigator.dismissInAppNotification();
actions.goToNotification(notification);
navigator.resetTo({
screen: 'Channel',
animated: false,
navigatorStyle: {
navBarHidden: true,
statusBarHidden: false,
statusBarHideWithNavBar: false,
screenBackgroundColor: theme.centerChannelBg
}
});
if (!notification.localNotification) {
actions.goToNotification(notification);
navigator.resetTo({
screen: 'Channel',
animated: false,
navigatorStyle: {
navBarHidden: true,
statusBarHidden: false,
statusBarHideWithNavBar: false,
screenBackgroundColor: theme.centerChannelBg
}
});
}
};
render() {

View file

@ -3,18 +3,21 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {injectIntl, intlShape} from 'react-intl';
import {
InteractionManager,
StatusBar,
View,
WebView
} from 'react-native';
import CookieManager from 'react-native-cookies';
import PushNotification from 'react-native-push-notification';
import {Client4} from 'mattermost-redux/client';
export default class Saml extends PureComponent {
class Saml extends PureComponent {
static propTypes = {
intl: intlShape.isRequired,
navigator: PropTypes.object,
theme: PropTypes.object,
serverUrl: PropTypes.string.isRequired,
@ -30,8 +33,23 @@ export default class Saml extends PureComponent {
});
}
goToLoadTeam = () => {
const {navigator, theme} = this.props;
goToLoadTeam = (expiresAt) => {
const {intl, navigator, theme} = this.props;
if (expiresAt) {
PushNotification.localNotificationSchedule({
alertAction: null,
date: new Date(expiresAt),
message: intl.formatMessage({
id: 'mobile.session_expired',
defaultMessage: 'Session Expired: Please log in to continue receiving notifications.'
}),
userInfo: {
localNotification: true
}
});
}
navigator.resetTo({
screen: 'LoadTeam',
title: '',
@ -63,8 +81,10 @@ export default class Saml extends PureComponent {
Client4.setToken(token);
handleSuccessfulLogin().
then(setStoreFromLocalData.bind(null, {url: this.props.serverUrl, token})).
then(this.goToLoadTeam);
then(async (expiresAt) => {
await setStoreFromLocalData({url: this.props.serverUrl, token});
this.goToLoadTeam(expiresAt);
});
}
});
}
@ -89,3 +109,5 @@ export default class Saml extends PureComponent {
);
}
}
export default injectIntl(Saml);

View file

@ -1745,6 +1745,7 @@
"mobile.routes.user_profile.send_message": "Send Message",
"mobile.server_ping_failed": "Cannot connect to the server. Please check your server URL and internet connection.",
"mobile.server_url.invalid_format": "URL must start with http:// or https://",
"mobile.session_expired": "Session Expired: Please log in to continue receiving notifications.",
"mobile.settings.team_selection": "Team Selection",
"more_channels.close": "Close",
"more_channels.create": "Create New Channel",

View file

@ -3526,7 +3526,7 @@ makeerror@1.0.x:
mattermost-redux@mattermost/mattermost-redux#master:
version "0.0.1"
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/894523bf84013922d344aa4aae374889604097c0"
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/3219aed65ab3ddfd738199db6ae42fe746226782"
dependencies:
deep-equal "1.0.1"
harmony-reflect "1.5.1"
@ -4303,10 +4303,6 @@ react-native-drawer@2.3.0:
dependencies:
tween-functions "^1.0.1"
react-native-image-picker@0.26.3:
version "0.26.3"
resolved "https://registry.yarnpkg.com/react-native-image-picker/-/react-native-image-picker-0.26.3.tgz#0ad2eede49501a7046d8046a73813696539c3dcd"
react-native-image-picker@jp928/react-native-image-picker#6ee35b69f3dbd6c7c66f580fd4d9eabf398703d4:
version "0.26.2"
resolved "https://codeload.github.com/jp928/react-native-image-picker/tar.gz/6ee35b69f3dbd6c7c66f580fd4d9eabf398703d4"