diff --git a/NOTICE.txt b/NOTICE.txt index 29e47752a..db7a2e124 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -650,36 +650,35 @@ SOFTWARE. --- -## react-native-push-notification +## react-native-notifications -This product contains 'react-native-push-notification', a library to provide React Native local and remote notifications for iOS and Android. +This product contains a modified version of 'react-native-notifications', a library to provide React Native local and remote notifications for iOS and Android. * HOMEPAGE - * https://github.com/zo0r/react-native-push-notification + * https://github.com/wix/react-native-notifications * LICENSE: The MIT License (MIT) -Copyright (c) 2015 Dieam +Copyright (c) 2016 Wix.com LTD -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --- diff --git a/android/app/build.gradle b/android/app/build.gradle index 82fff1d46..5732d65c3 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -151,11 +151,11 @@ dependencies { compile project(':react-native-image-picker') compile project(':react-native-orientation') compile project(':react-native-bottom-sheet') - compile project(':react-native-push-notification') compile ('com.google.android.gms:play-services-gcm:9.4.0') { force = true; } compile project(':react-native-device-info') + compile project(':reactnativenotifications') compile project(':react-native-cookies') compile project(':react-native-linear-gradient') compile project(':react-native-vector-icons') diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 643c3972e..63c94bf54 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -29,6 +29,7 @@ android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme" > + - - - - - - - - - - - - - - - - - - + diff --git a/android/app/src/main/java/com/mattermost/CustomPushNotification.java b/android/app/src/main/java/com/mattermost/CustomPushNotification.java new file mode 100644 index 000000000..a78613d9c --- /dev/null +++ b/android/app/src/main/java/com/mattermost/CustomPushNotification.java @@ -0,0 +1,103 @@ +package com.mattermost; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.res.Resources; +import android.content.pm.ApplicationInfo; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Bundle; +import android.os.Build; +import android.app.Notification; + +import com.wix.reactnativenotifications.core.notification.PushNotification; +import com.wix.reactnativenotifications.core.AppLaunchHelper; +import com.wix.reactnativenotifications.core.AppLifecycleFacade; +import com.wix.reactnativenotifications.core.JsIOHelper; +import com.wix.reactnativenotifications.helpers.ApplicationBadgeHelper; + +public class CustomPushNotification extends PushNotification { + + public CustomPushNotification(Context context, Bundle bundle, AppLifecycleFacade appLifecycleFacade, AppLaunchHelper appLaunchHelper, JsIOHelper jsIoHelper) { + super(context, bundle, appLifecycleFacade, appLaunchHelper, jsIoHelper); + } + + @Override + protected void postNotification(int id, Notification notification) { + if (!mAppLifecycleFacade.isAppVisible()) { + super.postNotification(id, notification); + } + } + + @Override + protected Notification.Builder getNotificationBuilder(PendingIntent intent) { + final Resources res = mContext.getResources(); + String packageName = mContext.getPackageName(); + + // First, get a builder initialized with defaults from the core class. + final Notification.Builder notification = super.getNotificationBuilder(intent); + Bundle bundle = mNotificationProps.asBundle(); + String title = bundle.getString("title"); + if (title == null) { + ApplicationInfo appInfo = mContext.getApplicationInfo(); + title = mContext.getPackageManager().getApplicationLabel(appInfo).toString(); + } + notification.setContentTitle(title); + String channelId = bundle.getString("channel_id"); + if (channelId != null) { + notification.setGroup(channelId).setGroupSummary(true); + } + notification.setContentText(bundle.getString("message")); + + String largeIcon = bundle.getString("largeIcon"); + + String subText = bundle.getString("subText"); + + if (subText != null) { + notification.setSubText(subText); + } + + String numberString = bundle.getString("badge"); + if (numberString != null) { + ApplicationBadgeHelper.instance.setApplicationIconBadgeNumber(mContext.getApplicationContext(), Integer.parseInt(numberString)); + } + + int smallIconResId; + int largeIconResId; + + String smallIcon = bundle.getString("smallIcon"); + + if (smallIcon != null) { + smallIconResId = res.getIdentifier(smallIcon, "mipmap", packageName); + } else { + smallIconResId = res.getIdentifier("ic_notification", "mipmap", packageName); + } + + if (smallIconResId == 0) { + smallIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName); + + if (smallIconResId == 0) { + smallIconResId = android.R.drawable.ic_dialog_info; + } + } + + if (largeIcon != null) { + largeIconResId = res.getIdentifier(largeIcon, "mipmap", packageName); + } else { + largeIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName); + } + + Bitmap largeIconBitmap = BitmapFactory.decodeResource(res, largeIconResId); + + if (largeIconResId != 0 && (largeIcon != null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)) { + notification.setLargeIcon(largeIconBitmap); + } + + notification.setSmallIcon(smallIconResId); + notification + .setVisibility(Notification.VISIBILITY_PRIVATE) + .setPriority(Notification.PRIORITY_HIGH); + + return notification; + } +} diff --git a/android/app/src/main/java/com/mattermost/MainApplication.java b/android/app/src/main/java/com/mattermost/MainApplication.java index ad858e09b..5d12ea907 100644 --- a/android/app/src/main/java/com/mattermost/MainApplication.java +++ b/android/app/src/main/java/com/mattermost/MainApplication.java @@ -3,6 +3,8 @@ package com.mattermost; import android.app.Application; import android.util.Log; import android.support.annotation.NonNull; +import android.content.Context; +import android.os.Bundle; import com.facebook.react.ReactApplication; import com.facebook.react.ReactInstanceManager; @@ -15,37 +17,24 @@ import com.imagepicker.ImagePickerPackage; import com.gnet.bottomsheet.RNBottomSheetPackage; import com.learnium.RNDeviceInfo.RNDeviceInfo; import com.psykar.cookiemanager.CookieManagerPackage; -import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage; import com.oblador.vectoricons.VectorIconsPackage; import com.horcrux.svg.SvgPackage; import com.BV.LinearGradient.LinearGradientPackage; import com.github.yamill.orientation.OrientationPackage; import com.reactnativenavigation.NavigationApplication; +import com.wix.reactnativenotifications.RNNotificationsPackage; +import com.wix.reactnativenotifications.core.notification.INotificationsApplication; +import com.wix.reactnativenotifications.core.notification.IPushNotification; +import com.wix.reactnativenotifications.core.AppLaunchHelper; +import com.wix.reactnativenotifications.core.AppLifecycleFacade; +import com.wix.reactnativenotifications.core.JsIOHelper; import java.util.Arrays; import java.util.List; -// public class MainApplication extends Application implements ReactApplication { -public class MainApplication extends NavigationApplication { +public class MainApplication extends NavigationApplication implements INotificationsApplication { - // private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { - // @Override - // protected boolean getUseDeveloperSupport() { - // return BuildConfig.DEBUG; - // } - // - // @Override - // protected List getPackages() { - // return Arrays.asList( - // new MainReactPackage() - // ); - // } - // }; - // - // @Override - // public ReactNativeHost getReactNativeHost() { - // return mReactNativeHost; - // } + NotificationsLifecycleFacade notificationsLifecycleFacade; @Override public boolean isDebug() { @@ -62,17 +51,35 @@ public class MainApplication extends NavigationApplication { new RNBottomSheetPackage(), new RNDeviceInfo(), new CookieManagerPackage(), - new ReactNativePushNotificationPackage(), new VectorIconsPackage(), new SvgPackage(), new LinearGradientPackage(), - new OrientationPackage() + new OrientationPackage(), + new RNNotificationsPackage(MainApplication.this) ); } @Override public void onCreate() { super.onCreate(); + + // Create an object of the custom facade impl + notificationsLifecycleFacade = new NotificationsLifecycleFacade(); + // Attach it to react-native-navigation + setActivityCallbacks(notificationsLifecycleFacade); + + SoLoader.init(this, /* native exopackage */ false); } + + @Override + public IPushNotification getPushNotification(Context context, Bundle bundle, AppLifecycleFacade defaultFacade, AppLaunchHelper defaultAppLaunchHelper) { + return new CustomPushNotification( + context, + bundle, + notificationsLifecycleFacade, // Instead of defaultFacade!!! + defaultAppLaunchHelper, + new JsIOHelper() + ); + } } diff --git a/android/app/src/main/java/com/mattermost/NotificationsLifecycleFacade.java b/android/app/src/main/java/com/mattermost/NotificationsLifecycleFacade.java new file mode 100644 index 000000000..2fd8ad9e4 --- /dev/null +++ b/android/app/src/main/java/com/mattermost/NotificationsLifecycleFacade.java @@ -0,0 +1,91 @@ +package com.mattermost; + +import android.app.Activity; +import android.util.Log; + +import com.facebook.react.bridge.ReactContext; +import com.reactnativenavigation.NavigationApplication; +import com.reactnativenavigation.controllers.ActivityCallbacks; +import com.reactnativenavigation.react.ReactGateway; +import com.wix.reactnativenotifications.core.AppLifecycleFacade; + +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +public class NotificationsLifecycleFacade extends ActivityCallbacks implements AppLifecycleFacade { + + private static final String TAG = NotificationsLifecycleFacade.class.getSimpleName(); + + private Activity mVisibleActivity; + private Set mListeners = new CopyOnWriteArraySet<>(); + + @Override + public void onActivityResumed(Activity activity) { + switchToVisible(activity); + } + + @Override + public void onActivityPaused(Activity activity) { + switchToInvisible(activity); + } + + @Override + public void onActivityStopped(Activity activity) { + switchToInvisible(activity); + } + + @Override + public void onActivityDestroyed(Activity activity) { + switchToInvisible(activity); + } + + @Override + public boolean isReactInitialized() { + return NavigationApplication.instance.isReactContextInitialized(); + } + + @Override + public ReactContext getRunningReactContext() { + final ReactGateway reactGateway = NavigationApplication.instance.getReactGateway(); + if (reactGateway == null || !reactGateway.isInitialized()) { + return null; + } + + return reactGateway.getReactContext(); + } + + @Override + public boolean isAppVisible() { + return mVisibleActivity != null; + } + + @Override + public synchronized void addVisibilityListener(AppVisibilityListener listener) { + mListeners.add(listener); + } + + @Override + public synchronized void removeVisibilityListener(AppVisibilityListener listener) { + mListeners.remove(listener); + } + + private synchronized void switchToVisible(Activity activity) { + if (mVisibleActivity == null) { + mVisibleActivity = activity; + Log.v(TAG, "Activity is now visible ("+activity+")"); + for (AppVisibilityListener listener : mListeners) { + listener.onAppVisible(); + } + } + } + + private synchronized void switchToInvisible(Activity activity) { + if (mVisibleActivity == activity) { + mVisibleActivity = null; + Log.v(TAG, "Activity is now NOT visible ("+activity+")"); + for (AppVisibilityListener listener : mListeners) { + listener.onAppNotVisible(); + } + } + } +} diff --git a/android/settings.gradle b/android/settings.gradle index e8f264566..1f8b709f2 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -9,10 +9,10 @@ include ':react-native-device-info' project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android') include ':react-native-cookies' project(':react-native-cookies').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-cookies/android') -include ':react-native-push-notification' -project(':react-native-push-notification').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-push-notification/android') include ':react-native-vector-icons' project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') +include ':reactnativenotifications' +project(':reactnativenotifications').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-notifications/android') include ':app' include ':react-native-orientation' diff --git a/app/components/root/root.js b/app/components/root/root.js index 791362551..203d95aec 100644 --- a/app/components/root/root.js +++ b/app/components/root/root.js @@ -14,19 +14,24 @@ export default class Root extends PureComponent { static propTypes = { children: PropTypes.node, navigator: PropTypes.object, + excludeEvents: PropTypes.bool, currentChannelId: PropTypes.string, locale: PropTypes.string.isRequired, theme: PropTypes.object.isRequired }; - componentWillMount() { - EventEmitter.on(ViewTypes.NOTIFICATION_IN_APP, this.handleInAppNotification); - EventEmitter.on(ViewTypes.NOTIFICATION_TAPPED, this.handleNotificationTapped); + componentDidMount() { + if (!this.props.excludeEvents) { + EventEmitter.on(ViewTypes.NOTIFICATION_IN_APP, this.handleInAppNotification); + EventEmitter.on(ViewTypes.NOTIFICATION_TAPPED, this.handleNotificationTapped); + } } componentWillUnmount() { - EventEmitter.off(ViewTypes.NOTIFICATION_IN_APP, this.handleInAppNotification); - EventEmitter.off(ViewTypes.NOTIFICATION_TAPPED, this.handleNotificationTapped); + if (!this.props.excludeEvents) { + EventEmitter.off(ViewTypes.NOTIFICATION_IN_APP, this.handleInAppNotification); + EventEmitter.off(ViewTypes.NOTIFICATION_TAPPED, this.handleNotificationTapped); + } } handleInAppNotification = (notification) => { diff --git a/app/mattermost.js b/app/mattermost.js index dbe3e920f..daf4fbadd 100644 --- a/app/mattermost.js +++ b/app/mattermost.js @@ -5,7 +5,6 @@ import 'babel-polyfill'; import Orientation from 'react-native-orientation'; import {Provider} from 'react-redux'; import {Navigation} from 'react-native-navigation'; -import PushNotification from 'react-native-push-notification'; import { Alert, AppState, @@ -24,6 +23,7 @@ import EventEmitter from 'mattermost-redux/utils/event_emitter'; import {goToNotification, loadConfigAndLicense, queueNotification} from 'app/actions/views/root'; import {NavigationTypes, ViewTypes} from 'app/constants'; import initialState from 'app/initial_state'; +import PushNotifications from 'app/push_notifications'; import {registerScreens} from 'app/screens'; import configureStore from 'app/store'; @@ -73,7 +73,7 @@ export default class Mattermost { handleReset = () => { const {dispatch, getState} = store; Client4.serverVersion = ''; - PushNotification.cancelAllLocalNotifications(); + PushNotifications.cancelAllLocalNotifications(); setServerVersion('')(dispatch, getState); this.startApp('fade'); }; @@ -82,7 +82,7 @@ export default class Mattermost { const {dispatch, getState} = store; Client4.serverVersion = ''; - PushNotification.setApplicationIconBadgeNumber(0); + PushNotifications.setApplicationIconBadgeNumber(0); if (getState().entities.general.credentials.token) { InteractionManager.runAfterInteractions(() => { @@ -101,10 +101,9 @@ export default class Mattermost { }; configurePushNotifications = () => { - PushNotification.configure({ + PushNotifications.configure({ onRegister: this.onRegisterDevice, onNotification: this.onPushNotification, - senderID: Config.GooglePlaySenderId, popInitialNotification: true, requestPermissions: true }); @@ -119,27 +118,10 @@ export default class Mattermost { onPushNotification = (deviceNotification) => { const {data, foreground, message, userInfo, userInteraction} = deviceNotification; - let notification; - - if (Platform.OS === 'android') { - notification = { - data: { - channel_id: deviceNotification.channel_id, - channel_name: deviceNotification.channel_name, - sender_id: deviceNotification.sender_id, - override_username: deviceNotification.override_username, - override_icon_url: deviceNotification.override_icon_url, - from_webhook: deviceNotification.from_webhook, - team_id: deviceNotification.team_id - }, - message - }; - } else { - notification = { - data, - message - }; - } + const notification = { + data, + message + }; if (userInfo) { notification.localNotification = userInfo.localNotification; @@ -165,7 +147,9 @@ export default class Mattermost { }; startApp = (animationType = 'none') => { - this.configurePushNotifications(); + if (animationType === 'none') { + this.configurePushNotifications(); + } Navigation.startSingleScreenApp({ screen: { diff --git a/app/push_notifications/index.js b/app/push_notifications/index.js new file mode 100644 index 000000000..bc5f085dc --- /dev/null +++ b/app/push_notifications/index.js @@ -0,0 +1,5 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import PushNotifications from './push_notifications'; +export default PushNotifications; diff --git a/app/push_notifications/push_notifications.android.js b/app/push_notifications/push_notifications.android.js new file mode 100644 index 000000000..6ec052f7e --- /dev/null +++ b/app/push_notifications/push_notifications.android.js @@ -0,0 +1,87 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import {AppState} from 'react-native'; +import {NotificationsAndroid, PendingNotifications} from 'react-native-notifications'; + +class PushNotification { + constructor() { + this.onRegister = null; + this.onNotification = null; + + NotificationsAndroid.setNotificationReceivedListener((notification) => { + const data = notification.getData(); + + if (notification) { + this.handleNotification(data, false); + } + }); + + NotificationsAndroid.setNotificationOpenedListener((notification) => { + const data = notification.getData(); + + if (notification) { + this.handleNotification(data, true); + } + }); + } + + handleNotification = (data, userInteraction) => { + const deviceNotification = { + data, + foreground: !userInteraction && AppState.currentState === 'active', + message: data.message, + userInfo: data.userInfo, + userInteraction + }; + + if (this.onNotification) { + this.onNotification(deviceNotification); + } + }; + + configure(options) { + this.onRegister = options.onRegister; + this.onNotification = options.onNotification; + + NotificationsAndroid.refreshToken(); + NotificationsAndroid.setRegistrationTokenUpdateListener((deviceToken) => { + if (this.onRegister) { + this.onRegister({token: deviceToken}); + } + }); + + if (options.popInitialNotification) { + PendingNotifications.getInitialNotification(). + then((notification) => { + if (notification) { + const data = notification.getData(); + if (data) { + this.handleNotification(data, true); + } + } + }). + catch((err) => { + console.log('Android getInitialNotifiation() failed', err); //eslint-disable-line no-console + }); + } + } + + localNotificationSchedule(notification) { + if (notification.date) { + notification.fireDate = notification.date.getTime(); + Reflect.deleteProperty(notification, 'date'); + NotificationsAndroid.scheduleLocalNotification(notification); + } + } + + cancelAllLocalNotifications() { + NotificationsAndroid.cancelAllLocalNotifications(); + } + + setApplicationIconBadgeNumber(number) { + NotificationsAndroid.setBadgesCount(number); + } +} + +export default new PushNotification(); diff --git a/app/push_notifications/push_notifications.ios.js b/app/push_notifications/push_notifications.ios.js new file mode 100644 index 000000000..eef25fadf --- /dev/null +++ b/app/push_notifications/push_notifications.ios.js @@ -0,0 +1,96 @@ +// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import {AppState} from 'react-native'; +import NotificationsIOS from 'react-native-notifications'; + +class PushNotification { + constructor() { + this.onRegister = null; + this.onNotification = null; + + NotificationsIOS.addEventListener('notificationReceivedForeground', (notification) => { + const info = { + ...notification.getData(), + message: notification.getMessage() + }; + this.handleNotification(info, true, false); + }); + + NotificationsIOS.addEventListener('notificationReceivedBackground', (notification) => { + const info = { + ...notification.getData(), + message: notification.getMessage() + }; + this.handleNotification(info, false, false); + }); + + NotificationsIOS.addEventListener('notificationOpened', (notification) => { + const info = { + ...notification.getData(), + message: notification.getMessage() + }; + this.handleNotification(info, false, true); + }); + } + + handleNotification = (data, foreground, userInteraction) => { + const deviceNotification = { + data, + foreground: foreground || (!userInteraction && AppState.currentState === 'active'), + message: data.message, + userInfo: data.userInfo, + userInteraction + }; + + if (this.onNotification) { + this.onNotification(deviceNotification); + } + }; + + configure(options) { + this.onRegister = options.onRegister; + this.onNotification = options.onNotification; + + NotificationsIOS.addEventListener('remoteNotificationsRegistered', (deviceToken) => { + if (this.onRegister) { + this.onRegister({token: deviceToken}); + } + }); + + if (options.requestPermissions) { + this.requestPermissions(); + } + + if (options.popInitialNotification) { + NotificationsIOS.consumeBackgroundQueue(); + } + } + + requestPermissions = () => { + NotificationsIOS.requestPermissions(); + }; + + localNotificationSchedule(notification) { + if (notification.date) { + const deviceNotification = { + fireDate: notification.date.toISOString(), + alertBody: notification.message, + alertAction: '', + userInfo: notification.userInfo + }; + + NotificationsIOS.localNotification(deviceNotification); + } + } + + cancelAllLocalNotifications() { + NotificationsIOS.cancelAllLocalNotifications(); + } + + setApplicationIconBadgeNumber(number) { + NotificationsIOS.setBadgesCount(number); + } +} + +export default new PushNotification(); diff --git a/app/screens/channel/channel_drawer_button.js b/app/screens/channel/channel_drawer_button.js index da2de395c..a6d796467 100644 --- a/app/screens/channel/channel_drawer_button.js +++ b/app/screens/channel/channel_drawer_button.js @@ -11,10 +11,11 @@ import { TouchableOpacity, View } from 'react-native'; -import DeviceNotification from 'react-native-push-notification'; + import Icon from 'react-native-vector-icons/Ionicons'; import Badge from 'app/components/badge'; +import PushNotifications from 'app/push_notifications'; import {getTheme} from 'app/selectors/preferences'; import {preventDoubleTap} from 'app/utils/tap'; import {makeStyleSheetFromTheme} from 'app/utils/theme'; @@ -63,7 +64,7 @@ class ChannelDrawerButton extends PureComponent { } componentWillReceiveProps(nextProps) { - DeviceNotification.setApplicationIconBadgeNumber(nextProps.mentionCount); + PushNotifications.setApplicationIconBadgeNumber(nextProps.mentionCount); } componentWillUnmount() { diff --git a/app/screens/index.js b/app/screens/index.js index 17a216224..52f770fdd 100644 --- a/app/screens/index.js +++ b/app/screens/index.js @@ -32,11 +32,14 @@ import UserProfile from 'app/screens/user_profile'; import IntlWrapper from 'app/components/root'; -function wrapWithContextProvider(Comp) { +function wrapWithContextProvider(Comp, excludeEvents = false) { return (props) => { //eslint-disable-line react/display-name const {navigator} = props; //eslint-disable-line react/prop-types return ( - + ); @@ -61,7 +64,7 @@ export function registerScreens(store, Provider) { Navigation.registerComponent('MoreChannels', () => wrapWithContextProvider(MoreChannels), store, Provider); Navigation.registerComponent('MoreDirectMessages', () => wrapWithContextProvider(MoreDirectMessages), store, Provider); Navigation.registerComponent('OptionsModal', () => wrapWithContextProvider(OptionsModal), store, Provider); - Navigation.registerComponent('Notification', () => wrapWithContextProvider(Notification), store, Provider); + Navigation.registerComponent('Notification', () => wrapWithContextProvider(Notification, true), store, Provider); Navigation.registerComponent('Root', () => Root, store, Provider); Navigation.registerComponent('SelectServer', () => wrapWithContextProvider(SelectServer), store, Provider); Navigation.registerComponent('SelectTeam', () => wrapWithContextProvider(SelectTeam), store, Provider); diff --git a/app/screens/login/login.js b/app/screens/login/login.js index cd016da4c..97fa9a406 100644 --- a/app/screens/login/login.js +++ b/app/screens/login/login.js @@ -18,10 +18,10 @@ 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'; +import PushNotifications from 'app/push_notifications'; import {GlobalStyles} from 'app/styles'; import logo from 'assets/images/logo.png'; @@ -78,8 +78,7 @@ class Login extends PureComponent { const {intl, navigator, theme} = this.props; if (expiresAt) { - PushNotification.localNotificationSchedule({ - alertAction: null, + PushNotifications.localNotificationSchedule({ date: new Date(expiresAt), message: intl.formatMessage({ id: 'mobile.session_expired', diff --git a/app/screens/sso/sso.js b/app/screens/sso/sso.js index 6412e36ae..cd5e7f77a 100644 --- a/app/screens/sso/sso.js +++ b/app/screens/sso/sso.js @@ -11,12 +11,12 @@ import { WebView } from 'react-native'; import CookieManager from 'react-native-cookies'; -import PushNotification from 'react-native-push-notification'; import {Client4} from 'mattermost-redux/client'; import {ViewTypes} from 'app/constants'; import Loading from 'app/components/loading'; +import PushNotifications from 'app/push_notifications'; class SSO extends PureComponent { static propTypes = { @@ -56,8 +56,7 @@ class SSO extends PureComponent { const {intl, navigator, theme} = this.props; if (expiresAt) { - PushNotification.localNotificationSchedule({ - alertAction: null, + PushNotifications.localNotificationSchedule({ date: new Date(expiresAt), message: intl.formatMessage({ id: 'mobile.session_expired', diff --git a/assets/base/config.json b/assets/base/config.json index bdebd5764..1ea80e91a 100644 --- a/assets/base/config.json +++ b/assets/base/config.json @@ -4,6 +4,5 @@ "DefaultLocale": "en", "DefaultTheme": "default", "ShowErrorsList": false, - "GooglePlaySenderId": "184930218130", "MinServerVersion": "3.8.0" } diff --git a/ios/Mattermost.xcodeproj/project.pbxproj b/ios/Mattermost.xcodeproj/project.pbxproj index c12c5dcd3..5e15d50d3 100644 --- a/ios/Mattermost.xcodeproj/project.pbxproj +++ b/ios/Mattermost.xcodeproj/project.pbxproj @@ -5,6 +5,7 @@ }; objectVersion = 46; objects = { + /* Begin PBXBuildFile section */ 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; @@ -12,6 +13,8 @@ 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 00E356F31AD99517003FC87E /* MattermostTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* MattermostTests.m */; }; + 0111A42B7F264BCF8CBDE3ED /* OpenSans-ExtraBoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FBBEC29EE2D3418D9AC33BD5 /* OpenSans-ExtraBoldItalic.ttf */; }; + 0C0D24F53F254F75869E5951 /* OpenSans-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */; }; 10CD747CE4304BD6AB38B4CD /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EE671DF7637347CD8C069819 /* libRNDeviceInfo.a */; }; 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; @@ -23,18 +26,22 @@ 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 1BCA51319AC6442991C6A208 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0A091BF1A3D04650AD306A0D /* Zocial.ttf */; }; 2B4C9B708010475DA575B81D /* SimpleLineIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F1F071EE85494E269A50AE88 /* SimpleLineIcons.ttf */; }; + 2D5296A8926B4D7FBAF2D6E2 /* OpenSans-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6561AEAC21CC40B8A72ABB93 /* OpenSans-Light.ttf */; }; 2E3655C7E15049DBBC3A666B /* libRNImagePicker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DFE628F5A526417D85AD635E /* libRNImagePicker.a */; }; 374634801E8480C2005E1244 /* libRCTOrientation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 374634671E848085005E1244 /* libRCTOrientation.a */; }; 382D94CF15EE4FC292C3F341 /* Foundation.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 51F5A483EA9F4A9A87ACFB59 /* Foundation.ttf */; }; 3D38ABA732A34A9BB3294F90 /* EvilIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 349FBA7338E74D9BBD709528 /* EvilIcons.ttf */; }; 420A7328E12C4B72AEF420CE /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = EDC04CBCF81642219D199CBB /* Octicons.ttf */; }; + 55C6561DDBBA45929D88B6D1 /* OpenSans-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */; }; 584837D6B55F405F908A2053 /* libBVLinearGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ACC6B9FDC0AD45A6BFA4FBCD /* libBVLinearGradient.a */; }; 5E1AF7B72B8D4A4E9E53FF9D /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 005346E5C0E542BFABAE1411 /* FontAwesome.ttf */; }; 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; + 62A8448264674B4D95A5A7C2 /* OpenSans-Semibold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C78A387124874496AD2C1466 /* OpenSans-Semibold.ttf */; }; + 69AC753E496743BABB7A7124 /* OpenSans-SemiboldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0E617BF0F36D4E738F51D169 /* OpenSans-SemiboldItalic.ttf */; }; + 7F2691A11EE1DC6A007574FE /* libRNNotifications.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F2691A01EE1DC51007574FE /* libRNNotifications.a */; }; 7F292A711E8AB73400A450A3 /* SplashScreenResource in Resources */ = {isa = PBXBuildFile; fileRef = 7F292A701E8AB73400A450A3 /* SplashScreenResource */; }; 7F292AA61E8ABB1100A450A3 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7F292AA41E8ABB1100A450A3 /* LaunchScreen.xib */; }; 7F292AA71E8ABB1100A450A3 /* splash.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F292AA51E8ABB1100A450A3 /* splash.png */; }; - 7F63D2841E6C9585001FAE12 /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F63D2811E6C957C001FAE12 /* libRCTPushNotification.a */; }; 7F6877B31E7836070094B63F /* libToolTipMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F6877B01E7835E50094B63F /* libToolTipMenu.a */; }; 7FBB5E9A1E1F5A4B000DE18A /* libRNSVG.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FDF28E11E1F4B1F00DBBE56 /* libRNSVG.a */; }; 7FBB5E9B1E1F5A4B000DE18A /* libRNVectorIcons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FDF290C1E1F4B4E00DBBE56 /* libRNVectorIcons.a */; }; @@ -42,20 +49,14 @@ 7FED0C321E7C4AAC001A7CCA /* libRNCookieManagerIOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F906D971E6A1ADF00B8F49A /* libRNCookieManagerIOS.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 895C9A56B94A45C1BAF568FE /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AC6EB561E1F64C17A69D2FAD /* Entypo.ttf */; }; + 9358B95F95184EE0A4DCE629 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */; }; + A08D512E7ADC40CCAD055A9E /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */; }; B50561A109B4442299F82327 /* libRNSearchBar.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F81F6DC42D394831B4549928 /* libRNSearchBar.a */; }; C035DB50ED2045F09923FFAE /* MaterialCommunityIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 04AA5E8EF3B54735A11E3B95 /* MaterialCommunityIcons.ttf */; }; C337E8708D2845C6A8DBB47E /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2DCFD31D3F4A4154822AB532 /* Ionicons.ttf */; }; - F006936FC2884C24A1321FC0 /* MaterialIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 356C9186FA374641A00EB2EA /* MaterialIcons.ttf */; }; - 9358B95F95184EE0A4DCE629 /* OpenSans-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */; }; - 55C6561DDBBA45929D88B6D1 /* OpenSans-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */; }; D719A67137964F08BE47A5FC /* OpenSans-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 3647DF63D6764CF093375861 /* OpenSans-ExtraBold.ttf */; }; - 0111A42B7F264BCF8CBDE3ED /* OpenSans-ExtraBoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FBBEC29EE2D3418D9AC33BD5 /* OpenSans-ExtraBoldItalic.ttf */; }; - 0C0D24F53F254F75869E5951 /* OpenSans-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */; }; - 2D5296A8926B4D7FBAF2D6E2 /* OpenSans-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6561AEAC21CC40B8A72ABB93 /* OpenSans-Light.ttf */; }; + F006936FC2884C24A1321FC0 /* MaterialIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 356C9186FA374641A00EB2EA /* MaterialIcons.ttf */; }; F083DB472349411A8E6E7AAD /* OpenSans-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */; }; - A08D512E7ADC40CCAD055A9E /* OpenSans-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */; }; - 62A8448264674B4D95A5A7C2 /* OpenSans-Semibold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C78A387124874496AD2C1466 /* OpenSans-Semibold.ttf */; }; - 69AC753E496743BABB7A7124 /* OpenSans-SemiboldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0E617BF0F36D4E738F51D169 /* OpenSans-SemiboldItalic.ttf */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -262,6 +263,13 @@ remoteGlobalIDString = 134814201AA4EA6300B7C361; remoteInfo = RCTLinking; }; + 7F26919F1EE1DC51007574FE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7F26919B1EE1DC51007574FE /* RNNotifications.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = RNNotifications; + }; 7F4890681E3B7D3B008EDBEA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 59954D479A89488091EB588F /* RNSearchBar.xcodeproj */; @@ -359,6 +367,7 @@ 00E356F21AD99517003FC87E /* MattermostTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MattermostTests.m; sourceTree = ""; }; 04AA5E8EF3B54735A11E3B95 /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialCommunityIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf"; sourceTree = ""; }; 0A091BF1A3D04650AD306A0D /* Zocial.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Zocial.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Zocial.ttf"; sourceTree = ""; }; + 0E617BF0F36D4E738F51D169 /* OpenSans-SemiboldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-SemiboldItalic.ttf"; path = "../assets/fonts/OpenSans-SemiboldItalic.ttf"; sourceTree = ""; }; 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* Mattermost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Mattermost.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -372,14 +381,19 @@ 2CBE9C0FB56E4FDA96C30792 /* RNSVG.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNSVG.xcodeproj; path = "../node_modules/react-native-svg/ios/RNSVG.xcodeproj"; sourceTree = ""; }; 2DCFD31D3F4A4154822AB532 /* Ionicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Ionicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Ionicons.ttf"; sourceTree = ""; }; 31A0780E2F224AC8AF8E6930 /* RNCookieManagerIOS.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNCookieManagerIOS.xcodeproj; path = "../node_modules/react-native-cookies/RNCookieManagerIOS.xcodeproj"; sourceTree = ""; }; + 32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-BoldItalic.ttf"; path = "../assets/fonts/OpenSans-BoldItalic.ttf"; sourceTree = ""; }; 349FBA7338E74D9BBD709528 /* EvilIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = EvilIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"; sourceTree = ""; }; 356C9186FA374641A00EB2EA /* MaterialIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = MaterialIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/MaterialIcons.ttf"; sourceTree = ""; }; + 3647DF63D6764CF093375861 /* OpenSans-ExtraBold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-ExtraBold.ttf"; path = "../assets/fonts/OpenSans-ExtraBold.ttf"; sourceTree = ""; }; + 41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Italic.ttf"; path = "../assets/fonts/OpenSans-Italic.ttf"; sourceTree = ""; }; 51F5A483EA9F4A9A87ACFB59 /* Foundation.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Foundation.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Foundation.ttf"; sourceTree = ""; }; 59954D479A89488091EB588F /* RNSearchBar.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNSearchBar.xcodeproj; path = "../node_modules/react-native-search-bar/RNSearchBar.xcodeproj"; sourceTree = ""; }; 5C3B95629BA74FB3A8377CB7 /* RCTOrientation.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RCTOrientation.xcodeproj; path = "../node_modules/react-native-orientation/iOS/RCTOrientation.xcodeproj"; sourceTree = ""; }; 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; }; + 6561AEAC21CC40B8A72ABB93 /* OpenSans-Light.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Light.ttf"; path = "../assets/fonts/OpenSans-Light.ttf"; sourceTree = ""; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 7DCC3D826CE640AF8F491692 /* BVLinearGradient.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = BVLinearGradient.xcodeproj; path = "../node_modules/react-native-linear-gradient/BVLinearGradient.xcodeproj"; sourceTree = ""; }; + 7F26919B1EE1DC51007574FE /* RNNotifications.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNNotifications.xcodeproj; path = "../node_modules/react-native-notifications/RNNotifications/RNNotifications.xcodeproj"; sourceTree = ""; }; 7F292A701E8AB73400A450A3 /* SplashScreenResource */ = {isa = PBXFileReference; lastKnownFileType = folder; path = SplashScreenResource; sourceTree = ""; }; 7F292AA41E8ABB1100A450A3 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = LaunchScreen.xib; path = SplashScreenResource/LaunchScreen.xib; sourceTree = ""; }; 7F292AA51E8ABB1100A450A3 /* splash.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = splash.png; path = SplashScreenResource/splash.png; sourceTree = ""; }; @@ -392,21 +406,16 @@ AC6EB561E1F64C17A69D2FAD /* Entypo.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Entypo.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"; sourceTree = ""; }; ACC6B9FDC0AD45A6BFA4FBCD /* libBVLinearGradient.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libBVLinearGradient.a; sourceTree = ""; }; B97AA6F961BB47D3A3297E8E /* RNDeviceInfo.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNDeviceInfo.xcodeproj; path = "../node_modules/react-native-device-info/RNDeviceInfo.xcodeproj"; sourceTree = ""; }; + BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Regular.ttf"; path = "../assets/fonts/OpenSans-Regular.ttf"; sourceTree = ""; }; + BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-LightItalic.ttf"; path = "../assets/fonts/OpenSans-LightItalic.ttf"; sourceTree = ""; }; + C78A387124874496AD2C1466 /* OpenSans-Semibold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Semibold.ttf"; path = "../assets/fonts/OpenSans-Semibold.ttf"; sourceTree = ""; }; + D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-Bold.ttf"; path = "../assets/fonts/OpenSans-Bold.ttf"; sourceTree = ""; }; DFE628F5A526417D85AD635E /* libRNImagePicker.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNImagePicker.a; sourceTree = ""; }; EDC04CBCF81642219D199CBB /* Octicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Octicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Octicons.ttf"; sourceTree = ""; }; EE671DF7637347CD8C069819 /* libRNDeviceInfo.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNDeviceInfo.a; sourceTree = ""; }; F1F071EE85494E269A50AE88 /* SimpleLineIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = SimpleLineIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf"; sourceTree = ""; }; F81F6DC42D394831B4549928 /* libRNSearchBar.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSearchBar.a; sourceTree = ""; }; - D4B1B363C2414DA19C1AC521 /* OpenSans-Bold.ttf */ = {isa = PBXFileReference; name = "OpenSans-Bold.ttf"; path = "../assets/fonts/OpenSans-Bold.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 32AC3D4EA79E44738A6E9766 /* OpenSans-BoldItalic.ttf */ = {isa = PBXFileReference; name = "OpenSans-BoldItalic.ttf"; path = "../assets/fonts/OpenSans-BoldItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 3647DF63D6764CF093375861 /* OpenSans-ExtraBold.ttf */ = {isa = PBXFileReference; name = "OpenSans-ExtraBold.ttf"; path = "../assets/fonts/OpenSans-ExtraBold.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - FBBEC29EE2D3418D9AC33BD5 /* OpenSans-ExtraBoldItalic.ttf */ = {isa = PBXFileReference; name = "OpenSans-ExtraBoldItalic.ttf"; path = "../assets/fonts/OpenSans-ExtraBoldItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 41F3AFE83AAF4B74878AB78A /* OpenSans-Italic.ttf */ = {isa = PBXFileReference; name = "OpenSans-Italic.ttf"; path = "../assets/fonts/OpenSans-Italic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 6561AEAC21CC40B8A72ABB93 /* OpenSans-Light.ttf */ = {isa = PBXFileReference; name = "OpenSans-Light.ttf"; path = "../assets/fonts/OpenSans-Light.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - BE17F630DB5D41FD93F32D22 /* OpenSans-LightItalic.ttf */ = {isa = PBXFileReference; name = "OpenSans-LightItalic.ttf"; path = "../assets/fonts/OpenSans-LightItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - BC977883E2624E05975CA65B /* OpenSans-Regular.ttf */ = {isa = PBXFileReference; name = "OpenSans-Regular.ttf"; path = "../assets/fonts/OpenSans-Regular.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - C78A387124874496AD2C1466 /* OpenSans-Semibold.ttf */ = {isa = PBXFileReference; name = "OpenSans-Semibold.ttf"; path = "../assets/fonts/OpenSans-Semibold.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 0E617BF0F36D4E738F51D169 /* OpenSans-SemiboldItalic.ttf */ = {isa = PBXFileReference; name = "OpenSans-SemiboldItalic.ttf"; path = "../assets/fonts/OpenSans-SemiboldItalic.ttf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + FBBEC29EE2D3418D9AC33BD5 /* OpenSans-ExtraBoldItalic.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "OpenSans-ExtraBoldItalic.ttf"; path = "../assets/fonts/OpenSans-ExtraBoldItalic.ttf"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -436,7 +445,6 @@ 374634801E8480C2005E1244 /* libRCTOrientation.a in Frameworks */, 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, - 7F63D2841E6C9585001FAE12 /* libRCTPushNotification.a in Frameworks */, B50561A109B4442299F82327 /* libRNSearchBar.a in Frameworks */, 7FED0C321E7C4AAC001A7CCA /* libRNCookieManagerIOS.a in Frameworks */, 10CD747CE4304BD6AB38B4CD /* libRNDeviceInfo.a in Frameworks */, @@ -444,6 +452,7 @@ 7F6877B31E7836070094B63F /* libToolTipMenu.a in Frameworks */, 2E3655C7E15049DBBC3A666B /* libRNImagePicker.a in Frameworks */, 7FC200E81EBB65370099331B /* libReactNativeNavigation.a in Frameworks */, + 7F2691A11EE1DC6A007574FE /* libRNNotifications.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -634,6 +643,14 @@ name = Products; sourceTree = ""; }; + 7F26919C1EE1DC51007574FE /* Products */ = { + isa = PBXGroup; + children = ( + 7F2691A01EE1DC51007574FE /* libRNNotifications.a */, + ); + name = Products; + sourceTree = ""; + }; 7F48904C1E3B7D3B008EDBEA /* Products */ = { isa = PBXGroup; children = ( @@ -695,6 +712,7 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( + 7F26919B1EE1DC51007574FE /* RNNotifications.xcodeproj */, 7FC200BC1EBB65100099331B /* ReactNativeNavigation.xcodeproj */, 7F6877AA1E7835E50094B63F /* ToolTipMenu.xcodeproj */, 7F63D27B1E6C957C001FAE12 /* RCTPushNotification.xcodeproj */, @@ -901,6 +919,10 @@ ProductGroup = 3779BE7C1EB1235400D081C1 /* Products */; ProjectRef = 85E82BCA0FD245EEA520D106 /* RNImagePicker.xcodeproj */; }, + { + ProductGroup = 7F26919C1EE1DC51007574FE /* Products */; + ProjectRef = 7F26919B1EE1DC51007574FE /* RNNotifications.xcodeproj */; + }, { ProductGroup = 7F48904C1E3B7D3B008EDBEA /* Products */; ProjectRef = 59954D479A89488091EB588F /* RNSearchBar.xcodeproj */; @@ -1123,6 +1145,13 @@ remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 7F2691A01EE1DC51007574FE /* libRNNotifications.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRNNotifications.a; + remoteRef = 7F26919F1EE1DC51007574FE /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 7F4890691E3B7D3B008EDBEA /* libRNSearchBar.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -1293,9 +1322,7 @@ INFOPLIST_FILE = MattermostTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mattermost.app/Mattermost"; @@ -1310,9 +1337,7 @@ INFOPLIST_FILE = MattermostTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mattermost.app/Mattermost"; @@ -1335,6 +1360,7 @@ "$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen/**", "$(SRCROOT)/../node_modules/react-native-image-picker/ios", "$(SRCROOT)/../node_modules/react-native-navigation/ios/**", + "$(SRCROOT)/../node_modules/react-native-notifications/RNNotifications/**", ); INFOPLIST_FILE = Mattermost/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1367,6 +1393,7 @@ "$(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen/**", "$(SRCROOT)/../node_modules/react-native-image-picker/ios", "$(SRCROOT)/../node_modules/react-native-navigation/ios/**", + "$(SRCROOT)/../node_modules/react-native-notifications/RNNotifications/**", ); INFOPLIST_FILE = Mattermost/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; diff --git a/ios/Mattermost/AppDelegate.m b/ios/Mattermost/AppDelegate.m index bca1affdc..32a1b3b44 100644 --- a/ios/Mattermost/AppDelegate.m +++ b/ios/Mattermost/AppDelegate.m @@ -8,11 +8,11 @@ */ #import "AppDelegate.h" -#import "RCTPushNotificationManager.h" #import #import #import "Orientation.h" #import "RCCManager.h" +#import "RNNotifications.h" @implementation AppDelegate @@ -22,20 +22,6 @@ jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; -// RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation -// moduleName:@"Mattermost" -// initialProperties:nil -// launchOptions:launchOptions]; -// -// [RCTSplashScreen open:rootView withImageNamed:@"splash"]; -// rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; -// -// self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; -// UIViewController *rootViewController = [UIViewController new]; -// rootViewController.view = rootView; -// self.window.rootViewController = rootViewController; -// [self.window makeKeyAndVisible]; - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.backgroundColor = [UIColor whiteColor]; [[RCCManager sharedInstance] initBridgeWithBundleURL:jsCodeLocation launchOptions:launchOptions]; @@ -43,35 +29,34 @@ return YES; } -// Required to register for notifications -- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings -{ - [RCTPushNotificationManager didRegisterUserNotificationSettings:notificationSettings]; -} -// Required for the register event. -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken -{ - [RCTPushNotificationManager didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; -} -// Required for the notification event. You must call the completion handler after handling the remote notification. -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo -fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler -{ - [RCTPushNotificationManager didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; -} -// Required for the registrationError event. -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error -{ - [RCTPushNotificationManager didFailToRegisterForRemoteNotificationsWithError:error]; -} -// Required for the localNotification event. -- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification -{ - [RCTPushNotificationManager didReceiveLocalNotification:notification]; -} - // Required for orientation - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return [Orientation getOrientation]; } + +// Required to register for notifications +- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings +{ + [RNNotifications didRegisterUserNotificationSettings:notificationSettings]; +} + +- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken +{ + [RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; +} + +- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { + [RNNotifications didFailToRegisterForRemoteNotificationsWithError:error]; +} + +// Required for the notification event. +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification { + [RNNotifications didReceiveRemoteNotification:notification]; +} + +// Required for the localNotification event. +- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification +{ + [RNNotifications didReceiveLocalNotification:notification]; +} @end diff --git a/package.json b/package.json index b7b99f33e..03724600c 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "react-native-keyboard-aware-scroll-view": "0.2.8", "react-native-linear-gradient": "2.0.0", "react-native-navigation": "1.1.72", + "react-native-notifications": "enahum/react-native-notifications.git", "react-native-orientation": "enahum/react-native-orientation.git", - "react-native-push-notification": "3.0.0", "react-native-search-bar": "enahum/react-native-search-bar.git", "react-native-svg": "5.1.8", "react-native-swiper": "1.5.4", diff --git a/yarn.lock b/yarn.lock index c933480d8..e9b3c2492 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4537,14 +4537,17 @@ react-native-navigation@1.1.72: dependencies: lodash "4.x.x" +react-native-notifications@enahum/react-native-notifications.git: + version "1.1.11" + resolved "https://codeload.github.com/enahum/react-native-notifications/tar.gz/a8450bcbfc6ae46ed4b97f6fe723aac44c8ad598" + dependencies: + core-js "^1.0.0" + uuid "^2.0.3" + react-native-orientation@enahum/react-native-orientation.git: version "1.17.0" resolved "https://codeload.github.com/enahum/react-native-orientation/tar.gz/75ba7da814b99a949324846ce3a63fcbaeee9fdc" -react-native-push-notification@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/react-native-push-notification/-/react-native-push-notification-3.0.0.tgz#00282ea656443e89df6057f14b10500e7b89551f" - react-native-scrollable-mixin@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/react-native-scrollable-mixin/-/react-native-scrollable-mixin-1.0.1.tgz#34a32167b64248594154fd0d6a8b03f22740548e"