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:
parent
e754e861a2
commit
aa9e074a4c
8 changed files with 90 additions and 85 deletions
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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},
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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 = () => {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue