MM-25956 Use new mobile modal style on Other User Profile (#4507)

* Changing other user profiles to be shown as modals

- Removed unnecessary props
- Updated user_profile unit tests
- Removed useless Platform.select call on channel_base

* Changed at_mention, channel_intro, and reaction_row profiles to modal
This commit is contained in:
Andre Vasconcelos 2020-07-09 08:34:42 +09:00 committed by GitHub
parent e754e861a2
commit aa9e074a4c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 90 additions and 85 deletions

View file

@ -5,13 +5,14 @@ import React from 'react';
import PropTypes from 'prop-types';
import {Clipboard, Text} from 'react-native';
import {intlShape} from 'react-intl';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import {displayUsername} from '@mm-redux/utils/user_utils';
import CustomPropTypes from 'app/constants/custom_prop_types';
import mattermostManaged from 'app/mattermost_managed';
import BottomSheet from 'app/utils/bottom_sheet';
import {goToScreen} from 'app/actions/navigation';
import {showModal} from 'app/actions/navigation';
export default class AtMention extends React.PureComponent {
static propTypes = {
@ -45,15 +46,29 @@ export default class AtMention extends React.PureComponent {
}
}
goToUserProfile = () => {
goToUserProfile = async () => {
const {intl} = this.context;
const {theme} = this.props;
const screen = 'UserProfile';
const title = intl.formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'});
const passProps = {
userId: this.state.user.id,
};
goToScreen(screen, title, passProps);
if (!this.closeButton) {
this.closeButton = await MaterialIcon.getImageSource('close', 20, theme.sidebarHeaderTextColor);
}
const options = {
topBar: {
leftButtons: [{
id: 'close-settings',
icon: this.closeButton,
}],
},
};
showModal(screen, title, passProps, options);
};
getUserDetailsFromMentionName() {

View file

@ -8,11 +8,12 @@ import {
View,
} from 'react-native';
import {injectIntl, intlShape} from 'react-intl';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import {displayUsername} from '@mm-redux/utils/user_utils';
import {General} from '@mm-redux/constants';
import {goToScreen} from 'app/actions/navigation';
import {showModal} from 'app/actions/navigation';
import ProfilePicture from 'app/components/profile_picture';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import {BotTag, GuestTag} from 'app/components/tag';
@ -37,15 +38,28 @@ class ChannelIntro extends PureComponent {
currentChannelMembers: [],
};
goToUserProfile = (userId) => {
const {intl} = this.props;
goToUserProfile = async (userId) => {
const {intl, theme} = this.props;
const screen = 'UserProfile';
const title = intl.formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'});
const passProps = {
userId,
};
goToScreen(screen, title, passProps);
if (!this.closeButton) {
this.closeButton = await MaterialIcon.getImageSource('close', 20, theme.sidebarHeaderTextColor);
}
const options = {
topBar: {
leftButtons: [{
id: 'close-settings',
icon: this.closeButton,
}],
},
};
showModal(screen, title, passProps, options);
};
getDisplayName = (member) => {

View file

@ -10,23 +10,27 @@ import {
ViewPropTypes,
} from 'react-native';
import {intlShape} from 'react-intl';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import {Posts} from '@mm-redux/constants';
import EventEmitter from '@mm-redux/utils/event_emitter';
import {isPostEphemeral, isPostPendingOrFailed, isSystemMessage} from '@mm-redux/utils/post_utils';
import PostBody from 'app/components/post_body';
import PostHeader from 'app/components/post_header';
import PostPreHeader from 'app/components/post_header/post_pre_header';
import PostProfilePicture from 'app/components/post_profile_picture';
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
import {NavigationTypes} from 'app/constants';
import {fromAutoResponder} from 'app/utils/general';
import {preventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import {t} from 'app/utils/i18n';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import {goToScreen, showModalOverCurrentContext} from 'app/actions/navigation';
import {showModalOverCurrentContext, showModal} from '@actions/navigation';
import PostBody from '@components/post_body';
import PostHeader from '@components/post_header';
import PostProfilePicture from '@components/post_profile_picture';
import PostPreHeader from '@components/post_header/post_pre_header';
import TouchableWithFeedback from '@components/touchable_with_feedback';
import {paddingHorizontal as padding} from '@components/safe_area_view/iphone_x_spacing';
import {NavigationTypes} from '@constants';
import {t} from '@utils/i18n';
import {preventDoubleTap} from '@utils/tap';
import {fromAutoResponder} from '@utils/general';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
export default class Post extends PureComponent {
static propTypes = {
@ -88,19 +92,30 @@ export default class Post extends PureComponent {
this.postBodyRef = React.createRef();
}
goToUserProfile = () => {
goToUserProfile = async () => {
const {intl} = this.context;
const {post} = this.props;
const {post, theme} = this.props;
const screen = 'UserProfile';
const title = intl.formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'});
const passProps = {
userId: post.user_id,
};
if (!this.closeButton) {
this.closeButton = await MaterialIcon.getImageSource('close', 20, theme.sidebarHeaderTextColor);
}
const options = {
topBar: {
leftButtons: [{
id: 'close-settings',
icon: this.closeButton,
}],
},
};
Keyboard.dismiss();
requestAnimationFrame(() => {
goToScreen(screen, title, passProps);
});
showModal(screen, title, passProps, options);
};
autofillUserMention = (username) => {

View file

@ -112,7 +112,7 @@ export default class SettingsSidebarBase extends PureComponent {
this.openModal(
'UserProfile',
intl.formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'}),
{userId, fromSettings: true},
{userId},
);
};

View file

@ -9,7 +9,6 @@ import {
Keyboard,
Linking,
StyleSheet,
Platform,
} from 'react-native';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
@ -169,11 +168,6 @@ export default class ChannelBase extends PureComponent {
icon: source,
}],
},
...Platform.select({
ios: {
modalPresentationStyle: 'pageSheet',
},
}),
};
Keyboard.dismiss();

View file

@ -9,6 +9,7 @@ import {
TouchableOpacity,
View,
} from 'react-native';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import {displayUsername} from '@mm-redux/utils/user_utils';
@ -16,7 +17,7 @@ import ProfilePicture from 'app/components/profile_picture';
import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone_x_spacing';
import {preventDoubleTap} from 'app/utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from 'app/utils/theme';
import {goToScreen} from 'app/actions/navigation';
import {showModal} from 'app/actions/navigation';
import Emoji from 'app/components/emoji';
@ -37,8 +38,8 @@ export default class ReactionRow extends React.PureComponent {
intl: intlShape,
};
goToUserProfile = () => {
const {user} = this.props;
goToUserProfile = async () => {
const {user, theme} = this.props;
const {formatMessage} = this.context.intl;
const screen = 'UserProfile';
const title = formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'});
@ -46,7 +47,20 @@ export default class ReactionRow extends React.PureComponent {
userId: user.id,
};
goToScreen(screen, title, passProps);
if (!this.closeButton) {
this.closeButton = await MaterialIcon.getImageSource('close', 20, theme.sidebarHeaderTextColor);
}
const options = {
topBar: {
leftButtons: [{
id: 'close-settings',
icon: this.closeButton,
}],
},
};
showModal(screen, title, passProps, options);
};
render() {

View file

@ -14,7 +14,6 @@ import {Navigation} from 'react-native-navigation';
import {
goToScreen,
popToRoot,
dismissModal,
setButtons,
} from '@actions/navigation';
@ -51,7 +50,6 @@ export default class UserProfile extends PureComponent {
militaryTime: PropTypes.bool.isRequired,
enableTimezone: PropTypes.bool.isRequired,
isMyUser: PropTypes.bool.isRequired,
fromSettings: PropTypes.bool,
isLandscape: PropTypes.bool.isRequired,
};
@ -99,14 +97,7 @@ export default class UserProfile extends PureComponent {
}
close = async () => {
const {fromSettings} = this.props;
if (fromSettings) {
dismissModal();
return;
}
await popToRoot();
dismissModal();
};
getDisplayName = () => {

View file

@ -145,47 +145,8 @@ describe('user_profile', () => {
expect(goToScreen).toHaveBeenCalledTimes(1);
});
test('close should dismiss modal when fromSettings is true', async () => {
const dismissModal = jest.spyOn(NavigationActions, 'dismissModal');
const dismissAllModals = jest.spyOn(NavigationActions, 'dismissAllModals');
const popToRoot = jest.spyOn(NavigationActions, 'popToRoot');
const props = {...baseProps, fromSettings: true};
const wrapper = shallow(
<UserProfile
{...props}
user={user}
/>,
{context: {intl: {formatMessage: jest.fn()}}},
);
await wrapper.instance().close();
expect(dismissModal).toHaveBeenCalledTimes(1);
expect(dismissAllModals).toHaveBeenCalledTimes(0);
expect(popToRoot).toHaveBeenCalledTimes(0);
});
test('close should dismiss all modals and pop to root when fromSettings is false', async () => {
const dismissModal = jest.spyOn(NavigationActions, 'dismissModal');
const popToRoot = jest.spyOn(NavigationActions, 'popToRoot');
const props = {...baseProps, fromSettings: false};
const wrapper = shallow(
<UserProfile
{...props}
user={user}
/>,
{context: {intl: {formatMessage: jest.fn()}}},
);
await wrapper.instance().close();
expect(dismissModal).toHaveBeenCalledTimes(0);
expect(popToRoot).toHaveBeenCalledTimes(1);
});
test('should call close', () => {
const dismissModal = jest.spyOn(NavigationActions, 'dismissModal');
const wrapper = shallow(
<UserProfile
{...baseProps}
@ -198,5 +159,6 @@ describe('user_profile', () => {
const event = {buttonId: 'close-settings'};
wrapper.instance().navigationButtonPressed(event);
expect(close).toHaveBeenCalledTimes(1);
expect(dismissModal).toHaveBeenCalledTimes(1);
});
});