From 12d33dafe474d157119af16e130b81fbc91f2cb0 Mon Sep 17 00:00:00 2001
From: Taras Perun <terry.perun@gmail.com>
Date: Sun, 9 Jul 2023 14:50:39 +0200
Subject: [PATCH 1/4] migrate

---
 src/components/Composer/index.ios.js | 101 ++++++++++++++-------------
 1 file changed, 52 insertions(+), 49 deletions(-)

diff --git a/src/components/Composer/index.ios.js b/src/components/Composer/index.ios.js
index 357a4b187417..b99499a8ffb2 100644
--- a/src/components/Composer/index.ios.js
+++ b/src/components/Composer/index.ios.js
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, {useEffect, useRef, useMemo} from 'react';
 import {StyleSheet} from 'react-native';
 import PropTypes from 'prop-types';
 import _ from 'underscore';
@@ -63,59 +63,62 @@ const defaultProps = {
     style: null,
 };
 
-class Composer extends React.Component {
-    constructor(props) {
-        super(props);
-
-        this.state = {
-            propStyles: StyleSheet.flatten(this.props.style),
-        };
-    }
-
-    componentDidMount() {
-        // This callback prop is used by the parent component using the constructor to
-        // get a ref to the inner textInput element e.g. if we do
-        // <constructor ref={el => this.textInput = el} /> this will not
-        // return a ref to the component, but rather the HTML element by default
-        if (!this.props.forwardedRef || !_.isFunction(this.props.forwardedRef)) {
+function Composer({
+  forwardedRef,
+  shouldClear,
+  onClear,
+  isDisabled,
+  maxLines,
+  setIsFullComposerAvailable,
+  isComposerFullSize,
+  ...props
+}) {
+    const textInput = useRef();
+
+    useEffect(() => {
+        if (!_.isFunction(forwardedRef)) {
             return;
         }
+        forwardedRef(textInput.current);
+    }, [forwardedRef]);
 
-        this.props.forwardedRef(this.textInput);
-    }
-
-    componentDidUpdate(prevProps) {
-        if (prevProps.shouldClear || !this.props.shouldClear) {
+    useEffect(() => {
+        if (!shouldClear) {
             return;
         }
-
-        this.textInput.clear();
-        this.props.onClear();
-    }
-
-    render() {
-        // On native layers we like to have the Text Input not focused so the
-        // user can read new chats without the keyboard in the way of the view.
-        // On Android, the selection prop is required on the TextInput but this prop has issues on IOS
-        // https://github.com/facebook/react-native/issues/29063
-        const propsToPass = _.omit(this.props, 'selection');
-        return (
-            <RNTextInput
-                autoComplete="off"
-                placeholderTextColor={themeColors.placeholderText}
-                ref={(el) => (this.textInput = el)}
-                onContentSizeChange={(e) => ComposerUtils.updateNumberOfLines(this.props, e)}
-                rejectResponderTermination={false}
-                textAlignVertical="center"
-                smartInsertDelete={false}
-                maximumNumberOfLines={this.props.isComposerFullSize ? undefined : this.props.maxLines}
-                style={this.state.propStyles}
-                /* eslint-disable-next-line react/jsx-props-no-spreading */
-                {...propsToPass}
-                editable={!this.props.isDisabled}
-            />
-        );
-    }
+        textInput.current.clear();
+        onClear();
+    }, [shouldClear, onClear]);
+
+    const maximumNumberOfLines = useMemo(() => {
+        if (isComposerFullSize) return undefined;
+        return maxLines;
+    }, [isComposerFullSize, maxLines]);
+
+    const styles = useMemo(() => {
+        StyleSheet.flatten(props.style);
+    }, [props.style]);
+
+    // On native layers we like to have the Text Input not focused so the
+    // user can read new chats without the keyboard in the way of the view.
+    // On Android the selection prop is required on the TextInput but this prop has issues on IOS
+    const propsToPass = _.omit(props, 'selection');
+    return (
+        <RNTextInput
+            autoComplete="off"
+            placeholderTextColor={themeColors.placeholderText}
+            ref={textInput}
+            onContentSizeChange={(e) => ComposerUtils.updateNumberOfLines({maxLines, isComposerFullSize, isDisabled, setIsFullComposerAvailable}, e)}
+            rejectResponderTermination={false}
+            textAlignVertical="center"
+            smartInsertDelete={false}
+            maximumNumberOfLines={maximumNumberOfLines}
+            style={styles}
+            /* eslint-disable-next-line react/jsx-props-no-spreading */
+            {...propsToPass}
+            editable={!isDisabled}
+        />
+    );
 }
 
 Composer.propTypes = propTypes;

From b2c8017ce52da16ef2fd4211ad853714d4c9d7de Mon Sep 17 00:00:00 2001
From: Taras Perun <terry.perun@gmail.com>
Date: Mon, 10 Jul 2023 11:42:01 +0200
Subject: [PATCH 2/4] add comments

---
 src/components/Composer/index.ios.js | 42 +++++++++++++++++++---------
 1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/src/components/Composer/index.ios.js b/src/components/Composer/index.ios.js
index b99499a8ffb2..34dbd8265a31 100644
--- a/src/components/Composer/index.ios.js
+++ b/src/components/Composer/index.ios.js
@@ -1,4 +1,4 @@
-import React, {useEffect, useRef, useMemo} from 'react';
+import React, {useEffect, useRef, useMemo, useCallback} from 'react';
 import {StyleSheet} from 'react-native';
 import PropTypes from 'prop-types';
 import _ from 'underscore';
@@ -64,23 +64,34 @@ const defaultProps = {
 };
 
 function Composer({
-  forwardedRef,
   shouldClear,
   onClear,
   isDisabled,
   maxLines,
-  setIsFullComposerAvailable,
+  forwardedRef,
   isComposerFullSize,
+  setIsFullComposerAvailable,
   ...props
 }) {
-    const textInput = useRef();
-
-    useEffect(() => {
-        if (!_.isFunction(forwardedRef)) {
-            return;
+    const textInput = useRef(null);
+
+    /**
+     * Set the TextInput Ref
+     * @param {Element} el
+     */
+    const setTextInputRef = useCallback((el) => {
+        textInput.current = el;
+        if (!_.isFunction(forwardedRef) || textInput.current === null) {
+          return;
         }
-        forwardedRef(textInput.current);
-    }, [forwardedRef]);
+
+      // This callback prop is used by the parent component using the constructor to
+      // get a ref to the inner textInput element e.g. if we do
+      // <constructor ref={el => this.textInput = el} /> this will not
+      // return a ref to the component, but rather the HTML element by default
+      forwardedRef(textInput.current);
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+    }, []);
 
     useEffect(() => {
         if (!shouldClear) {
@@ -90,10 +101,15 @@ function Composer({
         onClear();
     }, [shouldClear, onClear]);
 
+
+     /**
+      * Set maximum number of lines
+      * @return {Number}
+      */
     const maximumNumberOfLines = useMemo(() => {
-        if (isComposerFullSize) return undefined;
+        if (isComposerFullSize) return 1000000;
         return maxLines;
-    }, [isComposerFullSize, maxLines]);
+    },[isComposerFullSize, maxLines])
 
     const styles = useMemo(() => {
         StyleSheet.flatten(props.style);
@@ -107,7 +123,7 @@ function Composer({
         <RNTextInput
             autoComplete="off"
             placeholderTextColor={themeColors.placeholderText}
-            ref={textInput}
+            ref={setTextInputRef}
             onContentSizeChange={(e) => ComposerUtils.updateNumberOfLines({maxLines, isComposerFullSize, isDisabled, setIsFullComposerAvailable}, e)}
             rejectResponderTermination={false}
             textAlignVertical="center"

From 325062e52c5ce006372b9c0237870f2c9882fc04 Mon Sep 17 00:00:00 2001
From: Taras Perun <terry.perun@gmail.com>
Date: Mon, 10 Jul 2023 11:52:04 +0200
Subject: [PATCH 3/4] prettier

---
 src/components/Composer/index.ios.js | 36 ++++++++++------------------
 1 file changed, 13 insertions(+), 23 deletions(-)

diff --git a/src/components/Composer/index.ios.js b/src/components/Composer/index.ios.js
index 34dbd8265a31..017875687937 100644
--- a/src/components/Composer/index.ios.js
+++ b/src/components/Composer/index.ios.js
@@ -63,16 +63,7 @@ const defaultProps = {
     style: null,
 };
 
-function Composer({
-  shouldClear,
-  onClear,
-  isDisabled,
-  maxLines,
-  forwardedRef,
-  isComposerFullSize,
-  setIsFullComposerAvailable,
-  ...props
-}) {
+function Composer({shouldClear, onClear, isDisabled, maxLines, forwardedRef, isComposerFullSize, setIsFullComposerAvailable, ...props}) {
     const textInput = useRef(null);
 
     /**
@@ -82,15 +73,15 @@ function Composer({
     const setTextInputRef = useCallback((el) => {
         textInput.current = el;
         if (!_.isFunction(forwardedRef) || textInput.current === null) {
-          return;
+            return;
         }
 
-      // This callback prop is used by the parent component using the constructor to
-      // get a ref to the inner textInput element e.g. if we do
-      // <constructor ref={el => this.textInput = el} /> this will not
-      // return a ref to the component, but rather the HTML element by default
-      forwardedRef(textInput.current);
-    // eslint-disable-next-line react-hooks/exhaustive-deps
+        // This callback prop is used by the parent component using the constructor to
+        // get a ref to the inner textInput element e.g. if we do
+        // <constructor ref={el => this.textInput = el} /> this will not
+        // return a ref to the component, but rather the HTML element by default
+        forwardedRef(textInput.current);
+        // eslint-disable-next-line react-hooks/exhaustive-deps
     }, []);
 
     useEffect(() => {
@@ -101,15 +92,14 @@ function Composer({
         onClear();
     }, [shouldClear, onClear]);
 
-
-     /**
-      * Set maximum number of lines
-      * @return {Number}
-      */
+    /**
+     * Set maximum number of lines
+     * @return {Number}
+     */
     const maximumNumberOfLines = useMemo(() => {
         if (isComposerFullSize) return 1000000;
         return maxLines;
-    },[isComposerFullSize, maxLines])
+    }, [isComposerFullSize, maxLines]);
 
     const styles = useMemo(() => {
         StyleSheet.flatten(props.style);

From 238e6f7ffca712aa820e0ebd95a133bab5a565b0 Mon Sep 17 00:00:00 2001
From: Taras Perun <terry.perun@gmail.com>
Date: Wed, 12 Jul 2023 09:55:52 +0200
Subject: [PATCH 4/4] update maximumNumberOfLines

---
 src/components/Composer/index.ios.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/Composer/index.ios.js b/src/components/Composer/index.ios.js
index 017875687937..1032f89649e4 100644
--- a/src/components/Composer/index.ios.js
+++ b/src/components/Composer/index.ios.js
@@ -97,7 +97,7 @@ function Composer({shouldClear, onClear, isDisabled, maxLines, forwardedRef, isC
      * @return {Number}
      */
     const maximumNumberOfLines = useMemo(() => {
-        if (isComposerFullSize) return 1000000;
+        if (isComposerFullSize) return undefined;
         return maxLines;
     }, [isComposerFullSize, maxLines]);
 
