diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.js b/src/pages/workspace/WorkspaceInviteMessagePage.js index 64d086f6c407..d60f187fa7d2 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.js +++ b/src/pages/workspace/WorkspaceInviteMessagePage.js @@ -1,26 +1,28 @@ import {isEmpty} from 'lodash'; import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React from 'react'; +import React, {useEffect, useState} from 'react'; import {Keyboard, View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; -import Form from '@components/Form'; +import FormProvider from '@components/Form/FormProvider'; +import InputWrapper from '@components/Form/InputWrapper'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import MultipleAvatars from '@components/MultipleAvatars'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withNavigationFocus from '@components/withNavigationFocus'; -import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeStyles'; +import useAutoFocusInput from '@hooks/useAutoFocusInput'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; -import * as Localize from '@libs/Localize'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; +import updateMultilineInputRange from '@libs/updateMultilineInputRange'; import * as Link from '@userActions/Link'; import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; @@ -61,8 +63,6 @@ const propTypes = { }).isRequired, ...policyPropTypes, - ...withLocalizePropTypes, - ...withThemeStylesPropTypes, }; const defaultProps = { @@ -71,180 +71,144 @@ const defaultProps = { invitedEmailsToAccountIDsDraft: {}, }; -class WorkspaceInviteMessagePage extends React.Component { - constructor(props) { - super(props); +function WorkspaceInviteMessagePage(props) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); - this.sendInvitation = this.sendInvitation.bind(this); - this.validate = this.validate.bind(this); - this.openPrivacyURL = this.openPrivacyURL.bind(this); - this.debouncedSaveDraf = _.debounce((newDraft) => { - Policy.setWorkspaceInviteMessageDraft(this.props.route.params.policyID, newDraft); - }, 2000); - this.state = { - welcomeNote: this.props.workspaceInviteMessageDraft || this.getDefaultWelcomeNote(), - }; - } + const [welcomeNote, setWelcomeNote] = useState(); - componentDidMount() { - if (_.isEmpty(this.props.invitedEmailsToAccountIDsDraft)) { - Navigation.goBack(ROUTES.WORKSPACE_INVITE.getRoute(this.props.route.params.policyID), true); - return; - } - this.focusWelcomeMessageInput(); - } - - componentDidUpdate(prevProps) { - if (!prevProps.isFocused && this.props.isFocused) { - this.focusWelcomeMessageInput(); - } + const {inputCallbackRef} = useAutoFocusInput(); - if ( - !( - (prevProps.preferredLocale !== this.props.preferredLocale || prevProps.policy.name !== this.props.policy.name) && - this.state.welcomeNote === Localize.translate(prevProps.preferredLocale, 'workspace.inviteMessage.welcomeNote', {workspaceName: prevProps.policy.name}) - ) - ) { - return; - } - this.setState({welcomeNote: this.getDefaultWelcomeNote()}); - } + const getDefaultWelcomeNote = () => + props.workspaceInviteMessageDraft || + translate('workspace.inviteMessage.welcomeNote', { + workspaceName: props.policy.name, + }); - componentWillUnmount() { - if (!this.focusTimeout) { + useEffect(() => { + if (!_.isEmpty(props.invitedEmailsToAccountIDsDraft)) { + setWelcomeNote(getDefaultWelcomeNote()); return; } - clearTimeout(this.focusTimeout); - } + Navigation.goBack(ROUTES.WORKSPACE_INVITE.getRoute(props.route.params.policyID), true); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); - getDefaultWelcomeNote() { - return this.props.translate('workspace.inviteMessage.welcomeNote', { - workspaceName: this.props.policy.name, - }); - } + const debouncedSaveDraft = _.debounce((newDraft) => { + Policy.setWorkspaceInviteMessageDraft(props.route.params.policyID, newDraft); + }); - sendInvitation() { + const sendInvitation = () => { Keyboard.dismiss(); - Policy.addMembersToWorkspace(this.props.invitedEmailsToAccountIDsDraft, this.state.welcomeNote, this.props.route.params.policyID); - Policy.setWorkspaceInviteMembersDraft(this.props.route.params.policyID, {}); + Policy.addMembersToWorkspace(props.invitedEmailsToAccountIDsDraft, welcomeNote, props.route.params.policyID); + Policy.setWorkspaceInviteMembersDraft(props.route.params.policyID, {}); SearchInputManager.searchInput = ''; // Pop the invite message page before navigating to the members page. Navigation.goBack(ROUTES.HOME); - Navigation.navigate(ROUTES.WORKSPACE_MEMBERS.getRoute(this.props.route.params.policyID)); - } + Navigation.navigate(ROUTES.WORKSPACE_MEMBERS.getRoute(props.route.params.policyID)); + }; /** * Opens privacy url as an external link * @param {Object} event */ - openPrivacyURL(event) { + const openPrivacyURL = (event) => { event.preventDefault(); Link.openExternalLink(CONST.PRIVACY_URL); - } - - focusWelcomeMessageInput() { - this.focusTimeout = setTimeout(() => { - this.welcomeMessageInputRef.focus(); - // Below condition is needed for web, desktop and mweb only, for native cursor is set at end by default. - if (this.welcomeMessageInputRef.value && this.welcomeMessageInputRef.setSelectionRange) { - const length = this.welcomeMessageInputRef.value.length; - this.welcomeMessageInputRef.setSelectionRange(length, length); - } - }, CONST.ANIMATED_TRANSITION); - } + }; - validate() { + const validate = () => { const errorFields = {}; - if (_.isEmpty(this.props.invitedEmailsToAccountIDsDraft)) { + if (_.isEmpty(props.invitedEmailsToAccountIDsDraft)) { errorFields.welcomeMessage = 'workspace.inviteMessage.inviteNoMembersError'; } return errorFields; - } - - render() { - const policyName = lodashGet(this.props.policy, 'name'); - - return ( - + Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)} > - Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)} + Navigation.dismissModal()} + onBackButtonPress={() => Navigation.goBack(ROUTES.WORKSPACE_INVITE.getRoute(props.route.params.policyID))} + /> + + + {translate('common.privacy')} + + + } > - Navigation.dismissModal()} - onBackButtonPress={() => Navigation.goBack(ROUTES.WORKSPACE_INVITE.getRoute(this.props.route.params.policyID))} - /> - -
- - {this.props.translate('common.privacy')} - - - } - > - - - - - {this.props.translate('workspace.inviteMessage.inviteMessagePrompt')} - - - (this.welcomeMessageInputRef = el)} - role={CONST.ROLE.PRESENTATION} - inputID="welcomeMessage" - label={this.props.translate('workspace.inviteMessage.personalMessagePrompt')} - accessibilityLabel={this.props.translate('workspace.inviteMessage.personalMessagePrompt')} - autoCompleteType="off" - autoCorrect={false} - autoGrowHeight - containerStyles={[this.props.themeStyles.autoGrowHeightMultilineInput]} - defaultValue={this.state.welcomeNote} - value={this.state.welcomeNote} - onChangeText={(text) => { - this.debouncedSaveDraf(text); - this.setState({welcomeNote: text}); - }} - /> - -
-
-
- ); - } + + + + + {translate('workspace.inviteMessage.inviteMessagePrompt')} + + + { + setWelcomeNote(text); + debouncedSaveDraft(text); + }} + ref={(el) => { + if (!el) { + return; + } + inputCallbackRef(el); + updateMultilineInputRange(el); + }} + /> + + + + + ); } WorkspaceInviteMessagePage.propTypes = propTypes; @@ -252,7 +216,6 @@ WorkspaceInviteMessagePage.defaultProps = defaultProps; WorkspaceInviteMessagePage.displayName = 'WorkspaceInviteMessagePage'; export default compose( - withLocalize, withPolicyAndFullscreenLoading, withOnyx({ allPersonalDetails: { @@ -267,5 +230,4 @@ export default compose( }, }), withNavigationFocus, - withThemeStyles, )(WorkspaceInviteMessagePage);