From 2a543a212015993ee58541d51307f803c4d322ff Mon Sep 17 00:00:00 2001 From: Kadie Alexander Date: Wed, 16 Aug 2023 19:46:34 +1200 Subject: [PATCH 001/567] Updated variables and states (WIP) --- src/components/PDFView/index.native.js | 172 +++++++++++-------------- 1 file changed, 77 insertions(+), 95 deletions(-) diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index c240ade664e5..575d78ca955a 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -14,12 +14,10 @@ import withWindowDimensions from '../withWindowDimensions'; import withKeyboardState, {keyboardStatePropTypes} from '../withKeyboardState'; import withLocalize from '../withLocalize'; import CONST from '../../CONST'; - const propTypes = { ...pdfViewPropTypes, ...keyboardStatePropTypes, -}; - +} /** * On the native layer, we use react-native-pdf/PDF to display PDFs. If a PDF is * password-protected we render a PDFPasswordForm to request a password @@ -34,42 +32,24 @@ const propTypes = { * so that PDFPasswordForm doesn't bounce when react-native-pdf/PDF * is (temporarily) rendered. */ -class PDFView extends Component { - constructor(props) { - super(props); - this.state = { - shouldRequestPassword: false, - shouldAttemptPDFLoad: true, - shouldShowLoadingIndicator: true, - isPasswordInvalid: false, - failedToLoadPDF: false, - successToLoadPDF: false, - password: '', - }; - this.initiatePasswordChallenge = this.initiatePasswordChallenge.bind(this); - this.attemptPDFLoadWithPassword = this.attemptPDFLoadWithPassword.bind(this); - this.finishPDFLoad = this.finishPDFLoad.bind(this); - this.handleFailureToLoadPDF = this.handleFailureToLoadPDF.bind(this); - } - componentDidUpdate() { - this.props.onToggleKeyboard(this.props.isKeyboardShown); - } +const [shouldRequestPassword, setShouldRequestPassword] = useState(false); +const [shouldAttemptPDFLoad, setShouldAttemptPDFLoad] = useState(true); +const [shouldShowLoadingIndicator, setShouldShowLoadingIndicator] = useState(true), +const [isPasswordInvalid, setIsPasswordInvalid] = useState(false), +const [failedToLoadPDF, setFailedToLoadPDF] = useState(false), +const [successToLoadPDF, setSuccessToLoadPDF] = useState(false), +const [password, setPassword] = useState(''), + + +/* Ignoring this for last.*/ +componentDidUpdate() { + props .onToggleKeyboard(props.isKeyboardShown); +} - handleFailureToLoadPDF(error) { - if (error.message.match(/password/i)) { - this.initiatePasswordChallenge(); - return; - } - this.setState({ - failedToLoadPDF: true, - shouldAttemptPDFLoad: false, - shouldRequestPassword: false, - shouldShowLoadingIndicator: false, - }); - } +function PDFView(props) { /** * Initiate password challenge if message received from react-native-pdf/PDF * indicates that a password is required or invalid. @@ -78,23 +58,29 @@ class PDFView extends Component { * Note that the message doesn't specify whether the password is simply empty or * invalid. */ - initiatePasswordChallenge() { - this.setState({shouldShowLoadingIndicator: false}); - - // Render password form, and don't render PDF and loading indicator. - this.setState({ - shouldRequestPassword: true, - shouldAttemptPDFLoad: false, - }); - + function initiatePasswordChallenge() { + setShouldShowLoadingIndicator(false); + setShouldRequestPassword(true); + setShouldAttemptPDFLoad(false); // The message provided by react-native-pdf doesn't indicate whether this // is an initial password request or if the password is invalid. So we just assume // that if a password was already entered then it's an invalid password error. - if (this.state.password) { - this.setState({isPasswordInvalid: true}); + if (password !== '') { + setIsPasswordInvalid(true); } } + function handleFailureToLoadPDF(error) { + if (error.message.match(/password/i)) { + initiatePasswordChallenge(); + return; + }; + setFailedToLoadPDF(true); + setShouldShowLoadingIndicator(false); + setShouldRequestPassword(false); + setShouldAttemptPDFLoad(false); + } + /** * When the password is submitted via PDFPasswordForm, save the password * in state and attempt to load the PDF. Also show the loading indicator @@ -102,71 +88,69 @@ class PDFView extends Component { * * @param {String} password Password submitted via PDFPasswordForm */ - attemptPDFLoadWithPassword(password) { + function attemptPDFLoadWithPassword(password) { // Render react-native-pdf/PDF so that it can validate the password. // Note that at this point in the password challenge, shouldRequestPassword is true. // Thus react-native-pdf/PDF will be rendered - but not visible. - this.setState({ - password, - shouldAttemptPDFLoad: true, - shouldShowLoadingIndicator: true, - }); - } + setPassword(password), + setShouldAttemptPDFLoad(true); + setShouldShowLoadingIndicator(true); - /** - * After the PDF is successfully loaded hide PDFPasswordForm and the loading - * indicator. - */ - finishPDFLoad() { - this.setState({ - shouldRequestPassword: false, - shouldShowLoadingIndicator: false, - successToLoadPDF: true, - }); - this.props.onLoadComplete(); } + + + /** + * After the PDF is successfully loaded hide PDFPasswordForm and the loading + * indicator. + */ + finishPDFLoad() { + setShouldRequestPassword(false); + setShouldShowLoadingIndicator(false); + setsuccessToLoadPDF(true); + props.onLoadComplete(); + } renderPDFView() { - const pdfStyles = [styles.imageModalPDF, StyleUtils.getWidthAndHeightStyle(this.props.windowWidth, this.props.windowHeight)]; + const pdfStyles = [styles.imageModalPDF, StyleUtils.getWidthAndHeightStyle(props.windowWidth, props.windowHeight)]; // If we haven't yet successfully validated the password and loaded the PDF, // then we need to hide the react-native-pdf/PDF component so that PDFPasswordForm // is positioned nicely. We're specifically hiding it because we still need to render // the PDF component so that it can validate the password. - if (this.state.shouldRequestPassword) { + if (shouldRequestPassword) { pdfStyles.push(styles.invisible); } - const containerStyles = this.state.shouldRequestPassword && this.props.isSmallScreenWidth ? [styles.w100, styles.flex1] : [styles.alignItemsCenter, styles.flex1]; + const containerStyles = shouldRequestPassword && props.isSmallScreenWidth ? [styles.w100, styles.flex1] : [styles.alignItemsCenter, styles.flex1]; return ( - {this.state.failedToLoadPDF && ( + {failedToLoadPDF && ( - {this.props.translate('attachmentView.failedToLoadPDF')} + {props.translate('attachmentView.failedToLoadPDF')} )} - {this.state.shouldAttemptPDFLoad && ( + {shouldAttemptPDFLoad && ( } - source={{uri: this.props.sourceURL}} + source={{uri: props.sourceURL}} style={pdfStyles} - onError={this.handleFailureToLoadPDF} - password={this.state.password} - onLoadComplete={this.finishPDFLoad} - onPageSingleTap={this.props.onPress} - onScaleChanged={this.props.onScaleChanged} + onError={handleFailureToLoadPDF} + password={state.password} + onLoadComplete={finishPDFLoad} + onPageSingleTap={props.onPress} + onScaleChanged={props.onScaleChanged} /> )} {this.state.shouldRequestPassword && ( this.setState({isPasswordInvalid: false})} - isPasswordInvalid={this.state.isPasswordInvalid} - shouldShowLoadingIndicator={this.state.shouldShowLoadingIndicator} + isFocused={props.isFocused} + onSubmit={attemptPDFLoadWithPassword} + onPasswordUpdated={() => setIsPasswordInvalid(false)} + isPasswordInvalid={isPasswordInvalid} + shouldShowLoadingIndicator={shouldShowLoadingIndicator} /> )} @@ -174,20 +158,18 @@ class PDFView extends Component { ); } - render() { - return this.props.onPress && !this.state.successToLoadPDF ? ( - - {this.renderPDFView()} - - ) : ( - this.renderPDFView() - ); - } + return props.onPress && !successToLoadPDF ? ( + + {renderPDFView()} + + ) : ( + renderPDFView() + ); } PDFView.propTypes = propTypes; From 0b36d7cc37bc92b519ba6a415cd6c73dac5a79c3 Mon Sep 17 00:00:00 2001 From: Kadie Alexander Date: Wed, 16 Aug 2023 20:03:21 +1200 Subject: [PATCH 002/567] began updating lifecycle method to useEffect --- src/components/PDFView/index.native.js | 29 +++++++++++--------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index 575d78ca955a..22d2aa557b7f 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -41,15 +41,12 @@ const [failedToLoadPDF, setFailedToLoadPDF] = useState(false), const [successToLoadPDF, setSuccessToLoadPDF] = useState(false), const [password, setPassword] = useState(''), +function PDFView(props) { -/* Ignoring this for last.*/ -componentDidUpdate() { - props .onToggleKeyboard(props.isKeyboardShown); -} - - + useEffect(() => { + props.onToggleKeyboard(props.isKeyboardShown); + },); -function PDFView(props) { /** * Initiate password challenge if message received from react-native-pdf/PDF * indicates that a password is required or invalid. @@ -97,20 +94,18 @@ function PDFView(props) { setShouldShowLoadingIndicator(true); } - - /** * After the PDF is successfully loaded hide PDFPasswordForm and the loading * indicator. */ - finishPDFLoad() { - setShouldRequestPassword(false); - setShouldShowLoadingIndicator(false); - setsuccessToLoadPDF(true); - props.onLoadComplete(); - } + function finishPDFLoad() { + setShouldRequestPassword(false); + setShouldShowLoadingIndicator(false); + setsuccessToLoadPDF(true); + props.onLoadComplete(); + } - renderPDFView() { + function renderPDFView() { const pdfStyles = [styles.imageModalPDF, StyleUtils.getWidthAndHeightStyle(props.windowWidth, props.windowHeight)]; // If we haven't yet successfully validated the password and loaded the PDF, @@ -143,7 +138,7 @@ function PDFView(props) { onScaleChanged={props.onScaleChanged} /> )} - {this.state.shouldRequestPassword && ( + {shouldRequestPassword && ( Date: Tue, 29 Aug 2023 20:56:23 +1200 Subject: [PATCH 003/567] latest useEffect updates --- src/components/PDFView/index.native.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index 22d2aa557b7f..799c9a6f35d3 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -35,11 +35,11 @@ const propTypes = { const [shouldRequestPassword, setShouldRequestPassword] = useState(false); const [shouldAttemptPDFLoad, setShouldAttemptPDFLoad] = useState(true); -const [shouldShowLoadingIndicator, setShouldShowLoadingIndicator] = useState(true), -const [isPasswordInvalid, setIsPasswordInvalid] = useState(false), -const [failedToLoadPDF, setFailedToLoadPDF] = useState(false), -const [successToLoadPDF, setSuccessToLoadPDF] = useState(false), -const [password, setPassword] = useState(''), +const [shouldShowLoadingIndicator, setShouldShowLoadingIndicator] = useState(true); +const [isPasswordInvalid, setIsPasswordInvalid] = useState(false); +const [failedToLoadPDF, setFailedToLoadPDF] = useState(false); +const [successToLoadPDF, setSuccessToLoadPDF] = useState(false); +const [password, setPassword] = useState(''); function PDFView(props) { @@ -166,7 +166,6 @@ function PDFView(props) { renderPDFView() ); } - PDFView.propTypes = propTypes; PDFView.defaultProps = defaultProps; From 00efb240c7b2b1a01ee16c63d5d73bb27ae3c09a Mon Sep 17 00:00:00 2001 From: Kadie Alexander Date: Tue, 17 Oct 2023 10:53:46 +1300 Subject: [PATCH 004/567] small errors found during testing --- src/components/PDFView/index.js | 43 ++++++++++---------------- src/components/PDFView/index.native.js | 22 ++++++------- 2 files changed, 27 insertions(+), 38 deletions(-) diff --git a/src/components/PDFView/index.js b/src/components/PDFView/index.js index bd5fe8162d2e..fd0180c082b8 100644 --- a/src/components/PDFView/index.js +++ b/src/components/PDFView/index.js @@ -32,31 +32,20 @@ const PAGE_BORDER = 9; */ const LARGE_SCREEN_SIDE_SPACING = 40; -class PDFView extends Component { - constructor(props) { - super(props); - this.state = { - numPages: null, - pageViewports: [], - containerWidth: props.windowWidth, - containerHeight: props.windowHeight, - shouldRequestPassword: false, - isPasswordInvalid: false, - isKeyboardOpen: false, - }; - this.onDocumentLoadSuccess = this.onDocumentLoadSuccess.bind(this); - this.initiatePasswordChallenge = this.initiatePasswordChallenge.bind(this); - this.attemptPDFLoad = this.attemptPDFLoad.bind(this); - this.toggleKeyboardOnSmallScreens = this.toggleKeyboardOnSmallScreens.bind(this); - this.calculatePageHeight = this.calculatePageHeight.bind(this); - this.calculatePageWidth = this.calculatePageWidth.bind(this); - this.renderPage = this.renderPage.bind(this); - this.getDevicePixelRatio = _.memoize(this.getDevicePixelRatio); - this.setListAttributes = this.setListAttributes.bind(this); +const [numPages, setNumPages] = useState(null); +const [pageViewports, setPageViewports] = useState([]); +const [containerWidth, setContainerWidth] = useState(props.windowWidth); +const [containerHeight, setContainerHeight] = useState(props.windowHeight); +const [shouldRequestPassword, setShouldRequestPassword] = useState(false); +const [isPasswordInvalid, setIsPasswordInvalid] = useState(false); +const [isKeyboardOpen, setIsKeyboardOpen] = useState(false); + +function PDFView(props) { + constructor(props) { const workerBlob = new Blob([pdfWorkerSource], {type: 'text/javascript'}); pdfjs.GlobalWorkerOptions.workerSrc = URL.createObjectURL(workerBlob); - this.retrieveCanvasLimits(); + retrieveCanvasLimits(); } componentDidUpdate(prevProps) { @@ -129,9 +118,9 @@ class PDFView extends Component { */ getDevicePixelRatio(width, height) { const nbPixels = width * height; - const ratioHeight = this.props.maxCanvasHeight / height; - const ratioWidth = this.props.maxCanvasWidth / width; - const ratioArea = Math.sqrt(this.props.maxCanvasArea / nbPixels); + const ratioHeight = maxCanvasHeight / height; + const ratioWidth = maxCanvasWidth / width; + const ratioArea = Math.sqrt(maxCanvasArea / nbPixels); const ratio = Math.min(ratioHeight, ratioArea, ratioWidth); return ratio > window.devicePixelRatio ? undefined : ratio; } @@ -144,13 +133,13 @@ class PDFView extends Component { * @returns {Number} */ calculatePageHeight(pageIndex) { - if (this.state.pageViewports.length === 0) { + if (pageViewports.length === 0) { Log.warn('Dev error: calculatePageHeight() in PDFView called too early'); return 0; } - const pageViewport = this.state.pageViewports[pageIndex]; + setPageViewport(pageIndex); const pageWidth = this.calculatePageWidth(); const scale = pageWidth / pageViewport.width; const actualHeight = pageViewport.height * scale + PAGE_BORDER * 2; diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index 5e5b3b910e8a..346a3bb409af 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -1,4 +1,4 @@ -import React, {Component} from 'react'; +import React, {useState, useEffect} from 'react'; import {View} from 'react-native'; import PDF from 'react-native-pdf'; import KeyboardAvoidingView from '../KeyboardAvoidingView'; @@ -33,16 +33,16 @@ const propTypes = { * is (temporarily) rendered. */ -const [shouldRequestPassword, setShouldRequestPassword] = useState(false); -const [shouldAttemptPDFLoad, setShouldAttemptPDFLoad] = useState(true); -const [shouldShowLoadingIndicator, setShouldShowLoadingIndicator] = useState(true); -const [isPasswordInvalid, setIsPasswordInvalid] = useState(false); -const [failedToLoadPDF, setFailedToLoadPDF] = useState(false); -const [successToLoadPDF, setSuccessToLoadPDF] = useState(false); -const [password, setPassword] = useState(''); - function PDFView(props) { + const [shouldRequestPassword, setShouldRequestPassword] = useState(false); + const [shouldAttemptPDFLoad, setShouldAttemptPDFLoad] = useState(true); + const [shouldShowLoadingIndicator, setShouldShowLoadingIndicator] = useState(true); + const [isPasswordInvalid, setIsPasswordInvalid] = useState(false); + const [failedToLoadPDF, setFailedToLoadPDF] = useState(false); + const [successToLoadPDF, setSuccessToLoadPDF] = useState(false); + const [password, setPassword] = useState(''); + useEffect(() => { props.onToggleKeyboard(props.isKeyboardShown); },); @@ -101,7 +101,7 @@ function PDFView(props) { function finishPDFLoad() { setShouldRequestPassword(false); setShouldShowLoadingIndicator(false); - setsuccessToLoadPDF(true); + setSuccessToLoadPDF(true); props.onLoadComplete(); } @@ -133,7 +133,7 @@ function PDFView(props) { source={{uri: props.sourceURL}} style={pdfStyles} onError={handleFailureToLoadPDF} - password={state.password} + password={password} onLoadComplete={finishPDFLoad} onPageSingleTap={props.onPress} onScaleChanged={props.onScaleChanged} From 520b39d3c3445c52a94758c8dec9c28c64ae58ea Mon Sep 17 00:00:00 2001 From: Kadie Alexander Date: Tue, 17 Oct 2023 13:36:43 +1300 Subject: [PATCH 005/567] trying to make lint happy --- src/components/PDFView/index.js | 43 ++++++++++++++++---------- src/components/PDFView/index.native.js | 29 +++++++++-------- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/components/PDFView/index.js b/src/components/PDFView/index.js index fd0180c082b8..bd5fe8162d2e 100644 --- a/src/components/PDFView/index.js +++ b/src/components/PDFView/index.js @@ -32,20 +32,31 @@ const PAGE_BORDER = 9; */ const LARGE_SCREEN_SIDE_SPACING = 40; -const [numPages, setNumPages] = useState(null); -const [pageViewports, setPageViewports] = useState([]); -const [containerWidth, setContainerWidth] = useState(props.windowWidth); -const [containerHeight, setContainerHeight] = useState(props.windowHeight); -const [shouldRequestPassword, setShouldRequestPassword] = useState(false); -const [isPasswordInvalid, setIsPasswordInvalid] = useState(false); -const [isKeyboardOpen, setIsKeyboardOpen] = useState(false); - - -function PDFView(props) { +class PDFView extends Component { constructor(props) { + super(props); + this.state = { + numPages: null, + pageViewports: [], + containerWidth: props.windowWidth, + containerHeight: props.windowHeight, + shouldRequestPassword: false, + isPasswordInvalid: false, + isKeyboardOpen: false, + }; + this.onDocumentLoadSuccess = this.onDocumentLoadSuccess.bind(this); + this.initiatePasswordChallenge = this.initiatePasswordChallenge.bind(this); + this.attemptPDFLoad = this.attemptPDFLoad.bind(this); + this.toggleKeyboardOnSmallScreens = this.toggleKeyboardOnSmallScreens.bind(this); + this.calculatePageHeight = this.calculatePageHeight.bind(this); + this.calculatePageWidth = this.calculatePageWidth.bind(this); + this.renderPage = this.renderPage.bind(this); + this.getDevicePixelRatio = _.memoize(this.getDevicePixelRatio); + this.setListAttributes = this.setListAttributes.bind(this); + const workerBlob = new Blob([pdfWorkerSource], {type: 'text/javascript'}); pdfjs.GlobalWorkerOptions.workerSrc = URL.createObjectURL(workerBlob); - retrieveCanvasLimits(); + this.retrieveCanvasLimits(); } componentDidUpdate(prevProps) { @@ -118,9 +129,9 @@ function PDFView(props) { */ getDevicePixelRatio(width, height) { const nbPixels = width * height; - const ratioHeight = maxCanvasHeight / height; - const ratioWidth = maxCanvasWidth / width; - const ratioArea = Math.sqrt(maxCanvasArea / nbPixels); + const ratioHeight = this.props.maxCanvasHeight / height; + const ratioWidth = this.props.maxCanvasWidth / width; + const ratioArea = Math.sqrt(this.props.maxCanvasArea / nbPixels); const ratio = Math.min(ratioHeight, ratioArea, ratioWidth); return ratio > window.devicePixelRatio ? undefined : ratio; } @@ -133,13 +144,13 @@ function PDFView(props) { * @returns {Number} */ calculatePageHeight(pageIndex) { - if (pageViewports.length === 0) { + if (this.state.pageViewports.length === 0) { Log.warn('Dev error: calculatePageHeight() in PDFView called too early'); return 0; } - setPageViewport(pageIndex); + const pageViewport = this.state.pageViewports[pageIndex]; const pageWidth = this.calculatePageWidth(); const scale = pageWidth / pageViewport.width; const actualHeight = pageViewport.height * scale + PAGE_BORDER * 2; diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index 346a3bb409af..e4cfe408c2a9 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -14,10 +14,11 @@ import withWindowDimensions from '../withWindowDimensions'; import withKeyboardState, {keyboardStatePropTypes} from '../withKeyboardState'; import withLocalize from '../withLocalize'; import CONST from '../../CONST'; + const propTypes = { ...pdfViewPropTypes, ...keyboardStatePropTypes, -} +}; /** * On the native layer, we use react-native-pdf/PDF to display PDFs. If a PDF is * password-protected we render a PDFPasswordForm to request a password @@ -34,7 +35,6 @@ const propTypes = { */ function PDFView(props) { - const [shouldRequestPassword, setShouldRequestPassword] = useState(false); const [shouldAttemptPDFLoad, setShouldAttemptPDFLoad] = useState(true); const [shouldShowLoadingIndicator, setShouldShowLoadingIndicator] = useState(true); @@ -45,7 +45,7 @@ function PDFView(props) { useEffect(() => { props.onToggleKeyboard(props.isKeyboardShown); - },); + }); /** * Initiate password challenge if message received from react-native-pdf/PDF @@ -71,7 +71,7 @@ function PDFView(props) { if (error.message.match(/password/i)) { initiatePasswordChallenge(); return; - }; + } setFailedToLoadPDF(true); setShouldShowLoadingIndicator(false); setShouldRequestPassword(false); @@ -83,21 +83,20 @@ function PDFView(props) { * in state and attempt to load the PDF. Also show the loading indicator * since react-native-pdf/PDF will need to reload the PDF. * - * @param {String} password Password submitted via PDFPasswordForm + * @param {String} pdfPassword Password submitted via PDFPasswordForm */ - function attemptPDFLoadWithPassword(password) { + function attemptPDFLoadWithPassword(pdfPassword) { // Render react-native-pdf/PDF so that it can validate the password. // Note that at this point in the password challenge, shouldRequestPassword is true. // Thus react-native-pdf/PDF will be rendered - but not visible. - setPassword(password), + setPassword(pdfPassword); setShouldAttemptPDFLoad(true); setShouldShowLoadingIndicator(true); - } - /** - * After the PDF is successfully loaded hide PDFPasswordForm and the loading - * indicator. - */ + /** + * After the PDF is successfully loaded hide PDFPasswordForm and the loading + * indicator. + */ function finishPDFLoad() { setShouldRequestPassword(false); setShouldShowLoadingIndicator(false); @@ -132,9 +131,9 @@ function PDFView(props) { renderActivityIndicator={() => } source={{uri: props.sourceURL}} style={pdfStyles} - onError={handleFailureToLoadPDF} + onError={() => handleFailureToLoadPDF} password={password} - onLoadComplete={finishPDFLoad} + onLoadComplete={() => finishPDFLoad} onPageSingleTap={props.onPress} onScaleChanged={props.onScaleChanged} /> @@ -143,7 +142,7 @@ function PDFView(props) { attemptPDFLoadWithPassword} onPasswordUpdated={() => setIsPasswordInvalid(false)} isPasswordInvalid={isPasswordInvalid} shouldShowLoadingIndicator={shouldShowLoadingIndicator} From 72f601da2c7de3bbbb445edf56554d1afaec6332 Mon Sep 17 00:00:00 2001 From: Kadie Alexander Date: Tue, 17 Oct 2023 14:51:12 +1300 Subject: [PATCH 006/567] Revert "small errors found during testing" This reverts commit 00efb240c7b2b1a01ee16c63d5d73bb27ae3c09a. --- src/components/PDFView/index.native.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index e4cfe408c2a9..e65b11411d2a 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -1,4 +1,4 @@ -import React, {useState, useEffect} from 'react'; +import React, {Component} from 'react'; import {View} from 'react-native'; import PDF from 'react-native-pdf'; import KeyboardAvoidingView from '../KeyboardAvoidingView'; @@ -34,14 +34,15 @@ const propTypes = { * is (temporarily) rendered. */ +const [shouldRequestPassword, setShouldRequestPassword] = useState(false); +const [shouldAttemptPDFLoad, setShouldAttemptPDFLoad] = useState(true); +const [shouldShowLoadingIndicator, setShouldShowLoadingIndicator] = useState(true); +const [isPasswordInvalid, setIsPasswordInvalid] = useState(false); +const [failedToLoadPDF, setFailedToLoadPDF] = useState(false); +const [successToLoadPDF, setSuccessToLoadPDF] = useState(false); +const [password, setPassword] = useState(''); + function PDFView(props) { - const [shouldRequestPassword, setShouldRequestPassword] = useState(false); - const [shouldAttemptPDFLoad, setShouldAttemptPDFLoad] = useState(true); - const [shouldShowLoadingIndicator, setShouldShowLoadingIndicator] = useState(true); - const [isPasswordInvalid, setIsPasswordInvalid] = useState(false); - const [failedToLoadPDF, setFailedToLoadPDF] = useState(false); - const [successToLoadPDF, setSuccessToLoadPDF] = useState(false); - const [password, setPassword] = useState(''); useEffect(() => { props.onToggleKeyboard(props.isKeyboardShown); @@ -100,7 +101,7 @@ function PDFView(props) { function finishPDFLoad() { setShouldRequestPassword(false); setShouldShowLoadingIndicator(false); - setSuccessToLoadPDF(true); + setsuccessToLoadPDF(true); props.onLoadComplete(); } @@ -131,9 +132,9 @@ function PDFView(props) { renderActivityIndicator={() => } source={{uri: props.sourceURL}} style={pdfStyles} - onError={() => handleFailureToLoadPDF} + onError={handleFailureToLoadPDF} password={password} - onLoadComplete={() => finishPDFLoad} + onLoadComplete={finishPDFLoad} onPageSingleTap={props.onPress} onScaleChanged={props.onScaleChanged} /> From 437ebebe85a22bc08ac5e95e53aa6cb3989bf04f Mon Sep 17 00:00:00 2001 From: Kadie Alexander Date: Tue, 17 Oct 2023 14:53:25 +1300 Subject: [PATCH 007/567] Revert "small errors found during testing" This reverts commit 00efb240c7b2b1a01ee16c63d5d73bb27ae3c09a. --- src/components/PDFView/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index e65b11411d2a..20a0230b9931 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -133,7 +133,7 @@ function PDFView(props) { source={{uri: props.sourceURL}} style={pdfStyles} onError={handleFailureToLoadPDF} - password={password} + password={state.password} onLoadComplete={finishPDFLoad} onPageSingleTap={props.onPress} onScaleChanged={props.onScaleChanged} From 3597be6d5c79abe2a02ba5d3e019140b1230247c Mon Sep 17 00:00:00 2001 From: Kadie Alexander Date: Tue, 17 Oct 2023 15:59:49 +1300 Subject: [PATCH 008/567] fix functions and run lint/prettier --- src/components/PDFView/index.native.js | 27 +++++++++++++------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/components/PDFView/index.native.js b/src/components/PDFView/index.native.js index 20a0230b9931..d0b6af5a6be6 100644 --- a/src/components/PDFView/index.native.js +++ b/src/components/PDFView/index.native.js @@ -1,4 +1,4 @@ -import React, {Component} from 'react'; +import React, {useState, useEffect} from 'react'; import {View} from 'react-native'; import PDF from 'react-native-pdf'; import KeyboardAvoidingView from '../KeyboardAvoidingView'; @@ -34,15 +34,14 @@ const propTypes = { * is (temporarily) rendered. */ -const [shouldRequestPassword, setShouldRequestPassword] = useState(false); -const [shouldAttemptPDFLoad, setShouldAttemptPDFLoad] = useState(true); -const [shouldShowLoadingIndicator, setShouldShowLoadingIndicator] = useState(true); -const [isPasswordInvalid, setIsPasswordInvalid] = useState(false); -const [failedToLoadPDF, setFailedToLoadPDF] = useState(false); -const [successToLoadPDF, setSuccessToLoadPDF] = useState(false); -const [password, setPassword] = useState(''); - function PDFView(props) { + const [shouldRequestPassword, setShouldRequestPassword] = useState(false); + const [shouldAttemptPDFLoad, setShouldAttemptPDFLoad] = useState(true); + const [shouldShowLoadingIndicator, setShouldShowLoadingIndicator] = useState(true); + const [isPasswordInvalid, setIsPasswordInvalid] = useState(false); + const [failedToLoadPDF, setFailedToLoadPDF] = useState(false); + const [successToLoadPDF, setSuccessToLoadPDF] = useState(false); + const [password, setPassword] = useState(''); useEffect(() => { props.onToggleKeyboard(props.isKeyboardShown); @@ -101,7 +100,7 @@ function PDFView(props) { function finishPDFLoad() { setShouldRequestPassword(false); setShouldShowLoadingIndicator(false); - setsuccessToLoadPDF(true); + setSuccessToLoadPDF(true); props.onLoadComplete(); } @@ -132,9 +131,9 @@ function PDFView(props) { renderActivityIndicator={() => } source={{uri: props.sourceURL}} style={pdfStyles} - onError={handleFailureToLoadPDF} - password={state.password} - onLoadComplete={finishPDFLoad} + onError={(error) => handleFailureToLoadPDF(error)} + password={password} + onLoadComplete={() => finishPDFLoad()} onPageSingleTap={props.onPress} onScaleChanged={props.onScaleChanged} /> @@ -143,7 +142,7 @@ function PDFView(props) { attemptPDFLoadWithPassword} + onSubmit={() => attemptPDFLoadWithPassword()} onPasswordUpdated={() => setIsPasswordInvalid(false)} isPasswordInvalid={isPasswordInvalid} shouldShowLoadingIndicator={shouldShowLoadingIndicator} From d7ef177d026828596c934d6c421f9ece149b32ea Mon Sep 17 00:00:00 2001 From: Michal Muzyk Date: Wed, 25 Oct 2023 11:20:04 +0200 Subject: [PATCH 009/567] feat: personal info page --- .../substeps/FullNamePersonalStep.js | 67 +++++++++++++++++++ .../ReimbursementAccount/subStepPropTypes.js | 9 +++ 2 files changed, 76 insertions(+) create mode 100644 src/pages/ReimbursementAccount/PersonalInfo/substeps/FullNamePersonalStep.js create mode 100644 src/pages/ReimbursementAccount/subStepPropTypes.js diff --git a/src/pages/ReimbursementAccount/PersonalInfo/substeps/FullNamePersonalStep.js b/src/pages/ReimbursementAccount/PersonalInfo/substeps/FullNamePersonalStep.js new file mode 100644 index 000000000000..e74d1bb129c1 --- /dev/null +++ b/src/pages/ReimbursementAccount/PersonalInfo/substeps/FullNamePersonalStep.js @@ -0,0 +1,67 @@ +import React from 'react'; +import {View} from 'react-native'; +import useLocalize from '../../../../hooks/useLocalize'; +import styles from '../../../../styles/styles'; +import TextInput from '../../../../components/TextInput'; +import CONST from '../../../../CONST'; +import Form from '../../../../components/Form'; +import ONYXKEYS from '../../../../ONYXKEYS'; +import subStepPropTypes from '../../subStepPropTypes'; + +const propTypes = { + ...subStepPropTypes, +}; + +const validate = (values) => {}; + +function FullNamePersonalStep({onNext}) { + const {translate} = useLocalize(); + + return ( + +
+ + + props.onFieldChange({firstName: value})} + errorText={props.errors.firstName ? props.translate('bankAccount.error.firstName') : ''} + /> + + + props.onFieldChange({lastName: value})} + errorText={props.errors.lastName ? props.translate('bankAccount.error.lastName') : ''} + /> + + +
+
+ ); +} + +FullNamePersonalStep.propTypes = propTypes; +FullNamePersonalStep.defaultProps = defaultProps; +FullNamePersonalStep.displayName = 'FullNamePersonalStep'; + +export default compose(withOnyx({}))(FullNamePersonalStep); diff --git a/src/pages/ReimbursementAccount/subStepPropTypes.js b/src/pages/ReimbursementAccount/subStepPropTypes.js new file mode 100644 index 000000000000..058e0cc78c56 --- /dev/null +++ b/src/pages/ReimbursementAccount/subStepPropTypes.js @@ -0,0 +1,9 @@ +import PropTypes from 'prop-types'; + +const subStepPropTypes = { + isEditing: PropTypes.bool.isRequired, + onNext: PropTypes.func.isRequired, + onMove: PropTypes.func.isRequired, +}; + +export default subStepPropTypes; From 70e00562acef33a84af3118477d9873488693307 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Wed, 25 Oct 2023 15:14:24 +0200 Subject: [PATCH 010/567] Created Interactive Step Header --- src/components/InteractiveStepSubHeader.js | 100 ++++++++++++++++++ .../InteractiveStepSubHeader.stories.js | 54 ++++++++++ src/styles/styles.ts | 47 ++++++++ 3 files changed, 201 insertions(+) create mode 100644 src/components/InteractiveStepSubHeader.js create mode 100644 src/stories/InteractiveStepSubHeader.stories.js diff --git a/src/components/InteractiveStepSubHeader.js b/src/components/InteractiveStepSubHeader.js new file mode 100644 index 000000000000..63850230e0d2 --- /dev/null +++ b/src/components/InteractiveStepSubHeader.js @@ -0,0 +1,100 @@ +import React, {forwardRef, useState, useImperativeHandle} from 'react'; +import PropTypes from 'prop-types'; +import map from 'lodash/map'; +import {View} from 'react-native'; + +import CONST from '../CONST'; +import variables from '../styles/variables'; +import styles from '../styles/styles'; +import colors from '../styles/colors'; +import * as Expensicons from './Icon/Expensicons'; +import PressableWithFeedback from './Pressable/PressableWithFeedback'; +import Text from './Text'; +import Icon from './Icon'; + +const propTypes = { + stepNames: PropTypes.arrayOf(PropTypes.string).isRequired, + onStepSelected: PropTypes.func.isRequired, + startStep: PropTypes.number, +}; + +const defaultProps = { + startStep: 0, +}; + +const MIN_AMOUNT_FOR_EXPANDING = 3; +const MIN_AMOUNT_OF_STEPS = 2; + +function InteractiveStepSubHeader({stepNames, startStep, onStepSelected}, ref) { + const [currentStep, setCurrentStep] = useState(startStep); + useImperativeHandle( + ref, + () => ({ + moveNext: () => { + setCurrentStep((actualStep) => actualStep + 1); + }, + }), + [], + ); + + if (stepNames.length < MIN_AMOUNT_OF_STEPS) { + console.warn('InteractiveStepSubHeader: stepNames prop must have at least 2 elements'); + return null; + } + + const amountOfUnions = stepNames.length - 1; + + return ( + + {map(stepNames, (stepName, index) => { + const isCompletedStep = currentStep > index; + const isLockedStep = currentStep < index; + const isLockedLine = currentStep < index + 1; + const hasUnion = index < amountOfUnions; + + const moveToStep = () => { + if (isLockedStep) { + return; + } + setCurrentStep(index); + onStepSelected(stepNames[index]); + }; + return ( + + + {isCompletedStep ? ( + + ) : ( + {index + 1} + )} + + {hasUnion ? : null} + + ); + })} + + ); +} + +InteractiveStepSubHeader.propTypes = propTypes; +InteractiveStepSubHeader.defaultProps = defaultProps; +InteractiveStepSubHeader.displayName = 'InteractiveStepSubHeader'; + +export default forwardRef(InteractiveStepSubHeader); diff --git a/src/stories/InteractiveStepSubHeader.stories.js b/src/stories/InteractiveStepSubHeader.stories.js new file mode 100644 index 000000000000..4e932bc5a9d7 --- /dev/null +++ b/src/stories/InteractiveStepSubHeader.stories.js @@ -0,0 +1,54 @@ +/* eslint-disable react/jsx-props-no-spreading */ +import React, {useRef} from 'react'; +import {View, Button} from 'react-native'; + +import InteractiveStepSubHeader from '../components/InteractiveStepSubHeader'; + +/** + * We use the Component Story Format for writing stories. Follow the docs here: + * + * https://storybook.js.org/docs/react/writing-stories/introduction#component-story-format + */ +const story = { + title: 'Components/InteractiveStepSubHeader', + component: InteractiveStepSubHeader, +}; + +function Template(args) { + // eslint-disable-next-line react/jsx-props-no-spreading + return ; +} + +// Arguments can be passed to the component by binding +// See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +const Default = Template.bind({}); + +function BaseInteractiveStepSubHeader(props) { + const ref = useRef(null); + return ( + + +