From b81cd49fb476495be34d0f94aa4c64fa2f3fa542 Mon Sep 17 00:00:00 2001
From: Woolim Cho <2680v4@gmail.com>
Date: Wed, 5 Jun 2019 17:11:42 +0900
Subject: [PATCH] [MM-13879] Add Edit profile button to RHS menu and own
profile pop-over (#2832)
* Add Edit Profile button to right panel menu
* Make user info of right panel menu opens the users own profile
* Add an Edit button of the users own profile
* handle transitions
* Add commandType to propTypes
* Update test codes
* add unit tests for user_profile
* Assign commandType manually
* Remove async, set delay to 0
---
.../sidebars/settings/settings_sidebar.js | 25 ++++++-
.../__snapshots__/edit_profile.test.js.snap | 6 --
app/screens/edit_profile/edit_profile.js | 18 +++--
app/screens/edit_profile/edit_profile.test.js | 1 +
app/screens/user_profile/index.js | 2 +
app/screens/user_profile/user_profile.js | 67 ++++++++++++++++++
app/screens/user_profile/user_profile.test.js | 69 +++++++++++++++++++
7 files changed, 170 insertions(+), 18 deletions(-)
diff --git a/app/components/sidebars/settings/settings_sidebar.js b/app/components/sidebars/settings/settings_sidebar.js
index ffade1249..9d552978b 100644
--- a/app/components/sidebars/settings/settings_sidebar.js
+++ b/app/components/sidebars/settings/settings_sidebar.js
@@ -153,11 +153,12 @@ export default class SettingsDrawer extends PureComponent {
goToEditProfile = preventDoubleTap(() => {
const {currentUser} = this.props;
const {formatMessage} = this.context.intl;
+ const commandType = 'ShowModal';
this.openModal(
'EditProfile',
formatMessage({id: 'mobile.routes.edit_profile', defaultMessage: 'Edit Profile'}),
- {currentUser}
+ {currentUser, commandType}
);
});
@@ -179,6 +180,17 @@ export default class SettingsDrawer extends PureComponent {
);
});
+ goToUserProfile = preventDoubleTap(() => {
+ const userId = this.props.currentUser.id;
+ const {formatMessage} = this.context.intl;
+
+ this.openModal(
+ 'UserProfile',
+ formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'}),
+ {userId, fromSettings: true}
+ );
+ });
+
goToSettings = preventDoubleTap(() => {
const {intl} = this.context;
@@ -258,7 +270,7 @@ export default class SettingsDrawer extends PureComponent {
contentContainerStyle={style.wrapper}
>
@@ -293,6 +305,15 @@ export default class SettingsDrawer extends PureComponent {
+
{
- this.props.navigator.dismissModal({
- animationType: 'slide-down',
- });
+ if (this.props.commandType === 'Push') {
+ this.props.navigator.pop();
+ } else {
+ this.props.navigator.dismissModal({
+ animationType: 'slide-down',
+ });
+ }
};
emitCanUpdateAccount = (enabled) => {
diff --git a/app/screens/edit_profile/edit_profile.test.js b/app/screens/edit_profile/edit_profile.test.js
index 249fedf10..69682f745 100644
--- a/app/screens/edit_profile/edit_profile.test.js
+++ b/app/screens/edit_profile/edit_profile.test.js
@@ -45,6 +45,7 @@ describe('edit_profile', () => {
nickname: 'Dragon',
position: 'position',
},
+ commandType: 'ShowModal',
};
test('should match snapshot', async () => {
diff --git a/app/screens/user_profile/index.js b/app/screens/user_profile/index.js
index a9d6ba836..27b466ed1 100644
--- a/app/screens/user_profile/index.js
+++ b/app/screens/user_profile/index.js
@@ -12,6 +12,7 @@ import {getConfig} from 'mattermost-redux/selectors/entities/general';
import Preferences from 'mattermost-redux/constants/preferences';
import {loadBot} from 'mattermost-redux/actions/bots';
import {getBotAccounts} from 'mattermost-redux/selectors/entities/bots';
+import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
import {isTimezoneEnabled} from 'app/utils/timezone';
@@ -33,6 +34,7 @@ function mapStateToProps(state, ownProps) {
enableTimezone,
militaryTime,
theme: getTheme(state),
+ isMyUser: getCurrentUserId(state) === ownProps.userId,
};
}
diff --git a/app/screens/user_profile/user_profile.js b/app/screens/user_profile/user_profile.js
index 9a6ea0e66..f1bf1ba34 100644
--- a/app/screens/user_profile/user_profile.js
+++ b/app/screens/user_profile/user_profile.js
@@ -42,12 +42,34 @@ export default class UserProfile extends PureComponent {
bot: PropTypes.object,
militaryTime: PropTypes.bool.isRequired,
enableTimezone: PropTypes.bool.isRequired,
+ isMyUser: PropTypes.bool.isRequired,
+ fromSettings: PropTypes.bool,
};
static contextTypes = {
intl: intlShape.isRequired,
};
+ rightButton = {
+ id: 'edit-profile',
+ showAsAction: 'always',
+ };
+
+ constructor(props, context) {
+ super(props);
+
+ if (props.isMyUser) {
+ this.rightButton.title = context.intl.formatMessage({id: 'mobile.routes.user_profile.edit', defaultMessage: 'Edit'});
+
+ const buttons = {
+ rightButtons: [this.rightButton],
+ };
+
+ props.navigator.setOnNavigatorEvent(this.onNavigatorEvent);
+ props.navigator.setButtons(buttons);
+ }
+ }
+
componentWillReceiveProps(nextProps) {
if (this.props.theme !== nextProps.theme) {
setNavigatorStyles(this.props.navigator, nextProps.theme);
@@ -63,6 +85,13 @@ export default class UserProfile extends PureComponent {
close = () => {
const {navigator, theme} = this.props;
+ if (this.props.fromSettings) {
+ navigator.dismissModal({
+ animationType: 'slide-down',
+ });
+ return;
+ }
+
navigator.resetTo({
screen: 'Channel',
animated: true,
@@ -187,6 +216,44 @@ export default class UserProfile extends PureComponent {
};
};
+ goToEditProfile = () => {
+ const {user: currentUser} = this.props;
+ const {formatMessage} = this.context.intl;
+ const commandType = 'Push';
+
+ const {navigator, theme} = this.props;
+ const options = {
+ screen: 'EditProfile',
+ title: formatMessage({id: 'mobile.routes.edit_profile', defaultMessage: 'Edit Profile'}),
+ animated: true,
+ backButtonTitle: '',
+ passProps: {currentUser, commandType},
+ navigatorStyle: {
+ navBarTextColor: theme.sidebarHeaderTextColor,
+ navBarBackgroundColor: theme.sidebarHeaderBg,
+ navBarButtonColor: theme.sidebarHeaderTextColor,
+ screenBackgroundColor: theme.centerChannelBg,
+ },
+ };
+
+ requestAnimationFrame(() => {
+ navigator.push(options);
+ });
+ };
+
+ onNavigatorEvent = (event) => {
+ if (event.type === 'NavBarButtonPress') {
+ switch (event.id) {
+ case this.rightButton.id:
+ this.goToEditProfile();
+ break;
+ case 'close-settings':
+ this.close();
+ break;
+ }
+ }
+ };
+
renderAdditionalOptions = () => {
if (!Config.ExperimentalProfileLinks) {
return null;
diff --git a/app/screens/user_profile/user_profile.test.js b/app/screens/user_profile/user_profile.test.js
index 6b61fe051..e1dac798e 100644
--- a/app/screens/user_profile/user_profile.test.js
+++ b/app/screens/user_profile/user_profile.test.js
@@ -31,11 +31,14 @@ describe('user_profile', () => {
teammateNameDisplay: 'username',
navigator: {
resetTo: jest.fn(),
+ push: jest.fn(),
+ dismissModal: jest.fn(),
},
teams: [],
theme: Preferences.THEMES.default,
enableTimezone: false,
militaryTime: false,
+ isMyUser: false,
};
const user = {
@@ -84,4 +87,70 @@ describe('user_profile', () => {
/>
)).toEqual(true);
});
+
+ test('should push EditProfile', async () => {
+ const props = {
+ ...baseProps,
+ navigator: {
+ push: jest.fn(),
+ },
+ };
+
+ const wrapper = shallow(
+ ,
+ {context: {intl: {formatMessage: jest.fn()}}},
+ );
+
+ wrapper.instance().goToEditProfile();
+ setTimeout(() => {
+ expect(props.navigator.push).toHaveBeenCalledTimes(1);
+ }, 16);
+ });
+
+ test('should call goToEditProfile', () => {
+ const props = {
+ ...baseProps,
+ navigator: {
+ push: jest.fn(),
+ },
+ };
+
+ const wrapper = shallow(
+ ,
+ {context: {intl: {formatMessage: jest.fn()}}},
+ );
+
+ const event = {type: 'NavBarButtonPress', id: wrapper.instance().rightButton.id};
+ wrapper.instance().onNavigatorEvent(event);
+ setTimeout(() => {
+ expect(props.navigator.push).toHaveBeenCalledTimes(1);
+ }, 0);
+ });
+
+ test('should close', async () => {
+ const props = {...baseProps, fromSettings: true};
+
+ const wrapper = shallow(
+ ,
+ {context: {intl: {formatMessage: jest.fn()}}},
+ );
+
+ const event = {type: 'NavBarButtonPress', id: 'close-settings'};
+ wrapper.instance().onNavigatorEvent(event);
+ expect(props.navigator.dismissModal).toHaveBeenCalledTimes(1);
+
+ props.fromSettings = false;
+ wrapper.setProps({...props});
+ wrapper.instance().onNavigatorEvent(event);
+ expect(props.navigator.resetTo).toHaveBeenCalledTimes(1);
+ });
});