From 12d33dafe474d157119af16e130b81fbc91f2cb0 Mon Sep 17 00:00:00 2001 From: Taras Perun 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 - // 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 ( - (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 ( + 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 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 + // 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({ ComposerUtils.updateNumberOfLines({maxLines, isComposerFullSize, isDisabled, setIsFullComposerAvailable}, e)} rejectResponderTermination={false} textAlignVertical="center" From 325062e52c5ce006372b9c0237870f2c9882fc04 Mon Sep 17 00:00:00 2001 From: Taras Perun 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 - // 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 + // 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 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]);