From e70f7c595076d348d8a94f5257c492e84e21e7c7 Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Fri, 21 May 2021 07:42:55 +0530
Subject: [PATCH 01/11] chore: refactor Growl component files

---
 .../GrowlNotificationContainerPropTypes.js                    | 2 +-
 .../GrowlNotification/GrowlNotificationContainer/index.js     | 2 +-
 .../GrowlNotificationContainer/index.native.js                | 0
 src/{libs => components}/GrowlNotification/index.js           | 4 ++--
 src/pages/settings/Profile/ProfilePage.js                     | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)
 rename src/{libs => components}/GrowlNotification/GrowlNotificationContainer/GrowlNotificationContainerPropTypes.js (82%)
 rename src/{libs => components}/GrowlNotification/GrowlNotificationContainer/index.js (89%)
 rename src/{libs => components}/GrowlNotification/GrowlNotificationContainer/index.native.js (100%)
 rename src/{libs => components}/GrowlNotification/index.js (96%)

diff --git a/src/libs/GrowlNotification/GrowlNotificationContainer/GrowlNotificationContainerPropTypes.js b/src/components/GrowlNotification/GrowlNotificationContainer/GrowlNotificationContainerPropTypes.js
similarity index 82%
rename from src/libs/GrowlNotification/GrowlNotificationContainer/GrowlNotificationContainerPropTypes.js
rename to src/components/GrowlNotification/GrowlNotificationContainer/GrowlNotificationContainerPropTypes.js
index fb5d017e984a..1343c11821c1 100644
--- a/src/libs/GrowlNotification/GrowlNotificationContainer/GrowlNotificationContainerPropTypes.js
+++ b/src/components/GrowlNotification/GrowlNotificationContainer/GrowlNotificationContainerPropTypes.js
@@ -1,6 +1,6 @@
 import {Animated} from 'react-native';
 import PropTypes from 'prop-types';
-import {windowDimensionsPropTypes} from '../../../components/withWindowDimensions';
+import {windowDimensionsPropTypes} from '../../withWindowDimensions';
 
 const propTypes = {
     /** GrowlNotification content */
diff --git a/src/libs/GrowlNotification/GrowlNotificationContainer/index.js b/src/components/GrowlNotification/GrowlNotificationContainer/index.js
similarity index 89%
rename from src/libs/GrowlNotification/GrowlNotificationContainer/index.js
rename to src/components/GrowlNotification/GrowlNotificationContainer/index.js
index 82b0b68cbf6a..b1b051107ab0 100644
--- a/src/libs/GrowlNotification/GrowlNotificationContainer/index.js
+++ b/src/components/GrowlNotification/GrowlNotificationContainer/index.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import {Animated} from 'react-native';
 import styles from '../../../styles/styles';
-import withWindowDimensions from '../../../components/withWindowDimensions';
+import withWindowDimensions from '../../withWindowDimensions';
 import propTypes from './GrowlNotificationContainerPropTypes';
 
 const GrowlNotificationContainer = ({children, translateY, isSmallScreenWidth}) => (
diff --git a/src/libs/GrowlNotification/GrowlNotificationContainer/index.native.js b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js
similarity index 100%
rename from src/libs/GrowlNotification/GrowlNotificationContainer/index.native.js
rename to src/components/GrowlNotification/GrowlNotificationContainer/index.native.js
diff --git a/src/libs/GrowlNotification/index.js b/src/components/GrowlNotification/index.js
similarity index 96%
rename from src/libs/GrowlNotification/index.js
rename to src/components/GrowlNotification/index.js
index 16f232b498aa..ec11e4409be0 100644
--- a/src/libs/GrowlNotification/index.js
+++ b/src/components/GrowlNotification/index.js
@@ -6,8 +6,8 @@ import {
     Directions, FlingGestureHandler, State, TouchableWithoutFeedback,
 } from 'react-native-gesture-handler';
 import colors from '../../styles/colors';
-import Icon from '../../components/Icon';
-import {Checkmark, Exclamation} from '../../components/Icon/Expensicons';
+import Icon from '../Icon';
+import {Checkmark, Exclamation} from '../Icon/Expensicons';
 import styles from '../../styles/styles';
 import GrowlNotificationContainer from './GrowlNotificationContainer';
 
diff --git a/src/pages/settings/Profile/ProfilePage.js b/src/pages/settings/Profile/ProfilePage.js
index 00ea71e257dd..6a559227db25 100755
--- a/src/pages/settings/Profile/ProfilePage.js
+++ b/src/pages/settings/Profile/ProfilePage.js
@@ -29,7 +29,7 @@ import CreateMenu from '../../../components/CreateMenu';
 import Picker from '../../../components/Picker';
 import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
 import compose from '../../../libs/compose';
-import GrowlNotification from '../../../libs/GrowlNotification';
+import GrowlNotification from '../../../components/GrowlNotification';
 import Button from '../../../components/Button';
 
 const propTypes = {

From dc1e414cca0b27efc75f833a936764154688585a Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Fri, 21 May 2021 07:43:38 +0530
Subject: [PATCH 02/11] chg: updated the Error handling for image paste on
 composer

---
 src/Expensify.js                           |  3 ++
 src/components/TextInputFocusable/index.js | 32 ++++++++++++++++++++--
 src/libs/Growl.js                          | 17 ++++++++++++
 3 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 src/libs/Growl.js

diff --git a/src/Expensify.js b/src/Expensify.js
index 6ac9b68a25ea..5bb11f3ef801 100644
--- a/src/Expensify.js
+++ b/src/Expensify.js
@@ -16,6 +16,8 @@ import styles from './styles/styles';
 import PushNotification from './libs/Notification/PushNotification';
 import UpdateAppModal from './components/UpdateAppModal';
 import Visibility from './libs/Visibility';
+import GrowlNotification from './components/GrowlNotification';
+import {growlRef} from './libs/Growl';
 
 // Initialize the store when the app loads for the first time
 Onyx.init({
@@ -159,6 +161,7 @@ class Expensify extends PureComponent {
                 {/* We include the modal for showing a new update at the top level so the option is always present. */}
                 {this.props.updateAvailable ? <UpdateAppModal /> : null}
                 <NavigationRoot authenticated={Boolean(this.getAuthToken())} />
+                <GrowlNotification ref={growlRef} />
             </>
         );
     }
diff --git a/src/components/TextInputFocusable/index.js b/src/components/TextInputFocusable/index.js
index e884ef8cc2e5..4d64a96b4e93 100755
--- a/src/components/TextInputFocusable/index.js
+++ b/src/components/TextInputFocusable/index.js
@@ -3,6 +3,7 @@ import {TextInput, StyleSheet} from 'react-native';
 import PropTypes from 'prop-types';
 import _ from 'underscore';
 import withLocalize, {withLocalizePropTypes} from '../withLocalize';
+import Growl from '../../libs/Growl';
 
 const propTypes = {
     /** Maximum number of lines in the text input */
@@ -93,6 +94,11 @@ class TextInputFocusable extends React.Component {
                 end: initialValue.length,
             },
         };
+        this.selection = {
+            start: initialValue.length,
+            end: initialValue.length,
+        };
+        this.setCursorPosition = this.setCursorPosition.bind(this);
     }
 
     componentDidMount() {
@@ -156,6 +162,16 @@ class TextInputFocusable extends React.Component {
         return newNumberOfLines;
     }
 
+    /**
+     * Keeps track of user cursor position on the Composer
+     *
+     * @param {*} {nativeEvent: {selection}}
+     * @memberof TextInputFocusable
+     */
+    setCursorPosition({nativeEvent: {selection}}) {
+        this.selection = selection;
+    }
+
     /**
      * Check the paste event for an attachment, parse the data and
      * call onPasteFile from props with the selected file
@@ -165,6 +181,7 @@ class TextInputFocusable extends React.Component {
     checkForAttachment(event) {
         const {files, types} = event.clipboardData;
         const TEXT_HTML = 'text/html';
+        const TEXT_PLAIN = 'text/plain';
         if (files.length > 0) {
             // Prevent the default so we do not post the file name into the text box
             event.preventDefault();
@@ -172,6 +189,7 @@ class TextInputFocusable extends React.Component {
         } else if (types.includes(TEXT_HTML)) {
             const domparser = new DOMParser();
             const embededImages = domparser.parseFromString(event.clipboardData.getData(TEXT_HTML), TEXT_HTML).images;
+            const pastedText = event.clipboardData.getData(TEXT_PLAIN);
             if (embededImages.length > 0) {
                 event.preventDefault();
                 fetch(embededImages[0].src)
@@ -188,9 +206,18 @@ class TextInputFocusable extends React.Component {
                         return new File([x], `pasted_image.${extension}`, {});
                     })
                     .then(this.props.onPasteFile)
-                    .catch((error) => {
+                    .catch(() => {
                         const errorDesc = this.props.translate('textInputFocusable.problemGettingImageYouPasted');
-                        alert(`${errorDesc}. \n${error.message}`);
+                        Growl.show(errorDesc, 'error');
+
+                        // We can't paste synthatically as it is blocked from browser due not generated
+                        // directly by user action.
+                        // Thus set the value manually.
+                        this.textInput.value = this.textInput.value.substring(0, this.selection.start - 1)
+                        + pastedText + this.textInput.value.substring(this.selection.end);
+
+                        // To hide the scrollbar we set it manually
+                        this.textInput.rows = this.textInput.value.split('\n').length;
                     });
             }
         }
@@ -226,6 +253,7 @@ class TextInputFocusable extends React.Component {
                 onChange={() => {
                     this.updateNumberOfLines();
                 }}
+                onSelectionChange={this.setCursorPosition}
                 numberOfLines={this.state.numberOfLines}
                 style={propStyles}
                 /* eslint-disable-next-line react/jsx-props-no-spreading */
diff --git a/src/libs/Growl.js b/src/libs/Growl.js
new file mode 100644
index 000000000000..006d963130a1
--- /dev/null
+++ b/src/libs/Growl.js
@@ -0,0 +1,17 @@
+import React from 'react';
+
+export const growlRef = React.createRef();
+
+/**
+ * Show the growl notification
+ *
+ * @param {String} bodyText
+ * @param {String} type
+ * @param {Number} duration
+*/
+function show(bodyText, type, duration) {
+    growlRef.current.show(bodyText, type, duration);
+}
+
+
+export default {show};

From 781b63a6926145192fdf59269f16576fa685a202 Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Sat, 22 May 2021 00:53:36 +0530
Subject: [PATCH 03/11] fix: text pasting

---
 src/components/TextInputFocusable/index.js | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/components/TextInputFocusable/index.js b/src/components/TextInputFocusable/index.js
index 4d64a96b4e93..057ef04b351c 100755
--- a/src/components/TextInputFocusable/index.js
+++ b/src/components/TextInputFocusable/index.js
@@ -170,6 +170,7 @@ class TextInputFocusable extends React.Component {
      */
     setCursorPosition({nativeEvent: {selection}}) {
         this.selection = selection;
+        console.debug(this.selection);
     }
 
     /**
@@ -212,12 +213,14 @@ class TextInputFocusable extends React.Component {
 
                         // We can't paste synthatically as it is blocked from browser due not generated
                         // directly by user action.
-                        // Thus set the value manually.
-                        this.textInput.value = this.textInput.value.substring(0, this.selection.start - 1)
-                        + pastedText + this.textInput.value.substring(this.selection.end);
-
-                        // To hide the scrollbar we set it manually
-                        this.textInput.rows = this.textInput.value.split('\n').length;
+                        // Thus set the value manually. It won't trigger value chnage effect
+                        const beforeCursorText = this.textInput.value.substring(0, this.selection.start);
+                        const afterCursorText = this.textInput.value.substring(this.selection.end);
+                        this.textInput.value = beforeCursorText + pastedText + afterCursorText;
+                        this.updateNumberOfLines();
+                        this.props.onChangeText(this.textInput.value);
+                        const newCursorPosition = beforeCursorText.length + pastedText.length;
+                        this.setState({selection: {start: newCursorPosition, end: newCursorPosition}});
                     });
             }
         }

From 7d76ea4fc2306c152b230f9638172bef7b0c971f Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Sat, 22 May 2021 01:31:47 +0530
Subject: [PATCH 04/11] chg: refactor growl to the top so that it does not show
 statically on native

---
 src/Expensify.js                           | 2 +-
 src/components/TextInputFocusable/index.js | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/Expensify.js b/src/Expensify.js
index 5bb11f3ef801..431db2e8d9a1 100644
--- a/src/Expensify.js
+++ b/src/Expensify.js
@@ -158,10 +158,10 @@ class Expensify extends PureComponent {
         }
         return (
             <>
+                <GrowlNotification ref={growlRef} />
                 {/* We include the modal for showing a new update at the top level so the option is always present. */}
                 {this.props.updateAvailable ? <UpdateAppModal /> : null}
                 <NavigationRoot authenticated={Boolean(this.getAuthToken())} />
-                <GrowlNotification ref={growlRef} />
             </>
         );
     }
diff --git a/src/components/TextInputFocusable/index.js b/src/components/TextInputFocusable/index.js
index 057ef04b351c..4d87e279faa7 100755
--- a/src/components/TextInputFocusable/index.js
+++ b/src/components/TextInputFocusable/index.js
@@ -170,7 +170,6 @@ class TextInputFocusable extends React.Component {
      */
     setCursorPosition({nativeEvent: {selection}}) {
         this.selection = selection;
-        console.debug(this.selection);
     }
 
     /**

From 2f7389c7345f132c81b0c322b95fb1e6cbb270c1 Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Mon, 24 May 2021 22:12:29 +0530
Subject: [PATCH 05/11] correct misspelling

Co-authored-by: John Lee <johnmlee101@gmail.com>
---
 src/components/TextInputFocusable/index.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/TextInputFocusable/index.js b/src/components/TextInputFocusable/index.js
index 81c247913fce..b2834fcf02d1 100755
--- a/src/components/TextInputFocusable/index.js
+++ b/src/components/TextInputFocusable/index.js
@@ -213,7 +213,7 @@ class TextInputFocusable extends React.Component {
 
                         // We can't paste synthatically as it is blocked from browser due not generated
                         // directly by user action.
-                        // Thus set the value manually. It won't trigger value chnage effect
+                        // Thus set the value manually. It won't trigger value change effect
                         const beforeCursorText = this.textInput.value.substring(0, this.selection.start);
                         const afterCursorText = this.textInput.value.substring(this.selection.end);
                         this.textInput.value = beforeCursorText + pastedText + afterCursorText;

From 8a4f8fc56fb6ed8ecf60efb9c4784d121a8db00e Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Wed, 26 May 2021 06:32:59 +0530
Subject: [PATCH 06/11] comment updated

---
 src/components/TextInputFocusable/index.js | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/components/TextInputFocusable/index.js b/src/components/TextInputFocusable/index.js
index ad2380e4aac9..66763e484209 100755
--- a/src/components/TextInputFocusable/index.js
+++ b/src/components/TextInputFocusable/index.js
@@ -231,9 +231,12 @@ class TextInputFocusable extends React.Component {
                         const errorDesc = this.props.translate('textInputFocusable.problemGettingImageYouPasted');
                         Growl.show(errorDesc, 'error');
 
-                        // We can't paste synthatically as it is blocked from browser due not generated
-                        // directly by user action.
-                        // Thus set the value manually. It won't trigger value chnage effect
+                        /*
+                        * Since we intercepted the user-triggered paste event to check for attachments,
+                        * we need to manually set the value and call the `onChangeText` handler.
+                        * Synthetically-triggered paste events do not affect the document's contents.
+                        * See https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event for more details.
+                        */
                         const beforeCursorText = this.textInput.value.substring(0, this.selection.start);
                         const afterCursorText = this.textInput.value.substring(this.selection.end);
                         this.textInput.value = beforeCursorText + pastedText + afterCursorText;

From 4ddc39d17f3f54de438c3ec2db536c2fb3f6ae3e Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Thu, 27 May 2021 04:17:22 +0530
Subject: [PATCH 07/11] use global growl in Profile page

---
 src/pages/settings/Profile/ProfilePage.js | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/pages/settings/Profile/ProfilePage.js b/src/pages/settings/Profile/ProfilePage.js
index 6a559227db25..ebf63fd32267 100755
--- a/src/pages/settings/Profile/ProfilePage.js
+++ b/src/pages/settings/Profile/ProfilePage.js
@@ -29,8 +29,8 @@ import CreateMenu from '../../../components/CreateMenu';
 import Picker from '../../../components/Picker';
 import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
 import compose from '../../../libs/compose';
-import GrowlNotification from '../../../components/GrowlNotification';
 import Button from '../../../components/Button';
+import Growl from '../../../libs/Growl';
 
 const propTypes = {
     /* Onyx Props */
@@ -131,7 +131,6 @@ class ProfilePage extends Component {
         this.setAutomaticTimezone = this.setAutomaticTimezone.bind(this);
         this.getLogins = this.getLogins.bind(this);
         this.createMenuItems = this.createMenuItems.bind(this);
-        this.growlNotification = undefined;
     }
 
     componentDidUpdate(prevProps) {
@@ -211,7 +210,7 @@ class ProfilePage extends Component {
             },
         });
 
-        this.growlNotification.show(this.props.translate('profilePage.growlMessageOnSave'), 'success', 3000);
+        Growl.show(this.props.translate('profilePage.growlMessageOnSave'), 'success', 3000);
     }
 
     /**
@@ -261,7 +260,6 @@ class ProfilePage extends Component {
 
         return (
             <ScreenWrapper>
-                <GrowlNotification ref={el => this.growlNotification = el} />
                 <HeaderWithCloseButton
                     title={this.props.translate('common.profile')}
                     shouldShowBackButton

From 2f12f8630b7551980957495edbdbbf0660293970 Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Fri, 28 May 2021 01:05:45 +0530
Subject: [PATCH 08/11] fix: Growl position for native devices

---
 .../index.native.js                           | 24 ++++++++++++-------
 src/styles/styles.js                          |  4 ++--
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js
index d6d5a0bc0e8b..f718430f27b7 100644
--- a/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js
+++ b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.js
@@ -1,17 +1,23 @@
 import React from 'react';
 import {Animated} from 'react-native';
-import styles from '../../../styles/styles';
+import {SafeAreaInsetsContext} from 'react-native-safe-area-context';
+import styles, {getSafeAreaPadding} from '../../../styles/styles';
 import propTypes from './GrowlNotificationContainerPropTypes';
 
 const GrowlNotificationContainer = ({children, translateY}) => (
-    <Animated.View
-        style={[
-            styles.growlNotificationContainer,
-            styles.growlNotificationTranslateY(translateY),
-        ]}
-    >
-        {children}
-    </Animated.View>
+    <SafeAreaInsetsContext.Consumer>
+        {insets => (
+            <Animated.View
+                style={[
+                    styles.growlNotificationContainer,
+                    getSafeAreaPadding(insets),
+                    styles.growlNotificationTranslateY(translateY),
+                ]}
+            >
+                {children}
+            </Animated.View>
+        )}
+    </SafeAreaInsetsContext.Consumer>
 );
 
 GrowlNotificationContainer.propTypes = propTypes;
diff --git a/src/styles/styles.js b/src/styles/styles.js
index e7c7c388527b..481be6119c62 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -1456,12 +1456,12 @@ const styles = {
         justifyContent: 'flex-start',
         position: 'absolute',
         width: '100%',
+        top: 20,
         ...spacing.ph5,
     },
 
     growlNotificationDesktopContainer: {
-        maxWidth: '380px',
-        top: '20px',
+        maxWidth: 380,
         right: 0,
         position: 'fixed',
     },

From 68129ed7587bdefe64579401e0d514e18f80b584 Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Fri, 28 May 2021 07:59:33 +0530
Subject: [PATCH 09/11] added constants for GROWL types

---
 src/CONST.js                               | 7 +++++++
 src/components/GrowlNotification/index.js  | 9 +++++----
 src/components/TextInputFocusable/index.js | 3 ++-
 src/libs/Growl.js                          | 3 ++-
 src/pages/settings/Profile/ProfilePage.js  | 2 +-
 5 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/src/CONST.js b/src/CONST.js
index b98cf6cf70ec..d1b6a5b52e37 100755
--- a/src/CONST.js
+++ b/src/CONST.js
@@ -171,6 +171,13 @@ const CONST = {
         PHONE_E164_PLUS: /^\+?[1-9]\d{1,14}$/,
         NON_ALPHA_NUMERIC: /[^A-Za-z0-9+]/g,
     },
+
+    GROWL: {
+        SUCCESS: 'success',
+        ERROR: 'error',
+        WARNING: 'warning',
+        DURATION: 2000,
+    },
 };
 
 export default CONST;
diff --git a/src/components/GrowlNotification/index.js b/src/components/GrowlNotification/index.js
index ec11e4409be0..a19934816b85 100644
--- a/src/components/GrowlNotification/index.js
+++ b/src/components/GrowlNotification/index.js
@@ -10,17 +10,18 @@ import Icon from '../Icon';
 import {Checkmark, Exclamation} from '../Icon/Expensicons';
 import styles from '../../styles/styles';
 import GrowlNotificationContainer from './GrowlNotificationContainer';
+import CONST from '../../CONST';
 
 const types = {
-    success: {
+    [CONST.GROWL.SUCCESS]: {
         icon: Checkmark,
         iconColor: colors.green,
     },
-    error: {
+    [CONST.GROWL.ERROR]: {
         icon: Exclamation,
         iconColor: colors.red,
     },
-    warning: {
+    [CONST.GROWL.WARNING]: {
         icon: Exclamation,
         iconColor: colors.yellow,
     },
@@ -49,7 +50,7 @@ class GrowlNotification extends Component {
      * @param {String} type
      * @param {Number} duration - 2000
     */
-    show(bodyText, type, duration = 2000) {
+    show(bodyText, type, duration) {
         this.setState({
             bodyText,
             type,
diff --git a/src/components/TextInputFocusable/index.js b/src/components/TextInputFocusable/index.js
index 66763e484209..48329e4a5530 100755
--- a/src/components/TextInputFocusable/index.js
+++ b/src/components/TextInputFocusable/index.js
@@ -5,6 +5,7 @@ import _ from 'underscore';
 import withLocalize, {withLocalizePropTypes} from '../withLocalize';
 import Growl from '../../libs/Growl';
 import themeColors from '../../styles/themes/default';
+import CONST from '../../CONST';
 
 const propTypes = {
     /** Maximum number of lines in the text input */
@@ -229,7 +230,7 @@ class TextInputFocusable extends React.Component {
                     .then(this.props.onPasteFile)
                     .catch(() => {
                         const errorDesc = this.props.translate('textInputFocusable.problemGettingImageYouPasted');
-                        Growl.show(errorDesc, 'error');
+                        Growl.show(errorDesc, CONST.GROWL.ERROR);
 
                         /*
                         * Since we intercepted the user-triggered paste event to check for attachments,
diff --git a/src/libs/Growl.js b/src/libs/Growl.js
index 006d963130a1..69cc273895ab 100644
--- a/src/libs/Growl.js
+++ b/src/libs/Growl.js
@@ -1,4 +1,5 @@
 import React from 'react';
+import CONST from '../CONST';
 
 export const growlRef = React.createRef();
 
@@ -9,7 +10,7 @@ export const growlRef = React.createRef();
  * @param {String} type
  * @param {Number} duration
 */
-function show(bodyText, type, duration) {
+function show(bodyText, type, duration = CONST.GROWL.DURATION) {
     growlRef.current.show(bodyText, type, duration);
 }
 
diff --git a/src/pages/settings/Profile/ProfilePage.js b/src/pages/settings/Profile/ProfilePage.js
index ebf63fd32267..1487e85057b8 100755
--- a/src/pages/settings/Profile/ProfilePage.js
+++ b/src/pages/settings/Profile/ProfilePage.js
@@ -210,7 +210,7 @@ class ProfilePage extends Component {
             },
         });
 
-        Growl.show(this.props.translate('profilePage.growlMessageOnSave'), 'success', 3000);
+        Growl.show(this.props.translate('profilePage.growlMessageOnSave'), CONST.GROWL.SUCCESS, 3000);
     }
 
     /**

From 72d8d86c426ba7aebbdf45dc60cea54e6833f8d8 Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Sat, 29 May 2021 01:01:15 +0530
Subject: [PATCH 10/11] Update src/components/GrowlNotification/index.js

Co-authored-by: Rory Abraham <47436092+roryabraham@users.noreply.github.com>
---
 src/components/GrowlNotification/index.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/GrowlNotification/index.js b/src/components/GrowlNotification/index.js
index a19934816b85..c15ed036e5cf 100644
--- a/src/components/GrowlNotification/index.js
+++ b/src/components/GrowlNotification/index.js
@@ -48,7 +48,7 @@ class GrowlNotification extends Component {
      *
      * @param {String} bodyText
      * @param {String} type
-     * @param {Number} duration - 2000
+     * @param {Number} duration
     */
     show(bodyText, type, duration) {
         this.setState({

From d56ad45e7c317957dbd301169e2b147b64501267 Mon Sep 17 00:00:00 2001
From: Rajat Parashar <parasharrajat@users.noreply.github.com>
Date: Sat, 29 May 2021 01:01:23 +0530
Subject: [PATCH 11/11] Update src/libs/Growl.js

Co-authored-by: Rory Abraham <47436092+roryabraham@users.noreply.github.com>
---
 src/libs/Growl.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/Growl.js b/src/libs/Growl.js
index 69cc273895ab..9e20dcbcc2a6 100644
--- a/src/libs/Growl.js
+++ b/src/libs/Growl.js
@@ -8,7 +8,7 @@ export const growlRef = React.createRef();
  *
  * @param {String} bodyText
  * @param {String} type
- * @param {Number} duration
+ * @param {Number} [duration]
 */
 function show(bodyText, type, duration = CONST.GROWL.DURATION) {
     growlRef.current.show(bodyText, type, duration);
