From 182d10aa2e754d51347cbcdafdd8fcfe2d3ff46b Mon Sep 17 00:00:00 2001 From: Kadie Alexander Date: Tue, 14 Nov 2023 10:53:56 +1300 Subject: [PATCH 1/3] fix branch issues --- src/components/PDFView/index.js | 212 ++++++++++++++++---------------- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/src/components/PDFView/index.js b/src/components/PDFView/index.js index fd01176d9fb2..83629b0b67e1 100644 --- a/src/components/PDFView/index.js +++ b/src/components/PDFView/index.js @@ -32,44 +32,31 @@ 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 workerBlob = new Blob([pdfWorkerSource], {type: 'text/javascript'}); - pdfjs.GlobalWorkerOptions.workerSrc = URL.createObjectURL(workerBlob); - this.retrieveCanvasLimits(); - } +function PDFView(props) { + const [numPages, setNumPages] = null; + const [pageViewports, setPageViewports] = []; + const [containerWidth, setContainerWidth] = props.windowWidth; + const [containerHeight, setContainerHeight] = props.windowHeight; + const [shouldRequestPassword, setShouldRequestPassword] = false; + const [isPasswordInvalid, setIsPasswordInvalid] = false; + const [isKeyboardOpen, setIsKeyboardOpen] = false; + + const workerBlob = new Blob([pdfWorkerSource], {type: 'text/javascript'}); + pdfjs.GlobalWorkerOptions.workerSrc = URL.createObjectURL(workerBlob); + retrieveCanvasLimits(); + - componentDidUpdate(prevProps) { + function componentDidUpdate(prevProps) { // Use window height changes to toggle the keyboard. To maintain keyboard state // on all platforms we also use focus/blur events. So we need to make sure here // that we avoid redundant keyboard toggling. // Minus 100px is needed to make sure that when the internet connection is // disabled in android chrome and a small 'No internet connection' text box appears, // we do not take it as a sign to open the keyboard - if (!this.state.isKeyboardOpen && this.props.windowHeight < prevProps.windowHeight - 100) { - this.toggleKeyboardOnSmallScreens(true); - } else if (this.state.isKeyboardOpen && this.props.windowHeight > prevProps.windowHeight) { - this.toggleKeyboardOnSmallScreens(false); + if (!isKeyboardOpen && props.windowHeight < prevProps.windowHeight - 100) { + toggleKeyboardOnSmallScreens(true); + } else if (isKeyboardOpen && props.windowHeight > prevProps.windowHeight) { + toggleKeyboardOnSmallScreens(false); } } @@ -84,7 +71,7 @@ class PDFView extends Component { * @param {Function} pdf.getPage - A method to get page by its number. It requires to have the context. It should be the pdf itself. * @memberof PDFView */ - onDocumentLoadSuccess(pdf) { + function onDocumentLoadSuccess(pdf) { const {numPages} = pdf; Promise.all( @@ -94,12 +81,10 @@ class PDFView extends Component { return pdf.getPage(pageNumber).then((page) => page.getViewport({scale: 1})); }), ).then((pageViewports) => { - this.setState({ - pageViewports, - numPages, - shouldRequestPassword: false, - isPasswordInvalid: false, - }); + setPageViewports(); + setNumPages(); + setShouldRequestPassword(false); + setIsPasswordInvalid(false); }); } @@ -108,7 +93,7 @@ class PDFView extends Component { * It unblocks a default scroll by keyboard of browsers. * @param {Object|undefined} ref */ - setListAttributes(ref) { + function setListAttributes(ref) { if (!ref) { return; } @@ -127,11 +112,11 @@ class PDFView extends Component { * @param {Number} height of the page * @returns {Number} devicePixelRatio for this page on this platform */ - getDevicePixelRatio(width, height) { + function 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 = props.maxCanvasHeight / height; + const ratioWidth = props.maxCanvasWidth / width; + const ratioArea = Math.sqrt(props.maxCanvasArea / nbPixels); const ratio = Math.min(ratioHeight, ratioArea, ratioWidth); return ratio > window.devicePixelRatio ? undefined : ratio; } @@ -143,15 +128,15 @@ class PDFView extends Component { * @param {Number} pageIndex * @returns {Number} */ - calculatePageHeight(pageIndex) { - if (this.state.pageViewports.length === 0) { + function calculatePageHeight(pageIndex) { + if (pageViewports.length === 0) { Log.warn('Dev error: calculatePageHeight() in PDFView called too early'); return 0; } - const pageViewport = this.state.pageViewports[pageIndex]; - const pageWidth = this.calculatePageWidth(); + const pageViewport = pageViewports[pageIndex]; + const pageWidth = calculatePageWidth(); const scale = pageWidth / pageViewport.width; const actualHeight = pageViewport.height * scale + PAGE_BORDER * 2; @@ -163,10 +148,10 @@ class PDFView extends Component { * It depends on a screen size. Also, the app should take into account the page borders. * @returns {Number} */ - calculatePageWidth() { - const pdfContainerWidth = this.state.containerWidth; + function calculatePageWidth() { + const pdfContainerWidth = containerWidth; const pageWidthOnLargeScreen = Math.min(pdfContainerWidth - LARGE_SCREEN_SIDE_SPACING * 2, variables.pdfPageMaxWidth); - const pageWidth = this.props.isSmallScreenWidth ? this.state.containerWidth : pageWidthOnLargeScreen; + const pageWidth = props.isSmallScreenWidth ? containerWidth : pageWidthOnLargeScreen; return pageWidth + PAGE_BORDER * 2; } @@ -183,13 +168,14 @@ class PDFView extends Component { * @param {Function} callback Callback used to send password to react-pdf * @param {Number} reason Reason code for password request */ - initiatePasswordChallenge(callback, reason) { - this.onPasswordCallback = callback; + function initiatePasswordChallenge(callback, reason) { + onPasswordCallback = callback; if (reason === CONST.PDF_PASSWORD_FORM.REACT_PDF_PASSWORD_RESPONSES.NEED_PASSWORD) { - this.setState({shouldRequestPassword: true}); + setShouldRequestPassword(true); } else if (reason === CONST.PDF_PASSWORD_FORM.REACT_PDF_PASSWORD_RESPONSES.INCORRECT_PASSWORD) { - this.setState({shouldRequestPassword: true, isPasswordInvalid: true}); + setShouldRequestPassword(true); + setIsPasswordInvalid(true); } } @@ -199,8 +185,8 @@ class PDFView extends Component { * * @param {String} password Password to send via callback to react-pdf */ - attemptPDFLoad(password) { - this.onPasswordCallback(password); + function attemptPDFLoad(password) { + onPasswordCallback(password); } /** @@ -208,27 +194,27 @@ class PDFView extends Component { * * @param {Boolean} isKeyboardOpen True if keyboard is open */ - toggleKeyboardOnSmallScreens(isKeyboardOpen) { - if (!this.props.isSmallScreenWidth) { + function toggleKeyboardOnSmallScreens(isKeyboardOpen) { + if (!props.isSmallScreenWidth) { return; } - this.setState({isKeyboardOpen}); - this.props.onToggleKeyboard(isKeyboardOpen); + setIsKeyboardOpen(); + props.onToggleKeyboard(isKeyboardOpen); } /** * Verify that the canvas limits have been calculated already, if not calculate them and put them in Onyx */ - retrieveCanvasLimits() { - if (!this.props.maxCanvasArea) { + function retrieveCanvasLimits() { + if (!props.maxCanvasArea) { CanvasSize.retrieveMaxCanvasArea(); } - if (!this.props.maxCanvasHeight) { + if (!props.maxCanvasHeight) { CanvasSize.retrieveMaxCanvasHeight(); } - if (!this.props.maxCanvasWidth) { + if (!props.maxCanvasWidth) { CanvasSize.retrieveMaxCanvasWidth(); } } @@ -241,10 +227,10 @@ class PDFView extends Component { * @param {Object} page.style virtualized styles * @returns {JSX.Element} */ - renderPage({index, style}) { - const pageWidth = this.calculatePageWidth(); - const pageHeight = this.calculatePageHeight(index); - const devicePixelRatio = this.getDevicePixelRatio(pageWidth, pageHeight); + function renderPage({index, style}) { + const pageWidth = calculatePageWidth(); + const pageHeight = calculatePageHeight(index); + const devicePixelRatio = getDevicePixelRatio(pageWidth, pageHeight); return ( @@ -261,15 +247,15 @@ class PDFView extends Component { ); } - renderPDFView() { - const pageWidth = this.calculatePageWidth(); + function renderPDFView() { + const pageWidth = calculatePageWidth(); const outerContainerStyle = [styles.w100, styles.h100, styles.justifyContentCenter, styles.alignItemsCenter]; // If we're requesting a password then we need to hide - but still render - // the PDF component. - const pdfContainerStyle = this.state.shouldRequestPassword - ? [styles.PDFView, styles.noSelect, this.props.style, styles.invisible] - : [styles.PDFView, styles.noSelect, this.props.style]; + const pdfContainerStyle = shouldRequestPassword + ? [styles.PDFView, styles.noSelect, props.style, styles.invisible] + : [styles.PDFView, styles.noSelect, props.style]; return ( @@ -280,64 +266,64 @@ class PDFView extends Component { nativeEvent: { layout: {width, height}, }, - }) => this.setState({containerWidth: width, containerHeight: height})} + }) => setState({containerWidth: width, containerHeight: height})} > {this.props.translate('attachmentView.failedToLoadPDF')}} + error={{props.translate('attachmentView.failedToLoadPDF')}} loading={} - file={this.props.sourceURL} + file={props.sourceURL} options={{ cMapUrl: 'cmaps/', cMapPacked: true, }} externalLinkTarget="_blank" - onLoadSuccess={this.onDocumentLoadSuccess} - onPassword={this.initiatePasswordChallenge} + onLoadSuccess={onDocumentLoadSuccess} + onPassword={initiatePasswordChallenge} > - {this.state.pageViewports.length > 0 && ( + {pageViewports.length > 0 && ( - {this.renderPage} + {renderPage} )} - {this.state.shouldRequestPassword && ( + {shouldRequestPassword && ( this.setState({isPasswordInvalid: false})} - isPasswordInvalid={this.state.isPasswordInvalid} - onPasswordFieldFocused={this.toggleKeyboardOnSmallScreens} + isFocused={props.isFocused} + onSubmit={attemptPDFLoad} + onPasswordUpdated={() => setIsPasswordInvalid(false)} + isPasswordInvalid={isPasswordInvalid} + onPasswordFieldFocused={toggleKeyboardOnSmallScreens} /> )} ); } - render() { - return this.props.onPress ? ( - - {this.renderPDFView()} - - ) : ( - this.renderPDFView() - ); - } + + return props.onPress ? ( + + {renderPDFView()} + + ) : ( + renderPDFView() + ); } + PDFView.propTypes = pdfViewPropTypes.propTypes; PDFView.defaultProps = pdfViewPropTypes.defaultProps; @@ -355,4 +341,18 @@ export default compose( key: ONYXKEYS.MAX_CANVAS_WIDTH, }, }), +)(PDFView); + withLocalize, + withWindowDimensions, + withOnyx({ + maxCanvasArea: { + key: ONYXKEYS.MAX_CANVAS_AREA, + }, + maxCanvasHeight: { + key: ONYXKEYS.MAX_CANVAS_HEIGHT, + }, + maxCanvasWidth: { + key: ONYXKEYS.MAX_CANVAS_WIDTH, + }, + }), )(PDFView); From d553f84f1a2c496f1b6ed6db702d0d2937f4a974 Mon Sep 17 00:00:00 2001 From: Kadie Alexander Date: Tue, 28 Nov 2023 09:06:36 +1300 Subject: [PATCH 2/3] tweaks to functions --- src/components/PDFView/index.js | 104 +++++++++++++++----------------- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/src/components/PDFView/index.js b/src/components/PDFView/index.js index 83629b0b67e1..5757f0bd74a3 100644 --- a/src/components/PDFView/index.js +++ b/src/components/PDFView/index.js @@ -40,11 +40,20 @@ function PDFView(props) { const [shouldRequestPassword, setShouldRequestPassword] = false; const [isPasswordInvalid, setIsPasswordInvalid] = false; const [isKeyboardOpen, setIsKeyboardOpen] = false; + let onPasswordCallback; - const workerBlob = new Blob([pdfWorkerSource], {type: 'text/javascript'}); - pdfjs.GlobalWorkerOptions.workerSrc = URL.createObjectURL(workerBlob); - retrieveCanvasLimits(); - + /** + * On small screens notify parent that the keyboard has opened or closed. + * + * @param {Boolean} keyboardState True if keyboard is open + */ + function toggleKeyboardOnSmallScreens(keyboardState) { + if (!props.isSmallScreenWidth) { + return; + } + setIsKeyboardOpen(keyboardState); + props.onToggleKeyboard(keyboardState); + } function componentDidUpdate(prevProps) { // Use window height changes to toggle the keyboard. To maintain keyboard state @@ -72,17 +81,17 @@ function PDFView(props) { * @memberof PDFView */ function onDocumentLoadSuccess(pdf) { - const {numPages} = pdf; + const {numberOfPages} = pdf; Promise.all( - _.times(numPages, (index) => { + _.times(numberOfPages, (index) => { const pageNumber = index + 1; return pdf.getPage(pageNumber).then((page) => page.getViewport({scale: 1})); }), - ).then((pageViewports) => { - setPageViewports(); - setNumPages(); + ).then((pgViewports) => { + setPageViewports(pgViewports); + setNumPages(numberOfPages); setShouldRequestPassword(false); setIsPasswordInvalid(false); }); @@ -121,6 +130,19 @@ function PDFView(props) { return ratio > window.devicePixelRatio ? undefined : ratio; } + /** + * Calculates a proper page width. + * It depends on a screen size. Also, the app should take into account the page borders. + * @returns {Number} + */ + function calculatePageWidth() { + const pdfContainerWidth = containerWidth; + const pageWidthOnLargeScreen = Math.min(pdfContainerWidth - LARGE_SCREEN_SIDE_SPACING * 2, variables.pdfPageMaxWidth); + const pageWidth = props.isSmallScreenWidth ? containerWidth : pageWidthOnLargeScreen; + + return pageWidth + PAGE_BORDER * 2; + } + /** * Calculates a proper page height. The method should be called only when there are page viewports. * It is based on a ratio between the specific page viewport width and provided page width. @@ -143,19 +165,6 @@ function PDFView(props) { return actualHeight; } - /** - * Calculates a proper page width. - * It depends on a screen size. Also, the app should take into account the page borders. - * @returns {Number} - */ - function calculatePageWidth() { - const pdfContainerWidth = containerWidth; - const pageWidthOnLargeScreen = Math.min(pdfContainerWidth - LARGE_SCREEN_SIDE_SPACING * 2, variables.pdfPageMaxWidth); - const pageWidth = props.isSmallScreenWidth ? containerWidth : pageWidthOnLargeScreen; - - return pageWidth + PAGE_BORDER * 2; - } - /** * Initiate password challenge process. The react-pdf/Document * component calls this handler to indicate that a PDF requires a @@ -189,19 +198,6 @@ function PDFView(props) { onPasswordCallback(password); } - /** - * On small screens notify parent that the keyboard has opened or closed. - * - * @param {Boolean} isKeyboardOpen True if keyboard is open - */ - function toggleKeyboardOnSmallScreens(isKeyboardOpen) { - if (!props.isSmallScreenWidth) { - return; - } - setIsKeyboardOpen(); - props.onToggleKeyboard(isKeyboardOpen); - } - /** * Verify that the canvas limits have been calculated already, if not calculate them and put them in Onyx */ @@ -219,6 +215,10 @@ function PDFView(props) { } } + const workerBlob = new Blob([pdfWorkerSource], {type: 'text/javascript'}); + pdfjs.GlobalWorkerOptions.workerSrc = URL.createObjectURL(workerBlob); + retrieveCanvasLimits(); + /** * Render a specific page based on its index. * The method includes a wrapper to apply virtualized styles. @@ -266,7 +266,11 @@ function PDFView(props) { nativeEvent: { layout: {width, height}, }, - }) => setState({containerWidth: width, containerHeight: height})} + }) => { + setContainerWidth(width); + setContainerHeight(height); + } + } > {props.translate('attachmentView.failedToLoadPDF')}} @@ -277,18 +281,18 @@ function PDFView(props) { cMapPacked: true, }} externalLinkTarget="_blank" - onLoadSuccess={onDocumentLoadSuccess} - onPassword={initiatePasswordChallenge} + onLoadSuccess={() => onDocumentLoadSuccess} + onPassword={() => initiatePasswordChallenge} > {pageViewports.length > 0 && ( setListAttributes} style={styles.PDFViewList} width={props.isSmallScreenWidth ? pageWidth : containerWidth} height={containerHeight} estimatedItemSize={calculatePageHeight(0)} - itemCount={state.numPages} - itemSize={calculatePageHeight} + itemCount={() => numPages} + itemSize={() => calculatePageHeight} > {renderPage} @@ -298,10 +302,10 @@ function PDFView(props) { {shouldRequestPassword && ( attemptPDFLoad} onPasswordUpdated={() => setIsPasswordInvalid(false)} isPasswordInvalid={isPasswordInvalid} - onPasswordFieldFocused={toggleKeyboardOnSmallScreens} + onPasswordFieldFocused={() => toggleKeyboardOnSmallScreens} /> )} @@ -341,18 +345,4 @@ export default compose( key: ONYXKEYS.MAX_CANVAS_WIDTH, }, }), -)(PDFView); - withLocalize, - withWindowDimensions, - withOnyx({ - maxCanvasArea: { - key: ONYXKEYS.MAX_CANVAS_AREA, - }, - maxCanvasHeight: { - key: ONYXKEYS.MAX_CANVAS_HEIGHT, - }, - maxCanvasWidth: { - key: ONYXKEYS.MAX_CANVAS_WIDTH, - }, - }), )(PDFView); From 4c4694032c122b9df6b8d930d60bdabda3cd7742 Mon Sep 17 00:00:00 2001 From: Kadie Alexander Date: Tue, 9 Jan 2024 09:03:49 +1300 Subject: [PATCH 3/3] merging main --- src/components/PDFView/index.js | 41 +++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/components/PDFView/index.js b/src/components/PDFView/index.js index 4488ef9b9ee7..5dcb0be14b93 100644 --- a/src/components/PDFView/index.js +++ b/src/components/PDFView/index.js @@ -9,10 +9,15 @@ import _ from 'underscore'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import Text from '@components/Text'; -import withLocalize from '@components/withLocalize'; +import usePrevious from '@hooks/usePrevious'; +import useLocalize from '@components/useLocalize'; +import useKeyboardState from '@hooks/useKeyboardState'; +import useWindowDimensions from '@hooks/useWindowDimensions'; +import compose from '@libs/compose'; +import useStyleUtils from '@styles/useStyleUtils'; +import useThemeStyles from '@styles/useThemeStyles'; import withThemeStyles from '@components/withThemeStyles'; import withWindowDimensions from '@components/withWindowDimensions'; -import compose from '@libs/compose'; import Log from '@libs/Log'; import variables from '@styles/variables'; import * as CanvasSize from '@userActions/CanvasSize'; @@ -33,10 +38,15 @@ const PAGE_BORDER = 9; const LARGE_SCREEN_SIDE_SPACING = 40; function PDFView(props) { + const {windowWidth, windowHeight, isSmallScreenWidth} = useWindowDimensions(); + const {translate} = useLocalize(); + const styles = useThemeStyles(); + const isKeyboardShown = useKeyboardState(); + const StyleUtils = useStyleUtils(); const [numPages, setNumPages] = null; const [pageViewports, setPageViewports] = []; - const [containerWidth, setContainerWidth] = props.windowWidth; - const [containerHeight, setContainerHeight] = props.windowHeight; + const [containerWidth, setContainerWidth] = windowWidth; + const [containerHeight, setContainerHeight] = windowHeight; const [shouldRequestPassword, setShouldRequestPassword] = false; const [isPasswordInvalid, setIsPasswordInvalid] = false; const [isKeyboardOpen, setIsKeyboardOpen] = false; @@ -48,26 +58,27 @@ function PDFView(props) { * @param {Boolean} keyboardState True if keyboard is open */ function toggleKeyboardOnSmallScreens(keyboardState) { - if (!props.isSmallScreenWidth) { + if (isSmallScreenWidth) { return; } setIsKeyboardOpen(keyboardState); - props.onToggleKeyboard(keyboardState); + onToggleKeyboard(keyboardState); } - function componentDidUpdate(prevProps) { + useEffect(() => { + // Use window height changes to toggle the keyboard. To maintain keyboard state // on all platforms we also use focus/blur events. So we need to make sure here // that we avoid redundant keyboard toggling. // Minus 100px is needed to make sure that when the internet connection is // disabled in android chrome and a small 'No internet connection' text box appears, // we do not take it as a sign to open the keyboard - if (!isKeyboardOpen && props.windowHeight < prevProps.windowHeight - 100) { + if (!isKeyboardOpen && windowHeight < usePrevious(windowHeight) - 100) { toggleKeyboardOnSmallScreens(true); - } else if (isKeyboardOpen && props.windowHeight > prevProps.windowHeight) { + } else if (isKeyboardOpen && windowHeight > usePrevious(windowHeight)) { toggleKeyboardOnSmallScreens(false); } - } + }); /** * Upon successful document load, combine an array of page viewports, @@ -138,7 +149,7 @@ function PDFView(props) { function calculatePageWidth() { const pdfContainerWidth = containerWidth; const pageWidthOnLargeScreen = Math.min(pdfContainerWidth - LARGE_SCREEN_SIDE_SPACING * 2, variables.pdfPageMaxWidth); - const pageWidth = props.isSmallScreenWidth ? containerWidth : pageWidthOnLargeScreen; + const pageWidth = isSmallScreenWidth ? containerWidth : pageWidthOnLargeScreen; return pageWidth + PAGE_BORDER * 2; } @@ -248,7 +259,6 @@ function PDFView(props) { } renderPDFView() { - const styles = props.themeStyles; const pageWidth = this.calculatePageWidth(); const outerContainerStyle = [styles.w100, styles.h100, styles.justifyContentCenter, styles.alignItemsCenter]; @@ -274,7 +284,7 @@ function PDFView(props) { } > {props.translate('attachmentView.failedToLoadPDF')}} + error={{translate('attachmentView.failedToLoadPDF')}} loading={} file={props.sourceURL} options={{ @@ -289,7 +299,7 @@ function PDFView(props) { setListAttributes} style={styles.PDFViewList} - width={props.isSmallScreenWidth ? pageWidth : containerWidth} + width={isSmallScreenWidth ? pageWidth : containerWidth} height={containerHeight} estimatedItemSize={calculatePageHeight(0)} itemCount={() => numPages} @@ -334,9 +344,6 @@ PDFView.propTypes = pdfViewPropTypes.propTypes; PDFView.defaultProps = pdfViewPropTypes.defaultProps; export default compose( - withLocalize, - withWindowDimensions, - withThemeStyles, withOnyx({ maxCanvasArea: { key: ONYXKEYS.MAX_CANVAS_AREA,