Local push notification when session expires (#551)
This commit is contained in:
parent
dbafd2f45c
commit
04d63a3e93
7 changed files with 92 additions and 37 deletions
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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: '',
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in a new issue