diff --git a/app/actions/navigation.js b/app/actions/navigation.js
index 88880e01b..56eb887af 100644
--- a/app/actions/navigation.js
+++ b/app/actions/navigation.js
@@ -8,6 +8,8 @@ import merge from 'deepmerge';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import EphemeralStore from 'app/store/ephemeral_store';
+
export function resetToChannel(passProps = {}) {
return (dispatch, getState) => {
const theme = getTheme(getState());
@@ -128,9 +130,11 @@ export function resetToTeams(name, title, passProps = {}, options = {}) {
};
}
-export function goToScreen(componentId, name, title, passProps = {}, options = {}) {
+export function goToScreen(name, title, passProps = {}, options = {}) {
return (dispatch, getState) => {
- const theme = getTheme(getState());
+ const state = getState();
+ const componentId = EphemeralStore.getTopComponentId();
+ const theme = getTheme(state);
const defaultOptions = {
layout: {
backgroundColor: theme.centerChannelBg,
@@ -162,6 +166,22 @@ export function goToScreen(componentId, name, title, passProps = {}, options = {
};
}
+export function popTopScreen() {
+ return () => {
+ const componentId = EphemeralStore.getTopComponentId();
+
+ Navigation.pop(componentId);
+ };
+}
+
+export function popToRoot() {
+ return () => {
+ const componentId = EphemeralStore.getTopComponentId();
+
+ Navigation.popToRoot(componentId);
+ };
+}
+
export function showModal(name, title, passProps = {}, options = {}) {
return (dispatch, getState) => {
const theme = getTheme(getState());
@@ -186,6 +206,8 @@ export function showModal(name, title, passProps = {}, options = {}) {
color: theme.sidebarHeaderTextColor,
text: title,
},
+ leftButtonColor: theme.sidebarHeaderTextColor,
+ rightButtonColor: theme.sidebarHeaderTextColor,
},
};
@@ -257,8 +279,23 @@ export function showSearchModal(initialValue = '') {
};
}
-export function peek(componentId, name, passProps = {}, options = {}) {
+export function dismissModal(options = {}) {
return () => {
+ const componentId = EphemeralStore.getTopComponentId();
+
+ Navigation.dismissModal(componentId, options);
+ };
+}
+
+export function dismissAllModals(options = {}) {
+ return () => {
+ Navigation.dismissAllModals(options);
+ };
+}
+
+export function peek(name, passProps = {}, options = {}) {
+ return () => {
+ const componentId = EphemeralStore.getTopComponentId();
const defaultOptions = {
preview: {
commit: false,
@@ -273,4 +310,16 @@ export function peek(componentId, name, passProps = {}, options = {}) {
},
});
};
-}
\ No newline at end of file
+}
+
+export function setButtons(buttons = {leftButtons: [], rightButtons: []}) {
+ return () => {
+ const componentId = EphemeralStore.getTopComponentId();
+
+ Navigation.mergeOptions(componentId, {
+ topBar: {
+ ...buttons,
+ },
+ });
+ };
+}
diff --git a/app/components/at_mention/at_mention.js b/app/components/at_mention/at_mention.js
index e096c5e1b..d34bae8ff 100644
--- a/app/components/at_mention/at_mention.js
+++ b/app/components/at_mention/at_mention.js
@@ -3,7 +3,7 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {Clipboard, Platform, Text} from 'react-native';
+import {Clipboard, Text} from 'react-native';
import {intlShape} from 'react-intl';
import {displayUsername} from 'mattermost-redux/utils/user_utils';
@@ -14,10 +14,12 @@ import BottomSheet from 'app/utils/bottom_sheet';
export default class AtMention extends React.PureComponent {
static propTypes = {
+ actions: PropTypes.shape({
+ goToScreen: PropTypes.func.isRequired,
+ }).isRequired,
isSearchResult: PropTypes.bool,
mentionName: PropTypes.string.isRequired,
mentionStyle: CustomPropTypes.Style,
- navigator: PropTypes.object.isRequired,
onPostPress: PropTypes.func,
textStyle: CustomPropTypes.Style,
teammateNameDisplay: PropTypes.string,
@@ -48,29 +50,15 @@ export default class AtMention extends React.PureComponent {
}
goToUserProfile = () => {
- const {navigator, theme} = this.props;
+ const {actions} = this.props;
const {intl} = this.context;
- const options = {
- screen: 'UserProfile',
- title: intl.formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'}),
- animated: true,
- backButtonTitle: '',
- passProps: {
- userId: this.state.user.id,
- },
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
+ const screen = 'UserProfile';
+ const title = intl.formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'});
+ const passProps = {
+ userId: this.state.user.id,
};
- if (Platform.OS === 'ios') {
- navigator.push(options);
- } else {
- navigator.showModal(options);
- }
+ actions.goToScreen(screen, title, passProps);
};
getUserDetailsFromMentionName(props) {
diff --git a/app/components/at_mention/index.js b/app/components/at_mention/index.js
index 07ac8c733..857345ee5 100644
--- a/app/components/at_mention/index.js
+++ b/app/components/at_mention/index.js
@@ -1,12 +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 {getUsersByUsername} from 'mattermost-redux/selectors/entities/users';
import {getTeammateNameDisplaySetting, getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import {goToScreen} from 'app/actions/navigation';
+
import AtMention from './at_mention';
function mapStateToProps(state) {
@@ -17,4 +20,12 @@ function mapStateToProps(state) {
};
}
-export default connect(mapStateToProps)(AtMention);
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ goToScreen,
+ }, dispatch),
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(AtMention);
diff --git a/app/components/attachment_button/attachment_button.js b/app/components/attachment_button/attachment_button.js
index 5c746c5d8..07a3257c0 100644
--- a/app/components/attachment_button/attachment_button.js
+++ b/app/components/attachment_button/attachment_button.js
@@ -42,7 +42,6 @@ export default class AttachmentButton extends PureComponent {
fileCount: PropTypes.number,
maxFileCount: PropTypes.number.isRequired,
maxFileSize: PropTypes.number.isRequired,
- navigator: PropTypes.object.isRequired,
onShowFileMaxWarning: PropTypes.func,
onShowFileSizeWarning: PropTypes.func,
onShowUnsupportedMimeTypeWarning: PropTypes.func,
@@ -343,21 +342,6 @@ export default class AttachmentButton extends PureComponent {
}
};
- handleFileAttachmentOption = (action) => {
- this.props.navigator.dismissModal({
- animationType: 'none',
- });
-
- // Have to wait to launch the library attachment action.
- // If we call the action after dismissModal with no delay then the
- // Wix navigator will dismiss the library attachment modal as well.
- setTimeout(() => {
- if (typeof action === 'function') {
- action();
- }
- }, 100);
- };
-
showFileAttachmentOptions = () => {
const {
canBrowseFiles,
@@ -382,7 +366,7 @@ export default class AttachmentButton extends PureComponent {
if (canTakePhoto) {
items.push({
- action: () => this.handleFileAttachmentOption(this.attachPhotoFromCamera),
+ action: this.attachPhotoFromCamera,
text: {
id: t('mobile.file_upload.camera_photo'),
defaultMessage: 'Take Photo',
@@ -393,7 +377,7 @@ export default class AttachmentButton extends PureComponent {
if (canTakeVideo) {
items.push({
- action: () => this.handleFileAttachmentOption(this.attachVideoFromCamera),
+ action: this.attachVideoFromCamera,
text: {
id: t('mobile.file_upload.camera_video'),
defaultMessage: 'Take Video',
@@ -404,7 +388,7 @@ export default class AttachmentButton extends PureComponent {
if (canBrowsePhotoLibrary) {
items.push({
- action: () => this.handleFileAttachmentOption(this.attachFileFromLibrary),
+ action: this.attachFileFromLibrary,
text: {
id: t('mobile.file_upload.library'),
defaultMessage: 'Photo Library',
@@ -415,7 +399,7 @@ export default class AttachmentButton extends PureComponent {
if (canBrowseVideoLibrary && Platform.OS === 'android') {
items.push({
- action: () => this.handleFileAttachmentOption(this.attachVideoFromLibraryAndroid),
+ action: this.attachVideoFromLibraryAndroid,
text: {
id: t('mobile.file_upload.video'),
defaultMessage: 'Video Library',
@@ -426,7 +410,7 @@ export default class AttachmentButton extends PureComponent {
if (canBrowseFiles) {
items.push({
- action: () => this.handleFileAttachmentOption(this.attachFileFromFiles),
+ action: this.attachFileFromFiles,
text: {
id: t('mobile.file_upload.browse'),
defaultMessage: 'Browse Files',
diff --git a/app/components/attachment_button/attachment_button.test.js b/app/components/attachment_button/attachment_button.test.js
index b98df3716..e513d3634 100644
--- a/app/components/attachment_button/attachment_button.test.js
+++ b/app/components/attachment_button/attachment_button.test.js
@@ -17,7 +17,6 @@ describe('AttachmentButton', () => {
showModalOverCurrentContext: jest.fn(),
},
theme: Preferences.THEMES.default,
- navigator: {},
blurTextBox: jest.fn(),
maxFileSize: 10,
uploadFiles: jest.fn(),
diff --git a/app/components/autocomplete_selector/autocomplete_selector.js b/app/components/autocomplete_selector/autocomplete_selector.js
index 49cbc44d6..2817da990 100644
--- a/app/components/autocomplete_selector/autocomplete_selector.js
+++ b/app/components/autocomplete_selector/autocomplete_selector.js
@@ -18,6 +18,7 @@ export default class AutocompleteSelector extends PureComponent {
static propTypes = {
actions: PropTypes.shape({
setAutocompleteSelector: PropTypes.func.isRequired,
+ goToScreen: PropTypes.func.isRequired,
}).isRequired,
label: PropTypes.string,
placeholder: PropTypes.string.isRequired,
@@ -28,7 +29,6 @@ export default class AutocompleteSelector extends PureComponent {
showRequiredAsterisk: PropTypes.bool,
teammateNameDisplay: PropTypes.string,
theme: PropTypes.object.isRequired,
- navigator: PropTypes.object,
onSelected: PropTypes.func,
helpText: PropTypes.node,
errorText: PropTypes.node,
@@ -96,22 +96,12 @@ export default class AutocompleteSelector extends PureComponent {
goToSelectorScreen = preventDoubleTap(() => {
const {formatMessage} = this.context.intl;
- const {navigator, theme, actions, dataSource, options, placeholder} = this.props;
+ const {actions, dataSource, options, placeholder} = this.props;
+ const screen = 'SelectorScreen';
+ const title = placeholder || formatMessage({id: 'mobile.action_menu.select', defaultMessage: 'Select an option'});
actions.setAutocompleteSelector(dataSource, this.handleSelect, options);
-
- navigator.push({
- backButtonTitle: '',
- screen: 'SelectorScreen',
- title: placeholder || formatMessage({id: 'mobile.action_menu.select', defaultMessage: 'Select an option'}),
- animated: true,
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- });
+ actions.goToScreen(screen, title);
});
render() {
diff --git a/app/components/autocomplete_selector/index.js b/app/components/autocomplete_selector/index.js
index dc77afea9..afb4c445c 100644
--- a/app/components/autocomplete_selector/index.js
+++ b/app/components/autocomplete_selector/index.js
@@ -6,6 +6,7 @@ import {connect} from 'react-redux';
import {getTeammateNameDisplaySetting, getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import {goToScreen} from 'app/actions/navigation';
import {setAutocompleteSelector} from 'app/actions/views/post';
import AutocompleteSelector from './autocomplete_selector';
@@ -21,6 +22,7 @@ function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
setAutocompleteSelector,
+ goToScreen,
}, dispatch),
};
}
diff --git a/app/components/combined_system_message/combined_system_message.js b/app/components/combined_system_message/combined_system_message.js
index edf43bf40..72d6e82b0 100644
--- a/app/components/combined_system_message/combined_system_message.js
+++ b/app/components/combined_system_message/combined_system_message.js
@@ -177,7 +177,6 @@ export default class CombinedSystemMessage extends React.PureComponent {
currentUserId: PropTypes.string.isRequired,
currentUsername: PropTypes.string.isRequired,
messageData: PropTypes.array.isRequired,
- navigator: PropTypes.object.isRequired,
showJoinLeave: PropTypes.bool.isRequired,
textStyles: PropTypes.object,
theme: PropTypes.object.isRequired,
@@ -266,7 +265,6 @@ export default class CombinedSystemMessage extends React.PureComponent {
const {
currentUserId,
currentUsername,
- navigator,
textStyles,
theme,
} = this.props;
@@ -285,7 +283,6 @@ export default class CombinedSystemMessage extends React.PureComponent {
diff --git a/app/components/combined_system_message/last_users.js b/app/components/combined_system_message/last_users.js
index 5e026ad03..f85600ff7 100644
--- a/app/components/combined_system_message/last_users.js
+++ b/app/components/combined_system_message/last_users.js
@@ -53,7 +53,6 @@ export default class LastUsers extends React.PureComponent {
static propTypes = {
actor: PropTypes.string,
expandedLocale: PropTypes.object.isRequired,
- navigator: PropTypes.object.isRequired,
postType: PropTypes.string.isRequired,
style: PropTypes.object.isRequired,
textStyles: PropTypes.object,
@@ -88,7 +87,6 @@ export default class LastUsers extends React.PureComponent {
const {
actor,
expandedLocale,
- navigator,
style,
textStyles,
usernames,
@@ -106,7 +104,6 @@ export default class LastUsers extends React.PureComponent {
return (
@@ -116,7 +113,6 @@ export default class LastUsers extends React.PureComponent {
renderCollapsedView = () => {
const {
actor,
- navigator,
postType,
style,
textStyles,
@@ -134,7 +130,6 @@ export default class LastUsers extends React.PureComponent {
defaultMessage={'{firstUser} and '}
values={{firstUser}}
baseTextStyle={style.baseText}
- navigator={navigator}
style={style.baseText}
textStyles={textStyles}
theme={theme}
@@ -155,7 +150,6 @@ export default class LastUsers extends React.PureComponent {
defaultMessage={typeMessage[postType].defaultMessage}
values={{actor}}
baseTextStyle={style.baseText}
- navigator={navigator}
style={style.baseText}
textStyles={textStyles}
theme={theme}
diff --git a/app/components/file_attachment_list/file_attachment.js b/app/components/file_attachment_list/file_attachment.js
index f190cf0ee..6efe9563c 100644
--- a/app/components/file_attachment_list/file_attachment.js
+++ b/app/components/file_attachment_list/file_attachment.js
@@ -29,7 +29,6 @@ export default class FileAttachment extends PureComponent {
onLongPress: PropTypes.func,
onPreviewPress: PropTypes.func,
theme: PropTypes.object.isRequired,
- navigator: PropTypes.object,
};
static defaultProps = {
@@ -93,7 +92,6 @@ export default class FileAttachment extends PureComponent {
deviceWidth,
file,
theme,
- navigator,
onLongPress,
} = this.props;
const {data} = file;
@@ -120,7 +118,6 @@ export default class FileAttachment extends PureComponent {
ref={this.setDocumentRef}
canDownloadFiles={canDownloadFiles}
file={file}
- navigator={navigator}
onLongPress={onLongPress}
theme={theme}
/>
diff --git a/app/components/file_attachment_list/file_attachment_document.js b/app/components/file_attachment_list/file_attachment_document/file_attachment_document.js
similarity index 94%
rename from app/components/file_attachment_list/file_attachment_document.js
rename to app/components/file_attachment_list/file_attachment_document/file_attachment_document.js
index 473463227..d699b9a29 100644
--- a/app/components/file_attachment_list/file_attachment_document.js
+++ b/app/components/file_attachment_list/file_attachment_document/file_attachment_document.js
@@ -25,7 +25,7 @@ import {DeviceTypes} from 'app/constants/';
import mattermostBucket from 'app/mattermost_bucket';
import {changeOpacity} from 'app/utils/theme';
-import FileAttachmentIcon from './file_attachment_icon';
+import FileAttachmentIcon from 'app/components/file_attachment_list/file_attachment_icon';
const {DOCUMENTS_PATH} = DeviceTypes;
const DOWNLOADING_OFFSET = 28;
@@ -38,13 +38,15 @@ const circularProgressWidth = 4;
export default class FileAttachmentDocument extends PureComponent {
static propTypes = {
+ actions: PropTypes.shape({
+ goToScreen: PropTypes.func.isRequired,
+ }).isRequired,
backgroundColor: PropTypes.string,
canDownloadFiles: PropTypes.bool.isRequired,
iconHeight: PropTypes.number,
iconWidth: PropTypes.number,
file: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
- navigator: PropTypes.object,
onLongPress: PropTypes.func,
wrapperHeight: PropTypes.number,
wrapperWidth: PropTypes.number,
@@ -192,7 +194,7 @@ export default class FileAttachmentDocument extends PureComponent {
};
previewTextFile = (file, delay = 2000) => {
- const {navigator, theme} = this.props;
+ const {actions} = this.props;
const {data} = file;
const prefix = Platform.OS === 'android' ? 'file:/' : '';
const path = `${DOCUMENTS_PATH}/${data.id}-${file.caption}`;
@@ -200,21 +202,13 @@ export default class FileAttachmentDocument extends PureComponent {
setTimeout(async () => {
try {
const content = await readFile;
- navigator.push({
- screen: 'TextPreview',
- title: file.caption,
- animated: true,
- backButtonTitle: '',
- passProps: {
- content,
- },
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- });
+ const screen = 'TextPreview';
+ const title = file.caption;
+ const passProps = {
+ content,
+ };
+
+ actions.goToScreen(screen, title, passProps);
this.setState({downloading: false, progress: 0});
} catch (error) {
RNFetchBlob.fs.unlink(path);
diff --git a/app/components/file_attachment_list/file_attachment_document/index.js b/app/components/file_attachment_list/file_attachment_document/index.js
new file mode 100644
index 000000000..753d2d8ff
--- /dev/null
+++ b/app/components/file_attachment_list/file_attachment_document/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 {goToScreen} from 'app/actions/navigation';
+
+import FileAttachmentDocument from './file_attachment_document';
+
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ goToScreen,
+ }, dispatch),
+ };
+}
+
+export default connect(null, mapDispatchToProps)(FileAttachmentDocument);
diff --git a/app/components/file_attachment_list/file_attachment_list.js b/app/components/file_attachment_list/file_attachment_list.js
index f53eef22c..80f7d463c 100644
--- a/app/components/file_attachment_list/file_attachment_list.js
+++ b/app/components/file_attachment_list/file_attachment_list.js
@@ -20,14 +20,16 @@ import FileAttachment from './file_attachment';
export default class FileAttachmentList extends Component {
static propTypes = {
- actions: PropTypes.object.isRequired,
+ actions: PropTypes.shape({
+ loadFilesForPostIfNecessary: PropTypes.func.isRequired,
+ showModalOverCurrentContext: PropTypes.func.isRequired,
+ }).isRequired,
canDownloadFiles: PropTypes.bool.isRequired,
deviceHeight: PropTypes.number.isRequired,
deviceWidth: PropTypes.number.isRequired,
fileIds: PropTypes.array.isRequired,
files: PropTypes.array,
isFailed: PropTypes.bool,
- navigator: PropTypes.object,
onLongPress: PropTypes.func,
postId: PropTypes.string.isRequired,
theme: PropTypes.object.isRequired,
@@ -122,11 +124,12 @@ export default class FileAttachmentList extends Component {
};
handlePreviewPress = preventDoubleTap((idx) => {
- previewImageAtIndex(this.props.navigator, this.items, idx, this.galleryFiles);
+ const {actions} = this.props;
+ previewImageAtIndex(this.items, idx, this.galleryFiles, actions.showModalOverCurrentContext);
});
renderItems = () => {
- const {canDownloadFiles, deviceWidth, fileIds, files, navigator} = this.props;
+ const {canDownloadFiles, deviceWidth, fileIds, files} = this.props;
if (!files.length && fileIds.length > 0) {
return fileIds.map((id, idx) => (
@@ -156,7 +159,6 @@ export default class FileAttachmentList extends Component {
file={f}
id={file.id}
index={idx}
- navigator={navigator}
onCaptureRef={this.handleCaptureRef}
onPreviewPress={this.handlePreviewPress}
onLongPress={this.props.onLongPress}
diff --git a/app/components/file_attachment_list/file_attachment_list.test.js b/app/components/file_attachment_list/file_attachment_list.test.js
index 245e0bac1..e2035d542 100644
--- a/app/components/file_attachment_list/file_attachment_list.test.js
+++ b/app/components/file_attachment_list/file_attachment_list.test.js
@@ -16,6 +16,7 @@ describe('PostAttachmentOpenGraph', () => {
const baseProps = {
actions: {
loadFilesForPostIfNecessary,
+ showModalOverCurrentContext: jest.fn(),
},
canDownloadFiles: true,
deviceHeight: 680,
@@ -71,6 +72,7 @@ describe('PostAttachmentOpenGraph', () => {
files: [],
actions: {
loadFilesForPostIfNecessary: loadFilesForPostIfNecessaryMock,
+ showModalOverCurrentContext: jest.fn(),
},
};
diff --git a/app/components/file_attachment_list/index.js b/app/components/file_attachment_list/index.js
index 2230cd5df..29960f63a 100644
--- a/app/components/file_attachment_list/index.js
+++ b/app/components/file_attachment_list/index.js
@@ -8,6 +8,7 @@ import {canDownloadFilesOnMobile} from 'mattermost-redux/selectors/entities/gene
import {makeGetFilesForPost} from 'mattermost-redux/selectors/entities/files';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import {showModalOverCurrentContext} from 'app/actions/navigation';
import {loadFilesForPostIfNecessary} from 'app/actions/views/channel';
import {getDimensions} from 'app/selectors/device';
@@ -29,6 +30,7 @@ function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
loadFilesForPostIfNecessary,
+ showModalOverCurrentContext,
}, dispatch),
};
}
diff --git a/app/components/formatted_markdown_text.js b/app/components/formatted_markdown_text.js
index 965280d45..2f5b03fc2 100644
--- a/app/components/formatted_markdown_text.js
+++ b/app/components/formatted_markdown_text.js
@@ -35,7 +35,6 @@ class FormattedMarkdownText extends React.PureComponent {
baseTextStyle: CustomPropTypes.Style,
defaultMessage: PropTypes.string.isRequired,
id: PropTypes.string.isRequired,
- navigator: PropTypes.object.isRequired,
onPostPress: PropTypes.func,
style: CustomPropTypes.Style,
textStyles: PropTypes.object,
@@ -115,7 +114,6 @@ class FormattedMarkdownText extends React.PureComponent {
diff --git a/app/components/markdown/hashtag/hashtag.js b/app/components/markdown/hashtag/hashtag.js
index 75fc5486f..540d49bff 100644
--- a/app/components/markdown/hashtag/hashtag.js
+++ b/app/components/markdown/hashtag/hashtag.js
@@ -12,24 +12,31 @@ export default class Hashtag extends React.PureComponent {
hashtag: PropTypes.string.isRequired,
linkStyle: CustomPropTypes.Style.isRequired,
onHashtagPress: PropTypes.func,
- navigator: PropTypes.object.isRequired,
actions: PropTypes.shape({
+ popToRoot: PropTypes.func.isRequired,
showSearchModal: PropTypes.func.isRequired,
+ dismissAllModals: PropTypes.func.isRequired,
}).isRequired,
};
handlePress = () => {
- if (this.props.onHashtagPress) {
- this.props.onHashtagPress(this.props.hashtag);
+ const {
+ onHashtagPress,
+ hashtag,
+ actions,
+ } = this.props;
+
+ if (onHashtagPress) {
+ onHashtagPress(hashtag);
return;
}
// Close thread view, permalink view, etc
- this.props.navigator.dismissAllModals();
- this.props.navigator.popToRoot();
+ actions.dismissAllModals();
+ actions.popToRoot();
- this.props.actions.showSearchModal(this.props.navigator, '#' + this.props.hashtag);
+ actions.showSearchModal('#' + this.props.hashtag);
};
render() {
diff --git a/app/components/markdown/hashtag/hashtag.test.js b/app/components/markdown/hashtag/hashtag.test.js
index 05d87e3dd..d75fc2a74 100644
--- a/app/components/markdown/hashtag/hashtag.test.js
+++ b/app/components/markdown/hashtag/hashtag.test.js
@@ -11,12 +11,10 @@ describe('Hashtag', () => {
const baseProps = {
hashtag: 'test',
linkStyle: {color: 'red'},
- navigator: {
- dismissAllModals: jest.fn(),
- popToRoot: jest.fn(),
- },
actions: {
showSearchModal: jest.fn(),
+ dismissAllModals: jest.fn(),
+ popToRoot: jest.fn(),
},
};
@@ -35,9 +33,9 @@ describe('Hashtag', () => {
wrapper.find(Text).simulate('press');
- expect(props.navigator.dismissAllModals).toHaveBeenCalled();
- expect(props.navigator.popToRoot).toHaveBeenCalled();
- expect(props.actions.showSearchModal).toHaveBeenCalledWith(props.navigator, '#test');
+ expect(props.actions.dismissAllModals).toHaveBeenCalled();
+ expect(props.actions.popToRoot).toHaveBeenCalled();
+ expect(props.actions.showSearchModal).toHaveBeenCalledWith('#test');
});
test('should call onHashtagPress if provided', () => {
@@ -50,8 +48,8 @@ describe('Hashtag', () => {
wrapper.find(Text).simulate('press');
- expect(props.navigator.dismissAllModals).not.toBeCalled();
- expect(props.navigator.popToRoot).not.toBeCalled();
+ expect(props.actions.dismissAllModals).not.toBeCalled();
+ expect(props.actions.popToRoot).not.toBeCalled();
expect(props.actions.showSearchModal).not.toBeCalled();
expect(props.onHashtagPress).toBeCalled();
diff --git a/app/components/markdown/hashtag/index.js b/app/components/markdown/hashtag/index.js
index 3683f71ab..9ffc10e5c 100644
--- a/app/components/markdown/hashtag/index.js
+++ b/app/components/markdown/hashtag/index.js
@@ -4,14 +4,20 @@
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
-import {showSearchModal} from 'app/actions/views/search';
+import {
+ popToRoot,
+ showSearchModal,
+ dismissAllModals,
+} from 'app/actions/navigation';
import Hashtag from './hashtag';
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
+ popToRoot,
showSearchModal,
+ dismissAllModals,
}, dispatch),
};
}
diff --git a/app/components/markdown/markdown.js b/app/components/markdown/markdown.js
index 80aa2df39..93edb1296 100644
--- a/app/components/markdown/markdown.js
+++ b/app/components/markdown/markdown.js
@@ -49,7 +49,6 @@ export default class Markdown extends PureComponent {
isSearchResult: PropTypes.bool,
mentionKeys: PropTypes.array.isRequired,
minimumHashtagLength: PropTypes.number.isRequired,
- navigator: PropTypes.object.isRequired,
onChannelLinkPress: PropTypes.func,
onHashtagPress: PropTypes.func,
onPermalinkPress: PropTypes.func,
@@ -176,7 +175,6 @@ export default class Markdown extends PureComponent {
{reactChildren}
@@ -188,7 +186,6 @@ export default class Markdown extends PureComponent {
linkDestination={linkDestination}
imagesMetadata={this.props.imagesMetadata}
isReplyPost={this.props.isReplyPost}
- navigator={this.props.navigator}
source={src}
errorTextStyle={[this.computeTextStyle(this.props.baseTextStyle, context), this.props.textStyles.error]}
>
@@ -209,7 +206,6 @@ export default class Markdown extends PureComponent {
isSearchResult={this.props.isSearchResult}
mentionName={mentionName}
onPostPress={this.props.onPostPress}
- navigator={this.props.navigator}
/>
);
};
@@ -250,7 +246,6 @@ export default class Markdown extends PureComponent {
hashtag={hashtag}
linkStyle={this.props.textStyles.link}
onHashtagPress={this.props.onHashtagPress}
- navigator={this.props.navigator}
/>
);
};
@@ -295,7 +290,6 @@ export default class Markdown extends PureComponent {
return (
{
return (
{children}
diff --git a/app/components/markdown/markdown_code_block/index.js b/app/components/markdown/markdown_code_block/index.js
index 37ccabce4..76e8cbb51 100644
--- a/app/components/markdown/markdown_code_block/index.js
+++ b/app/components/markdown/markdown_code_block/index.js
@@ -1,10 +1,13 @@
// 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 {getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import {goToScreen} from 'app/actions/navigation';
+
import MarkdownCodeBlock from './markdown_code_block';
function mapStateToProps(state) {
@@ -13,4 +16,12 @@ function mapStateToProps(state) {
};
}
-export default connect(mapStateToProps)(MarkdownCodeBlock);
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ goToScreen,
+ }, dispatch),
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(MarkdownCodeBlock);
diff --git a/app/components/markdown/markdown_code_block/markdown_code_block.js b/app/components/markdown/markdown_code_block/markdown_code_block.js
index d6ff764ed..eaef682e2 100644
--- a/app/components/markdown/markdown_code_block/markdown_code_block.js
+++ b/app/components/markdown/markdown_code_block/markdown_code_block.js
@@ -24,7 +24,9 @@ const MAX_LINES = 4;
export default class MarkdownCodeBlock extends React.PureComponent {
static propTypes = {
- navigator: PropTypes.object.isRequired,
+ actions: PropTypes.shape({
+ goToScreen: PropTypes.func.isRequired,
+ }).isRequired,
theme: PropTypes.object.isRequired,
language: PropTypes.string,
content: PropTypes.string.isRequired,
@@ -40,10 +42,14 @@ export default class MarkdownCodeBlock extends React.PureComponent {
};
handlePress = preventDoubleTap(() => {
- const {navigator, theme} = this.props;
+ const {actions, language, content} = this.props;
const {intl} = this.context;
+ const screen = 'Code';
+ const passProps = {
+ content,
+ };
- const languageDisplayName = getDisplayNameForLanguage(this.props.language);
+ const languageDisplayName = getDisplayNameForLanguage(language);
let title;
if (languageDisplayName) {
title = intl.formatMessage(
@@ -62,21 +68,7 @@ export default class MarkdownCodeBlock extends React.PureComponent {
});
}
- navigator.push({
- screen: 'Code',
- title,
- animated: true,
- backButtonTitle: '',
- passProps: {
- content: this.props.content,
- },
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- });
+ actions.goToScreen(screen, title, passProps);
});
handleLongPress = async () => {
diff --git a/app/components/markdown/markdown_image/index.js b/app/components/markdown/markdown_image/index.js
index 19ef387fa..f15c54ccc 100644
--- a/app/components/markdown/markdown_image/index.js
+++ b/app/components/markdown/markdown_image/index.js
@@ -1,10 +1,13 @@
// 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 {getCurrentUrl} from 'mattermost-redux/selectors/entities/general';
+import {showModalOverCurrentContext} from 'app/actions/navigation';
+
import {getDimensions} from 'app/selectors/device';
import MarkdownImage from './markdown_image';
@@ -16,4 +19,12 @@ function mapStateToProps(state) {
};
}
-export default connect(mapStateToProps)(MarkdownImage);
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ showModalOverCurrentContext,
+ }, dispatch),
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(MarkdownImage);
diff --git a/app/components/markdown/markdown_image/markdown_image.js b/app/components/markdown/markdown_image/markdown_image.js
index 6f9fc9bf5..526bb4a82 100644
--- a/app/components/markdown/markdown_image/markdown_image.js
+++ b/app/components/markdown/markdown_image/markdown_image.js
@@ -33,13 +33,15 @@ const VIEWPORT_IMAGE_REPLY_OFFSET = 13;
export default class MarkdownImage extends React.Component {
static propTypes = {
+ actions: PropTypes.shape({
+ showModalOverCurrentContext: PropTypes.func.isRequired,
+ }).isRequired,
children: PropTypes.node,
deviceHeight: PropTypes.number.isRequired,
deviceWidth: PropTypes.number.isRequired,
imagesMetadata: PropTypes.object,
linkDestination: PropTypes.string,
isReplyPost: PropTypes.bool,
- navigator: PropTypes.object.isRequired,
serverURL: PropTypes.string.isRequired,
source: PropTypes.string.isRequired,
errorTextStyle: CustomPropTypes.Style,
@@ -175,6 +177,7 @@ export default class MarkdownImage extends React.Component {
originalWidth,
uri,
} = this.state;
+ const {actions} = this.props;
const link = this.getSource();
let filename = link.substring(link.lastIndexOf('/') + 1, link.indexOf('?') === -1 ? link.length : link.indexOf('?'));
const extension = filename.split('.').pop();
@@ -195,7 +198,8 @@ export default class MarkdownImage extends React.Component {
localPath: uri,
},
}];
- previewImageAtIndex(this.props.navigator, [this.refs.item], 0, files);
+
+ previewImageAtIndex([this.refs.item], 0, files, actions.showModalOverCurrentContext);
};
loadImageSize = (source) => {
diff --git a/app/components/markdown/markdown_table/index.js b/app/components/markdown/markdown_table/index.js
index e3e37c016..4100a3fc4 100644
--- a/app/components/markdown/markdown_table/index.js
+++ b/app/components/markdown/markdown_table/index.js
@@ -1,10 +1,13 @@
// 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 {getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import {goToScreen} from 'app/actions/navigation';
+
import MarkdownTable from './markdown_table';
function mapStateToProps(state) {
@@ -13,4 +16,12 @@ function mapStateToProps(state) {
};
}
-export default connect(mapStateToProps)(MarkdownTable);
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ goToScreen,
+ }, dispatch),
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(MarkdownTable);
diff --git a/app/components/markdown/markdown_table/markdown_table.js b/app/components/markdown/markdown_table/markdown_table.js
index 2d6cf6d73..deffa3174 100644
--- a/app/components/markdown/markdown_table/markdown_table.js
+++ b/app/components/markdown/markdown_table/markdown_table.js
@@ -19,8 +19,10 @@ const MAX_HEIGHT = 300;
export default class MarkdownTable extends React.PureComponent {
static propTypes = {
+ actions: PropTypes.shape({
+ goToScreen: PropTypes.func.isRequired,
+ }).isRequired,
children: PropTypes.node.isRequired,
- navigator: PropTypes.object.isRequired,
numColumns: PropTypes.number.isRequired,
theme: PropTypes.object.isRequired,
};
@@ -44,27 +46,19 @@ export default class MarkdownTable extends React.PureComponent {
};
handlePress = preventDoubleTap(() => {
- const {navigator, theme} = this.props;
-
- navigator.push({
- screen: 'Table',
- title: this.context.intl.formatMessage({
- id: 'mobile.routes.table',
- defaultMessage: 'Table',
- }),
- animated: true,
- backButtonTitle: '',
- passProps: {
- renderRows: this.renderRows,
- tableWidth: this.getTableWidth(),
- },
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
+ const {actions} = this.props;
+ const {intl} = this.context;
+ const screen = 'Table';
+ const title = intl.formatMessage({
+ id: 'mobile.routes.table',
+ defaultMessage: 'Table',
});
+ const passProps = {
+ renderRows: this.renderRows,
+ tableWidth: this.getTableWidth(),
+ };
+
+ actions.goToScreen(screen, title, passProps);
});
handleContainerLayout = (e) => {
diff --git a/app/components/markdown/markdown_table_image/index.js b/app/components/markdown/markdown_table_image/index.js
index 96174a3a8..c1eea7804 100644
--- a/app/components/markdown/markdown_table_image/index.js
+++ b/app/components/markdown/markdown_table_image/index.js
@@ -1,11 +1,14 @@
// 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 {getCurrentUrl} from 'mattermost-redux/selectors/entities/general';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import {goToScreen} from 'app/actions/navigation';
+
import MarkdownTableImage from './markdown_table_image';
function mapStateToProps(state) {
@@ -15,4 +18,12 @@ function mapStateToProps(state) {
};
}
-export default connect(mapStateToProps)(MarkdownTableImage);
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ goToScreen,
+ }, dispatch),
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(MarkdownTableImage);
diff --git a/app/components/markdown/markdown_table_image/markdown_table_image.js b/app/components/markdown/markdown_table_image/markdown_table_image.js
index c75942201..b2fdfd5f3 100644
--- a/app/components/markdown/markdown_table_image/markdown_table_image.js
+++ b/app/components/markdown/markdown_table_image/markdown_table_image.js
@@ -11,10 +11,12 @@ import {preventDoubleTap} from 'app/utils/tap';
export default class MarkdownTableImage extends React.PureComponent {
static propTypes = {
+ actions: PropTypes.shape({
+ goToScreen: PropTypes.func.isRequired,
+ }).isRequired,
children: PropTypes.node.isRequired,
source: PropTypes.string.isRequired,
textStyle: CustomPropTypes.Style.isRequired,
- navigator: PropTypes.object.isRequired,
serverURL: PropTypes.string.isRequired,
theme: PropTypes.object.isRequired,
};
@@ -24,26 +26,18 @@ export default class MarkdownTableImage extends React.PureComponent {
};
handlePress = preventDoubleTap(() => {
- const {navigator, theme} = this.props;
-
- navigator.push({
- screen: 'TableImage',
- title: this.context.intl.formatMessage({
- id: 'mobile.routes.tableImage',
- defaultMessage: 'Image',
- }),
- animated: true,
- backButtonTitle: '',
- passProps: {
- imageSource: this.getImageSource(),
- },
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
+ const {actions} = this.props;
+ const {intl} = this.context;
+ const screen = 'TableImage';
+ const title = intl.formatMessage({
+ id: 'mobile.routes.tableImage',
+ defaultMessage: 'Image',
});
+ const passProps = {
+ imageSource: this.getImageSource(),
+ };
+
+ actions.goToScreen(screen, title, passProps);
});
getImageSource = () => {
diff --git a/app/components/message_attachments/action_menu/action_menu.js b/app/components/message_attachments/action_menu/action_menu.js
index 96197ecf0..3ea8d46fd 100644
--- a/app/components/message_attachments/action_menu/action_menu.js
+++ b/app/components/message_attachments/action_menu/action_menu.js
@@ -18,7 +18,6 @@ export default class ActionMenu extends PureComponent {
options: PropTypes.arrayOf(PropTypes.object),
postId: PropTypes.string.isRequired,
selected: PropTypes.object,
- navigator: PropTypes.object,
};
constructor(props) {
@@ -63,7 +62,6 @@ export default class ActionMenu extends PureComponent {
name,
dataSource,
options,
- navigator,
} = this.props;
const {selected} = this.state;
@@ -73,7 +71,6 @@ export default class ActionMenu extends PureComponent {
dataSource={dataSource}
options={options}
selected={selected}
- navigator={navigator}
onSelected={this.handleSelect}
/>
);
diff --git a/app/components/message_attachments/attachment_actions.js b/app/components/message_attachments/attachment_actions.js
index 8b46580c2..67e77886e 100644
--- a/app/components/message_attachments/attachment_actions.js
+++ b/app/components/message_attachments/attachment_actions.js
@@ -10,14 +10,12 @@ import ActionButton from './action_button';
export default class AttachmentActions extends PureComponent {
static propTypes = {
actions: PropTypes.array,
- navigator: PropTypes.object.isRequired,
postId: PropTypes.string.isRequired,
};
render() {
const {
actions,
- navigator,
postId,
} = this.props;
@@ -43,7 +41,6 @@ export default class AttachmentActions extends PureComponent {
defaultOption={action.default_option}
options={action.options}
postId={postId}
- navigator={navigator}
/>
);
break;
diff --git a/app/components/message_attachments/attachment_fields.js b/app/components/message_attachments/attachment_fields.js
index 67d76dda4..ba96553d0 100644
--- a/app/components/message_attachments/attachment_fields.js
+++ b/app/components/message_attachments/attachment_fields.js
@@ -15,7 +15,6 @@ export default class AttachmentFields extends PureComponent {
blockStyles: PropTypes.object.isRequired,
fields: PropTypes.array,
metadata: PropTypes.object,
- navigator: PropTypes.object.isRequired,
onPermalinkPress: PropTypes.func,
textStyles: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
@@ -27,7 +26,6 @@ export default class AttachmentFields extends PureComponent {
blockStyles,
fields,
metadata,
- navigator,
onPermalinkPress,
textStyles,
theme,
@@ -88,7 +86,6 @@ export default class AttachmentFields extends PureComponent {
blockStyles={blockStyles}
imagesMetadata={metadata?.images}
value={(field.value || '')}
- navigator={navigator}
onPermalinkPress={onPermalinkPress}
/>
diff --git a/app/components/message_attachments/attachment_image.js b/app/components/message_attachments/attachment_image/attachment_image.js
similarity index 95%
rename from app/components/message_attachments/attachment_image.js
rename to app/components/message_attachments/attachment_image/attachment_image.js
index 249c1e9ec..dfb04ac13 100644
--- a/app/components/message_attachments/attachment_image.js
+++ b/app/components/message_attachments/attachment_image/attachment_image.js
@@ -15,11 +15,13 @@ const VIEWPORT_IMAGE_CONTAINER_OFFSET = 10;
export default class AttachmentImage extends PureComponent {
static propTypes = {
+ actions: PropTypes.shape({
+ showModalOverCurrentContext: PropTypes.func.isRequired,
+ }).isRequired,
deviceHeight: PropTypes.number.isRequired,
deviceWidth: PropTypes.number.isRequired,
imageMetadata: PropTypes.object,
imageUrl: PropTypes.string,
- navigator: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
};
@@ -47,7 +49,7 @@ export default class AttachmentImage extends PureComponent {
}
handlePreviewImage = () => {
- const {imageUrl, navigator} = this.props;
+ const {actions, imageUrl} = this.props;
const {
imageUri: uri,
originalHeight,
@@ -73,7 +75,7 @@ export default class AttachmentImage extends PureComponent {
localPath: uri,
},
}];
- previewImageAtIndex(navigator, [this.refs.item], 0, files);
+ previewImageAtIndex([this.refs.item], 0, files, actions.showModalOverCurrentContext);
};
setImageDimensions = (imageUri, dimensions, originalWidth, originalHeight) => {
diff --git a/app/components/message_attachments/attachment_image/index.js b/app/components/message_attachments/attachment_image/index.js
new file mode 100644
index 000000000..17bfedae3
--- /dev/null
+++ b/app/components/message_attachments/attachment_image/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 AttachmentImage from './attachment_image';
+
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ showModalOverCurrentContext,
+ }, dispatch),
+ };
+}
+
+export default connect(null, mapDispatchToProps)(AttachmentImage);
diff --git a/app/components/message_attachments/attachment_pretext.js b/app/components/message_attachments/attachment_pretext.js
index fcb1e900d..827af5ca7 100644
--- a/app/components/message_attachments/attachment_pretext.js
+++ b/app/components/message_attachments/attachment_pretext.js
@@ -13,7 +13,6 @@ export default class AttachmentPreText extends PureComponent {
baseTextStyle: CustomPropTypes.Style.isRequired,
blockStyles: PropTypes.object.isRequired,
metadata: PropTypes.object,
- navigator: PropTypes.object.isRequired,
onPermalinkPress: PropTypes.func,
textStyles: PropTypes.object.isRequired,
value: PropTypes.string,
@@ -24,7 +23,6 @@ export default class AttachmentPreText extends PureComponent {
baseTextStyle,
blockStyles,
metadata,
- navigator,
onPermalinkPress,
value,
textStyles,
@@ -42,7 +40,6 @@ export default class AttachmentPreText extends PureComponent {
blockStyles={blockStyles}
imagesMetadata={metadata?.images}
value={value}
- navigator={navigator}
onPermalinkPress={onPermalinkPress}
/>
diff --git a/app/components/message_attachments/attachment_text.js b/app/components/message_attachments/attachment_text.js
index 66ef572ca..b155d5178 100644
--- a/app/components/message_attachments/attachment_text.js
+++ b/app/components/message_attachments/attachment_text.js
@@ -18,7 +18,6 @@ export default class AttachmentText extends PureComponent {
deviceHeight: PropTypes.number.isRequired,
hasThumbnail: PropTypes.bool,
metadata: PropTypes.object,
- navigator: PropTypes.object.isRequired,
onPermalinkPress: PropTypes.func,
textStyles: PropTypes.object.isRequired,
value: PropTypes.string,
@@ -68,7 +67,6 @@ export default class AttachmentText extends PureComponent {
blockStyles,
hasThumbnail,
metadata,
- navigator,
onPermalinkPress,
value,
textStyles,
@@ -97,7 +95,6 @@ export default class AttachmentText extends PureComponent {
blockStyles={blockStyles}
imagesMetadata={metadata?.images}
value={value}
- navigator={navigator}
onPermalinkPress={onPermalinkPress}
/>
diff --git a/app/components/message_attachments/attachment_title.js b/app/components/message_attachments/attachment_title.js
index bfd673edd..12a525748 100644
--- a/app/components/message_attachments/attachment_title.js
+++ b/app/components/message_attachments/attachment_title.js
@@ -13,7 +13,6 @@ export default class AttachmentTitle extends PureComponent {
link: PropTypes.string,
theme: PropTypes.object.isRequired,
value: PropTypes.string,
- navigator: PropTypes.object.isRequired,
};
openLink = () => {
@@ -28,7 +27,6 @@ export default class AttachmentTitle extends PureComponent {
link,
value,
theme,
- navigator,
} = this.props;
if (!value) {
@@ -57,7 +55,6 @@ export default class AttachmentTitle extends PureComponent {
disableChannelLink={true}
autolinkedUrlSchemes={[]}
mentionKeys={[]}
- navigator={navigator}
theme={theme}
value={value}
baseTextStyle={style.title}
diff --git a/app/components/message_attachments/message_attachment.js b/app/components/message_attachments/message_attachment.js
index eafba47aa..5e544b6c8 100644
--- a/app/components/message_attachments/message_attachment.js
+++ b/app/components/message_attachments/message_attachment.js
@@ -31,7 +31,6 @@ export default class MessageAttachment extends PureComponent {
deviceHeight: PropTypes.number.isRequired,
deviceWidth: PropTypes.number.isRequired,
metadata: PropTypes.object,
- navigator: PropTypes.object.isRequired,
postId: PropTypes.string.isRequired,
onPermalinkPress: PropTypes.func,
theme: PropTypes.object,
@@ -46,7 +45,6 @@ export default class MessageAttachment extends PureComponent {
deviceHeight,
deviceWidth,
metadata,
- navigator,
onPermalinkPress,
postId,
textStyles,
@@ -70,7 +68,6 @@ export default class MessageAttachment extends PureComponent {
baseTextStyle={baseTextStyle}
blockStyles={blockStyles}
metadata={metadata}
- navigator={navigator}
onPermalinkPress={onPermalinkPress}
textStyles={textStyles}
value={attachment.pretext}
@@ -86,7 +83,6 @@ export default class MessageAttachment extends PureComponent {
link={attachment.title_link}
theme={theme}
value={attachment.title}
- navigator={navigator}
/>
diff --git a/app/components/post/index.js b/app/components/post/index.js
index bd501d2ff..300c7feaf 100644
--- a/app/components/post/index.js
+++ b/app/components/post/index.js
@@ -12,6 +12,7 @@ import {getUser, getCurrentUserId} from 'mattermost-redux/selectors/entities/use
import {getMyPreferences, getTheme} from 'mattermost-redux/selectors/entities/preferences';
import {isPostFlagged, isSystemMessage} from 'mattermost-redux/utils/post_utils';
+import {goToScreen, showModalOverCurrentContext} from 'app/actions/navigation';
import {insertToDraft, setPostTooltipVisible} from 'app/actions/views/channel';
import Post from './post';
@@ -93,6 +94,8 @@ function mapDispatchToProps(dispatch) {
removePost,
setPostTooltipVisible,
insertToDraft,
+ goToScreen,
+ showModalOverCurrentContext,
}, dispatch),
};
}
diff --git a/app/components/post/post.js b/app/components/post/post.js
index 0fc4e6f85..4345e0955 100644
--- a/app/components/post/post.js
+++ b/app/components/post/post.js
@@ -34,6 +34,8 @@ export default class Post extends PureComponent {
createPost: PropTypes.func.isRequired,
insertToDraft: PropTypes.func.isRequired,
removePost: PropTypes.func.isRequired,
+ goToScreen: PropTypes.func.isRequired,
+ showModalOverCurrentContext: PropTypes.func.isRequired,
}).isRequired,
channelIsReadOnly: PropTypes.bool,
currentUserId: PropTypes.string.isRequired,
@@ -49,7 +51,6 @@ export default class Post extends PureComponent {
isSearchResult: PropTypes.bool,
commentedOnPost: PropTypes.object,
managedConfig: PropTypes.object.isRequired,
- navigator: PropTypes.object,
onHashtagPress: PropTypes.func,
onPermalinkPress: PropTypes.func,
shouldRenderReplyButton: PropTypes.bool,
@@ -88,30 +89,16 @@ export default class Post extends PureComponent {
goToUserProfile = () => {
const {intl} = this.context;
- const {navigator, post, theme} = this.props;
- const options = {
- screen: 'UserProfile',
- title: intl.formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'}),
- animated: true,
- backButtonTitle: '',
- passProps: {
- userId: post.user_id,
- },
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
+ const {actions, post} = this.props;
+ const screen = 'UserProfile';
+ const title = intl.formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'});
+ const passProps = {
+ userId: post.user_id,
};
Keyboard.dismiss();
requestAnimationFrame(() => {
- if (Platform.OS === 'ios') {
- navigator.push(options);
- } else {
- navigator.showModal(options);
- }
+ actions.goToScreen(screen, title, passProps);
});
};
@@ -120,7 +107,8 @@ export default class Post extends PureComponent {
};
handleFailedPostPress = () => {
- const options = {
+ const screen = 'OptionsModal';
+ const passProps = {
title: {
id: t('mobile.post.failed_title'),
defaultMessage: 'Unable to send your message:',
@@ -151,22 +139,7 @@ export default class Post extends PureComponent {
}],
};
- this.props.navigator.showModal({
- screen: 'OptionsModal',
- title: '',
- animationType: 'none',
- passProps: {
- items: options.items,
- title: options.title,
- },
- navigatorStyle: {
- navBarHidden: true,
- statusBarHidden: false,
- statusBarHideWithNavBar: false,
- screenBackgroundColor: 'transparent',
- modalPresentationStyle: 'overCurrentContext',
- },
- });
+ this.props.actions.showModalOverCurrentContext(screen, passProps);
};
handlePress = preventDoubleTap(() => {
@@ -352,7 +325,6 @@ export default class Post extends PureComponent {
channelIsReadOnly={channelIsReadOnly}
isLastPost={isLastPost}
isSearchResult={isSearchResult}
- navigator={this.props.navigator}
onFailedPostPress={this.handleFailedPostPress}
onHashtagPress={onHashtagPress}
onPermalinkPress={onPermalinkPress}
diff --git a/app/components/post_add_channel_member/post_add_channel_member.js b/app/components/post_add_channel_member/post_add_channel_member.js
index 84fa69f37..de79f312f 100644
--- a/app/components/post_add_channel_member/post_add_channel_member.js
+++ b/app/components/post_add_channel_member/post_add_channel_member.js
@@ -31,7 +31,6 @@ export default class PostAddChannelMember extends React.PureComponent {
userIds: PropTypes.array.isRequired,
usernames: PropTypes.array.isRequired,
noGroupsUsernames: PropTypes.array,
- navigator: PropTypes.object.isRequired,
onPostPress: PropTypes.func,
textStyles: PropTypes.object,
};
@@ -90,7 +89,6 @@ export default class PostAddChannelMember extends React.PureComponent {
mentionStyle={this.props.textStyles.mention}
mentionName={usernames[0]}
onPostPress={this.props.onPostPress}
- navigator={this.props.navigator}
/>
);
} else if (usernames.length > 1) {
@@ -119,7 +117,6 @@ export default class PostAddChannelMember extends React.PureComponent {
mentionStyle={this.props.textStyles.mention}
mentionName={username}
onPostPress={this.props.onPostPress}
- navigator={this.props.navigator}
/>
);
}).reduce((acc, el, idx, arr) => {
diff --git a/app/components/post_attachment_opengraph/index.js b/app/components/post_attachment_opengraph/index.js
index f422ddf5e..d18e1585b 100644
--- a/app/components/post_attachment_opengraph/index.js
+++ b/app/components/post_attachment_opengraph/index.js
@@ -6,6 +6,8 @@ import {bindActionCreators} from 'redux';
import {getOpenGraphMetadata} from 'mattermost-redux/actions/posts';
+import {showModalOverCurrentContext} from 'app/actions/navigation';
+
import {getDimensions} from 'app/selectors/device';
import PostAttachmentOpenGraph from './post_attachment_opengraph';
@@ -20,6 +22,7 @@ function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
getOpenGraphMetadata,
+ showModalOverCurrentContext,
}, dispatch),
};
}
diff --git a/app/components/post_attachment_opengraph/post_attachment_opengraph.js b/app/components/post_attachment_opengraph/post_attachment_opengraph.js
index d74293ea7..9ae9ace99 100644
--- a/app/components/post_attachment_opengraph/post_attachment_opengraph.js
+++ b/app/components/post_attachment_opengraph/post_attachment_opengraph.js
@@ -28,13 +28,13 @@ export default class PostAttachmentOpenGraph extends PureComponent {
static propTypes = {
actions: PropTypes.shape({
getOpenGraphMetadata: PropTypes.func.isRequired,
+ showModalOverCurrentContext: PropTypes.func.isRequired,
}).isRequired,
deviceHeight: PropTypes.number.isRequired,
deviceWidth: PropTypes.number.isRequired,
imagesMetadata: PropTypes.object,
isReplyPost: PropTypes.bool,
link: PropTypes.string.isRequired,
- navigator: PropTypes.object.isRequired,
openGraphData: PropTypes.object,
theme: PropTypes.object.isRequired,
};
@@ -181,6 +181,7 @@ export default class PostAttachmentOpenGraph extends PureComponent {
originalWidth,
originalHeight,
} = this.state;
+ const {actions} = this.props;
const filename = this.getFilename(link);
const files = [{
@@ -195,7 +196,7 @@ export default class PostAttachmentOpenGraph extends PureComponent {
},
}];
- previewImageAtIndex(this.props.navigator, [this.refs.item], 0, files);
+ previewImageAtIndex([this.refs.item], 0, files, actions.showModalOverCurrentContext);
};
renderDescription = () => {
diff --git a/app/components/post_attachment_opengraph/post_attachment_opengraph.test.js b/app/components/post_attachment_opengraph/post_attachment_opengraph.test.js
index d86e41e65..4d03ae92d 100644
--- a/app/components/post_attachment_opengraph/post_attachment_opengraph.test.js
+++ b/app/components/post_attachment_opengraph/post_attachment_opengraph.test.js
@@ -25,6 +25,7 @@ describe('PostAttachmentOpenGraph', () => {
const baseProps = {
actions: {
getOpenGraphMetadata: jest.fn(),
+ showModalOverCurrentContext: jest.fn(),
},
deviceHeight: 600,
deviceWidth: 400,
diff --git a/app/components/post_body/index.js b/app/components/post_body/index.js
index 7830d1eaa..01c0de74a 100644
--- a/app/components/post_body/index.js
+++ b/app/components/post_body/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, Posts} from 'mattermost-redux/constants';
@@ -20,6 +21,8 @@ import {
} from 'mattermost-redux/utils/post_utils';
import {isAdmin as checkIsAdmin, isSystemAdmin as checkIsSystemAdmin} from 'mattermost-redux/utils/user_utils';
+import {showModalOverCurrentContext} from 'app/actions/navigation';
+
import {getDimensions} from 'app/selectors/device';
import {hasEmojisOnly} from 'app/utils/emoji_utils';
@@ -99,4 +102,12 @@ function makeMapStateToProps() {
};
}
-export default connect(makeMapStateToProps, null, null, {forwardRef: true})(PostBody);
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ showModalOverCurrentContext,
+ }, dispatch),
+ };
+}
+
+export default connect(makeMapStateToProps, mapDispatchToProps, null, {forwardRef: true})(PostBody);
diff --git a/app/components/post_body/post_body.js b/app/components/post_body/post_body.js
index 018905393..26e279fe3 100644
--- a/app/components/post_body/post_body.js
+++ b/app/components/post_body/post_body.js
@@ -36,6 +36,9 @@ const SHOW_MORE_HEIGHT = 60;
export default class PostBody extends PureComponent {
static propTypes = {
+ actions: PropTypes.shape({
+ showModalOverCurrentContext: PropTypes.func.isRequired,
+ }).isRequired,
canDelete: PropTypes.bool,
channelIsReadOnly: PropTypes.bool.isRequired,
deviceHeight: PropTypes.number.isRequired,
@@ -56,7 +59,6 @@ export default class PostBody extends PureComponent {
metadata: PropTypes.object,
managedConfig: PropTypes.object,
message: PropTypes.string,
- navigator: PropTypes.object.isRequired,
onFailedPostPress: PropTypes.func,
onHashtagPress: PropTypes.func,
onPermalinkPress: PropTypes.func,
@@ -130,31 +132,25 @@ export default class PostBody extends PureComponent {
openLongPost = preventDoubleTap(() => {
const {
managedConfig,
- navigator,
onHashtagPress,
onPermalinkPress,
post,
+ actions,
} = this.props;
-
+ const screen = 'LongPost';
+ const passProps = {
+ postId: post.id,
+ managedConfig,
+ onHashtagPress,
+ onPermalinkPress,
+ };
const options = {
- screen: 'LongPost',
- animationType: 'none',
- backButtonTitle: '',
- overrideBackPress: true,
- navigatorStyle: {
- navBarHidden: true,
- screenBackgroundColor: changeOpacity('#000', 0.2),
- modalPresentationStyle: 'overCurrentContext',
- },
- passProps: {
- postId: post.id,
- managedConfig,
- onHashtagPress,
- onPermalinkPress,
+ layout: {
+ backgroundColor: changeOpacity('#000', 0.2),
},
};
- navigator.showModal(options);
+ actions.showModalOverCurrentContext(screen, passProps, options);
});
showPostOptions = () => {
@@ -168,10 +164,10 @@ export default class PostBody extends PureComponent {
isPostEphemeral,
isSystemMessage,
managedConfig,
- navigator,
post,
showAddReaction,
location,
+ actions,
} = this.props;
if (isSystemMessage && (!canDelete || hasBeenDeleted)) {
@@ -182,32 +178,22 @@ export default class PostBody extends PureComponent {
return;
}
- const options = {
- screen: 'PostOptions',
- animationType: 'none',
- backButtonTitle: '',
- navigatorStyle: {
- navBarHidden: true,
- navBarTransparent: true,
- screenBackgroundColor: 'transparent',
- modalPresentationStyle: 'overCurrentContext',
- },
- passProps: {
- canDelete,
- channelIsReadOnly,
- hasBeenDeleted,
- isFlagged,
- isSystemMessage,
- post,
- managedConfig,
- showAddReaction,
- location,
- },
+ const screen = 'PostOptions';
+ const passProps = {
+ canDelete,
+ channelIsReadOnly,
+ hasBeenDeleted,
+ isFlagged,
+ isSystemMessage,
+ post,
+ managedConfig,
+ showAddReaction,
+ location,
};
Keyboard.dismiss();
requestAnimationFrame(() => {
- navigator.showModal(options);
+ actions.showModalOverCurrentContext(screen, passProps);
});
};
@@ -231,7 +217,6 @@ export default class PostBody extends PureComponent {
return (
);
}
@@ -281,7 +264,6 @@ export default class PostBody extends PureComponent {
isSystemMessage,
message,
metadata,
- navigator,
onHashtagPress,
onPermalinkPress,
post,
@@ -304,7 +286,6 @@ export default class PostBody extends PureComponent {
);
};
@@ -356,7 +335,6 @@ export default class PostBody extends PureComponent {
isSystemMessage,
message,
metadata,
- navigator,
onFailedPostPress,
onHashtagPress,
onPermalinkPress,
@@ -395,7 +373,6 @@ export default class PostBody extends PureComponent {
allUsernames={allUsernames}
linkStyle={textStyles.link}
messageData={messageData}
- navigator={navigator}
textStyles={textStyles}
theme={theme}
/>
@@ -424,7 +401,6 @@ export default class PostBody extends PureComponent {
isEdited={hasBeenEdited}
isReplyPost={isReplyPost}
isSearchResult={isSearchResult}
- navigator={navigator}
onHashtagPress={onHashtagPress}
onPermalinkPress={onPermalinkPress}
onPostPress={onPress}
diff --git a/app/components/post_body/post_body.test.js b/app/components/post_body/post_body.test.js
index aa78520cb..94dcbc48c 100644
--- a/app/components/post_body/post_body.test.js
+++ b/app/components/post_body/post_body.test.js
@@ -12,6 +12,9 @@ import PostBody from './post_body.js';
describe('PostBody', () => {
const baseProps = {
+ actions: {
+ showModalOverCurrentContext: jest.fn(),
+ },
canDelete: true,
channelIsReadOnly: false,
deviceHeight: 1920,
@@ -30,7 +33,6 @@ describe('PostBody', () => {
isSystemMessage: false,
managedConfig: {},
message: 'Hello, World!',
- navigator: {},
onFailedPostPress: jest.fn(),
onHashtagPress: jest.fn(),
onPermalinkPress: jest.fn(),
diff --git a/app/components/post_body_additional_content/index.js b/app/components/post_body_additional_content/index.js
index 481b1b5ec..b55ed5ffa 100644
--- a/app/components/post_body_additional_content/index.js
+++ b/app/components/post_body_additional_content/index.js
@@ -10,6 +10,7 @@ import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getOpenGraphMetadataForUrl} from 'mattermost-redux/selectors/entities/posts';
import {getBool, getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import {showModalOverCurrentContext} from 'app/actions/navigation';
import {ViewTypes} from 'app/constants';
import {getDimensions} from 'app/selectors/device';
import {extractFirstLink} from 'app/utils/url';
@@ -73,6 +74,7 @@ function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
getRedirectLocation,
+ showModalOverCurrentContext,
}, dispatch),
};
}
diff --git a/app/components/post_body_additional_content/post_body_additional_content.js b/app/components/post_body_additional_content/post_body_additional_content.js
index 4adcdc806..80c925615 100644
--- a/app/components/post_body_additional_content/post_body_additional_content.js
+++ b/app/components/post_body_additional_content/post_body_additional_content.js
@@ -35,6 +35,7 @@ export default class PostBodyAdditionalContent extends PureComponent {
static propTypes = {
actions: PropTypes.shape({
getRedirectLocation: PropTypes.func.isRequired,
+ showModalOverCurrentContext: PropTypes.func.isRequired,
}).isRequired,
baseTextStyle: CustomPropTypes.Style,
blockStyles: PropTypes.object,
@@ -45,7 +46,6 @@ export default class PostBodyAdditionalContent extends PureComponent {
isReplyPost: PropTypes.bool,
link: PropTypes.string,
message: PropTypes.string.isRequired,
- navigator: PropTypes.object.isRequired,
onHashtagPress: PropTypes.func,
onPermalinkPress: PropTypes.func,
openGraphData: PropTypes.object,
@@ -183,7 +183,7 @@ export default class PostBodyAdditionalContent extends PureComponent {
return null;
}
- const {isReplyPost, link, metadata, navigator, openGraphData, showLinkPreviews, theme} = this.props;
+ const {isReplyPost, link, metadata, openGraphData, showLinkPreviews, theme} = this.props;
const attachments = this.getMessageAttachment();
if (attachments) {
return attachments;
@@ -202,7 +202,6 @@ export default class PostBodyAdditionalContent extends PureComponent {
{
const {shortenedLink} = this.state;
let {link} = this.props;
- const {navigator} = this.props;
+ const {actions} = this.props;
if (shortenedLink) {
link = shortenedLink;
}
@@ -431,7 +428,7 @@ export default class PostBodyAdditionalContent extends PureComponent {
},
}];
- previewImageAtIndex(navigator, [imageRef], 0, files);
+ previewImageAtIndex([imageRef], 0, files, actions.showModalOverCurrentContext);
};
playYouTubeVideo = () => {
diff --git a/app/components/reactions/index.js b/app/components/reactions/index.js
index e778343b6..87c20b010 100644
--- a/app/components/reactions/index.js
+++ b/app/components/reactions/index.js
@@ -13,6 +13,7 @@ import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
import {getChannel} from 'mattermost-redux/selectors/entities/channels';
+import {showModal, showModalOverCurrentContext} from 'app/actions/navigation';
import {addReaction} from 'app/actions/views/emoji';
import Reactions from './reactions';
@@ -63,6 +64,8 @@ function mapDispatchToProps(dispatch) {
addReaction,
getReactionsForPost,
removeReaction,
+ showModal,
+ showModalOverCurrentContext,
}, dispatch),
};
}
diff --git a/app/components/reactions/reactions.js b/app/components/reactions/reactions.js
index 3fead81a7..5548ed180 100644
--- a/app/components/reactions/reactions.js
+++ b/app/components/reactions/reactions.js
@@ -23,9 +23,10 @@ export default class Reactions extends PureComponent {
addReaction: PropTypes.func.isRequired,
getReactionsForPost: PropTypes.func.isRequired,
removeReaction: PropTypes.func.isRequired,
+ showModal: PropTypes.func.isRequired,
+ showModalOverCurrentContext: PropTypes.func.isRequired,
}).isRequired,
currentUserId: PropTypes.string.isRequired,
- navigator: PropTypes.object.isRequired,
position: PropTypes.oneOf(['right', 'left']),
postId: PropTypes.string.isRequired,
reactions: PropTypes.object,
@@ -50,25 +51,18 @@ export default class Reactions extends PureComponent {
}
handleAddReaction = preventDoubleTap(() => {
+ const {actions, theme} = this.props;
const {formatMessage} = this.context.intl;
- const {navigator, theme} = this.props;
+ const screen = 'AddReaction';
+ const title = formatMessage({id: 'mobile.post_info.add_reaction', defaultMessage: 'Add Reaction'});
MaterialIcon.getImageSource('close', 20, theme.sidebarHeaderTextColor).then((source) => {
- navigator.showModal({
- screen: 'AddReaction',
- title: formatMessage({id: 'mobile.post_info.add_reaction', defaultMessage: 'Add Reaction'}),
- animated: true,
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- passProps: {
- closeButton: source,
- onEmojiPress: this.handleAddReactionToPost,
- },
- });
+ const passProps = {
+ closeButton: source,
+ onEmojiPress: this.handleAddReactionToPost,
+ };
+
+ actions.showModal(screen, title, passProps);
});
});
@@ -87,28 +81,18 @@ export default class Reactions extends PureComponent {
};
showReactionList = () => {
- const {navigator, postId} = this.props;
+ const {actions, postId} = this.props;
- const options = {
- screen: 'ReactionList',
- animationType: 'none',
- backButtonTitle: '',
- navigatorStyle: {
- navBarHidden: true,
- navBarTransparent: true,
- screenBackgroundColor: 'transparent',
- modalPresentationStyle: 'overCurrentContext',
- },
- passProps: {
- postId,
- },
+ const screen = 'ReactionList';
+ const passProps = {
+ postId,
};
- navigator.showModal(options);
+ actions.showModalOverCurrentContext(screen, passProps);
}
renderReactions = () => {
- const {currentUserId, navigator, reactions, theme, postId} = this.props;
+ const {currentUserId, reactions, theme, postId} = this.props;
const highlightedReactions = [];
const reactionsByName = Object.values(reactions).reduce((acc, reaction) => {
if (acc.has(reaction.emoji_name)) {
@@ -131,7 +115,6 @@ export default class Reactions extends PureComponent {
count={reactionsByName.get(r).length}
emojiName={r}
highlight={highlightedReactions.includes(r)}
- navigator={navigator}
onPress={this.handleReactionPress}
onLongPress={this.showReactionList}
postId={postId}
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 f1bd342cd..4758c992e 100644
--- a/app/components/safe_area_view/safe_area_view.ios.js
+++ b/app/components/safe_area_view/safe_area_view.ios.js
@@ -21,7 +21,6 @@ export default class SafeAreaIos extends PureComponent {
forceTop: PropTypes.number,
keyboardOffset: PropTypes.number.isRequired,
navBarBackgroundColor: PropTypes.string,
- navigator: PropTypes.object,
headerComponent: PropTypes.node,
theme: PropTypes.object.isRequired,
};
diff --git a/app/components/sidebars/settings/index.js b/app/components/sidebars/settings/index.js
index 140b697d0..66406da3f 100644
--- a/app/components/sidebars/settings/index.js
+++ b/app/components/sidebars/settings/index.js
@@ -8,6 +8,12 @@ import {logout, setStatus} from 'mattermost-redux/actions/users';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentUser, getStatusForUserId} from 'mattermost-redux/selectors/entities/users';
+import {
+ showModal,
+ showModalOverCurrentContext,
+ dismissModal,
+} from 'app/actions/navigation';
+
import {isLandscape, getDimensions} from 'app/selectors/device';
import SettingsSidebar from './settings_sidebar';
@@ -30,6 +36,9 @@ function mapDispatchToProps(dispatch) {
actions: bindActionCreators({
logout,
setStatus,
+ showModal,
+ showModalOverCurrentContext,
+ dismissModal,
}, dispatch),
};
}
diff --git a/app/components/sidebars/settings/settings_sidebar.js b/app/components/sidebars/settings/settings_sidebar.js
index 726b9db4f..9a3fff5b3 100644
--- a/app/components/sidebars/settings/settings_sidebar.js
+++ b/app/components/sidebars/settings/settings_sidebar.js
@@ -37,13 +37,15 @@ export default class SettingsDrawer extends PureComponent {
actions: PropTypes.shape({
logout: PropTypes.func.isRequired,
setStatus: PropTypes.func.isRequired,
+ showModal: PropTypes.func.isRequired,
+ showModalOverCurrentContext: PropTypes.func.isRequired,
+ dismissModal: PropTypes.func.isRequired,
}).isRequired,
blurPostTextBox: PropTypes.func.isRequired,
children: PropTypes.node,
currentUser: PropTypes.object.isRequired,
deviceWidth: PropTypes.number.isRequired,
isLandscape: PropTypes.bool.isRequired,
- navigator: PropTypes.object,
status: PropTypes.string,
theme: PropTypes.object.isRequired,
};
@@ -107,6 +109,7 @@ export default class SettingsDrawer extends PureComponent {
};
handleSetStatus = preventDoubleTap(() => {
+ const {actions} = this.props;
const items = [{
action: () => this.setStatus(General.ONLINE),
text: {
@@ -133,21 +136,7 @@ export default class SettingsDrawer 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});
});
goToEditProfile = preventDoubleTap(() => {
@@ -194,9 +183,6 @@ export default class SettingsDrawer extends PureComponent {
goToSettings = preventDoubleTap(() => {
const {intl} = this.context;
- // TODO: Ensure all styles used in app/utils/theme's setNavigatorStyles
- // are passed to Settings when this showModal call is updated to RNN v2,
- // then remove setNavigatorStyles call in app/screens/settings/general/settings.js
this.openModal(
'Settings',
intl.formatMessage({id: 'mobile.routes.settings', defaultMessage: 'Settings'}),
@@ -210,31 +196,20 @@ export default class SettingsDrawer extends PureComponent {
});
openModal = (screen, title, passProps) => {
- const {navigator, theme} = this.props;
-
this.closeSettingsSidebar();
+ const {actions} = this.props;
+ const options = {
+ topBar: {
+ leftButtons: [{
+ id: 'close-settings',
+ icon: this.closeButton,
+ }],
+ },
+ };
+
InteractionManager.runAfterInteractions(() => {
- navigator.showModal({
- screen,
- title,
- animationType: 'slide-up',
- animated: true,
- backButtonTitle: '',
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- navigatorButtons: {
- leftButtons: [{
- id: 'close-settings',
- icon: this.closeButton,
- }],
- },
- passProps,
- });
+ actions.showModal(screen, title, passProps, options);
});
};
@@ -254,7 +229,7 @@ export default class SettingsDrawer extends PureComponent {
};
renderNavigationView = () => {
- const {currentUser, navigator, theme} = this.props;
+ const {currentUser, theme} = this.props;
const style = getStyleSheet(theme);
return (
@@ -264,7 +239,6 @@ export default class SettingsDrawer extends PureComponent {
footerColor={theme.centerChannelBg}
footerComponent={}
headerComponent={}
- navigator={navigator}
theme={theme}
>
@@ -359,12 +333,10 @@ export default class SettingsDrawer extends PureComponent {
};
setStatus = (status) => {
- const {status: currentUserStatus, navigator} = this.props;
+ const {status: currentUserStatus, actions} = this.props;
if (currentUserStatus === General.OUT_OF_OFFICE) {
- navigator.dismissModal({
- animationType: 'none',
- });
+ actions.dismissModal();
this.closeSettingsSidebar();
this.confirmReset(status);
return;
diff --git a/app/mattermost.js b/app/mattermost.js
index 106a3e889..32744fff4 100644
--- a/app/mattermost.js
+++ b/app/mattermost.js
@@ -48,6 +48,7 @@ import LocalConfig from 'assets/config';
import telemetry from 'app/telemetry';
import App from './app';
+import EphemeralStore from 'app/store/ephemeral_store';
import './fetch_preconfig';
const PROMPT_IN_APP_PIN_CODE_AFTER = 5 * 60 * 1000;
@@ -448,6 +449,14 @@ const launchEntry = () => {
'start:channel_screen',
]);
+ // Keep track of the latest componentId to appear and disappear
+ Navigation.events().registerComponentDidAppearListener(({componentId}) => {
+ EphemeralStore.addComponentIdToStack(componentId);
+ });
+ Navigation.events().registerComponentDidDisappearListener(({componentId}) => {
+ EphemeralStore.removeComponentIdFromStack(componentId);
+ });
+
Navigation.setRoot({
root: {
stack: {
diff --git a/app/screens/channel/channel.ios.js b/app/screens/channel/channel.ios.js
index 05d67f9ca..700de6ab7 100644
--- a/app/screens/channel/channel.ios.js
+++ b/app/screens/channel/channel.ios.js
@@ -26,10 +26,10 @@ const CHANNEL_POST_TEXTBOX_VALUE_CHANGE = 'onChannelTextBoxValueChange';
export default class ChannelIOS extends ChannelBase {
previewChannel = (passProps, options) => {
- const {actions, componentId} = this.props;
+ const {actions} = this.props;
const screen = 'ChannelPeek';
- actions.peek(componentId, screen, passProps, options);
+ actions.peek(screen, passProps, options);
};
optionalProps = {previewChannel: this.previewChannel};
diff --git a/app/screens/client_upgrade/client_upgrade.js b/app/screens/client_upgrade/client_upgrade.js
index a57dccac1..c0768a3a5 100644
--- a/app/screens/client_upgrade/client_upgrade.js
+++ b/app/screens/client_upgrade/client_upgrade.js
@@ -26,6 +26,8 @@ export default class ClientUpgrade extends PureComponent {
actions: PropTypes.shape({
logError: PropTypes.func.isRequired,
setLastUpgradeCheck: PropTypes.func.isRequired,
+ popTopScreen: PropTypes.func.isRequired,
+ dismissModal: PropTypes.func.isRequired,
}).isRequired,
componentId: PropTypes.string,
currentVersion: PropTypes.string,
@@ -66,7 +68,7 @@ export default class ClientUpgrade extends PureComponent {
navigationButtonPressed({buttonId}) {
if (buttonId === 'close-upgrade') {
- Navigation.dismissModal(this.props.componentId);
+ this.props.actions.dismissModal();
}
}
@@ -95,15 +97,15 @@ export default class ClientUpgrade extends PureComponent {
const {
closeAction,
userCheckedForUpgrade,
- componentId,
+ actions,
} = this.props;
if (closeAction) {
closeAction();
} else if (userCheckedForUpgrade) {
- Navigation.pop(componentId);
+ actions.popTopScreen();
} else {
- Navigation.dismissModal(componentId);
+ actions.dismissModal();
}
};
diff --git a/app/screens/client_upgrade/index.js b/app/screens/client_upgrade/index.js
index b0984934c..14f67f586 100644
--- a/app/screens/client_upgrade/index.js
+++ b/app/screens/client_upgrade/index.js
@@ -5,6 +5,7 @@ import {connect} from 'react-redux';
import {logError} from 'mattermost-redux/actions/errors';
+import {popTopScreen, dismissModal} from 'app/actions/navigation';
import {setLastUpgradeCheck} from 'app/actions/views/client_upgrade';
import getClientUpgrade from 'app/selectors/client_upgrade';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
@@ -29,6 +30,8 @@ function mapDispatchToProps(dispatch) {
actions: bindActionCreators({
logError,
setLastUpgradeCheck,
+ popTopScreen,
+ dismissModal,
}, dispatch),
};
}
diff --git a/app/screens/edit_profile/__snapshots__/edit_profile.test.js.snap b/app/screens/edit_profile/__snapshots__/edit_profile.test.js.snap
index 9c8aa9c0e..2830f2a22 100644
--- a/app/screens/edit_profile/__snapshots__/edit_profile.test.js.snap
+++ b/app/screens/edit_profile/__snapshots__/edit_profile.test.js.snap
@@ -26,34 +26,6 @@ exports[`edit_profile should match snapshot 1`] = `
}
}
maxFileSize={20971520}
- navigator={
- Object {
- "dismissModal": [MockFunction],
- "push": [MockFunction],
- "setButtons": [MockFunction] {
- "calls": Array [
- Array [
- Object {
- "rightButtons": Array [
- Object {
- "disabled": true,
- "id": "update-profile",
- "showAsAction": "always",
- "title": undefined,
- },
- ],
- },
- ],
- ],
- "results": Array [
- Object {
- "type": "return",
- "value": undefined,
- },
- ],
- },
- }
- }
onShowFileSizeWarning={[Function]}
onShowUnsupportedMimeTypeWarning={[Function]}
removeProfileImage={[Function]}
diff --git a/app/screens/edit_profile/edit_profile.js b/app/screens/edit_profile/edit_profile.js
index 0beb7c1da..640da9921 100644
--- a/app/screens/edit_profile/edit_profile.js
+++ b/app/screens/edit_profile/edit_profile.js
@@ -88,11 +88,13 @@ export default class EditProfile extends PureComponent {
setProfileImageUri: PropTypes.func.isRequired,
removeProfileImage: PropTypes.func.isRequired,
updateUser: PropTypes.func.isRequired,
+ popTopScreen: PropTypes.func.isRequired,
+ dismissModal: PropTypes.func.isRequired,
+ setButtons: PropTypes.func.isRequired,
}).isRequired,
currentUser: PropTypes.object.isRequired,
firstNameDisabled: PropTypes.bool.isRequired,
lastNameDisabled: PropTypes.bool.isRequired,
- navigator: PropTypes.object.isRequired,
nicknameDisabled: PropTypes.bool.isRequired,
positionDisabled: PropTypes.bool.isRequired,
theme: PropTypes.object.isRequired,
@@ -118,7 +120,7 @@ export default class EditProfile extends PureComponent {
};
this.rightButton.title = context.intl.formatMessage({id: t('mobile.account.settings.save'), defaultMessage: 'Save'});
- props.navigator.setButtons(buttons);
+ props.actions.setButtons(buttons);
this.state = {
email,
@@ -176,12 +178,11 @@ export default class EditProfile extends PureComponent {
};
close = () => {
- if (this.props.commandType === 'Push') {
- this.props.navigator.pop();
+ const {commandType, actions} = this.props;
+ if (commandType === 'Push') {
+ actions.popTopScreen();
} else {
- this.props.navigator.dismissModal({
- animationType: 'slide-down',
- });
+ actions.dismissModal();
}
};
@@ -190,7 +191,7 @@ export default class EditProfile extends PureComponent {
rightButtons: [{...this.rightButton, disabled: !enabled}],
};
- this.props.navigator.setButtons(buttons);
+ this.props.actions.setButtons(buttons);
};
handleRequestError = (error) => {
@@ -254,9 +255,7 @@ export default class EditProfile extends PureComponent {
handleRemoveProfileImage = () => {
this.setState({profileImageRemove: true});
this.emitCanUpdateAccount(true);
- this.props.navigator.dismissModal({
- animationType: 'none',
- });
+ this.props.actions.dismissModal();
}
uploadProfileImage = async () => {
@@ -500,7 +499,6 @@ export default class EditProfile extends PureComponent {
const {
currentUser,
theme,
- navigator,
} = this.props;
const {
@@ -521,7 +519,6 @@ export default class EditProfile extends PureComponent {
canTakeVideo={false}
canBrowseVideoLibrary={false}
maxFileSize={MAX_SIZE}
- navigator={navigator}
wrapper={true}
uploadFiles={this.handleUploadProfileImage}
removeProfileImage={this.handleRemoveProfileImage}
diff --git a/app/screens/edit_profile/edit_profile.test.js b/app/screens/edit_profile/edit_profile.test.js
index 98efa50a2..71bd67850 100644
--- a/app/screens/edit_profile/edit_profile.test.js
+++ b/app/screens/edit_profile/edit_profile.test.js
@@ -17,16 +17,13 @@ jest.mock('app/utils/theme', () => {
});
describe('edit_profile', () => {
- const navigator = {
- setButtons: jest.fn(),
- dismissModal: jest.fn(),
- push: jest.fn(),
- };
-
const actions = {
updateUser: jest.fn(),
setProfileImageUri: jest.fn(),
removeProfileImage: jest.fn(),
+ popTopScreen: jest.fn(),
+ dismissModal: jest.fn(),
+ setButtons: jest.fn(),
};
const baseProps = {
@@ -36,7 +33,6 @@ describe('edit_profile', () => {
nicknameDisabled: true,
positionDisabled: true,
theme: Preferences.THEMES.default,
- navigator,
currentUser: {
first_name: 'Dwight',
last_name: 'Schrute',
@@ -58,14 +54,9 @@ describe('edit_profile', () => {
});
test('should match state on handleRemoveProfileImage', () => {
- const newNavigator = {
- dismissModal: jest.fn(),
- setButtons: jest.fn(),
- };
const wrapper = shallow(
,
{context: {intl: {formatMessage: jest.fn()}}},
);
@@ -79,7 +70,6 @@ describe('edit_profile', () => {
expect(instance.emitCanUpdateAccount).toHaveBeenCalledTimes(1);
expect(instance.emitCanUpdateAccount).toBeCalledWith(true);
- expect(newNavigator.dismissModal).toHaveBeenCalledTimes(1);
- expect(newNavigator.dismissModal).toBeCalledWith({animationType: 'none'});
+ expect(baseProps.actions.dismissModal).toHaveBeenCalledTimes(1);
});
});
diff --git a/app/screens/edit_profile/index.js b/app/screens/edit_profile/index.js
index 44ee8b27f..81a29cb97 100644
--- a/app/screens/edit_profile/index.js
+++ b/app/screens/edit_profile/index.js
@@ -8,6 +8,7 @@ import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
import {isMinimumServerVersion} from 'mattermost-redux/utils/helpers';
+import {popTopScreen, dismissModal, setButtons} from 'app/actions/navigation';
import {setProfileImageUri, removeProfileImage, updateUser} from 'app/actions/views/edit_profile';
import EditProfile from './edit_profile';
@@ -49,6 +50,9 @@ function mapDispatchToProps(dispatch) {
setProfileImageUri,
removeProfileImage,
updateUser,
+ popTopScreen,
+ dismissModal,
+ setButtons,
}, dispatch),
};
}
diff --git a/app/screens/flagged_posts/flagged_posts.js b/app/screens/flagged_posts/flagged_posts.js
index ca5b27681..bb8a03e52 100644
--- a/app/screens/flagged_posts/flagged_posts.js
+++ b/app/screens/flagged_posts/flagged_posts.js
@@ -36,10 +36,11 @@ export default class FlaggedPosts extends PureComponent {
selectFocusedPostId: PropTypes.func.isRequired,
selectPost: PropTypes.func.isRequired,
showSearchModal: PropTypes.func.isRequired,
+ dismissModal: PropTypes.func.isRequired,
+ showModalOverCurrentContext: PropTypes.func.isRequired,
}).isRequired,
didFail: PropTypes.bool,
isLoading: PropTypes.bool,
- navigator: PropTypes.object,
postIds: PropTypes.array,
theme: PropTypes.object.isRequired,
};
@@ -65,38 +66,25 @@ export default class FlaggedPosts extends PureComponent {
navigationButtonPressed({buttonId}) {
if (buttonId === 'close-settings') {
- this.props.navigator.dismissModal({
- animationType: 'slide-down',
- });
+ this.props.actions.dismissModal();
}
}
goToThread = (post) => {
- const {actions, navigator, theme} = this.props;
+ const {actions} = this.props;
const channelId = post.channel_id;
const rootId = (post.root_id || post.id);
+ const screen = 'Thread';
+ const title = '';
+ const passProps = {
+ channelId,
+ rootId,
+ };
Keyboard.dismiss();
actions.loadThreadIfNecessary(rootId);
actions.selectPost(rootId);
-
- const options = {
- screen: 'Thread',
- animated: true,
- backButtonTitle: '',
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- passProps: {
- channelId,
- rootId,
- },
- };
-
- navigator.push(options);
+ actions.goToScreen(screen, title, passProps);
};
handleClosePermalink = () => {
@@ -111,11 +99,11 @@ export default class FlaggedPosts extends PureComponent {
};
handleHashtagPress = async (hashtag) => {
- const {actions, navigator} = this.props;
+ const {actions} = this.props;
- await navigator.dismissModal();
+ await actions.dismissModal();
- actions.showSearchModal(navigator, '#' + hashtag);
+ actions.showSearchModal('#' + hashtag);
};
keyExtractor = (item) => item;
@@ -169,7 +157,6 @@ export default class FlaggedPosts extends PureComponent {
previewPost={this.previewPost}
highlightPinnedOrFlagged={false}
goToThread={this.goToThread}
- navigator={this.props.navigator}
onHashtagPress={this.handleHashtagPress}
onPermalinkPress={this.handlePermalinkPress}
managedConfig={mattermostManaged.getCachedConfig()}
@@ -183,29 +170,24 @@ export default class FlaggedPosts extends PureComponent {
};
showPermalinkView = (postId, isPermalink) => {
- const {actions, navigator} = this.props;
+ const {actions} = this.props;
actions.selectFocusedPostId(postId);
if (!this.showingPermalink) {
+ const screen = 'Permalink';
+ const passProps = {
+ isPermalink,
+ onClose: this.handleClosePermalink,
+ };
const options = {
- screen: 'Permalink',
- animationType: 'none',
- backButtonTitle: '',
- overrideBackPress: true,
- navigatorStyle: {
- navBarHidden: true,
- screenBackgroundColor: changeOpacity('#000', 0.2),
- modalPresentationStyle: 'overCurrentContext',
- },
- passProps: {
- isPermalink,
- onClose: this.handleClosePermalink,
+ layout: {
+ backgroundColor: changeOpacity('#000', 0.2),
},
};
this.showingPermalink = true;
- navigator.showModal(options);
+ actions.showModalOverCurrentContext(screen, passProps, options);
}
};
diff --git a/app/screens/flagged_posts/index.js b/app/screens/flagged_posts/index.js
index 16d3446f8..d48a92c54 100644
--- a/app/screens/flagged_posts/index.js
+++ b/app/screens/flagged_posts/index.js
@@ -9,8 +9,13 @@ import {clearSearch, getFlaggedPosts} from 'mattermost-redux/actions/search';
import {RequestStatus} from 'mattermost-redux/constants';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import {
+ dismissModal,
+ goToScreen,
+ showSearchModal,
+ showModalOverCurrentContext,
+} from 'app/actions/navigation';
import {loadChannelsByTeamName, loadThreadIfNecessary} from 'app/actions/views/channel';
-import {showSearchModal} from 'app/actions/views/search';
import {makePreparePostIdsForSearchPosts} from 'app/selectors/post_list';
import FlaggedPosts from './flagged_posts';
@@ -42,6 +47,9 @@ function mapDispatchToProps(dispatch) {
selectFocusedPostId,
selectPost,
showSearchModal,
+ dismissModal,
+ goToScreen,
+ showModalOverCurrentContext,
}, dispatch),
};
}
diff --git a/app/screens/interactive_dialog/interactive_dialog.js b/app/screens/interactive_dialog/interactive_dialog.js
index eda0cf7ca..94ace245b 100644
--- a/app/screens/interactive_dialog/interactive_dialog.js
+++ b/app/screens/interactive_dialog/interactive_dialog.js
@@ -17,7 +17,6 @@ import DialogElement from './dialog_element.js';
export default class InteractiveDialog extends PureComponent {
static propTypes = {
- componentId: PropTypes.string,
url: PropTypes.string.isRequired,
callbackId: PropTypes.string,
elements: PropTypes.arrayOf(PropTypes.object).isRequired,
diff --git a/app/screens/login/login.js b/app/screens/login/login.js
index 047aaed56..0157f5567 100644
--- a/app/screens/login/login.js
+++ b/app/screens/login/login.js
@@ -45,7 +45,6 @@ export default class Login extends PureComponent {
resetToChannel: PropTypes.func.isRequired,
goToScreen: PropTypes.func.isRequired,
}).isRequired,
- componentId: PropTypes.string.isRequired,
theme: PropTypes.object,
config: PropTypes.object.isRequired,
license: PropTypes.object.isRequired,
@@ -95,12 +94,12 @@ export default class Login extends PureComponent {
};
goToMfa = () => {
- const {componentId, actions} = this.props;
+ const {actions} = this.props;
const {intl} = this.context;
const screen = 'MFA';
const title = intl.formatMessage({id: 'mobile.routes.mfa', defaultMessage: 'Multi-factor Authentication'});
- actions.goToScreen(componentId, screen, title);
+ actions.goToScreen(screen, title);
};
blur = () => {
@@ -287,12 +286,12 @@ export default class Login extends PureComponent {
};
forgotPassword = () => {
- const {actions, componentId} = this.props;
+ const {actions} = this.props;
const {intl} = this.context;
const screen = 'ForgotPassword';
const title = intl.formatMessage({id: 'password_form.title', defaultMessage: 'Password Reset'});
- actions.goToScreen(componentId, screen, title);
+ actions.goToScreen(screen, title);
}
render() {
diff --git a/app/screens/login/login.test.js b/app/screens/login/login.test.js
index 040221c12..3a3998d4f 100644
--- a/app/screens/login/login.test.js
+++ b/app/screens/login/login.test.js
@@ -24,7 +24,6 @@ describe('Login', () => {
loginId: '',
password: '',
loginRequest: {},
- componentId: 'component-id',
actions: {
handleLoginIdChanged: jest.fn(),
handlePasswordChanged: jest.fn(),
@@ -129,7 +128,6 @@ describe('Login', () => {
expect(baseProps.actions.goToScreen).
toHaveBeenCalledWith(
- baseProps.componentId,
'MFA',
'Multi-factor Authentication',
);
@@ -141,7 +139,6 @@ describe('Login', () => {
expect(baseProps.actions.goToScreen).
toHaveBeenCalledWith(
- baseProps.componentId,
'ForgotPassword',
'Password Reset',
);
diff --git a/app/screens/login_options/index.js b/app/screens/login_options/index.js
index 6df348adf..e29cd446a 100644
--- a/app/screens/login_options/index.js
+++ b/app/screens/login_options/index.js
@@ -4,11 +4,11 @@
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
-import {goToScreen} from 'app/actions/navigation';
-
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
+import {goToScreen} from 'app/actions/navigation';
+
import LoginOptions from './login_options';
function mapStateToProps(state) {
diff --git a/app/screens/login_options/login_options.js b/app/screens/login_options/login_options.js
index 8d4425bc0..9df26aa0f 100644
--- a/app/screens/login_options/login_options.js
+++ b/app/screens/login_options/login_options.js
@@ -28,7 +28,6 @@ export default class LoginOptions extends PureComponent {
actions: PropTypes.shape({
goToScreen: PropTypes.func.isRequired,
}).isRequired,
- componentId: PropTypes.string.isRequired,
config: PropTypes.object.isRequired,
license: PropTypes.object.isRequired,
};
@@ -46,21 +45,21 @@ export default class LoginOptions extends PureComponent {
}
goToLogin = preventDoubleTap(() => {
- const {actions, componentId} = this.props;
+ const {actions} = this.props;
const {intl} = this.context;
const screen = 'Login';
const title = intl.formatMessage({id: 'mobile.routes.login', defaultMessage: 'Login'});
- actions.goToScreen(componentId, screen, title);
+ actions.goToScreen(screen, title);
});
goToSSO = (ssoType) => {
- const {actions, componentId} = this.props;
+ const {actions} = this.props;
const {intl} = this.context;
const screen = 'SSO';
const title = intl.formatMessage({id: 'mobile.routes.sso', defaultMessage: 'Single Sign-On'});
- actions.goToScreen(componentId, screen, title, {ssoType});
+ actions.goToScreen(screen, title, {ssoType});
};
orientationDidChange = () => {
diff --git a/app/screens/mfa/index.js b/app/screens/mfa/index.js
index 4707c0bd2..4dea96eb2 100644
--- a/app/screens/mfa/index.js
+++ b/app/screens/mfa/index.js
@@ -6,6 +6,8 @@ import {connect} from 'react-redux';
import {login} from 'mattermost-redux/actions/users';
+import {popTopScreen} from 'app/actions/navigation';
+
import Mfa from './mfa';
function mapStateToProps(state) {
@@ -22,6 +24,7 @@ function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
login,
+ popTopScreen,
}, dispatch),
};
}
diff --git a/app/screens/mfa/mfa.js b/app/screens/mfa/mfa.js
index 81ef5f6f5..f530f783b 100644
--- a/app/screens/mfa/mfa.js
+++ b/app/screens/mfa/mfa.js
@@ -14,7 +14,6 @@ import {
View,
} from 'react-native';
import Button from 'react-native-button';
-import {Navigation} from 'react-native-navigation';
import {RequestStatus} from 'mattermost-redux/constants';
@@ -31,8 +30,8 @@ export default class Mfa extends PureComponent {
static propTypes = {
actions: PropTypes.shape({
login: PropTypes.func.isRequired,
+ popTopScreen: PropTypes.func.isRequired,
}).isRequired,
- componentId: PropTypes.string.isRequired,
loginId: PropTypes.string.isRequired,
password: PropTypes.string.isRequired,
loginRequest: PropTypes.object.isRequired,
@@ -57,7 +56,7 @@ export default class Mfa extends PureComponent {
// In case the login is successful the previous scene (login) will take care of the transition
if (this.props.loginRequest.status === RequestStatus.STARTED &&
nextProps.loginRequest.status === RequestStatus.FAILURE) {
- Navigation.pop(this.props.componentId);
+ this.props.actions.popTopScreen();
}
}
diff --git a/app/screens/options_modal/index.js b/app/screens/options_modal/index.js
index 0c73b392b..75216f0f6 100644
--- a/app/screens/options_modal/index.js
+++ b/app/screens/options_modal/index.js
@@ -1,8 +1,11 @@
// 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 {dismissModal} from 'app/actions/navigation';
+
import {getDimensions} from 'app/selectors/device';
import OptionsModal from './options_modal';
@@ -13,4 +16,12 @@ function mapStateToProps(state) {
};
}
-export default connect(mapStateToProps)(OptionsModal);
+function mapDispatchToProps(dispatch) {
+ return {
+ actions: bindActionCreators({
+ dismissModal,
+ }, dispatch),
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(OptionsModal);
diff --git a/app/screens/options_modal/options_modal.js b/app/screens/options_modal/options_modal.js
index 062e8dac9..d39a62f29 100644
--- a/app/screens/options_modal/options_modal.js
+++ b/app/screens/options_modal/options_modal.js
@@ -9,7 +9,6 @@ import {
TouchableWithoutFeedback,
View,
} from 'react-native';
-import {Navigation} from 'react-native-navigation';
import EventEmitter from 'mattermost-redux/utils/event_emitter';
@@ -23,7 +22,9 @@ const DURATION = 200;
export default class OptionsModal extends PureComponent {
static propTypes = {
- componentId: PropTypes.string.isRequired,
+ actions: PropTypes.shape({
+ dismissModal: PropTypes.func.isRequired,
+ }).isRequired,
items: PropTypes.array.isRequired,
deviceHeight: PropTypes.number.isRequired,
deviceWidth: PropTypes.number.isRequired,
@@ -68,12 +69,12 @@ export default class OptionsModal extends PureComponent {
toValue: this.props.deviceHeight,
duration: DURATION,
}).start(() => {
- Navigation.dismissModal(this.props.componentId);
+ this.props.actions.dismissModal();
});
};
onItemPress = () => {
- Navigation.dismissModal(this.props.componentId);
+ this.props.actions.dismissModal();
}
render() {
diff --git a/app/screens/permalink/permalink.js b/app/screens/permalink/permalink.js
index 38b688174..d223b031b 100644
--- a/app/screens/permalink/permalink.js
+++ b/app/screens/permalink/permalink.js
@@ -58,7 +58,6 @@ export default class Permalink extends PureComponent {
setChannelDisplayName: PropTypes.func.isRequired,
setChannelLoading: PropTypes.func.isRequired,
}).isRequired,
- componentId: PropTypes.string,
channelId: PropTypes.string,
channelIsArchived: PropTypes.bool,
channelName: PropTypes.string,
diff --git a/app/screens/pinned_posts/pinned_posts.js b/app/screens/pinned_posts/pinned_posts.js
index 899331ebb..2d36da00a 100644
--- a/app/screens/pinned_posts/pinned_posts.js
+++ b/app/screens/pinned_posts/pinned_posts.js
@@ -28,7 +28,6 @@ import noResultsImage from 'assets/images/no_results/pin.png';
export default class PinnedPosts extends PureComponent {
static propTypes = {
- componentId: PropTypes.string,
actions: PropTypes.shape({
clearSearch: PropTypes.func.isRequired,
loadChannelsByTeamName: PropTypes.func.isRequired,
diff --git a/app/screens/reaction_list/reaction_list.js b/app/screens/reaction_list/reaction_list.js
index 3e7189105..14a3a4787 100644
--- a/app/screens/reaction_list/reaction_list.js
+++ b/app/screens/reaction_list/reaction_list.js
@@ -29,7 +29,6 @@ export default class ReactionList extends PureComponent {
actions: PropTypes.shape({
getMissingProfilesByIds: PropTypes.func.isRequired,
}).isRequired,
- componentId: PropTypes.string,
navigator: PropTypes.object,
reactions: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
diff --git a/app/screens/recent_mentions/index.js b/app/screens/recent_mentions/index.js
index 914e756f2..7ee56b2ef 100644
--- a/app/screens/recent_mentions/index.js
+++ b/app/screens/recent_mentions/index.js
@@ -9,8 +9,13 @@ import {clearSearch, getRecentMentions} from 'mattermost-redux/actions/search';
import {RequestStatus} from 'mattermost-redux/constants';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
+import {
+ dismissModal,
+ goToScreen,
+ showSearchModal,
+ showModalOverCurrentContext,
+} from 'app/actions/navigation';
import {loadChannelsByTeamName, loadThreadIfNecessary} from 'app/actions/views/channel';
-import {showSearchModal} from 'app/actions/views/search';
import {makePreparePostIdsForSearchPosts} from 'app/selectors/post_list';
import RecentMentions from './recent_mentions';
@@ -42,6 +47,9 @@ function mapDispatchToProps(dispatch) {
selectFocusedPostId,
selectPost,
showSearchModal,
+ dismissModal,
+ goToScreen,
+ showModalOverCurrentContext,
}, dispatch),
};
}
diff --git a/app/screens/recent_mentions/recent_mentions.js b/app/screens/recent_mentions/recent_mentions.js
index e836194d9..9fd2ba7a1 100644
--- a/app/screens/recent_mentions/recent_mentions.js
+++ b/app/screens/recent_mentions/recent_mentions.js
@@ -36,10 +36,11 @@ export default class RecentMentions extends PureComponent {
selectFocusedPostId: PropTypes.func.isRequired,
selectPost: PropTypes.func.isRequired,
showSearchModal: PropTypes.func.isRequired,
+ dismissModal: PropTypes.func.isRequired,
+ showModalOverCurrentContext: PropTypes.func.isRequired,
}).isRequired,
didFail: PropTypes.bool,
isLoading: PropTypes.bool,
- navigator: PropTypes.object,
postIds: PropTypes.array,
theme: PropTypes.object.isRequired,
};
@@ -64,31 +65,20 @@ export default class RecentMentions extends PureComponent {
}
goToThread = (post) => {
- const {actions, navigator, theme} = this.props;
+ const {actions} = this.props;
const channelId = post.channel_id;
const rootId = (post.root_id || post.id);
+ const screen = 'Thread';
+ const title = '';
+ const passProps = {
+ channelId,
+ rootId,
+ };
Keyboard.dismiss();
actions.loadThreadIfNecessary(rootId);
actions.selectPost(rootId);
-
- const options = {
- screen: 'Thread',
- animated: true,
- backButtonTitle: '',
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- passProps: {
- channelId,
- rootId,
- },
- };
-
- navigator.push(options);
+ actions.goToScreen(screen, title, passProps);
};
handleClosePermalink = () => {
@@ -103,20 +93,18 @@ export default class RecentMentions extends PureComponent {
};
handleHashtagPress = async (hashtag) => {
- const {actions, navigator} = this.props;
+ const {actions} = this.props;
- await navigator.dismissModal();
+ await actions.dismissModal();
- actions.showSearchModal(navigator, '#' + hashtag);
+ actions.showSearchModal('#' + hashtag);
};
keyExtractor = (item) => item;
navigationButtonPressed({buttonId}) {
if (buttonId === 'close-settings') {
- this.props.navigator.dismissModal({
- animationType: 'slide-down',
- });
+ this.props.actions.dismissModal();
}
}
@@ -168,7 +156,6 @@ export default class RecentMentions extends PureComponent {
postId={item}
previewPost={this.previewPost}
goToThread={this.goToThread}
- navigator={this.props.navigator}
onHashtagPress={this.handleHashtagPress}
onPermalinkPress={this.handlePermalinkPress}
managedConfig={mattermostManaged.getCachedConfig()}
@@ -181,29 +168,24 @@ export default class RecentMentions extends PureComponent {
};
showPermalinkView = (postId, isPermalink) => {
- const {actions, navigator} = this.props;
+ const {actions} = this.props;
actions.selectFocusedPostId(postId);
if (!this.showingPermalink) {
+ const screen = 'Permalink';
+ const passProps = {
+ isPermalink,
+ onClose: this.handleClosePermalink,
+ };
const options = {
- screen: 'Permalink',
- animationType: 'none',
- backButtonTitle: '',
- overrideBackPress: true,
- navigatorStyle: {
- navBarHidden: true,
- screenBackgroundColor: changeOpacity('#000', 0.2),
- modalPresentationStyle: 'overCurrentContext',
- },
- passProps: {
- isPermalink,
- onClose: this.handleClosePermalink,
+ layout: {
+ backgroundColor: changeOpacity('#000', 0.2),
},
};
this.showingPermalink = true;
- navigator.showModal(options);
+ actions.showModalOverCurrentContext(screen, passProps, options);
}
};
diff --git a/app/screens/search/index.js b/app/screens/search/index.js
index c7194a20c..a8751a9f6 100644
--- a/app/screens/search/index.js
+++ b/app/screens/search/index.js
@@ -8,18 +8,19 @@ import {selectFocusedPostId, selectPost} from 'mattermost-redux/actions/posts';
import {clearSearch, removeSearchTerms, searchPostsWithParams, getMorePostsForSearch} from 'mattermost-redux/actions/search';
import {getCurrentChannelId, filterPostIds} from 'mattermost-redux/selectors/entities/channels';
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
+import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
import {isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
import {isMinimumServerVersion} from 'mattermost-redux/utils/helpers';
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
+import {dismissModal} from 'app/actions/navigation';
import {loadChannelsByTeamName, loadThreadIfNecessary} from 'app/actions/views/channel';
+import {handleSearchDraftChanged} from 'app/actions/views/search';
import {isLandscape} from 'app/selectors/device';
import {makePreparePostIdsForSearchPosts} from 'app/selectors/post_list';
-import {handleSearchDraftChanged} from 'app/actions/views/search';
import {getDeviceUtcOffset, getUtcOffsetForTimeZone} from 'app/utils/timezone';
-import {getConfig} from 'mattermost-redux/selectors/entities/general';
import Search from './search';
@@ -84,6 +85,7 @@ function mapDispatchToProps(dispatch) {
searchPostsWithParams,
getMorePostsForSearch,
selectPost,
+ dismissModal,
}, dispatch),
};
}
diff --git a/app/screens/search/search.js b/app/screens/search/search.js
index 4bd53c82c..82acb7e3e 100644
--- a/app/screens/search/search.js
+++ b/app/screens/search/search.js
@@ -56,6 +56,7 @@ export default class Search extends PureComponent {
getMorePostsForSearch: PropTypes.func.isRequired,
selectFocusedPostId: PropTypes.func.isRequired,
selectPost: PropTypes.func.isRequired,
+ dismissModal: PropTypes.func.isRequired,
}).isRequired,
componentId: PropTypes.string.isRequired,
currentTeamId: PropTypes.string.isRequired,
@@ -147,7 +148,7 @@ export default class Search extends PureComponent {
if (this.state.preview) {
this.refs.preview.handleClose();
} else {
- Navigation.dismissModal(this.props.componentId);
+ this.props.actions.dismissModal();
}
}
}
@@ -178,7 +179,7 @@ export default class Search extends PureComponent {
cancelSearch = preventDoubleTap(() => {
this.handleTextChanged('', true);
- Navigation.dismissModal(this.props.componentId);
+ this.props.actions.dismissModal();
});
goToThread = (post) => {
@@ -211,7 +212,7 @@ export default class Search extends PureComponent {
handleHashtagPress = (hashtag) => {
if (this.showingPermalink) {
- Navigation.dismissModal(this.props.componentId);
+ this.props.actions.dismissModal();
this.handleClosePermalink();
}
diff --git a/app/screens/search/search_result_post/search_result_post.js b/app/screens/search/search_result_post/search_result_post.js
index 6e4481b1d..dc8e60261 100644
--- a/app/screens/search/search_result_post/search_result_post.js
+++ b/app/screens/search/search_result_post/search_result_post.js
@@ -12,7 +12,6 @@ export default class SearchResultPost extends PureComponent {
goToThread: PropTypes.func.isRequired,
highlightPinnedOrFlagged: PropTypes.bool,
managedConfig: PropTypes.object.isRequired,
- navigator: PropTypes.object.isRequired,
onHashtagPress: PropTypes.func,
onPermalinkPress: PropTypes.func.isRequired,
postId: PropTypes.string.isRequired,
@@ -50,7 +49,6 @@ export default class SearchResultPost extends PureComponent {
isSearchResult={true}
showAddReaction={false}
showFullDate={this.props.showFullDate}
- navigator={this.props.navigator}
/>
);
}
diff --git a/app/screens/select_server/select_server.js b/app/screens/select_server/select_server.js
index 16cb8e4b6..052044aa2 100644
--- a/app/screens/select_server/select_server.js
+++ b/app/screens/select_server/select_server.js
@@ -56,7 +56,6 @@ export default class SelectServer extends PureComponent {
setServerVersion: PropTypes.func.isRequired,
}).isRequired,
allowOtherServers: PropTypes.bool,
- componentId: PropTypes.string.isRequired,
config: PropTypes.object,
currentVersion: PropTypes.string,
hasConfigAndLicense: PropTypes.bool.isRequired,
@@ -158,7 +157,7 @@ export default class SelectServer extends PureComponent {
};
goToNextScreen = (screen, title, passProps = {}, navOptions = {}) => {
- const {actions, componentId} = this.props;
+ const {actions} = this.props;
const defaultOptions = {
popGesture: !LocalConfig.AutoSelectServerUrl,
topBar: {
@@ -168,7 +167,7 @@ export default class SelectServer extends PureComponent {
};
const options = merge(defaultOptions, navOptions);
- actions.goToScreen(componentId, screen, title, passProps, options);
+ actions.goToScreen(screen, title, passProps, options);
};
handleAndroidKeyboard = () => {
diff --git a/app/screens/select_team/index.js b/app/screens/select_team/index.js
index 3cfe25e34..cfbe925f1 100644
--- a/app/screens/select_team/index.js
+++ b/app/screens/select_team/index.js
@@ -8,7 +8,7 @@ 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 {resetToChannel, dismissModal} from 'app/actions/navigation';
import {handleTeamChange} from 'app/actions/views/select_team';
import SelectTeam from './select_team.js';
@@ -28,6 +28,7 @@ function mapDispatchToProps(dispatch) {
joinTeam,
logout,
resetToChannel,
+ dismissModal,
}, dispatch),
};
}
diff --git a/app/screens/select_team/select_team.js b/app/screens/select_team/select_team.js
index 5b66520fb..2e0866aca 100644
--- a/app/screens/select_team/select_team.js
+++ b/app/screens/select_team/select_team.js
@@ -46,8 +46,9 @@ export default class SelectTeam extends PureComponent {
joinTeam: PropTypes.func.isRequired,
logout: PropTypes.func.isRequired,
resetToChannel: PropTypes.func.isRequired,
+ dismissModal: PropTypes.func.isRequired,
}).isRequired,
- componentId: PropTypes.string,
+ componentId: PropTypes.string.isRequired,
currentUrl: PropTypes.string.isRequired,
userWithoutTeams: PropTypes.bool,
teams: PropTypes.array.isRequired,
@@ -124,7 +125,7 @@ export default class SelectTeam extends PureComponent {
};
close = () => {
- Navigation.dismissModal(this.props.componentId);
+ this.props.actions.dismissModal();
};
goToChannelView = () => {
diff --git a/app/screens/select_team/select_team.test.js b/app/screens/select_team/select_team.test.js
index 9d6adc9df..7e3a1219b 100644
--- a/app/screens/select_team/select_team.test.js
+++ b/app/screens/select_team/select_team.test.js
@@ -30,6 +30,7 @@ describe('SelectTeam', () => {
joinTeam: jest.fn(),
logout: jest.fn(),
resetToChannel: jest.fn(),
+ dismissModal: jest.fn(),
};
const baseProps = {
diff --git a/app/screens/settings/display_settings/display_settings.js b/app/screens/settings/display_settings/display_settings.js
index 24ffdca47..19d135d35 100644
--- a/app/screens/settings/display_settings/display_settings.js
+++ b/app/screens/settings/display_settings/display_settings.js
@@ -8,12 +8,11 @@ import {
Platform,
View,
} from 'react-native';
-import {Navigation} from 'react-native-navigation';
import SettingsItem from 'app/screens/settings/settings_item';
import StatusBar from 'app/components/status_bar';
import {preventDoubleTap} from 'app/utils/tap';
-import {changeOpacity, makeStyleSheetFromTheme, setNavigatorStyles} from 'app/utils/theme';
+import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import ClockDisplay from 'app/screens/clock_display';
@@ -34,16 +33,6 @@ export default class DisplaySettings extends PureComponent {
showClockDisplaySettings: false,
};
- componentDidMount() {
- this.navigationEventListener = Navigation.events().bindComponent(this);
- }
-
- // TODO: Remove this once styles are passed in push call in
- // app/screens/settings/general/settings.js
- componentDidAppear() {
- setNavigatorStyles(this.props.componentId, this.props.theme);
- }
-
closeClockDisplaySettings = () => {
this.setState({showClockDisplaySettings: false});
};
diff --git a/app/screens/settings/general/index.js b/app/screens/settings/general/index.js
index ab8457df1..09cc293ab 100644
--- a/app/screens/settings/general/index.js
+++ b/app/screens/settings/general/index.js
@@ -7,9 +7,10 @@ import {connect} from 'react-redux';
import {clearErrors} from 'mattermost-redux/actions/errors';
import {getCurrentUrl, getConfig} from 'mattermost-redux/selectors/entities/general';
import {getJoinableTeams} from 'mattermost-redux/selectors/entities/teams';
-
-import {purgeOfflineStore} from 'app/actions/views/root';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
+
+import {goToScreen, dismissModal} from 'app/actions/navigation';
+import {purgeOfflineStore} from 'app/actions/views/root';
import {removeProtocol} from 'app/utils/url';
import Settings from './settings';
@@ -33,6 +34,8 @@ function mapDispatchToProps(dispatch) {
actions: bindActionCreators({
clearErrors,
purgeOfflineStore,
+ goToScreen,
+ dismissModal,
}, dispatch),
};
}
diff --git a/app/screens/settings/general/settings.js b/app/screens/settings/general/settings.js
index f1569a2fc..94cbdba27 100644
--- a/app/screens/settings/general/settings.js
+++ b/app/screens/settings/general/settings.js
@@ -16,7 +16,7 @@ import {Navigation} from 'react-native-navigation';
import SettingsItem from 'app/screens/settings/settings_item';
import StatusBar from 'app/components/status_bar';
import {preventDoubleTap} from 'app/utils/tap';
-import {changeOpacity, makeStyleSheetFromTheme, setNavigatorStyles} from 'app/utils/theme';
+import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import {isValidUrl} from 'app/utils/url';
import {t} from 'app/utils/i18n';
@@ -27,6 +27,8 @@ class Settings extends PureComponent {
actions: PropTypes.shape({
clearErrors: PropTypes.func.isRequired,
purgeOfflineStore: PropTypes.func.isRequired,
+ goToScreen: PropTypes.func.isRequired,
+ dismissModal: PropTypes.func.isRequired,
}).isRequired,
componentId: PropTypes.string,
config: PropTypes.object.isRequired,
@@ -36,7 +38,6 @@ class Settings extends PureComponent {
errors: PropTypes.array.isRequired,
intl: intlShape.isRequired,
joinableTeams: PropTypes.array.isRequired,
- navigator: PropTypes.object,
theme: PropTypes.object,
};
@@ -49,17 +50,9 @@ class Settings extends PureComponent {
this.navigationEventListener = Navigation.events().bindComponent(this);
}
- // TODO: Remove this once styles are passed in push/showModal call in
- // app/components/sidebars/settings/settings_sidebar.js
- componentDidAppear() {
- setNavigatorStyles(this.props.componentId, this.props.theme);
- }
-
navigationButtonPressed({buttonId}) {
if (buttonId === 'close-settings') {
- this.props.navigator.dismissModal({
- animationType: 'slide-down',
- });
+ this.props.actions.dismissModal();
}
}
@@ -90,111 +83,58 @@ class Settings extends PureComponent {
};
goToAbout = preventDoubleTap(() => {
- const {intl, navigator, theme, config} = this.props;
- navigator.push({
- screen: 'About',
- title: intl.formatMessage({id: 'about.title', defaultMessage: 'About {appTitle}'}, {appTitle: config.SiteName || 'Mattermost'}),
- animated: true,
- backButtonTitle: '',
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- },
- });
+ const {actions, intl, config} = this.props;
+ const screen = 'About';
+ const title = intl.formatMessage({id: 'about.title', defaultMessage: 'About {appTitle}'}, {appTitle: config.SiteName || 'Mattermost'});
+
+ actions.goToScreen(screen, title);
});
goToNotifications = preventDoubleTap(() => {
- const {intl, navigator, theme} = this.props;
- navigator.push({
- screen: 'NotificationSettings',
- backButtonTitle: '',
- title: intl.formatMessage({id: 'user.settings.modal.notifications', defaultMessage: 'Notifications'}),
- animated: true,
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- });
+ const {actions, intl} = this.props;
+ const screen = 'NotificationSettings';
+ const title = intl.formatMessage({id: 'user.settings.modal.notifications', defaultMessage: 'Notifications'});
+
+ actions.goToScreen(screen, title);
});
goToDisplaySettings = preventDoubleTap(() => {
- const {intl, navigator, theme} = this.props;
+ const {actions, intl} = this.props;
+ const screen = 'DisplaySettings';
+ const title = intl.formatMessage({id: 'user.settings.modal.display', defaultMessage: 'Display'});
- // TODO: Ensure all styles used in app/utils/theme's setNavigatorStyles
- // are passed to DisplaySettings when this push call is updated to RNN v2
- // then remove setNavigatorStyles call in app/screens/settings/display_settings/display_settings.js
- navigator.push({
- screen: 'DisplaySettings',
- title: intl.formatMessage({id: 'user.settings.modal.display', defaultMessage: 'Display'}),
- animated: true,
- backButtonTitle: '',
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- });
+ actions.goToScreen(screen, title);
});
goToAdvancedSettings = preventDoubleTap(() => {
- const {intl, navigator, theme} = this.props;
- navigator.push({
- screen: 'AdvancedSettings',
- title: intl.formatMessage({id: 'mobile.advanced_settings.title', defaultMessage: 'Advanced Settings'}),
- animated: true,
- backButtonTitle: '',
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- });
+ const {actions, intl} = this.props;
+ const screen = 'AdvancedSettings';
+ const title = intl.formatMessage({id: 'mobile.advanced_settings.title', defaultMessage: 'Advanced Settings'});
+
+ actions.goToScreen(screen, title);
});
goToSelectTeam = preventDoubleTap(() => {
- const {currentUrl, intl, navigator, theme} = this.props;
+ const {actions, currentUrl, intl, theme} = this.props;
+ const screen = 'SelectTeam';
+ const title = intl.formatMessage({id: 'mobile.routes.selectTeam', defaultMessage: 'Select Team'});
+ const passProps = {
+ currentUrl,
+ theme,
+ };
- navigator.push({
- screen: 'SelectTeam',
- title: intl.formatMessage({id: 'mobile.routes.selectTeam', defaultMessage: 'Select Team'}),
- animated: true,
- backButtonTitle: '',
- navigatorStyle: {
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- screenBackgroundColor: theme.centerChannelBg,
- },
- passProps: {
- currentUrl,
- theme,
- },
- });
+ actions.goToScreen(screen, title, passProps);
});
goToClientUpgrade = preventDoubleTap(() => {
- const {intl, theme} = this.props;
+ const {actions, intl} = this.props;
+ const screen = 'ClientUpgrade';
+ const title = intl.formatMessage({id: 'mobile.client_upgrade', defaultMessage: 'Upgrade App'});
+ const passProps = {
+ userCheckedForUpgrade: true,
+ };
- this.props.navigator.push({
- screen: 'ClientUpgrade',
- title: intl.formatMessage({id: 'mobile.client_upgrade', defaultMessage: 'Upgrade App'}),
- animated: true,
- backButtonTitle: '',
- navigatorStyle: {
- navBarHidden: false,
- navBarTextColor: theme.sidebarHeaderTextColor,
- navBarBackgroundColor: theme.sidebarHeaderBg,
- navBarButtonColor: theme.sidebarHeaderTextColor,
- },
- passProps: {
- userCheckedForUpgrade: true,
- },
- });
+ actions.goToScreen(screen, title, passProps);
});
openErrorEmail = preventDoubleTap(() => {
diff --git a/app/store/ephemeral_store.js b/app/store/ephemeral_store.js
new file mode 100644
index 000000000..7e69decae
--- /dev/null
+++ b/app/store/ephemeral_store.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+class EphemeralStore {
+ constructor() {
+ this.componentIdStack = [];
+ }
+
+ getTopComponentId = () => this.componentIdStack[0];
+
+ addComponentIdToStack = (componentId) => {
+ this.componentIdStack.unshift(componentId);
+ }
+
+ removeComponentIdFromStack = (componentId) => {
+ this.componentIdStack = this.componentIdStack.filter((id) => {
+ return id !== componentId;
+ });
+ }
+}
+
+export default new EphemeralStore();
diff --git a/app/utils/images.js b/app/utils/images.js
index 2d0ab6771..c231e2ca2 100644
--- a/app/utils/images.js
+++ b/app/utils/images.js
@@ -57,44 +57,27 @@ export const calculateDimensions = (height, width, viewPortWidth = 0, viewPortHe
};
};
-export function previewImageAtIndex(navigator, components, index, files) {
+export function previewImageAtIndex(components, index, files, showModalOverCurrentContext) {
previewComponents = components;
const component = components[index];
if (component) {
component.measure((rx, ry, width, height, x, y) => {
- goToImagePreview(
- navigator,
- {
+ Keyboard.dismiss();
+ requestAnimationFrame(() => {
+ const screen = 'ImagePreview';
+ const passProps = {
index,
origin: {x, y, width, height},
target: {x: 0, y: 0, opacity: 1},
files,
getItemMeasures,
- }
- );
+ };
+ showModalOverCurrentContext(screen, passProps);
+ });
});
}
}
-function goToImagePreview(navigator, passProps) {
- Keyboard.dismiss();
- requestAnimationFrame(() => {
- navigator.showModal({
- screen: 'ImagePreview',
- title: '',
- animationType: 'none',
- passProps,
- navigatorStyle: {
- navBarHidden: true,
- statusBarHidden: false,
- statusBarHideWithNavBar: false,
- screenBackgroundColor: 'transparent',
- modalPresentationStyle: 'overCurrentContext',
- },
- });
- });
-}
-
function getItemMeasures(index, cb) {
const activeComponent = previewComponents[index];