[MM-16012] [MM-16084] Update screens related to settings sidebar + update SearchResultPost screen and its children (#2913)
* Update screens * Update login tests * Remove done * Fix failing tests * Update screens and components * Check styles fix * Update tests * Prevent setState call after component unmounts * Add empty setButtons func to dummy navigator * Remove platform check * Remove Platform import * Update react-native-navigation version * Add separate showModalOverCurrentContext function * check-style fixes * Remove overriding of AppDelegate's window * Fix modal over current context animation * Add showSearchModal navigation action * Check-style fix * Address review comments * Update SettingsSidebar and children * Update EditProfile screen * Update SettingsSidebar * Keep track of latest componentId to appear * Track componentId in state to use in navigation actions * Update FlaggedPosts and children * Update RecentMentions * Update Settings * Store componentIds in ephemeral store * Update AttachmentButton * Remove unnecessary dismissModal * Fix typo * Check-style fix * Address review comments
This commit is contained in:
parent
913f05e131
commit
150253d392
89 changed files with 614 additions and 727 deletions
|
|
@ -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 = {}) {
|
|||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function setButtons(buttons = {leftButtons: [], rightButtons: []}) {
|
||||
return () => {
|
||||
const componentId = EphemeralStore.getTopComponentId();
|
||||
|
||||
Navigation.mergeOptions(componentId, {
|
||||
topBar: {
|
||||
...buttons,
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ describe('AttachmentButton', () => {
|
|||
showModalOverCurrentContext: jest.fn(),
|
||||
},
|
||||
theme: Preferences.THEMES.default,
|
||||
navigator: {},
|
||||
blurTextBox: jest.fn(),
|
||||
maxFileSize: 10,
|
||||
uploadFiles: jest.fn(),
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
|||
<LastUsers
|
||||
actor={actor}
|
||||
expandedLocale={postTypeMessage[postType].many_expanded}
|
||||
navigator={navigator}
|
||||
postType={postType}
|
||||
style={style}
|
||||
textStyles={textStyles}
|
||||
|
|
@ -314,7 +311,6 @@ export default class CombinedSystemMessage extends React.PureComponent {
|
|||
return (
|
||||
<Markdown
|
||||
baseTextStyle={style.baseText}
|
||||
navigator={navigator}
|
||||
textStyles={textStyles}
|
||||
value={formattedMessage}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Markdown
|
||||
baseTextStyle={style.baseText}
|
||||
navigator={navigator}
|
||||
textStyles={textStyles}
|
||||
value={formattedMessage}
|
||||
/>
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
|||
<AtMention
|
||||
mentionStyle={this.props.textStyles.mention}
|
||||
mentionName={mentionName}
|
||||
navigator={this.props.navigator}
|
||||
onPostPress={this.props.onPostPress}
|
||||
textStyle={this.computeTextStyle(this.props.baseTextStyle, context)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
|||
<MarkdownTableImage
|
||||
source={src}
|
||||
textStyle={[this.computeTextStyle(this.props.baseTextStyle, context), this.props.textStyles.link]}
|
||||
navigator={this.props.navigator}
|
||||
>
|
||||
{reactChildren}
|
||||
</MarkdownTableImage>
|
||||
|
|
@ -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 (
|
||||
<MarkdownCodeBlock
|
||||
navigator={this.props.navigator}
|
||||
content={content}
|
||||
language={props.language}
|
||||
textStyle={this.props.textStyles.codeBlock}
|
||||
|
|
@ -371,7 +365,6 @@ export default class Markdown extends PureComponent {
|
|||
renderTable = ({children, numColumns}) => {
|
||||
return (
|
||||
<MarkdownTable
|
||||
navigator={this.props.navigator}
|
||||
numColumns={numColumns}
|
||||
>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 () => {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 = () => {
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
19
app/components/message_attachments/attachment_image/index.js
Normal file
19
app/components/message_attachments/attachment_image/index.js
Normal file
|
|
@ -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);
|
||||
|
|
@ -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}
|
||||
/>
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
<AttachmentThumbnail url={attachment.thumb_url}/>
|
||||
<AttachmentText
|
||||
|
|
@ -95,7 +91,6 @@ export default class MessageAttachment extends PureComponent {
|
|||
deviceHeight={deviceHeight}
|
||||
hasThumbnail={Boolean(attachment.thumb_url)}
|
||||
metadata={metadata}
|
||||
navigator={navigator}
|
||||
onPermalinkPress={onPermalinkPress}
|
||||
textStyles={textStyles}
|
||||
value={attachment.text}
|
||||
|
|
@ -105,14 +100,12 @@ export default class MessageAttachment extends PureComponent {
|
|||
blockStyles={blockStyles}
|
||||
fields={attachment.fields}
|
||||
metadata={metadata}
|
||||
navigator={navigator}
|
||||
onPermalinkPress={onPermalinkPress}
|
||||
textStyles={textStyles}
|
||||
theme={theme}
|
||||
/>
|
||||
<AttachmentActions
|
||||
actions={attachment.actions}
|
||||
navigator={navigator}
|
||||
postId={postId}
|
||||
/>
|
||||
<AttachmentImage
|
||||
|
|
@ -120,7 +113,6 @@ export default class MessageAttachment extends PureComponent {
|
|||
deviceWidth={deviceWidth}
|
||||
imageUrl={attachment.image_url}
|
||||
imageMetadata={metadata?.images?.[attachment.image_url]}
|
||||
navigator={navigator}
|
||||
theme={theme}
|
||||
/>
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = () => {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ describe('PostAttachmentOpenGraph', () => {
|
|||
const baseProps = {
|
||||
actions: {
|
||||
getOpenGraphMetadata: jest.fn(),
|
||||
showModalOverCurrentContext: jest.fn(),
|
||||
},
|
||||
deviceHeight: 600,
|
||||
deviceWidth: 400,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<PostAddChannelMember
|
||||
baseTextStyle={messageStyle}
|
||||
navigator={navigator}
|
||||
onPostPress={onPress}
|
||||
textStyles={textStyles}
|
||||
postId={postProps.add_channel_member.post_id}
|
||||
|
|
@ -246,7 +231,6 @@ export default class PostBody extends PureComponent {
|
|||
const {
|
||||
fileIds,
|
||||
isFailed,
|
||||
navigator,
|
||||
post,
|
||||
showLongPost,
|
||||
} = this.props;
|
||||
|
|
@ -267,7 +251,6 @@ export default class PostBody extends PureComponent {
|
|||
isFailed={isFailed}
|
||||
onLongPress={this.showPostOptions}
|
||||
postId={post.id}
|
||||
navigator={navigator}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -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 {
|
|||
<PostBodyAdditionalContent
|
||||
baseTextStyle={messageStyle}
|
||||
blockStyles={blockStyles}
|
||||
navigator={navigator}
|
||||
message={message}
|
||||
metadata={metadata}
|
||||
postId={post.id}
|
||||
|
|
@ -321,7 +302,6 @@ export default class PostBody extends PureComponent {
|
|||
const {
|
||||
hasReactions,
|
||||
isSearchResult,
|
||||
navigator,
|
||||
post,
|
||||
showLongPost,
|
||||
} = this.props;
|
||||
|
|
@ -337,7 +317,6 @@ export default class PostBody extends PureComponent {
|
|||
return (
|
||||
<Reactions
|
||||
postId={post.id}
|
||||
navigator={navigator}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
|||
<PostAttachmentOpenGraph
|
||||
isReplyPost={isReplyPost}
|
||||
link={link}
|
||||
navigator={navigator}
|
||||
openGraphData={openGraphData}
|
||||
imagesMetadata={metadata && metadata.images}
|
||||
theme={theme}
|
||||
|
|
@ -339,7 +338,6 @@ export default class PostBodyAdditionalContent extends PureComponent {
|
|||
deviceHeight,
|
||||
deviceWidth,
|
||||
metadata,
|
||||
navigator,
|
||||
onHashtagPress,
|
||||
onPermalinkPress,
|
||||
textStyles,
|
||||
|
|
@ -360,7 +358,6 @@ export default class PostBodyAdditionalContent extends PureComponent {
|
|||
deviceHeight={deviceHeight}
|
||||
deviceWidth={deviceWidth}
|
||||
metadata={metadata}
|
||||
navigator={navigator}
|
||||
postId={postId}
|
||||
textStyles={textStyles}
|
||||
theme={theme}
|
||||
|
|
@ -409,7 +406,7 @@ export default class PostBodyAdditionalContent extends PureComponent {
|
|||
handlePreviewImage = (imageRef) => {
|
||||
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 = () => {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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={<View style={style.container}/>}
|
||||
headerComponent={<View style={style.container}/>}
|
||||
navigator={navigator}
|
||||
theme={theme}
|
||||
>
|
||||
<View style={style.container}>
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
<EditProfile
|
||||
{...baseProps}
|
||||
navigator={newNavigator}
|
||||
/>,
|
||||
{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);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 = () => {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = () => {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = () => {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ describe('SelectTeam', () => {
|
|||
joinTeam: jest.fn(),
|
||||
logout: jest.fn(),
|
||||
resetToChannel: jest.fn(),
|
||||
dismissModal: jest.fn(),
|
||||
};
|
||||
|
||||
const baseProps = {
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(() => {
|
||||
|
|
|
|||
22
app/store/ephemeral_store.js
Normal file
22
app/store/ephemeral_store.js
Normal file
|
|
@ -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();
|
||||
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue