diff --git a/app/actions/navigation.js b/app/actions/navigation.js
index 3cb3e7dc0..88880e01b 100644
--- a/app/actions/navigation.js
+++ b/app/actions/navigation.js
@@ -1,13 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
+import {Platform} from 'react-native';
import {Navigation} from 'react-native-navigation';
import merge from 'deepmerge';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
-export function resetToChannel() {
+export function resetToChannel(passProps = {}) {
return (dispatch, getState) => {
const theme = getTheme(getState());
@@ -17,6 +18,7 @@ export function resetToChannel() {
children: [{
component: {
name: 'Channel',
+ passProps,
options: {
layout: {
backgroundColor: 'transparent',
@@ -25,6 +27,8 @@ export function resetToChannel() {
visible: true,
},
topBar: {
+ visible: false,
+ height: 0,
backButton: {
color: theme.sidebarHeaderTextColor,
title: '',
@@ -35,8 +39,6 @@ export function resetToChannel() {
title: {
color: theme.sidebarHeaderTextColor,
},
- visible: false,
- height: 0,
},
},
},
@@ -84,6 +86,48 @@ export function resetToSelectServer(allowOtherServers) {
};
}
+export function resetToTeams(name, title, passProps = {}, options = {}) {
+ return (dispatch, getState) => {
+ const theme = getTheme(getState());
+ const defaultOptions = {
+ layout: {
+ backgroundColor: theme.centerChannelBg,
+ },
+ statusBar: {
+ visible: true,
+ },
+ topBar: {
+ visible: true,
+ title: {
+ color: theme.sidebarHeaderTextColor,
+ text: title,
+ },
+ backButton: {
+ color: theme.sidebarHeaderTextColor,
+ title: '',
+ },
+ background: {
+ color: theme.sidebarHeaderBg,
+ },
+ },
+ };
+
+ Navigation.setRoot({
+ root: {
+ stack: {
+ children: [{
+ component: {
+ name,
+ passProps,
+ options: merge(defaultOptions, options),
+ },
+ }],
+ },
+ },
+ });
+ };
+}
+
export function goToScreen(componentId, name, title, passProps = {}, options = {}) {
return (dispatch, getState) => {
const theme = getTheme(getState());
@@ -108,6 +152,119 @@ export function goToScreen(componentId, name, title, passProps = {}, options = {
},
};
+ Navigation.push(componentId, {
+ component: {
+ name,
+ passProps,
+ options: merge(defaultOptions, options),
+ },
+ });
+ };
+}
+
+export function showModal(name, title, passProps = {}, options = {}) {
+ return (dispatch, getState) => {
+ const theme = getTheme(getState());
+ const defaultOptions = {
+ layout: {
+ backgroundColor: theme.centerChannelBg,
+ },
+ statusBar: {
+ visible: true,
+ },
+ topBar: {
+ animate: true,
+ visible: true,
+ backButton: {
+ color: theme.sidebarHeaderTextColor,
+ title: '',
+ },
+ background: {
+ color: theme.sidebarHeaderBg,
+ },
+ title: {
+ color: theme.sidebarHeaderTextColor,
+ text: title,
+ },
+ },
+ };
+
+ Navigation.showModal({
+ stack: {
+ children: [{
+ component: {
+ name,
+ passProps,
+ options: merge(defaultOptions, options),
+ },
+ }],
+ },
+ });
+ };
+}
+
+export function showModalOverCurrentContext(name, passProps = {}, options = {}) {
+ return (dispatch) => {
+ const title = '';
+ const animationsEnabled = (Platform.OS === 'android').toString();
+ const defaultOptions = {
+ modalPresentationStyle: 'overCurrentContext',
+ layout: {
+ backgroundColor: 'transparent',
+ },
+ topBar: {
+ visible: false,
+ height: 0,
+ },
+ animations: {
+ showModal: {
+ enabled: animationsEnabled,
+ alpha: {
+ from: 0,
+ to: 1,
+ duration: 250,
+ },
+ },
+ dismissModal: {
+ enabled: animationsEnabled,
+ alpha: {
+ from: 1,
+ to: 0,
+ duration: 250,
+ },
+ },
+ },
+ };
+ const mergeOptions = merge(defaultOptions, options);
+
+ dispatch(showModal(name, title, passProps, mergeOptions));
+ };
+}
+
+export function showSearchModal(initialValue = '') {
+ return (dispatch) => {
+ const name = 'Search';
+ const title = '';
+ const passProps = {initialValue};
+ const options = {
+ topBar: {
+ visible: false,
+ height: 0,
+ },
+ };
+
+ dispatch(showModal(name, title, passProps, options));
+ };
+}
+
+export function peek(componentId, name, passProps = {}, options = {}) {
+ return () => {
+ const defaultOptions = {
+ preview: {
+ commit: false,
+ },
+ };
+
Navigation.push(componentId, {
component: {
name,
diff --git a/app/actions/views/search.js b/app/actions/views/search.js
index 2726e6635..0e6f0c3a2 100644
--- a/app/actions/views/search.js
+++ b/app/actions/views/search.js
@@ -14,6 +14,8 @@ export function handleSearchDraftChanged(text) {
};
}
+// TODO: Remove this once all screens/components call
+// app/actions/navigation's showSearchModal
export function showSearchModal(navigator, initialValue = '') {
return (dispatch, getState) => {
const theme = getTheme(getState());
diff --git a/app/components/__snapshots__/profile_picture_button.test.js.snap b/app/components/__snapshots__/profile_picture_button.test.js.snap
index c93aadecd..97f0ea52d 100644
--- a/app/components/__snapshots__/profile_picture_button.test.js.snap
+++ b/app/components/__snapshots__/profile_picture_button.test.js.snap
@@ -1,20 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`profile_picture_button should match snapshot 1`] = `
-
`;
diff --git a/app/components/__snapshots__/attachment_button.test.js.snap b/app/components/attachment_button/__snapshots__/attachment_button.test.js.snap
similarity index 100%
rename from app/components/__snapshots__/attachment_button.test.js.snap
rename to app/components/attachment_button/__snapshots__/attachment_button.test.js.snap
diff --git a/app/components/attachment_button.js b/app/components/attachment_button/attachment_button.js
similarity index 97%
rename from app/components/attachment_button.js
rename to app/components/attachment_button/attachment_button.js
index 29bd3d0d0..5c746c5d8 100644
--- a/app/components/attachment_button.js
+++ b/app/components/attachment_button/attachment_button.js
@@ -27,6 +27,9 @@ const ShareExtension = NativeModules.MattermostShare;
export default class AttachmentButton extends PureComponent {
static propTypes = {
+ actions: PropTypes.shape({
+ showModalOverCurrentContext: PropTypes.func.isRequired,
+ }).isRequired,
blurTextBox: PropTypes.func.isRequired,
browseFileTypes: PropTypes.string,
validMimeTypes: PropTypes.array,
@@ -366,6 +369,7 @@ export default class AttachmentButton extends PureComponent {
maxFileCount,
onShowFileMaxWarning,
extraOptions,
+ actions,
} = this.props;
if (fileCount === maxFileCount) {
@@ -439,21 +443,7 @@ export default class AttachmentButton extends PureComponent {
});
}
- this.props.navigator.showModal({
- screen: 'OptionsModal',
- title: '',
- animationType: 'none',
- passProps: {
- items,
- },
- navigatorStyle: {
- navBarHidden: true,
- statusBarHidden: false,
- statusBarHideWithNavBar: false,
- screenBackgroundColor: 'transparent',
- modalPresentationStyle: 'overCurrentContext',
- },
- });
+ actions.showModalOverCurrentContext('OptionsModal', {items});
};
render() {
diff --git a/app/components/attachment_button.test.js b/app/components/attachment_button/attachment_button.test.js
similarity index 96%
rename from app/components/attachment_button.test.js
rename to app/components/attachment_button/attachment_button.test.js
index ae789c5c6..b98df3716 100644
--- a/app/components/attachment_button.test.js
+++ b/app/components/attachment_button/attachment_button.test.js
@@ -13,6 +13,9 @@ jest.mock('react-intl');
describe('AttachmentButton', () => {
const baseProps = {
+ actions: {
+ showModalOverCurrentContext: jest.fn(),
+ },
theme: Preferences.THEMES.default,
navigator: {},
blurTextBox: jest.fn(),
diff --git a/app/components/attachment_button/index.js b/app/components/attachment_button/index.js
new file mode 100644
index 000000000..d48573136
--- /dev/null
+++ b/app/components/attachment_button/index.js
@@ -0,0 +1,19 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import {bindActionCreators} from 'redux';
+import {connect} from 'react-redux';
+
+import {showModalOverCurrentContext} from 'app/actions/navigation';
+
+import AttachmentButton from './attachment_button';
+
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ showModalOverCurrentContext,
+ }, dispatch),
+ };
+}
+
+export default connect(null, mapDispatchToProps)(AttachmentButton);
diff --git a/app/components/root/index.js b/app/components/root/index.js
index c2234531c..747bfdb9c 100644
--- a/app/components/root/index.js
+++ b/app/components/root/index.js
@@ -1,13 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
+import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {getCurrentChannelId} from 'mattermost-redux/selectors/entities/channels';
import {getCurrentUrl} from 'mattermost-redux/selectors/entities/general';
-
-import {getCurrentLocale} from 'app/selectors/i18n';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
+
+import {resetToTeams} from 'app/actions/navigation';
+import {getCurrentLocale} from 'app/selectors/i18n';
import {removeProtocol} from 'app/utils/url';
import Root from './root';
@@ -23,4 +25,12 @@ function mapStateToProps(state) {
};
}
-export default connect(mapStateToProps)(Root);
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ resetToTeams,
+ }, dispatch),
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(Root);
diff --git a/app/components/root/root.js b/app/components/root/root.js
index 5566e7335..051c4c715 100644
--- a/app/components/root/root.js
+++ b/app/components/root/root.js
@@ -14,6 +14,9 @@ import {getTranslations} from 'app/i18n';
export default class Root extends PureComponent {
static propTypes = {
+ actions: PropTypes.shape({
+ resetToTeams: PropTypes.func.isRequired,
+ }).isRequired,
children: PropTypes.node,
navigator: PropTypes.object,
excludeEvents: PropTypes.bool,
@@ -83,28 +86,24 @@ export default class Root extends PureComponent {
}
navigateToTeamsPage = (screen) => {
- const {currentUrl, navigator, theme} = this.props;
+ const {currentUrl, theme, actions} = this.props;
const {intl} = this.refs.provider.getChildContext();
- let navigatorButtons;
let passProps = {theme};
+ const options = {topBar: {}};
if (Platform.OS === 'android') {
- navigatorButtons = {
- rightButtons: [{
- title: intl.formatMessage({id: 'sidebar_right_menu.logout', defaultMessage: 'Logout'}),
- id: 'logout',
- buttonColor: theme.sidebarHeaderTextColor,
- showAsAction: 'always',
- }],
- };
+ options.topBar.rightButtons = [{
+ id: 'logout',
+ text: intl.formatMessage({id: 'sidebar_right_menu.logout', defaultMessage: 'Logout'}),
+ color: theme.sidebarHeaderTextColor,
+ showAsAction: 'always',
+ }];
} else {
- navigatorButtons = {
- leftButtons: [{
- title: intl.formatMessage({id: 'sidebar_right_menu.logout', defaultMessage: 'Logout'}),
- id: 'logout',
- buttonColor: theme.sidebarHeaderTextColor,
- }],
- };
+ options.topBar.leftButtons = [{
+ id: 'logout',
+ text: intl.formatMessage({id: 'sidebar_right_menu.logout', defaultMessage: 'Logout'}),
+ color: theme.sidebarHeaderTextColor,
+ }];
}
if (screen === 'SelectTeam') {
@@ -115,20 +114,9 @@ export default class Root extends PureComponent {
};
}
- navigator.resetTo({
- screen,
- title: intl.formatMessage({id: 'mobile.routes.selectTeam', defaultMessage: 'Select Team'}),
- animated: false,
- backButtonTitle: '',
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- navigatorButtons,
- passProps,
- });
+ const title = intl.formatMessage({id: 'mobile.routes.selectTeam', defaultMessage: 'Select Team'});
+
+ actions.resetToTeams(screen, title, passProps, options);
}
handleNotificationTapped = async () => {
diff --git a/app/components/safe_area_view/safe_area_view.ios.js b/app/components/safe_area_view/safe_area_view.ios.js
index b69b77ec9..f1bd342cd 100644
--- a/app/components/safe_area_view/safe_area_view.ios.js
+++ b/app/components/safe_area_view/safe_area_view.ios.js
@@ -5,7 +5,6 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Dimensions, Keyboard, NativeModules, View} from 'react-native';
import SafeArea from 'react-native-safe-area';
-import {Navigation} from 'react-native-navigation';
import {DeviceTypes} from 'app/constants';
import mattermostManaged from 'app/mattermost_managed';
@@ -53,8 +52,6 @@ export default class SafeAreaIos extends PureComponent {
}
componentDidMount() {
- this.navigationEventListener = Navigation.events().bindComponent(this);
-
Dimensions.addEventListener('change', this.getSafeAreaInsets);
this.keyboardDidShowListener = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow);
this.keyboardDidHideListener = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide);
@@ -69,14 +66,6 @@ export default class SafeAreaIos extends PureComponent {
this.mounted = false;
}
- componentDidAppear() {
- this.getSafeAreaInsets();
- }
-
- componentDidDisappear() {
- this.getSafeAreaInsets();
- }
-
getStatusBarHeight = () => {
try {
StatusBarManager.getHeight(
diff --git a/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap b/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap
index 5940ff56f..e69b5ce57 100644
--- a/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap
+++ b/app/components/sidebars/main/channels_list/channel_item/__snapshots__/channel_item.test.js.snap
@@ -2,11 +2,10 @@
exports[`ChannelItem should match snapshot 1`] = `
-
-
+
`;
exports[`ChannelItem should match snapshot for current user i.e currentUser (you) 1`] = `
-
-
+
`;
exports[`ChannelItem should match snapshot for current user i.e currentUser (you) when isSearchResult 1`] = `
-
-
+
`;
exports[`ChannelItem should match snapshot for deactivated user and is currentChannel 1`] = `
-
-
+
`;
exports[`ChannelItem should match snapshot for deactivated user and is searchResult 1`] = `
-
-
+
`;
@@ -561,11 +556,10 @@ exports[`ChannelItem should match snapshot for showUnreadForMsgs 1`] = `null`;
exports[`ChannelItem should match snapshot with draft 1`] = `
-
-
+
`;
exports[`ChannelItem should match snapshot with mentions and muted 1`] = `
-
-
+
`;
diff --git a/app/components/sidebars/main/channels_list/channel_item/channel_item.js b/app/components/sidebars/main/channels_list/channel_item/channel_item.js
index 4e5301985..a5d01ffce 100644
--- a/app/components/sidebars/main/channels_list/channel_item/channel_item.js
+++ b/app/components/sidebars/main/channels_list/channel_item/channel_item.js
@@ -2,17 +2,17 @@
// See LICENSE.txt for license information.
import React, {PureComponent} from 'react';
-import {General} from 'mattermost-redux/constants';
-
import PropTypes from 'prop-types';
import {
Animated,
- Platform,
TouchableHighlight,
Text,
View,
} from 'react-native';
import {intlShape} from 'react-intl';
+import {Navigation} from 'react-native-navigation';
+
+import {General} from 'mattermost-redux/constants';
import Badge from 'app/components/badge';
import ChannelIcon from 'app/components/channel_icon';
@@ -32,7 +32,6 @@ export default class ChannelItem extends PureComponent {
isUnread: PropTypes.bool,
hasDraft: PropTypes.bool,
mentions: PropTypes.number.isRequired,
- navigator: PropTypes.object,
onSelectChannel: PropTypes.func.isRequired,
shouldHideChannel: PropTypes.bool,
showUnreadForMsgs: PropTypes.bool.isRequired,
@@ -40,6 +39,7 @@ export default class ChannelItem extends PureComponent {
unreadMsgs: PropTypes.number.isRequired,
isSearchResult: PropTypes.bool,
isBot: PropTypes.bool.isRequired,
+ previewChannel: PropTypes.func,
};
static defaultProps = {
@@ -58,28 +58,25 @@ export default class ChannelItem extends PureComponent {
});
});
- onPreview = () => {
- const {channelId, navigator} = this.props;
- if (Platform.OS === 'ios' && navigator && this.previewRef) {
+ onPreview = ({reactTag}) => {
+ const {channelId, previewChannel} = this.props;
+ if (previewChannel) {
const {intl} = this.context;
-
- navigator.push({
- screen: 'ChannelPeek',
- previewCommit: false,
- previewView: this.previewRef,
- previewActions: [{
- id: 'action-mark-as-read',
- title: intl.formatMessage({id: 'mobile.channel.markAsRead', defaultMessage: 'Mark As Read'}),
- }],
- passProps: {
- channelId,
+ const passProps = {
+ channelId,
+ };
+ const options = {
+ preview: {
+ reactTag,
+ actions: [{
+ id: 'action-mark-as-read',
+ title: intl.formatMessage({id: 'mobile.channel.markAsRead', defaultMessage: 'Mark As Read'}),
+ }],
},
- });
- }
- };
+ };
- setPreviewRef = (ref) => {
- this.previewRef = ref;
+ previewChannel(passProps, options);
+ }
};
showChannelAsUnread = () => {
@@ -190,11 +187,12 @@ export default class ChannelItem extends PureComponent {
);
return (
-
-
+
{extraBorder}
@@ -210,7 +208,7 @@ export default class ChannelItem extends PureComponent {
{badge}
-
+
);
}
diff --git a/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js b/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js
index 8774c4614..38334340d 100644
--- a/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js
+++ b/app/components/sidebars/main/channels_list/channel_item/channel_item.test.js
@@ -3,7 +3,7 @@
import React from 'react';
import {shallow} from 'enzyme';
-import {TouchableHighlight} from 'react-native';
+import {Navigation} from 'react-native-navigation';
import Preferences from 'mattermost-redux/constants/preferences';
@@ -216,7 +216,7 @@ describe('ChannelItem', () => {
{context: {intl: {formatMessage: jest.fn()}}},
);
- wrapper.find(TouchableHighlight).simulate('press');
+ wrapper.find(Navigation.TouchablePreview).simulate('press');
jest.runAllTimers();
const expectedChannelParams = {id: baseProps.channelId, display_name: baseProps.displayName, fake: channel.fake, type: channel.type};
diff --git a/app/components/sidebars/main/channels_list/channels_list.js b/app/components/sidebars/main/channels_list/channels_list.js
index 4d5ec4d15..1a26c82f0 100644
--- a/app/components/sidebars/main/channels_list/channels_list.js
+++ b/app/components/sidebars/main/channels_list/channels_list.js
@@ -22,7 +22,6 @@ let FilteredList = null;
export default class ChannelsList extends PureComponent {
static propTypes = {
- navigator: PropTypes.object,
onJoinChannel: PropTypes.func.isRequired,
onSearchEnds: PropTypes.func.isRequired,
onSearchStart: PropTypes.func.isRequired,
@@ -30,6 +29,7 @@ export default class ChannelsList extends PureComponent {
onShowTeams: PropTypes.func.isRequired,
theme: PropTypes.object.isRequired,
drawerOpened: PropTypes.bool,
+ previewChannel: PropTypes.func,
};
static contextTypes = {
@@ -86,9 +86,9 @@ export default class ChannelsList extends PureComponent {
render() {
const {intl} = this.context;
const {
- navigator,
onShowTeams,
theme,
+ previewChannel,
} = this.props;
const {searching, term} = this.state;
@@ -101,14 +101,15 @@ export default class ChannelsList extends PureComponent {
onSelectChannel={this.onSelectChannel}
styles={styles}
term={term}
+ previewChannel={previewChannel}
/>
);
} else {
list = (
);
}
diff --git a/app/components/sidebars/main/channels_list/filtered_list/filtered_list.js b/app/components/sidebars/main/channels_list/filtered_list/filtered_list.js
index 7546f3630..d37d56c42 100644
--- a/app/components/sidebars/main/channels_list/filtered_list/filtered_list.js
+++ b/app/components/sidebars/main/channels_list/filtered_list/filtered_list.js
@@ -54,6 +54,7 @@ class FilteredList extends Component {
styles: PropTypes.object.isRequired,
term: PropTypes.string,
theme: PropTypes.object.isRequired,
+ previewChannel: PropTypes.func,
};
static defaultProps = {
@@ -126,6 +127,7 @@ class FilteredList extends Component {
isUnread={channel.isUnread}
mentions={0}
onSelectChannel={this.onSelectChannel}
+ previewChannel={this.props.previewChannel}
/>
);
};
diff --git a/app/components/sidebars/main/channels_list/list/index.js b/app/components/sidebars/main/channels_list/list/index.js
index adb6f31a7..eaca23964 100644
--- a/app/components/sidebars/main/channels_list/list/index.js
+++ b/app/components/sidebars/main/channels_list/list/index.js
@@ -1,6 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
+import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {General} from 'mattermost-redux/constants';
@@ -17,6 +18,8 @@ import {memoizeResult} from 'mattermost-redux/utils/helpers';
import {isAdmin as checkIsAdmin, isSystemAdmin as checkIsSystemAdmin} from 'mattermost-redux/utils/user_utils';
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
+import {showModal} from 'app/actions/navigation';
+
import {DeviceTypes, ViewTypes} from 'app/constants';
import List from './list';
@@ -67,6 +70,14 @@ function mapStateToProps(state) {
};
}
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ showModal,
+ }, dispatch),
+ };
+}
+
function areStatesEqual(next, prev) {
const equalRoles = getCurrentUserRoles(prev) === getCurrentUserRoles(next);
const equalChannels = next.entities.channels === prev.entities.channels;
@@ -77,4 +88,4 @@ function areStatesEqual(next, prev) {
return equalChannels && equalConfig && equalRoles && equalUsers && equalFav;
}
-export default connect(mapStateToProps, null, null, {pure: true, areStatesEqual})(List);
+export default connect(mapStateToProps, mapDispatchToProps, null, {pure: true, areStatesEqual})(List);
diff --git a/app/components/sidebars/main/channels_list/list/list.js b/app/components/sidebars/main/channels_list/list/list.js
index 27ce989e1..9e0e3101f 100644
--- a/app/components/sidebars/main/channels_list/list/list.js
+++ b/app/components/sidebars/main/channels_list/list/list.js
@@ -34,14 +34,17 @@ let UnreadIndicator = null;
export default class List extends PureComponent {
static propTypes = {
+ actions: PropTypes.shape({
+ showModal: PropTypes.func.isRequired,
+ }).isRequired,
canCreatePrivateChannels: PropTypes.bool.isRequired,
favoriteChannelIds: PropTypes.array.isRequired,
- navigator: PropTypes.object,
onSelectChannel: PropTypes.func.isRequired,
unreadChannelIds: PropTypes.array.isRequired,
styles: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
orderedChannelIds: PropTypes.array.isRequired,
+ previewChannel: PropTypes.func,
};
static contextTypes = {
@@ -159,7 +162,10 @@ export default class List extends PureComponent {
};
showCreateChannelOptions = () => {
- const {canCreatePrivateChannels, navigator} = this.props;
+ const {
+ canCreatePrivateChannels,
+ actions,
+ } = this.props;
const items = [];
const moreChannels = {
@@ -197,117 +203,87 @@ export default class List extends PureComponent {
}
items.push(newConversation);
- navigator.showModal({
- screen: 'OptionsModal',
- title: '',
- animationType: 'none',
- passProps: {
- items,
- onItemPress: () => navigator.dismissModal({
- animationType: 'none',
- }),
+ const screen = 'OptionsModal';
+ const title = '';
+ const passProps = {
+ items,
+ };
+ const options = {
+ modalPresentationStyle: 'overCurrentContext',
+ layout: {
+ backgroundColor: 'transparent',
},
- navigatorStyle: {
- navBarHidden: true,
- statusBarHidden: false,
- statusBarHideWithNavBar: false,
- screenBackgroundColor: 'transparent',
- modalPresentationStyle: 'overCurrentContext',
+ topBar: {
+ visible: false,
+ height: 0,
},
- });
+ animations: {
+ showModal: {
+ enable: false,
+ },
+ dismissModal: {
+ enable: false,
+ },
+ },
+ };
+
+ actions.showModal(screen, title, passProps, options);
};
goToCreatePublicChannel = preventDoubleTap(() => {
- const {navigator, theme} = this.props;
+ const {actions} = this.props;
const {intl} = this.context;
+ const screen = 'CreateChannel';
+ const title = intl.formatMessage({id: 'mobile.create_channel.public', defaultMessage: 'New Public Channel'});
+ const passProps = {
+ channelType: General.OPEN_CHANNEL,
+ closeButton: this.closeButton,
+ };
- navigator.showModal({
- screen: 'CreateChannel',
- animationType: 'slide-up',
- title: intl.formatMessage({id: 'mobile.create_channel.public', defaultMessage: 'New Public Channel'}),
- backButtonTitle: '',
- animated: true,
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- passProps: {
- channelType: General.OPEN_CHANNEL,
- closeButton: this.closeButton,
- },
- });
+ actions.showModal(screen, title, passProps);
});
goToCreatePrivateChannel = preventDoubleTap(() => {
- const {navigator, theme} = this.props;
+ const {actions} = this.props;
const {intl} = this.context;
+ const screen = 'CreateChannel';
+ const title = intl.formatMessage({id: 'mobile.create_channel.private', defaultMessage: 'New Private Channel'});
+ const passProps = {
+ channelType: General.PRIVATE_CHANNEL,
+ closeButton: this.closeButton,
+ };
- navigator.showModal({
- screen: 'CreateChannel',
- animationType: 'slide-up',
- title: intl.formatMessage({id: 'mobile.create_channel.private', defaultMessage: 'New Private Channel'}),
- backButtonTitle: '',
- animated: true,
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- passProps: {
- channelType: General.PRIVATE_CHANNEL,
- closeButton: this.closeButton,
- },
- });
+ actions.showModal(screen, title, passProps);
});
goToDirectMessages = preventDoubleTap(() => {
- const {navigator, theme} = this.props;
+ const {actions} = this.props;
const {intl} = this.context;
-
- navigator.showModal({
- screen: 'MoreDirectMessages',
- title: intl.formatMessage({id: 'mobile.more_dms.title', defaultMessage: 'New Conversation'}),
- animationType: 'slide-up',
- animated: true,
- backButtonTitle: '',
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- navigatorButtons: {
+ const screen = 'MoreDirectMessages';
+ const title = intl.formatMessage({id: 'mobile.more_dms.title', defaultMessage: 'New Conversation'});
+ const passProps = {};
+ const options = {
+ topBar: {
leftButtons: [{
id: 'close-dms',
icon: this.closeButton,
}],
},
- });
+ };
+
+ actions.showModal(screen, title, passProps, options);
});
goToMoreChannels = preventDoubleTap(() => {
- const {navigator, theme} = this.props;
+ const {actions} = this.props;
const {intl} = this.context;
+ const screen = 'MoreChannels';
+ const title = intl.formatMessage({id: 'more_channels.title', defaultMessage: 'More Channels'});
+ const passProps = {
+ closeButton: this.closeButton,
+ };
- navigator.showModal({
- screen: 'MoreChannels',
- animationType: 'slide-up',
- title: intl.formatMessage({id: 'more_channels.title', defaultMessage: 'More Channels'}),
- backButtonTitle: '',
- animated: true,
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- passProps: {
- closeButton: this.closeButton,
- },
- });
+ actions.showModal(screen, title, passProps);
});
keyExtractor = (item) => item.id || item;
@@ -349,15 +325,15 @@ export default class List extends PureComponent {
};
renderItem = ({item}) => {
- const {favoriteChannelIds, unreadChannelIds} = this.props;
+ const {favoriteChannelIds, unreadChannelIds, previewChannel} = this.props;
return (
);
};
diff --git a/app/components/sidebars/main/main_sidebar.js b/app/components/sidebars/main/main_sidebar.js
index c4f89b70a..1b048cc00 100644
--- a/app/components/sidebars/main/main_sidebar.js
+++ b/app/components/sidebars/main/main_sidebar.js
@@ -44,9 +44,9 @@ export default class ChannelSidebar extends Component {
currentUserId: PropTypes.string.isRequired,
deviceWidth: PropTypes.number.isRequired,
isLandscape: PropTypes.bool.isRequired,
- navigator: PropTypes.object,
teamsCount: PropTypes.number.isRequired,
theme: PropTypes.object.isRequired,
+ previewChannel: PropTypes.func,
};
static contextTypes = {
@@ -297,9 +297,9 @@ export default class ChannelSidebar extends Component {
renderNavigationView = (drawerWidth) => {
const {
- navigator,
teamsCount,
theme,
+ previewChannel,
} = this.props;
const {
@@ -331,7 +331,6 @@ export default class ChannelSidebar extends Component {
>
);
@@ -345,7 +344,6 @@ export default class ChannelSidebar extends Component {
>
);
@@ -362,7 +361,6 @@ export default class ChannelSidebar extends Component {
navBarBackgroundColor={theme.sidebarBg}
backgroundColor={theme.sidebarHeaderBg}
footerColor={theme.sidebarHeaderBg}
- navigator={navigator}
>
{
const {intl} = this.context;
- const {currentUrl, navigator, theme} = this.props;
-
- navigator.showModal({
- screen: 'SelectTeam',
- title: intl.formatMessage({id: 'mobile.routes.selectTeam', defaultMessage: 'Select Team'}),
- animationType: 'slide-up',
- animated: true,
- backButtonTitle: '',
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- navigatorButtons: {
+ const {currentUrl, theme, actions} = this.props;
+ const screen = 'SelectTeam';
+ const title = intl.formatMessage({id: 'mobile.routes.selectTeam', defaultMessage: 'Select Team'});
+ const passProps = {
+ currentUrl,
+ theme,
+ };
+ const options = {
+ topBar: {
leftButtons: [{
id: 'close-teams',
icon: this.closeButton,
}],
},
- passProps: {
- currentUrl,
- theme,
- },
- });
+ };
+
+ actions.showModal(screen, title, passProps, options);
});
keyExtractor = (item) => {
diff --git a/app/screens/channel/channel.ios.js b/app/screens/channel/channel.ios.js
index d53d567de..05d67f9ca 100644
--- a/app/screens/channel/channel.ios.js
+++ b/app/screens/channel/channel.ios.js
@@ -25,6 +25,15 @@ const CHANNEL_POST_TEXTBOX_CURSOR_CHANGE = 'onChannelTextBoxCursorChange';
const CHANNEL_POST_TEXTBOX_VALUE_CHANGE = 'onChannelTextBoxValueChange';
export default class ChannelIOS extends ChannelBase {
+ previewChannel = (passProps, options) => {
+ const {actions, componentId} = this.props;
+ const screen = 'ChannelPeek';
+
+ actions.peek(componentId, screen, passProps, options);
+ };
+
+ optionalProps = {previewChannel: this.previewChannel};
+
render() {
const {height} = Dimensions.get('window');
const {
@@ -82,6 +91,6 @@ export default class ChannelIOS extends ChannelBase {
);
- return this.renderChannel(drawerContent);
+ return this.renderChannel(drawerContent, this.optionalProps);
}
}
diff --git a/app/screens/channel/channel_base.js b/app/screens/channel/channel_base.js
index da40eacda..53e40b4ef 100644
--- a/app/screens/channel/channel_base.js
+++ b/app/screens/channel/channel_base.js
@@ -39,6 +39,7 @@ export default class ChannelBase extends PureComponent {
selectDefaultTeam: PropTypes.func.isRequired,
selectInitialChannel: PropTypes.func.isRequired,
recordLoadTime: PropTypes.func.isRequired,
+ peek: PropTypes.func.isRequired,
}).isRequired,
currentChannelId: PropTypes.string,
channelsRequestFailed: PropTypes.bool,
@@ -259,7 +260,7 @@ export default class ChannelBase extends PureComponent {
}
};
- renderChannel(drawerContent) {
+ renderChannel(drawerContent, optionalProps = {}) {
const {
channelsRequestFailed,
currentChannelId,
@@ -298,6 +299,7 @@ export default class ChannelBase extends PureComponent {
ref={this.channelSidebarRef}
blurPostTextBox={this.blurPostTextBox}
navigator={navigator}
+ {...optionalProps}
>
{
- const {actions, navigator} = this.props;
+ const {actions} = this.props;
Keyboard.dismiss();
await actions.clearSearch();
- await actions.showSearchModal(navigator);
+ await actions.showSearchModal();
});
render() {
diff --git a/app/screens/channel/channel_nav_bar/channel_search_button/index.js b/app/screens/channel/channel_nav_bar/channel_search_button/index.js
index 12e7f3d09..8bbb62cfb 100644
--- a/app/screens/channel/channel_nav_bar/channel_search_button/index.js
+++ b/app/screens/channel/channel_nav_bar/channel_search_button/index.js
@@ -6,7 +6,7 @@ import {connect} from 'react-redux';
import {clearSearch} from 'mattermost-redux/actions/search';
-import {showSearchModal} from 'app/actions/views/search';
+import {showSearchModal} from 'app/actions/navigation';
import ChannelSearchButton from './channel_search_button';
diff --git a/app/screens/channel/index.js b/app/screens/channel/index.js
index 40b00d318..1c9fc4c26 100644
--- a/app/screens/channel/index.js
+++ b/app/screens/channel/index.js
@@ -19,6 +19,7 @@ import {
import {connection} from 'app/actions/device';
import {recordLoadTime} from 'app/actions/views/root';
import {selectDefaultTeam} from 'app/actions/views/select_team';
+import {peek} from 'app/actions/navigation';
import {isLandscape} from 'app/selectors/device';
import Channel from './channel';
@@ -48,6 +49,7 @@ function mapDispatchToProps(dispatch) {
recordLoadTime,
startPeriodicStatusUpdates,
stopPeriodicStatusUpdates,
+ peek,
}, dispatch),
};
}
diff --git a/app/screens/channel_peek/channel_peek.js b/app/screens/channel_peek/channel_peek.js
index 081952558..162cdd85b 100644
--- a/app/screens/channel_peek/channel_peek.js
+++ b/app/screens/channel_peek/channel_peek.js
@@ -21,12 +21,11 @@ export default class ChannelPeek extends PureComponent {
currentUserId: PropTypes.string,
lastViewedAt: PropTypes.number,
navigator: PropTypes.object,
- postIds: PropTypes.array.isRequired,
+ postIds: PropTypes.array,
theme: PropTypes.object.isRequired,
};
static defaultProps = {
- postIds: [],
postVisibility: 15,
};
@@ -65,7 +64,7 @@ export default class ChannelPeek extends PureComponent {
}
getVisiblePostIds = (props) => {
- return props.postIds.slice(0, 15);
+ return props.postIds?.slice(0, 15) || [];
};
render() {
diff --git a/app/screens/index.js b/app/screens/index.js
index bd19a2f6d..e5ab8f5af 100644
--- a/app/screens/index.js
+++ b/app/screens/index.js
@@ -15,6 +15,7 @@ const navigator = {
push: () => {}, // eslint-disable-line no-empty-function
setOnNavigatorEvent: () => {}, // eslint-disable-line no-empty-function
setStyle: () => {}, // eslint-disable-line no-empty-function
+ setButtons: () => {}, // eslint-disable-line no-empty-function
};
export function registerScreens(store, Provider) {
diff --git a/app/screens/more_channels/more_channels.js b/app/screens/more_channels/more_channels.js
index 0330b8c59..ac118b36f 100644
--- a/app/screens/more_channels/more_channels.js
+++ b/app/screens/more_channels/more_channels.js
@@ -54,6 +54,7 @@ export default class MoreChannels extends PureComponent {
this.searchTimeoutId = 0;
this.page = -1;
this.next = true;
+ this.mounted = false;
this.state = {
channels: props.channels.slice(0, General.CHANNELS_CHUNK_SIZE),
@@ -86,10 +87,14 @@ export default class MoreChannels extends PureComponent {
componentDidMount() {
this.navigationEventListener = Navigation.events().bindComponent(this);
-
+ this.mounted = true;
this.doGetChannels();
}
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
componentWillReceiveProps(nextProps) {
const {term} = this.state;
let channels;
@@ -138,7 +143,7 @@ export default class MoreChannels extends PureComponent {
const {actions, currentTeamId} = this.props;
const {loading, term} = this.state;
- if (this.next && !loading && !term) {
+ if (this.next && !loading && !term && this.mounted) {
this.setState({loading: true}, () => {
actions.getChannels(
currentTeamId,
@@ -172,12 +177,14 @@ export default class MoreChannels extends PureComponent {
};
loadedChannels = ({data}) => {
- if (data && !data.length) {
- this.next = false;
- }
+ if (this.mounted) {
+ if (data && !data.length) {
+ this.next = false;
+ }
- this.page += 1;
- this.setState({loading: false});
+ this.page += 1;
+ this.setState({loading: false});
+ }
};
onSelectChannel = async (id) => {
diff --git a/app/screens/more_dms/more_dms.js b/app/screens/more_dms/more_dms.js
index 1af96f318..0d8723af3 100644
--- a/app/screens/more_dms/more_dms.js
+++ b/app/screens/more_dms/more_dms.js
@@ -61,6 +61,7 @@ export default class MoreDirectMessages extends PureComponent {
this.searchTimeoutId = 0;
this.next = true;
this.page = -1;
+ this.mounted = false;
this.state = {
profiles: [],
@@ -77,10 +78,15 @@ export default class MoreDirectMessages extends PureComponent {
componentDidMount() {
this.navigationEventListener = Navigation.events().bindComponent(this);
+ this.mounted = true;
this.getProfiles();
}
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
componentDidUpdate(prevProps) {
const {componentId, theme} = this.props;
const {selectedCount, startingConversation} = this.state;
@@ -111,7 +117,7 @@ export default class MoreDirectMessages extends PureComponent {
getProfiles = debounce(() => {
const {loading, term} = this.state;
- if (this.next && !loading && !term) {
+ if (this.next && !loading && !term && this.mounted) {
this.setState({loading: true}, () => {
const {actions, currentTeamId, restrictDirectMessage} = this.props;
@@ -182,13 +188,15 @@ export default class MoreDirectMessages extends PureComponent {
};
loadedProfiles = ({data}) => {
- const {profiles} = this.state;
- if (data && !data.length) {
- this.next = false;
- }
+ if (this.mounted) {
+ const {profiles} = this.state;
+ if (data && !data.length) {
+ this.next = false;
+ }
- this.page += 1;
- this.setState({loading: false, profiles: [...profiles, ...data]});
+ this.page += 1;
+ this.setState({loading: false, profiles: [...profiles, ...data]});
+ }
};
makeDirectChannel = async (id) => {
diff --git a/app/screens/options_modal/options_modal.js b/app/screens/options_modal/options_modal.js
index 55835939d..062e8dac9 100644
--- a/app/screens/options_modal/options_modal.js
+++ b/app/screens/options_modal/options_modal.js
@@ -9,6 +9,7 @@ import {
TouchableWithoutFeedback,
View,
} from 'react-native';
+import {Navigation} from 'react-native-navigation';
import EventEmitter from 'mattermost-redux/utils/event_emitter';
@@ -22,12 +23,11 @@ const DURATION = 200;
export default class OptionsModal extends PureComponent {
static propTypes = {
+ componentId: PropTypes.string.isRequired,
items: PropTypes.array.isRequired,
deviceHeight: PropTypes.number.isRequired,
deviceWidth: PropTypes.number.isRequired,
- navigator: PropTypes.object,
onCancelPress: PropTypes.func,
- onItemPress: PropTypes.func,
title: PropTypes.oneOfType([
PropTypes.string,
PropTypes.object,
@@ -36,7 +36,6 @@ export default class OptionsModal extends PureComponent {
static defaultProps = {
onCancelPress: emptyFunction,
- onItemPress: emptyFunction,
};
constructor(props) {
@@ -69,16 +68,17 @@ export default class OptionsModal extends PureComponent {
toValue: this.props.deviceHeight,
duration: DURATION,
}).start(() => {
- this.props.navigator.dismissModal({
- animationType: 'none',
- });
+ Navigation.dismissModal(this.props.componentId);
});
};
+ onItemPress = () => {
+ Navigation.dismissModal(this.props.componentId);
+ }
+
render() {
const {
items,
- onItemPress,
title,
} = this.props;
@@ -89,7 +89,7 @@ export default class OptionsModal extends PureComponent {
diff --git a/app/screens/search/search.js b/app/screens/search/search.js
index 23ef8a56b..4bd53c82c 100644
--- a/app/screens/search/search.js
+++ b/app/screens/search/search.js
@@ -57,6 +57,7 @@ export default class Search extends PureComponent {
selectFocusedPostId: PropTypes.func.isRequired,
selectPost: PropTypes.func.isRequired,
}).isRequired,
+ componentId: PropTypes.string.isRequired,
currentTeamId: PropTypes.string.isRequired,
initialValue: PropTypes.string,
isLandscape: PropTypes.bool.isRequired,
@@ -146,7 +147,7 @@ export default class Search extends PureComponent {
if (this.state.preview) {
this.refs.preview.handleClose();
} else {
- this.props.navigator.dismissModal();
+ Navigation.dismissModal(this.props.componentId);
}
}
}
@@ -176,9 +177,8 @@ export default class Search extends PureComponent {
};
cancelSearch = preventDoubleTap(() => {
- const {navigator} = this.props;
this.handleTextChanged('', true);
- navigator.dismissModal({animationType: 'slide-down'});
+ Navigation.dismissModal(this.props.componentId);
});
goToThread = (post) => {
@@ -211,7 +211,7 @@ export default class Search extends PureComponent {
handleHashtagPress = (hashtag) => {
if (this.showingPermalink) {
- this.props.navigator.dismissModal();
+ Navigation.dismissModal(this.props.componentId);
this.handleClosePermalink();
}
diff --git a/app/screens/select_team/index.js b/app/screens/select_team/index.js
index edc3c6f2a..3cfe25e34 100644
--- a/app/screens/select_team/index.js
+++ b/app/screens/select_team/index.js
@@ -4,12 +4,13 @@
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
-import {handleTeamChange} from 'app/actions/views/select_team';
-
import {getTeams, joinTeam} from 'mattermost-redux/actions/teams';
import {logout} from 'mattermost-redux/actions/users';
import {getJoinableTeams} from 'mattermost-redux/selectors/entities/teams';
+import {resetToChannel} from 'app/actions/navigation';
+import {handleTeamChange} from 'app/actions/views/select_team';
+
import SelectTeam from './select_team.js';
function mapStateToProps(state) {
@@ -26,6 +27,7 @@ function mapDispatchToProps(dispatch) {
handleTeamChange,
joinTeam,
logout,
+ resetToChannel,
}, dispatch),
};
}
diff --git a/app/screens/select_team/select_team.js b/app/screens/select_team/select_team.js
index 54661ee00..5b66520fb 100644
--- a/app/screens/select_team/select_team.js
+++ b/app/screens/select_team/select_team.js
@@ -45,10 +45,10 @@ export default class SelectTeam extends PureComponent {
handleTeamChange: PropTypes.func.isRequired,
joinTeam: PropTypes.func.isRequired,
logout: PropTypes.func.isRequired,
+ resetToChannel: PropTypes.func.isRequired,
}).isRequired,
componentId: PropTypes.string,
currentUrl: PropTypes.string.isRequired,
- navigator: PropTypes.object,
userWithoutTeams: PropTypes.bool,
teams: PropTypes.array.isRequired,
theme: PropTypes.object,
@@ -124,27 +124,15 @@ export default class SelectTeam extends PureComponent {
};
close = () => {
- this.props.navigator.dismissModal({
- animationType: 'slide-down',
- });
+ Navigation.dismissModal(this.props.componentId);
};
goToChannelView = () => {
- const {navigator, theme} = this.props;
+ const passProps = {
+ disableTermsModal: true,
+ };
- navigator.resetTo({
- screen: 'Channel',
- animated: false,
- navigatorStyle: {
- navBarHidden: true,
- statusBarHidden: false,
- statusBarHideWithNavBar: false,
- screenBackgroundColor: theme.centerChannelBg,
- },
- passProps: {
- disableTermsModal: true,
- },
- });
+ this.props.actions.resetToChannel(passProps);
};
onSelectTeam = async (team) => {
diff --git a/app/screens/select_team/select_team.test.js b/app/screens/select_team/select_team.test.js
index 19e3d6440..9d6adc9df 100644
--- a/app/screens/select_team/select_team.test.js
+++ b/app/screens/select_team/select_team.test.js
@@ -29,6 +29,7 @@ describe('SelectTeam', () => {
handleTeamChange: jest.fn(),
joinTeam: jest.fn(),
logout: jest.fn(),
+ resetToChannel: jest.fn(),
};
const baseProps = {
diff --git a/ios/Mattermost/AppDelegate.m b/ios/Mattermost/AppDelegate.m
index f261b1423..33cce9067 100644
--- a/ios/Mattermost/AppDelegate.m
+++ b/ios/Mattermost/AppDelegate.m
@@ -56,8 +56,6 @@ NSString* const NotificationClearAction = @"clear";
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
[ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions];
- self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
- self.window.backgroundColor = [UIColor whiteColor];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil];
os_log(OS_LOG_DEFAULT, "Mattermost started!!");
diff --git a/package-lock.json b/package-lock.json
index c2c6bbba2..f2058a1c8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15534,9 +15534,9 @@
"from": "github:mattermost/react-native-local-auth#cc9ce2f468fbf7b431dfad3191a31aaa9227a6ab"
},
"react-native-navigation": {
- "version": "2.20.2",
- "resolved": "https://registry.npmjs.org/react-native-navigation/-/react-native-navigation-2.20.2.tgz",
- "integrity": "sha512-Ok1x2bBFLcIGzYF5k9SFikkUSDr4MWp1zLYy6KernL4g20DE9flgPphOrllbOEDSA87NwDUv+QsUPbpOPeW1iw==",
+ "version": "2.21.1",
+ "resolved": "https://registry.npmjs.org/react-native-navigation/-/react-native-navigation-2.21.1.tgz",
+ "integrity": "sha512-CcICsn02NhfUZtTEg5QnXn7MiAlewc+uA3Q+UBO3SZw2rN94j8FBmEhvbvhFSWecBzqUTRvsXueMFVo4ruTAcQ==",
"requires": {
"hoist-non-react-statics": "3.x.x",
"lodash": "4.17.x",
diff --git a/package.json b/package.json
index 36a79f431..45878152d 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
"react-native-keychain": "3.1.3",
"react-native-linear-gradient": "2.5.4",
"react-native-local-auth": "github:mattermost/react-native-local-auth#cc9ce2f468fbf7b431dfad3191a31aaa9227a6ab",
- "react-native-navigation": "2.20.2",
+ "react-native-navigation": "2.21.1",
"react-native-notifications": "github:mattermost/react-native-notifications#f6d32b55ecda9f6a6765437c21b075e13ac64141",
"react-native-passcode-status": "1.1.1",
"react-native-permissions": "1.1.1",