From ecdafb4c738a908c38e48d852ccba16f38680642 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Tue, 9 May 2023 18:57:52 +0200
Subject: [PATCH 01/18] Add MenuItemWithTopDescription

---
 src/pages/ReportSettingsPage.js | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/pages/ReportSettingsPage.js b/src/pages/ReportSettingsPage.js
index dfb5c19f92ff..3cc1f666ba11 100644
--- a/src/pages/ReportSettingsPage.js
+++ b/src/pages/ReportSettingsPage.js
@@ -25,6 +25,8 @@ import reportPropTypes from './reportPropTypes';
 import withReportOrNotFound from './home/report/withReportOrNotFound';
 import Form from '../components/Form';
 import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView';
+import MenuItemWithTopDescription from "../components/MenuItemWithTopDescription";
+import ROUTES from "../ROUTES";
 
 const propTypes = {
     /** Route params */
@@ -145,7 +147,7 @@ class ReportSettingsPage extends Component {
     render() {
         const shouldShowRoomName = !ReportUtils.isPolicyExpenseChat(this.props.report);
         const linkedWorkspace = _.find(this.props.policies, policy => policy && policy.id === this.props.report.policyID);
-        const shouldDisableRename = this.shouldDisableRename(linkedWorkspace);
+        const shouldDisableRenameOrWelcomeMessage = this.shouldDisableRename(linkedWorkspace);
 
         return (
             <ScreenWrapper>
@@ -161,9 +163,9 @@ class ReportSettingsPage extends Component {
                         submitButtonText={this.props.translate('common.save')}
                         style={[styles.mh5, styles.mt5, styles.flexGrow1]}
                         validate={this.validate}
-                        onSubmit={values => !shouldDisableRename && this.updatePolicyRoomName(values)}
+                        onSubmit={values => !shouldDisableRenameOrWelcomeMessage && this.updatePolicyRoomName(values)}
                         scrollContextEnabled
-                        isSubmitButtonVisible={shouldShowRoomName && !shouldDisableRename}
+                        isSubmitButtonVisible={shouldShowRoomName && !shouldDisableRenameOrWelcomeMessage}
                         enabledWhenOffline
                     >
                         <View>
@@ -195,7 +197,7 @@ class ReportSettingsPage extends Component {
                                 >
                                     <View style={[styles.flexRow]}>
                                         <View style={[styles.flex3]}>
-                                            {shouldDisableRename ? (
+                                            {shouldDisableRenameOrWelcomeMessage ? (
                                                 <View>
                                                     <Text style={[styles.textLabelSupporting, styles.lh16, styles.mb1]} numberOfLines={1}>
                                                         {this.props.translate('newRoomPage.roomName')}
@@ -216,6 +218,14 @@ class ReportSettingsPage extends Component {
                                 </OfflineWithFeedback>
                             </View>
                         )}
+                        {!shouldDisableRenameOrWelcomeMessage && (
+                            <MenuItemWithTopDescription
+                                shouldShowRightIcon
+                                title={priorityModes[props.priorityMode].label}
+                                description={props.translate('priorityModePage.priorityMode')}
+                                onPress={() => Navigation.navigate(ROUTES.SETTINGS_PRIORITY_MODE)}
+                            />
+                        )}
                         {Boolean(linkedWorkspace) && (
                             <View style={[styles.mt4]}>
                                 <Text style={[styles.textLabelSupporting, styles.lh16, styles.mb1]} numberOfLines={1}>

From 258cac78813fd7602a35fd0b6ef77d00dc53c312 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Wed, 10 May 2023 13:05:59 +0200
Subject: [PATCH 02/18] Move menu itel to room menu instead

---
 src/CONST.js                    |  1 +
 src/languages/en.js             |  4 ++++
 src/languages/es.js             |  4 ++++
 src/pages/ReportDetailsPage.js  | 10 ++++++++++
 src/pages/ReportSettingsPage.js | 21 +++++++--------------
 5 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/src/CONST.js b/src/CONST.js
index abca3e1a5838..6c25c4234081 100755
--- a/src/CONST.js
+++ b/src/CONST.js
@@ -1089,6 +1089,7 @@ const CONST = {
         MEMBERS: 'member',
         SETTINGS: 'settings',
         LEAVE_ROOM: 'leaveRoom',
+        WELCOME_MESSAGE: 'welcomeMessage',
     },
 
     FOOTER: {
diff --git a/src/languages/en.js b/src/languages/en.js
index 3b48f890b05d..2ef49dd60bb1 100755
--- a/src/languages/en.js
+++ b/src/languages/en.js
@@ -572,6 +572,10 @@ export default {
             },
         },
     },
+    welcomeMessagePage: {
+        welcomeMessage: 'Welcome message',
+        explainerText: 'Choose whether to show all chats by default sorted with most recent with pinned items at the top, or #focus on unread pinned items, sorted alphabetically.',
+    },
     languagePage: {
         language: 'Language',
         languages: {
diff --git a/src/languages/es.js b/src/languages/es.js
index 1898baf8aced..97a36f6c359e 100644
--- a/src/languages/es.js
+++ b/src/languages/es.js
@@ -571,6 +571,10 @@ export default {
             },
         },
     },
+    welcomeMessagePage: {
+        welcomeMessage: 'Mensaje de bienvenida',
+        explainerText: 'Choose whether to show all chats by default sorted with most recent with pinned items at the top, or #focus on unread pinned items, sorted alphabetically.',
+    },
     languagePage: {
         language: 'Idioma',
         languages: {
diff --git a/src/pages/ReportDetailsPage.js b/src/pages/ReportDetailsPage.js
index 8dc81875fa6d..f7e8636639ea 100644
--- a/src/pages/ReportDetailsPage.js
+++ b/src/pages/ReportDetailsPage.js
@@ -82,7 +82,17 @@ class ReportDetailsPage extends Component {
             });
         }
 
+        // We only want policy owners and admins to be able to modify the welcome message.
         const policy = this.props.policies[`${ONYXKEYS.COLLECTION.POLICY}${this.props.report.policyID}`];
+        if (!ReportUtils.isArchivedRoom(this.props.report) && (Policy.isPolicyOwner(policy) && policy.role === CONST.POLICY.ROLE.ADMIN)) {
+            menuItems.push({
+                key: CONST.REPORT_DETAILS_MENU_ITEM.WELCOME_MESSAGE,
+                translationKey: 'welcomeMessagePage.welcomeMessage',
+                icon: Expensicons.ChatBubble,
+                action: () => { Navigation.navigate(ROUTES.getReportSettingsRoute(this.props.report.reportID)); },
+            });
+        }
+
         if (ReportUtils.isUserCreatedPolicyRoom(this.props.report) || ReportUtils.canLeaveRoom(this.props.report, !_.isEmpty(policy))) {
             menuItems.push({
                 key: CONST.REPORT_DETAILS_MENU_ITEM.LEAVE_ROOM,
diff --git a/src/pages/ReportSettingsPage.js b/src/pages/ReportSettingsPage.js
index 3cc1f666ba11..43aa8b55f353 100644
--- a/src/pages/ReportSettingsPage.js
+++ b/src/pages/ReportSettingsPage.js
@@ -25,8 +25,9 @@ import reportPropTypes from './reportPropTypes';
 import withReportOrNotFound from './home/report/withReportOrNotFound';
 import Form from '../components/Form';
 import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView';
-import MenuItemWithTopDescription from "../components/MenuItemWithTopDescription";
-import ROUTES from "../ROUTES";
+import ROUTES from '../ROUTES';
+import MenuItem from '../components/MenuItem';
+import * as Expensicons from '../components/Icon/Expensicons';
 
 const propTypes = {
     /** Route params */
@@ -147,7 +148,7 @@ class ReportSettingsPage extends Component {
     render() {
         const shouldShowRoomName = !ReportUtils.isPolicyExpenseChat(this.props.report);
         const linkedWorkspace = _.find(this.props.policies, policy => policy && policy.id === this.props.report.policyID);
-        const shouldDisableRenameOrWelcomeMessage = this.shouldDisableRename(linkedWorkspace);
+        const shouldDisableRename = this.shouldDisableRename(linkedWorkspace);
 
         return (
             <ScreenWrapper>
@@ -163,9 +164,9 @@ class ReportSettingsPage extends Component {
                         submitButtonText={this.props.translate('common.save')}
                         style={[styles.mh5, styles.mt5, styles.flexGrow1]}
                         validate={this.validate}
-                        onSubmit={values => !shouldDisableRenameOrWelcomeMessage && this.updatePolicyRoomName(values)}
+                        onSubmit={values => !shouldDisableRename && this.updatePolicyRoomName(values)}
                         scrollContextEnabled
-                        isSubmitButtonVisible={shouldShowRoomName && !shouldDisableRenameOrWelcomeMessage}
+                        isSubmitButtonVisible={shouldShowRoomName && !shouldDisableRename}
                         enabledWhenOffline
                     >
                         <View>
@@ -197,7 +198,7 @@ class ReportSettingsPage extends Component {
                                 >
                                     <View style={[styles.flexRow]}>
                                         <View style={[styles.flex3]}>
-                                            {shouldDisableRenameOrWelcomeMessage ? (
+                                            {shouldDisableRename ? (
                                                 <View>
                                                     <Text style={[styles.textLabelSupporting, styles.lh16, styles.mb1]} numberOfLines={1}>
                                                         {this.props.translate('newRoomPage.roomName')}
@@ -218,14 +219,6 @@ class ReportSettingsPage extends Component {
                                 </OfflineWithFeedback>
                             </View>
                         )}
-                        {!shouldDisableRenameOrWelcomeMessage && (
-                            <MenuItemWithTopDescription
-                                shouldShowRightIcon
-                                title={priorityModes[props.priorityMode].label}
-                                description={props.translate('priorityModePage.priorityMode')}
-                                onPress={() => Navigation.navigate(ROUTES.SETTINGS_PRIORITY_MODE)}
-                            />
-                        )}
                         {Boolean(linkedWorkspace) && (
                             <View style={[styles.mt4]}>
                                 <Text style={[styles.textLabelSupporting, styles.lh16, styles.mb1]} numberOfLines={1}>

From b43148e7d9d57cb71fa6584353eab407bdf982af Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Wed, 10 May 2023 13:24:36 +0200
Subject: [PATCH 03/18] Add new route

---
 src/ROUTES.js                                 |  2 +
 .../Navigation/AppNavigator/AuthScreens.js    |  6 ++
 .../AppNavigator/ModalStackNavigators.js      |  9 +++
 src/libs/Navigation/linkingConfig.js          |  5 ++
 src/pages/ReportDetailsPage.js                |  2 +-
 src/pages/ReportSettingsPage.js               |  3 -
 src/pages/ReportWelcomeMessagePage.js         | 71 +++++++++++++++++++
 7 files changed, 94 insertions(+), 4 deletions(-)
 create mode 100644 src/pages/ReportWelcomeMessagePage.js

diff --git a/src/ROUTES.js b/src/ROUTES.js
index b4ae96eb5967..5d84e9cc83da 100644
--- a/src/ROUTES.js
+++ b/src/ROUTES.js
@@ -115,6 +115,8 @@ export default {
     getReportDetailsRoute: reportID => `r/${reportID}/details`,
     REPORT_SETTINGS: 'r/:reportID/settings',
     getReportSettingsRoute: reportID => `r/${reportID}/settings`,
+    REPORT_WELCOME_MESSAGE: 'r/:reportID/welcomeMessage',
+    getReportWelcomeMessageRoute: reportID => `r/${reportID}/welcomeMessage`,
     TRANSITION_FROM_OLD_DOT: 'transition',
     VALIDATE_LOGIN: 'v/:accountID/:validateCode',
     GET_ASSISTANCE: 'get-assistance/:taskID',
diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js
index 99752b462c77..5e792b485ab6 100644
--- a/src/libs/Navigation/AppNavigator/AuthScreens.js
+++ b/src/libs/Navigation/AppNavigator/AuthScreens.js
@@ -287,6 +287,12 @@ class AuthScreens extends React.Component {
                     component={ModalStackNavigators.ReportSettingsModalStackNavigator}
                     listeners={modalScreenListeners}
                 />
+                <RootStack.Screen
+                    name="Report_WelcomeMessage"
+                    options={modalScreenOptions}
+                    component={ModalStackNavigators.ReportWelcomeMessageModalStackNavigator}
+                    listeners={modalScreenListeners}
+                />
                 <RootStack.Screen
                     name="Participants"
                     options={modalScreenOptions}
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
index 87fb89dfdee6..f0c49163ba52 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
@@ -177,6 +177,14 @@ const ReportSettingsModalStackNavigator = createModalStackNavigator([{
     name: 'Report_Settings_Root',
 }]);
 
+const ReportWelcomeMessageModalStackNavigator = createModalStackNavigator([{
+    getComponent: () => {
+        const ReportWelcomeMessagePage = require('../../../pages/ReportWelcomeMessagePage').default;
+        return ReportWelcomeMessagePage;
+    },
+    name: 'Report_WelcomeMessage_Root',
+}]);
+
 const ReportParticipantsModalStackNavigator = createModalStackNavigator([
     {
         getComponent: () => {
@@ -610,6 +618,7 @@ export {
     ReportDetailsModalStackNavigator,
     TaskModalStackNavigator,
     ReportSettingsModalStackNavigator,
+    ReportWelcomeMessageModalStackNavigator,
     ReportParticipantsModalStackNavigator,
     SearchModalStackNavigator,
     NewGroupModalStackNavigator,
diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js
index 9ce9c763a4d1..fada9e3279d2 100644
--- a/src/libs/Navigation/linkingConfig.js
+++ b/src/libs/Navigation/linkingConfig.js
@@ -200,6 +200,11 @@ export default {
                     Report_Settings_Root: ROUTES.REPORT_SETTINGS,
                 },
             },
+            Report_WelcomeMessage: {
+                screens: {
+                    Report_WelcomeMessage_Root: ROUTES.REPORT_WELCOME_MESSAGE,
+                },
+            },
             NewGroup: {
                 screens: {
                     NewGroup_Root: ROUTES.NEW_GROUP,
diff --git a/src/pages/ReportDetailsPage.js b/src/pages/ReportDetailsPage.js
index f7e8636639ea..29c1caf3c039 100644
--- a/src/pages/ReportDetailsPage.js
+++ b/src/pages/ReportDetailsPage.js
@@ -89,7 +89,7 @@ class ReportDetailsPage extends Component {
                 key: CONST.REPORT_DETAILS_MENU_ITEM.WELCOME_MESSAGE,
                 translationKey: 'welcomeMessagePage.welcomeMessage',
                 icon: Expensicons.ChatBubble,
-                action: () => { Navigation.navigate(ROUTES.getReportSettingsRoute(this.props.report.reportID)); },
+                action: () => { Navigation.navigate(ROUTES.getReportWelcomeMessageRoute(this.props.report.reportID)); },
             });
         }
 
diff --git a/src/pages/ReportSettingsPage.js b/src/pages/ReportSettingsPage.js
index 43aa8b55f353..dfb5c19f92ff 100644
--- a/src/pages/ReportSettingsPage.js
+++ b/src/pages/ReportSettingsPage.js
@@ -25,9 +25,6 @@ import reportPropTypes from './reportPropTypes';
 import withReportOrNotFound from './home/report/withReportOrNotFound';
 import Form from '../components/Form';
 import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView';
-import ROUTES from '../ROUTES';
-import MenuItem from '../components/MenuItem';
-import * as Expensicons from '../components/Icon/Expensicons';
 
 const propTypes = {
     /** Route params */
diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
new file mode 100644
index 000000000000..c669fd031930
--- /dev/null
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -0,0 +1,71 @@
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import {withOnyx} from 'react-native-onyx';
+import _ from 'underscore';
+import {ScrollView} from 'react-native';
+import compose from '../libs/compose';
+import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
+import ONYXKEYS from '../ONYXKEYS';
+import ScreenWrapper from '../components/ScreenWrapper';
+import Navigation from '../libs/Navigation/Navigation';
+import HeaderWithCloseButton from '../components/HeaderWithCloseButton';
+import styles from '../styles/styles';
+import reportPropTypes from './reportPropTypes';
+import withReportOrNotFound from './home/report/withReportOrNotFound';
+import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView';
+
+const propTypes = {
+    ...withLocalizePropTypes,
+
+    /** The report currently being looked at */
+    report: reportPropTypes.isRequired,
+
+    /** The policies which the user has access to and which the report could be tied to */
+    policies: PropTypes.shape({
+        /** Name of the policy */
+        name: PropTypes.string,
+    }),
+
+    /** Route params */
+    route: PropTypes.shape({
+        params: PropTypes.shape({
+            /** Report ID passed via route r/:reportID/details */
+            reportID: PropTypes.string,
+        }),
+    }).isRequired,
+};
+
+const defaultProps = {
+    policies: {},
+};
+
+class ReportWelcomeMessagePage extends Component {
+    render() {
+        return (
+            <ScreenWrapper>
+                <FullPageNotFoundView shouldShow={_.isEmpty(this.props.report)}>
+                    <HeaderWithCloseButton
+                        title={this.props.translate('common.details')}
+                        onBackButtonPress={() => Navigation.goBack()}
+                        onCloseButtonPress={() => Navigation.dismissModal()}
+                    />
+                    <ScrollView style={[styles.flex1]}>
+                        <Text>Example</Text>
+                    </ScrollView>
+                </FullPageNotFoundView>
+            </ScreenWrapper>
+        );
+    }
+}
+
+ReportWelcomeMessagePage.propTypes = propTypes;
+ReportWelcomeMessagePage.defaultProps = defaultProps;
+export default compose(
+    withLocalize,
+    withReportOrNotFound,
+    withOnyx({
+        policies: {
+            key: ONYXKEYS.COLLECTION.POLICY,
+        },
+    }),
+)(ReportWelcomeMessagePage);

From 44fc179e9c7970e05c5f32ded8aa030155ef23c4 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Wed, 10 May 2023 13:40:29 +0200
Subject: [PATCH 04/18] use hooks

---
 src/languages/en.js                   |  2 +-
 src/languages/es.js                   |  2 +-
 src/pages/ReportWelcomeMessagePage.js | 48 +++++++++++++++++----------
 3 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/src/languages/en.js b/src/languages/en.js
index 2ef49dd60bb1..8e57cc99f8c9 100755
--- a/src/languages/en.js
+++ b/src/languages/en.js
@@ -574,7 +574,7 @@ export default {
     },
     welcomeMessagePage: {
         welcomeMessage: 'Welcome message',
-        explainerText: 'Choose whether to show all chats by default sorted with most recent with pinned items at the top, or #focus on unread pinned items, sorted alphabetically.',
+        explainerText: 'Set a custom welcome message that will be sent users when they join this room.',
     },
     languagePage: {
         language: 'Language',
diff --git a/src/languages/es.js b/src/languages/es.js
index 97a36f6c359e..486329e7aa92 100644
--- a/src/languages/es.js
+++ b/src/languages/es.js
@@ -573,7 +573,7 @@ export default {
     },
     welcomeMessagePage: {
         welcomeMessage: 'Mensaje de bienvenida',
-        explainerText: 'Choose whether to show all chats by default sorted with most recent with pinned items at the top, or #focus on unread pinned items, sorted alphabetically.',
+        explainerText: 'Set a custom welcome message that will be sent users when they join this room.',
     },
     languagePage: {
         language: 'Idioma',
diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index c669fd031930..9334d4fc8312 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -1,4 +1,6 @@
-import React, {Component} from 'react';
+import React, {
+    useCallback, useMemo, useRef, useState,
+} from 'react';
 import PropTypes from 'prop-types';
 import {withOnyx} from 'react-native-onyx';
 import _ from 'underscore';
@@ -39,23 +41,33 @@ const defaultProps = {
     policies: {},
 };
 
-class ReportWelcomeMessagePage extends Component {
-    render() {
-        return (
-            <ScreenWrapper>
-                <FullPageNotFoundView shouldShow={_.isEmpty(this.props.report)}>
-                    <HeaderWithCloseButton
-                        title={this.props.translate('common.details')}
-                        onBackButtonPress={() => Navigation.goBack()}
-                        onCloseButtonPress={() => Navigation.dismissModal()}
-                    />
-                    <ScrollView style={[styles.flex1]}>
-                        <Text>Example</Text>
-                    </ScrollView>
-                </FullPageNotFoundView>
-            </ScreenWrapper>
-        );
-    }
+function ReportWelcomeMessagePage(props) {
+    const [welcomeMessage, setWelcomeMessage] = useState('');
+
+    const handleWelcomeMessageChange = useCallback((value) => {
+        setWelcomeMessage(value);
+    }, []);
+
+    const submitForm = useCallback(() => {
+        // TODO: Save welcome message
+    }, [welcomeMessage]);
+
+    return (
+        <ScreenWrapper>
+            <FullPageNotFoundView shouldShow={_.isEmpty(this.props.report)}>
+                <HeaderWithCloseButton
+                    title={props.translate('welcomeMessagePage.welcomeMessage')}
+                    onBackButtonPress={() => Navigation.goBack()}
+                    onCloseButtonPress={() => Navigation.dismissModal()}
+                />
+                <ScrollView style={[styles.flex1]}>
+                    <Text style={[styles.ph5, styles.mb5]}>
+                        {props.translate('welcomeMessagePage.explainerText')}
+                    </Text>
+                </ScrollView>
+            </FullPageNotFoundView>
+        </ScreenWrapper>
+    );
 }
 
 ReportWelcomeMessagePage.propTypes = propTypes;

From 86f683defc2fe3e035ad8dd01c428e1be8a14bef Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Wed, 10 May 2023 13:50:58 +0200
Subject: [PATCH 05/18] Add elements to return

---
 src/pages/ReportWelcomeMessagePage.js | 35 ++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index 9334d4fc8312..89a66ef658e2 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -1,10 +1,10 @@
 import React, {
-    useCallback, useMemo, useRef, useState,
+    useCallback, useRef, useState,
 } from 'react';
 import PropTypes from 'prop-types';
 import {withOnyx} from 'react-native-onyx';
 import _ from 'underscore';
-import {ScrollView} from 'react-native';
+import {ScrollView, TextInput, View} from 'react-native';
 import compose from '../libs/compose';
 import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
 import ONYXKEYS from '../ONYXKEYS';
@@ -15,6 +15,8 @@ import styles from '../styles/styles';
 import reportPropTypes from './reportPropTypes';
 import withReportOrNotFound from './home/report/withReportOrNotFound';
 import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView';
+import FixedFooter from '../components/FixedFooter';
+import Button from '../components/Button';
 
 const propTypes = {
     ...withLocalizePropTypes,
@@ -43,6 +45,7 @@ const defaultProps = {
 
 function ReportWelcomeMessagePage(props) {
     const [welcomeMessage, setWelcomeMessage] = useState('');
+    const welcomeMessageInputRef = useRef(null);
 
     const handleWelcomeMessageChange = useCallback((value) => {
         setWelcomeMessage(value);
@@ -53,7 +56,14 @@ function ReportWelcomeMessagePage(props) {
     }, [welcomeMessage]);
 
     return (
-        <ScreenWrapper>
+        <ScreenWrapper
+            onTransitionEnd={() => {
+                if (!welcomeMessageInputRef.current) {
+                    return;
+                }
+                welcomeMessageInputRef.current.focus();
+            }}
+        >
             <FullPageNotFoundView shouldShow={_.isEmpty(this.props.report)}>
                 <HeaderWithCloseButton
                     title={props.translate('welcomeMessagePage.welcomeMessage')}
@@ -64,7 +74,26 @@ function ReportWelcomeMessagePage(props) {
                     <Text style={[styles.ph5, styles.mb5]}>
                         {props.translate('welcomeMessagePage.explainerText')}
                     </Text>
+                    <View style={[styles.ph5, styles.mb6]}>
+                        <TextInput
+                            label={props.translate('welcomeMessagePage.welcomeMessage')}
+                            multiline
+                            numberOfLines={4}
+                            ref={welcomeMessageInputRef}
+                            value={welcomeMessage}
+                            onChangeText={handleWelcomeMessageChange}
+                            autoCapitalize="none"
+                        />
+                    </View>
                 </ScrollView>
+                <FixedFooter style={[styles.flexGrow0]}>
+                    <Button
+                        success
+                        text={props.translate('common.save')}
+                        onPress={submitForm}
+                        pressOnEnter
+                    />
+                </FixedFooter>
             </FullPageNotFoundView>
         </ScreenWrapper>
     );

From 8def699542853f066bff32aa8e454b452dc8bab4 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Wed, 10 May 2023 14:19:16 +0200
Subject: [PATCH 06/18] Fix component for text area

---
 src/languages/es.js                   |  2 +-
 src/pages/ReportWelcomeMessagePage.js | 10 ++++++----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/languages/es.js b/src/languages/es.js
index 486329e7aa92..4de3c1ae5dd1 100644
--- a/src/languages/es.js
+++ b/src/languages/es.js
@@ -573,7 +573,7 @@ export default {
     },
     welcomeMessagePage: {
         welcomeMessage: 'Mensaje de bienvenida',
-        explainerText: 'Set a custom welcome message that will be sent users when they join this room.',
+        explainerText: 'Configura un mensaje de bienvenida privado y personalizado que se enviará cuando los usuarios se unan a esta sala de chat.',
     },
     languagePage: {
         language: 'Idioma',
diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index 89a66ef658e2..ebbdc04fb1ad 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -4,7 +4,7 @@ import React, {
 import PropTypes from 'prop-types';
 import {withOnyx} from 'react-native-onyx';
 import _ from 'underscore';
-import {ScrollView, TextInput, View} from 'react-native';
+import {ScrollView, View} from 'react-native';
 import compose from '../libs/compose';
 import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
 import ONYXKEYS from '../ONYXKEYS';
@@ -17,6 +17,8 @@ import withReportOrNotFound from './home/report/withReportOrNotFound';
 import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView';
 import FixedFooter from '../components/FixedFooter';
 import Button from '../components/Button';
+import Text from '../components/Text';
+import TextInput from '../components/TextInput';
 
 const propTypes = {
     ...withLocalizePropTypes,
@@ -33,7 +35,7 @@ const propTypes = {
     /** Route params */
     route: PropTypes.shape({
         params: PropTypes.shape({
-            /** Report ID passed via route r/:reportID/details */
+            /** Report ID passed via route r/:reportID/welcomeMessage */
             reportID: PropTypes.string,
         }),
     }).isRequired,
@@ -64,7 +66,7 @@ function ReportWelcomeMessagePage(props) {
                 welcomeMessageInputRef.current.focus();
             }}
         >
-            <FullPageNotFoundView shouldShow={_.isEmpty(this.props.report)}>
+            <FullPageNotFoundView shouldShow={_.isEmpty(props.report)}>
                 <HeaderWithCloseButton
                     title={props.translate('welcomeMessagePage.welcomeMessage')}
                     onBackButtonPress={() => Navigation.goBack()}
@@ -78,7 +80,7 @@ function ReportWelcomeMessagePage(props) {
                         <TextInput
                             label={props.translate('welcomeMessagePage.welcomeMessage')}
                             multiline
-                            numberOfLines={4}
+                            numberOfLines={8}
                             ref={welcomeMessageInputRef}
                             value={welcomeMessage}
                             onChangeText={handleWelcomeMessageChange}

From c026928c4a2a085854ee8e573e42552ce19a54cd Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Wed, 10 May 2023 14:48:07 +0200
Subject: [PATCH 07/18] Add endpoint

---
 src/libs/actions/Report.js            | 24 ++++++++++++++++++++++++
 src/pages/ReportWelcomeMessagePage.js |  3 ++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js
index 7eff22d315c0..d58c9d06d368 100644
--- a/src/libs/actions/Report.js
+++ b/src/libs/actions/Report.js
@@ -1023,6 +1023,29 @@ function updateNotificationPreference(reportID, previousValue, newValue) {
     API.write('UpdateReportNotificationPreference', {reportID, notificationPreference: newValue}, {optimisticData, failureData});
 }
 
+/**
+ * @param {String} reportID
+ * @param {String} previousValue
+ * @param {String} newValue
+ */
+function updateWelcomeMessage(reportID, previousValue, newValue) {
+    const optimisticData = [
+        {
+            onyxMethod: Onyx.METHOD.MERGE,
+            key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
+            value: {welcomeMessage: newValue},
+        },
+    ];
+    const failureData = [
+        {
+            onyxMethod: Onyx.METHOD.MERGE,
+            key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
+            value: {welcomeMessage: previousValue},
+        },
+    ];
+    API.write('UpdateWelcomeMessage', {reportID, welcomeMessage: newValue}, {optimisticData, failureData});
+}
+
 /**
  * Navigates to the 1:1 report with Concierge
  */
@@ -1505,6 +1528,7 @@ export {
     addAttachment,
     reconnect,
     updateNotificationPreference,
+    updateWelcomeMessage,
     subscribeToReportTypingEvents,
     unsubscribeFromReportChannel,
     saveReportComment,
diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index ebbdc04fb1ad..5beac3e33683 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -19,6 +19,7 @@ import FixedFooter from '../components/FixedFooter';
 import Button from '../components/Button';
 import Text from '../components/Text';
 import TextInput from '../components/TextInput';
+import * as Report from '../libs/actions/Report';
 
 const propTypes = {
     ...withLocalizePropTypes,
@@ -54,7 +55,7 @@ function ReportWelcomeMessagePage(props) {
     }, []);
 
     const submitForm = useCallback(() => {
-        // TODO: Save welcome message
+        Report.updateWelcomeMessage(props.report.reportID, props.report.welcomeMessage, welcomeMessage);
     }, [welcomeMessage]);
 
     return (

From ff4172c20335f0e1ec9f68cee586994c8bd86932 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Wed, 10 May 2023 15:13:06 +0200
Subject: [PATCH 08/18] Parse message

---
 src/libs/actions/Report.js            |  5 ++++-
 src/pages/ReportWelcomeMessagePage.js | 16 ----------------
 2 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js
index d58c9d06d368..2be7efb7ecdb 100644
--- a/src/libs/actions/Report.js
+++ b/src/libs/actions/Report.js
@@ -21,6 +21,7 @@ import * as ReportActionsUtils from '../ReportActionsUtils';
 import * as OptionsListUtils from '../OptionsListUtils';
 import * as Localize from '../Localize';
 import * as CollectionUtils from '../CollectionUtils';
+import {getParsedComment} from "../ReportUtils";
 
 let currentUserEmail;
 let currentUserAccountID;
@@ -1029,6 +1030,7 @@ function updateNotificationPreference(reportID, previousValue, newValue) {
  * @param {String} newValue
  */
 function updateWelcomeMessage(reportID, previousValue, newValue) {
+    const parsedWelcomeMessage = ReportUtils.getParsedComment(newValue);
     const optimisticData = [
         {
             onyxMethod: Onyx.METHOD.MERGE,
@@ -1043,7 +1045,8 @@ function updateWelcomeMessage(reportID, previousValue, newValue) {
             value: {welcomeMessage: previousValue},
         },
     ];
-    API.write('UpdateWelcomeMessage', {reportID, welcomeMessage: newValue}, {optimisticData, failureData});
+    API.write('UpdateWelcomeMessage', {reportID, welcomeMessage: parsedWelcomeMessage}, {optimisticData, failureData});
+    Navigation.goBack();
 }
 
 /**
diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index 5beac3e33683..9ad95dfb4014 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -27,12 +27,6 @@ const propTypes = {
     /** The report currently being looked at */
     report: reportPropTypes.isRequired,
 
-    /** The policies which the user has access to and which the report could be tied to */
-    policies: PropTypes.shape({
-        /** Name of the policy */
-        name: PropTypes.string,
-    }),
-
     /** Route params */
     route: PropTypes.shape({
         params: PropTypes.shape({
@@ -42,10 +36,6 @@ const propTypes = {
     }).isRequired,
 };
 
-const defaultProps = {
-    policies: {},
-};
-
 function ReportWelcomeMessagePage(props) {
     const [welcomeMessage, setWelcomeMessage] = useState('');
     const welcomeMessageInputRef = useRef(null);
@@ -103,13 +93,7 @@ function ReportWelcomeMessagePage(props) {
 }
 
 ReportWelcomeMessagePage.propTypes = propTypes;
-ReportWelcomeMessagePage.defaultProps = defaultProps;
 export default compose(
     withLocalize,
     withReportOrNotFound,
-    withOnyx({
-        policies: {
-            key: ONYXKEYS.COLLECTION.POLICY,
-        },
-    }),
 )(ReportWelcomeMessagePage);

From cb0b74e709ec592bd8638a0eae29d41f12d91b35 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Wed, 10 May 2023 17:11:05 +0200
Subject: [PATCH 09/18] Persist message

---
 src/pages/ReportDetailsPage.js        | 2 +-
 src/pages/ReportWelcomeMessagePage.js | 6 ++----
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/pages/ReportDetailsPage.js b/src/pages/ReportDetailsPage.js
index 29c1caf3c039..95f85411f65a 100644
--- a/src/pages/ReportDetailsPage.js
+++ b/src/pages/ReportDetailsPage.js
@@ -84,7 +84,7 @@ class ReportDetailsPage extends Component {
 
         // We only want policy owners and admins to be able to modify the welcome message.
         const policy = this.props.policies[`${ONYXKEYS.COLLECTION.POLICY}${this.props.report.policyID}`];
-        if (!ReportUtils.isArchivedRoom(this.props.report) && (Policy.isPolicyOwner(policy) && policy.role === CONST.POLICY.ROLE.ADMIN)) {
+        if (!ReportUtils.isArchivedRoom(this.props.report) && !_.isEmpty(policy) && Policy.isPolicyOwner(policy) && policy.role === CONST.POLICY.ROLE.ADMIN) {
             menuItems.push({
                 key: CONST.REPORT_DETAILS_MENU_ITEM.WELCOME_MESSAGE,
                 translationKey: 'welcomeMessagePage.welcomeMessage',
diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index 9ad95dfb4014..9b8ebbd259a9 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -2,12 +2,10 @@ import React, {
     useCallback, useRef, useState,
 } from 'react';
 import PropTypes from 'prop-types';
-import {withOnyx} from 'react-native-onyx';
 import _ from 'underscore';
 import {ScrollView, View} from 'react-native';
 import compose from '../libs/compose';
 import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
-import ONYXKEYS from '../ONYXKEYS';
 import ScreenWrapper from '../components/ScreenWrapper';
 import Navigation from '../libs/Navigation/Navigation';
 import HeaderWithCloseButton from '../components/HeaderWithCloseButton';
@@ -37,7 +35,7 @@ const propTypes = {
 };
 
 function ReportWelcomeMessagePage(props) {
-    const [welcomeMessage, setWelcomeMessage] = useState('');
+    const [welcomeMessage, setWelcomeMessage] = useState(props.report.welcomeMessage);
     const welcomeMessageInputRef = useRef(null);
 
     const handleWelcomeMessageChange = useCallback((value) => {
@@ -46,7 +44,7 @@ function ReportWelcomeMessagePage(props) {
 
     const submitForm = useCallback(() => {
         Report.updateWelcomeMessage(props.report.reportID, props.report.welcomeMessage, welcomeMessage);
-    }, [welcomeMessage]);
+    }, [props.report.reportID, props.report.welcomeMessage, welcomeMessage]);
 
     return (
         <ScreenWrapper

From f58dbbba6a4df9b2f3e52e5b27adf08d88786c10 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Wed, 10 May 2023 17:45:20 +0200
Subject: [PATCH 10/18] Prettier

---
 src/ROUTES.js                                      |  2 +-
 .../AppNavigator/ModalStackNavigators.js           | 14 ++++++++------
 src/libs/OptionsListUtils.js                       |  2 +-
 src/libs/actions/Report.js                         |  2 +-
 src/pages/ReportDetailsPage.js                     |  4 +++-
 src/pages/ReportWelcomeMessagePage.js              | 13 +++----------
 6 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/src/ROUTES.js b/src/ROUTES.js
index 54128d30fdc8..84c0e994b30c 100644
--- a/src/ROUTES.js
+++ b/src/ROUTES.js
@@ -116,7 +116,7 @@ export default {
     REPORT_SETTINGS: 'r/:reportID/settings',
     getReportSettingsRoute: (reportID) => `r/${reportID}/settings`,
     REPORT_WELCOME_MESSAGE: 'r/:reportID/welcomeMessage',
-    getReportWelcomeMessageRoute: reportID => `r/${reportID}/welcomeMessage`,
+    getReportWelcomeMessageRoute: (reportID) => `r/${reportID}/welcomeMessage`,
     TRANSITION_FROM_OLD_DOT: 'transition',
     VALIDATE_LOGIN: 'v/:accountID/:validateCode',
     GET_ASSISTANCE: 'get-assistance/:taskID',
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
index c9f9a7d655d7..ad5f30ac0597 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
@@ -189,13 +189,15 @@ const ReportSettingsModalStackNavigator = createModalStackNavigator([
     },
 ]);
 
-const ReportWelcomeMessageModalStackNavigator = createModalStackNavigator([{
-    getComponent: () => {
-        const ReportWelcomeMessagePage = require('../../../pages/ReportWelcomeMessagePage').default;
-        return ReportWelcomeMessagePage;
+const ReportWelcomeMessageModalStackNavigator = createModalStackNavigator([
+    {
+        getComponent: () => {
+            const ReportWelcomeMessagePage = require('../../../pages/ReportWelcomeMessagePage').default;
+            return ReportWelcomeMessagePage;
+        },
+        name: 'Report_WelcomeMessage_Root',
     },
-    name: 'Report_WelcomeMessage_Root',
-}]);
+]);
 
 const ReportParticipantsModalStackNavigator = createModalStackNavigator([
     {
diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js
index 5a2652a56580..9839482efcae 100644
--- a/src/libs/OptionsListUtils.js
+++ b/src/libs/OptionsListUtils.js
@@ -195,7 +195,7 @@ function getPersonalDetailsForLogins(logins, personalDetails) {
  * @returns {boolean}
  */
 function isPersonalDetailsReady(personalDetails) {
-    return !_.isEmpty(personalDetails) && !_.some(_.keys(personalDetails), key => !personalDetails[key].login);
+    return !_.isEmpty(personalDetails) && !_.some(_.keys(personalDetails), (key) => !personalDetails[key].login);
 }
 
 /**
diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js
index 6c79bd0598fe..721578e62bd4 100644
--- a/src/libs/actions/Report.js
+++ b/src/libs/actions/Report.js
@@ -21,7 +21,7 @@ import * as ReportActionsUtils from '../ReportActionsUtils';
 import * as OptionsListUtils from '../OptionsListUtils';
 import * as Localize from '../Localize';
 import * as CollectionUtils from '../CollectionUtils';
-import {getParsedComment} from "../ReportUtils";
+import {getParsedComment} from '../ReportUtils';
 
 let currentUserEmail;
 let currentUserAccountID;
diff --git a/src/pages/ReportDetailsPage.js b/src/pages/ReportDetailsPage.js
index 25618130fee4..ac750e9a1d0f 100644
--- a/src/pages/ReportDetailsPage.js
+++ b/src/pages/ReportDetailsPage.js
@@ -93,7 +93,9 @@ class ReportDetailsPage extends Component {
                 key: CONST.REPORT_DETAILS_MENU_ITEM.WELCOME_MESSAGE,
                 translationKey: 'welcomeMessagePage.welcomeMessage',
                 icon: Expensicons.ChatBubble,
-                action: () => { Navigation.navigate(ROUTES.getReportWelcomeMessageRoute(this.props.report.reportID)); },
+                action: () => {
+                    Navigation.navigate(ROUTES.getReportWelcomeMessageRoute(this.props.report.reportID));
+                },
             });
         }
 
diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index 9b8ebbd259a9..0ecaab0f80c6 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -1,6 +1,4 @@
-import React, {
-    useCallback, useRef, useState,
-} from 'react';
+import React, {useCallback, useRef, useState} from 'react';
 import PropTypes from 'prop-types';
 import _ from 'underscore';
 import {ScrollView, View} from 'react-native';
@@ -62,9 +60,7 @@ function ReportWelcomeMessagePage(props) {
                     onCloseButtonPress={() => Navigation.dismissModal()}
                 />
                 <ScrollView style={[styles.flex1]}>
-                    <Text style={[styles.ph5, styles.mb5]}>
-                        {props.translate('welcomeMessagePage.explainerText')}
-                    </Text>
+                    <Text style={[styles.ph5, styles.mb5]}>{props.translate('welcomeMessagePage.explainerText')}</Text>
                     <View style={[styles.ph5, styles.mb6]}>
                         <TextInput
                             label={props.translate('welcomeMessagePage.welcomeMessage')}
@@ -91,7 +87,4 @@ function ReportWelcomeMessagePage(props) {
 }
 
 ReportWelcomeMessagePage.propTypes = propTypes;
-export default compose(
-    withLocalize,
-    withReportOrNotFound,
-)(ReportWelcomeMessagePage);
+export default compose(withLocalize, withReportOrNotFound)(ReportWelcomeMessagePage);

From 3227895a5f2e1500ee43d246a82f5af70aeefe38 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Wed, 10 May 2023 18:27:34 +0200
Subject: [PATCH 11/18] Linter

---
 src/libs/actions/Report.js            | 1 -
 src/pages/ReportWelcomeMessagePage.js | 3 ++-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js
index 721578e62bd4..c20c282dc213 100644
--- a/src/libs/actions/Report.js
+++ b/src/libs/actions/Report.js
@@ -21,7 +21,6 @@ import * as ReportActionsUtils from '../ReportActionsUtils';
 import * as OptionsListUtils from '../OptionsListUtils';
 import * as Localize from '../Localize';
 import * as CollectionUtils from '../CollectionUtils';
-import {getParsedComment} from '../ReportUtils';
 
 let currentUserEmail;
 let currentUserAccountID;
diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index 0ecaab0f80c6..d5ce9baa50bc 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -2,6 +2,7 @@ import React, {useCallback, useRef, useState} from 'react';
 import PropTypes from 'prop-types';
 import _ from 'underscore';
 import {ScrollView, View} from 'react-native';
+import Str from "expensify-common/lib/str";
 import compose from '../libs/compose';
 import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
 import ScreenWrapper from '../components/ScreenWrapper';
@@ -33,7 +34,7 @@ const propTypes = {
 };
 
 function ReportWelcomeMessagePage(props) {
-    const [welcomeMessage, setWelcomeMessage] = useState(props.report.welcomeMessage);
+    const [welcomeMessage, setWelcomeMessage] = useState(Str.htmlDecode(props.report.welcomeMessage));
     const welcomeMessageInputRef = useRef(null);
 
     const handleWelcomeMessageChange = useCallback((value) => {

From 4aa46652592b901ca345ff80278679e8785ff657 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Thu, 18 May 2023 16:57:33 +0200
Subject: [PATCH 12/18] Move welcome message to Settings

---
 src/pages/ReportDetailsPage.js                | 12 -----------
 .../settings/Report/ReportSettingsPage.js     | 21 +++++++++++++++++++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/src/pages/ReportDetailsPage.js b/src/pages/ReportDetailsPage.js
index 2209ebcad31e..11badcede40b 100644
--- a/src/pages/ReportDetailsPage.js
+++ b/src/pages/ReportDetailsPage.js
@@ -93,19 +93,7 @@ class ReportDetailsPage extends Component {
             });
         }
 
-        // We only want policy owners and admins to be able to modify the welcome message.
         const policy = this.props.policies[`${ONYXKEYS.COLLECTION.POLICY}${this.props.report.policyID}`];
-        if (!ReportUtils.isArchivedRoom(this.props.report) && !_.isEmpty(policy) && Policy.isPolicyOwner(policy) && policy.role === CONST.POLICY.ROLE.ADMIN) {
-            menuItems.push({
-                key: CONST.REPORT_DETAILS_MENU_ITEM.WELCOME_MESSAGE,
-                translationKey: 'welcomeMessagePage.welcomeMessage',
-                icon: Expensicons.ChatBubble,
-                action: () => {
-                    Navigation.navigate(ROUTES.getReportWelcomeMessageRoute(this.props.report.reportID));
-                },
-            });
-        }
-
         const isThread = ReportUtils.isThread(this.props.report);
         if (ReportUtils.isUserCreatedPolicyRoom(this.props.report) || ReportUtils.canLeaveRoom(this.props.report, !_.isEmpty(policy)) || isThread) {
             menuItems.push({
diff --git a/src/pages/settings/Report/ReportSettingsPage.js b/src/pages/settings/Report/ReportSettingsPage.js
index 07ccf07d4db3..3b7016ca4a88 100644
--- a/src/pages/settings/Report/ReportSettingsPage.js
+++ b/src/pages/settings/Report/ReportSettingsPage.js
@@ -22,6 +22,8 @@ import withReportOrNotFound from '../../home/report/withReportOrNotFound';
 import FullPageNotFoundView from '../../../components/BlockingViews/FullPageNotFoundView';
 import MenuItemWithTopDescription from '../../../components/MenuItemWithTopDescription';
 import ROUTES from '../../../ROUTES';
+import * as Expensicons from "../../../components/Icon/Expensicons";
+import MenuItem from "../../../components/MenuItem";
 
 const propTypes = {
     /** Route params */
@@ -79,11 +81,22 @@ class ReportSettingsPage extends Component {
         return !Policy.isPolicyOwner(linkedWorkspace) && linkedWorkspace.role !== CONST.POLICY.ROLE.ADMIN;
     }
 
+    /**
+     * We only want policy owners and admins to be able to modify the welcome message.
+     *
+     * @param {Object|null} linkedWorkspace - the workspace the report is on, null if the user isn't a member of the workspace
+     * @returns {Boolean}
+     */
+    shouldDisableWelcomeMessage(linkedWorkspace) {
+        return !ReportUtils.isArchivedRoom(this.props.report) && !_.isEmpty(linkedWorkspace) && Policy.isPolicyOwner(linkedWorkspace) && linkedWorkspace.role === CONST.POLICY.ROLE.ADMIN;
+    }
+
     render() {
         const shouldShowRoomName = !ReportUtils.isPolicyExpenseChat(this.props.report) && !ReportUtils.isThread(this.props.report);
         const linkedWorkspace = _.find(this.props.policies, (policy) => policy && policy.id === this.props.report.policyID);
         const shouldDisableRename = this.shouldDisableRename(linkedWorkspace) || ReportUtils.isThread(this.props.report);
         const notificationPreference = this.props.translate(`notificationPreferencesPage.notificationPreferences.${this.props.report.notificationPreference}`);
+        const shouldDisableWelcomeMessage = this.shouldDisableRename(linkedWorkspace);
 
         return (
             <ScreenWrapper>
@@ -169,6 +182,14 @@ class ReportSettingsPage extends Component {
                                 </Text>
                             </View>
                         )}
+                        {!shouldDisableWelcomeMessage && (
+                            <MenuItem
+                                title={this.props.translate('welcomeMessagePage.welcomeMessage')}
+                                icon={Expensicons.ChatBubble}
+                                onPress={() => Navigation.navigate(ROUTES.getReportWelcomeMessageRoute(this.props.report.reportID))}
+                                shouldShowRightIcon
+                            />
+                        )}
                     </View>
                 </FullPageNotFoundView>
             </ScreenWrapper>

From b159e3b99ec2e8a36f5c4663a3ec027a5d2af055 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Thu, 18 May 2023 17:17:42 +0200
Subject: [PATCH 13/18] Prettier

---
 src/pages/ReportWelcomeMessagePage.js         |  2 +-
 .../settings/Report/ReportSettingsPage.js     | 20 +++++++++----------
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index d5ce9baa50bc..989d40b41977 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -2,7 +2,7 @@ import React, {useCallback, useRef, useState} from 'react';
 import PropTypes from 'prop-types';
 import _ from 'underscore';
 import {ScrollView, View} from 'react-native';
-import Str from "expensify-common/lib/str";
+import Str from 'expensify-common/lib/str';
 import compose from '../libs/compose';
 import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
 import ScreenWrapper from '../components/ScreenWrapper';
diff --git a/src/pages/settings/Report/ReportSettingsPage.js b/src/pages/settings/Report/ReportSettingsPage.js
index 3b7016ca4a88..9e339d919952 100644
--- a/src/pages/settings/Report/ReportSettingsPage.js
+++ b/src/pages/settings/Report/ReportSettingsPage.js
@@ -22,8 +22,8 @@ import withReportOrNotFound from '../../home/report/withReportOrNotFound';
 import FullPageNotFoundView from '../../../components/BlockingViews/FullPageNotFoundView';
 import MenuItemWithTopDescription from '../../../components/MenuItemWithTopDescription';
 import ROUTES from '../../../ROUTES';
-import * as Expensicons from "../../../components/Icon/Expensicons";
-import MenuItem from "../../../components/MenuItem";
+import * as Expensicons from '../../../components/Icon/Expensicons';
+import MenuItem from '../../../components/MenuItem';
 
 const propTypes = {
     /** Route params */
@@ -182,15 +182,15 @@ class ReportSettingsPage extends Component {
                                 </Text>
                             </View>
                         )}
-                        {!shouldDisableWelcomeMessage && (
-                            <MenuItem
-                                title={this.props.translate('welcomeMessagePage.welcomeMessage')}
-                                icon={Expensicons.ChatBubble}
-                                onPress={() => Navigation.navigate(ROUTES.getReportWelcomeMessageRoute(this.props.report.reportID))}
-                                shouldShowRightIcon
-                            />
-                        )}
                     </View>
+                    {!shouldDisableWelcomeMessage && (
+                        <MenuItem
+                            title={this.props.translate('welcomeMessagePage.welcomeMessage')}
+                            icon={Expensicons.ChatBubble}
+                            onPress={() => Navigation.navigate(ROUTES.getReportWelcomeMessageRoute(this.props.report.reportID))}
+                            shouldShowRightIcon
+                        />
+                    )}
                 </FullPageNotFoundView>
             </ScreenWrapper>
         );

From a1dc8bb5a28b4ffd53a41e380437cb9e25415edb Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Thu, 18 May 2023 18:17:16 +0200
Subject: [PATCH 14/18] Add Form

---
 src/ONYXKEYS.js                       |  1 +
 src/libs/actions/Report.js            |  6 +++++
 src/pages/ReportWelcomeMessagePage.js | 37 +++++++++++++++------------
 3 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js
index 1805db98f1d5..9e282e478e89 100755
--- a/src/ONYXKEYS.js
+++ b/src/ONYXKEYS.js
@@ -198,6 +198,7 @@ export default {
         PROFILE_SETTINGS_FORM: 'profileSettingsForm',
         DISPLAY_NAME_FORM: 'displayNameForm',
         ROOM_NAME_FORM: 'roomNameForm',
+        WELCOME_MESSAGE_FORM: 'welcomeMessageForm',
         LEGAL_NAME_FORM: 'legalNameForm',
         WORKSPACE_INVITE_MESSAGE_FORM: 'workspaceInviteMessageForm',
         DATE_OF_BIRTH_FORM: 'dateOfBirthForm',
diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js
index 2a719e7072ff..df0b05d6083e 100644
--- a/src/libs/actions/Report.js
+++ b/src/libs/actions/Report.js
@@ -1124,6 +1124,12 @@ function updateNotificationPreferenceAndNavigate(reportID, previousValue, newVal
  * @param {String} newValue
  */
 function updateWelcomeMessage(reportID, previousValue, newValue) {
+    // No change needed, navigate back
+    if (previousValue === newValue) {
+        Navigation.goBack();
+        return;
+    }
+
     const parsedWelcomeMessage = ReportUtils.getParsedComment(newValue);
     const optimisticData = [
         {
diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index 989d40b41977..44945336ffdd 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -1,7 +1,7 @@
 import React, {useCallback, useRef, useState} from 'react';
 import PropTypes from 'prop-types';
 import _ from 'underscore';
-import {ScrollView, View} from 'react-native';
+import {View} from 'react-native';
 import Str from 'expensify-common/lib/str';
 import compose from '../libs/compose';
 import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
@@ -11,12 +11,14 @@ import HeaderWithCloseButton from '../components/HeaderWithCloseButton';
 import styles from '../styles/styles';
 import reportPropTypes from './reportPropTypes';
 import withReportOrNotFound from './home/report/withReportOrNotFound';
-import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView';
-import FixedFooter from '../components/FixedFooter';
-import Button from '../components/Button';
 import Text from '../components/Text';
 import TextInput from '../components/TextInput';
 import * as Report from '../libs/actions/Report';
+import ONYXKEYS from "../ONYXKEYS";
+import CONST from "../CONST";
+import * as ErrorUtils from "../libs/ErrorUtils";
+import FullPageNotFoundView from "../components/BlockingViews/FullPageNotFoundView";
+import Form from "../components/Form";
 
 const propTypes = {
     ...withLocalizePropTypes,
@@ -60,28 +62,29 @@ function ReportWelcomeMessagePage(props) {
                     onBackButtonPress={() => Navigation.goBack()}
                     onCloseButtonPress={() => Navigation.dismissModal()}
                 />
-                <ScrollView style={[styles.flex1]}>
-                    <Text style={[styles.ph5, styles.mb5]}>{props.translate('welcomeMessagePage.explainerText')}</Text>
-                    <View style={[styles.ph5, styles.mb6]}>
+                <Form
+                    style={[styles.flexGrow1, styles.ph5]}
+                    formID={ONYXKEYS.FORMS.WELCOME_MESSAGE_FORM}
+                    onSubmit={submitForm}
+                    validate={() => ({})}
+                    submitButtonText={props.translate('common.save')}
+                    enabledWhenOffline
+                >
+                    <Text style={[styles.mb5]}>{props.translate('welcomeMessagePage.explainerText')}</Text>
+                    <View style={[styles.mb6]}>
                         <TextInput
+                            inputID="welcomeMessage"
                             label={props.translate('welcomeMessagePage.welcomeMessage')}
                             multiline
-                            numberOfLines={8}
+                            numberOfLines={10}
+                            maxLength={CONST.MAX_COMMENT_LENGTH}
                             ref={welcomeMessageInputRef}
                             value={welcomeMessage}
                             onChangeText={handleWelcomeMessageChange}
                             autoCapitalize="none"
                         />
                     </View>
-                </ScrollView>
-                <FixedFooter style={[styles.flexGrow0]}>
-                    <Button
-                        success
-                        text={props.translate('common.save')}
-                        onPress={submitForm}
-                        pressOnEnter
-                    />
-                </FixedFooter>
+                </Form>
             </FullPageNotFoundView>
         </ScreenWrapper>
     );

From 5cfeecd98bd673450089cf5060fbcbf5c50e7736 Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Thu, 18 May 2023 19:06:15 +0200
Subject: [PATCH 15/18] Use markdown

---
 src/pages/ReportWelcomeMessagePage.js | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index 44945336ffdd..d642132c89b2 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -19,6 +19,7 @@ import CONST from "../CONST";
 import * as ErrorUtils from "../libs/ErrorUtils";
 import FullPageNotFoundView from "../components/BlockingViews/FullPageNotFoundView";
 import Form from "../components/Form";
+import ExpensiMark from "expensify-common/lib/ExpensiMark";
 
 const propTypes = {
     ...withLocalizePropTypes,
@@ -36,7 +37,8 @@ const propTypes = {
 };
 
 function ReportWelcomeMessagePage(props) {
-    const [welcomeMessage, setWelcomeMessage] = useState(Str.htmlDecode(props.report.welcomeMessage));
+    const parser = new ExpensiMark();
+    const [welcomeMessage, setWelcomeMessage] = useState(parser.htmlToMarkdown(props.report.welcomeMessage));
     const welcomeMessageInputRef = useRef(null);
 
     const handleWelcomeMessageChange = useCallback((value) => {

From 02ca68e5322d19acf098463361fa7cee2165ff8e Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Thu, 18 May 2023 19:06:45 +0200
Subject: [PATCH 16/18] Prettier

---
 src/pages/ReportWelcomeMessagePage.js | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index d642132c89b2..601b3021ab52 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -14,12 +14,12 @@ import withReportOrNotFound from './home/report/withReportOrNotFound';
 import Text from '../components/Text';
 import TextInput from '../components/TextInput';
 import * as Report from '../libs/actions/Report';
-import ONYXKEYS from "../ONYXKEYS";
-import CONST from "../CONST";
-import * as ErrorUtils from "../libs/ErrorUtils";
-import FullPageNotFoundView from "../components/BlockingViews/FullPageNotFoundView";
-import Form from "../components/Form";
-import ExpensiMark from "expensify-common/lib/ExpensiMark";
+import ONYXKEYS from '../ONYXKEYS';
+import CONST from '../CONST';
+import * as ErrorUtils from '../libs/ErrorUtils';
+import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView';
+import Form from '../components/Form';
+import ExpensiMark from 'expensify-common/lib/ExpensiMark';
 
 const propTypes = {
     ...withLocalizePropTypes,

From 21de4e2b46cc75286b45d68eebf109b9b84d954a Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <rocio@expensify.com>
Date: Thu, 18 May 2023 19:17:01 +0200
Subject: [PATCH 17/18] Linter

---
 src/pages/ReportWelcomeMessagePage.js | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js
index 601b3021ab52..60ffbebb3638 100644
--- a/src/pages/ReportWelcomeMessagePage.js
+++ b/src/pages/ReportWelcomeMessagePage.js
@@ -2,7 +2,7 @@ import React, {useCallback, useRef, useState} from 'react';
 import PropTypes from 'prop-types';
 import _ from 'underscore';
 import {View} from 'react-native';
-import Str from 'expensify-common/lib/str';
+import ExpensiMark from 'expensify-common/lib/ExpensiMark';
 import compose from '../libs/compose';
 import withLocalize, {withLocalizePropTypes} from '../components/withLocalize';
 import ScreenWrapper from '../components/ScreenWrapper';
@@ -16,10 +16,8 @@ import TextInput from '../components/TextInput';
 import * as Report from '../libs/actions/Report';
 import ONYXKEYS from '../ONYXKEYS';
 import CONST from '../CONST';
-import * as ErrorUtils from '../libs/ErrorUtils';
 import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView';
 import Form from '../components/Form';
-import ExpensiMark from 'expensify-common/lib/ExpensiMark';
 
 const propTypes = {
     ...withLocalizePropTypes,

From 59bcd35e1268e156efe557260178e0cfd2bd964b Mon Sep 17 00:00:00 2001
From: Rocio Perez-Cano <pecanoro@users.noreply.github.com>
Date: Wed, 24 May 2023 19:22:52 +0200
Subject: [PATCH 18/18] Update src/languages/en.js

Co-authored-by: Paulo Gaspar Sena do Vale <paulogaspar404@gmail.com>
---
 src/languages/en.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/languages/en.js b/src/languages/en.js
index 6a1ea1a3429a..9185c2434fd8 100755
--- a/src/languages/en.js
+++ b/src/languages/en.js
@@ -641,7 +641,7 @@ export default {
     },
     welcomeMessagePage: {
         welcomeMessage: 'Welcome message',
-        explainerText: 'Set a custom welcome message that will be sent users when they join this room.',
+        explainerText: 'Set a custom welcome message that will be sent to users when they join this room.',
     },
     languagePage: {
         language: 'Language',
