Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TS migration] Migrate 'PDFView' component to TypeScript #39011

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ function BaseAttachmentViewPdf({

return (
<PDFView
// @ts-expect-error waiting for https://github.com/Expensify/App/issues/16186 merge
onPress={onPress}
isFocused={isFocused}
sourceURL={encryptedSourceUrl}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type AttachmentViewPdfProps from './types';
function AttachmentViewPdf({file, encryptedSourceUrl, isFocused, onPress, onToggleKeyboard, onLoadComplete, errorLabelStyles, style}: AttachmentViewPdfProps) {
return (
<PDFView
// @ts-expect-error waiting for https://github.com/Expensify/App/issues/16186 merge
onPress={onPress}
isFocused={isFocused}
sourceURL={encryptedSourceUrl}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {StyleProp, ViewStyle} from 'react-native';
import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
import type {AttachmentViewProps} from '..';

type AttachmentViewPdfProps = Pick<AttachmentViewProps, 'file' | 'onPress' | 'isUsedInCarousel' | 'isFocused' | 'onToggleKeyboard'> & {
Expand All @@ -9,7 +9,7 @@ type AttachmentViewPdfProps = Pick<AttachmentViewProps, 'file' | 'onPress' | 'is
style?: StyleProp<ViewStyle>;

/** Styles for the error label */
errorLabelStyles?: StyleProp<ViewStyle>;
errorLabelStyles?: StyleProp<TextStyle>;

/** Triggered when the PDF's onScaleChanged event is triggered */
onScaleChanged?: (scale: number) => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import PropTypes from 'prop-types';
import type {KeyboardEvent} from 'react';
import React from 'react';
import type {GestureResponderEvent} from 'react-native';
import {View} from 'react-native';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import variables from '@styles/variables';

const propTypes = {
type PDFInfoMessageProps = {
/** Callback function to indicate that PDF password form should be shown */
onShowForm: PropTypes.func.isRequired,

...withLocalizePropTypes,
onShowForm: (event: GestureResponderEvent | KeyboardEvent) => void;
};

function PDFInfoMessage(props) {
function PDFInfoMessage({onShowForm}: PDFInfoMessageProps) {
const theme = useTheme();
const styles = useThemeStyles();
const {translate} = useLocalize();

return (
<View style={styles.alignItemsCenter}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return (
return (

<Icon
Expand All @@ -28,18 +29,17 @@ function PDFInfoMessage(props) {
width={variables.iconSizeSuperLarge}
height={variables.iconSizeSuperLarge}
/>
<Text style={[styles.textHeadline, styles.mb3, styles.mt3]}>{props.translate('attachmentView.pdfPasswordForm.title')}</Text>
<Text>{props.translate('attachmentView.pdfPasswordForm.infoText')}</Text>
<Text style={[styles.textHeadline, styles.mb3, styles.mt3]}>{translate('attachmentView.pdfPasswordForm.title')}</Text>
<Text>{translate('attachmentView.pdfPasswordForm.infoText')}</Text>
<Text>
{props.translate('attachmentView.pdfPasswordForm.beforeLinkText')}
<TextLink onPress={props.onShowForm}>{` ${props.translate('attachmentView.pdfPasswordForm.linkText')} `}</TextLink>
{props.translate('attachmentView.pdfPasswordForm.afterLinkText')}
{translate('attachmentView.pdfPasswordForm.beforeLinkText')}
<TextLink onPress={onShowForm}>{` ${translate('attachmentView.pdfPasswordForm.linkText')} `}</TextLink>
{translate('attachmentView.pdfPasswordForm.afterLinkText')}
</Text>
</View>
);
}

PDFInfoMessage.propTypes = propTypes;
PDFInfoMessage.displayName = 'PDFInfoMessage';

export default withLocalize(PDFInfoMessage);
export default PDFInfoMessage;
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import PropTypes from 'prop-types';
import React, {useEffect, useMemo, useRef, useState} from 'react';
import {View} from 'react-native';
import _ from 'underscore';
import Button from '@components/Button';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import TextInput from '@components/TextInput';
import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
Expand All @@ -14,51 +13,43 @@ import shouldDelayFocus from '@libs/shouldDelayFocus';
import CONST from '@src/CONST';
import PDFInfoMessage from './PDFInfoMessage';

const propTypes = {
type PDFPasswordFormProps = {
/** If the submitted password is invalid (show an error message) */
isPasswordInvalid: PropTypes.bool,
isPasswordInvalid?: boolean;

/** If loading indicator should be shown */
shouldShowLoadingIndicator: PropTypes.bool,
shouldShowLoadingIndicator?: boolean;

/** Notify parent that the password form has been submitted */
onSubmit: PropTypes.func,
onSubmit?: (password: string) => void;

/** Notify parent that the password has been updated/edited */
onPasswordUpdated: PropTypes.func,
onPasswordUpdated?: (newPassword: string) => void;

/** Notify parent that a text field has been focused or blurred */
onPasswordFieldFocused: PropTypes.func,
onPasswordFieldFocused?: (isFocused: boolean) => void;

/** Should focus to the password input */
isFocused: PropTypes.bool.isRequired,
isFocused: boolean;
};

const defaultProps = {
isPasswordInvalid: false,
shouldShowLoadingIndicator: false,
onSubmit: () => {},
onPasswordUpdated: () => {},
onPasswordFieldFocused: () => {},
};

function PDFPasswordForm({isFocused, isPasswordInvalid, shouldShowLoadingIndicator, onSubmit, onPasswordUpdated, onPasswordFieldFocused}) {
function PDFPasswordForm({isFocused, isPasswordInvalid = false, shouldShowLoadingIndicator = false, onSubmit, onPasswordUpdated, onPasswordFieldFocused}: PDFPasswordFormProps) {
const styles = useThemeStyles();
const {isSmallScreenWidth} = useWindowDimensions();
const {translate} = useLocalize();

const [password, setPassword] = useState('');
const [validationErrorText, setValidationErrorText] = useState('');
const [shouldShowForm, setShouldShowForm] = useState(false);
const textInputRef = useRef(null);
const textInputRef = useRef<BaseTextInputRef>(null);

const focusTimeoutRef = useRef(null);
const focusTimeoutRef = useRef<NodeJS.Timeout>();

const errorText = useMemo(() => {
if (isPasswordInvalid) {
return 'attachmentView.passwordIncorrect';
}
if (!_.isEmpty(validationErrorText)) {
if (validationErrorText) {
return validationErrorText;
}
return '';
Expand All @@ -76,7 +67,7 @@ function PDFPasswordForm({isFocused, isPasswordInvalid, shouldShowLoadingIndicat
* Relevant thread: https://expensify.slack.com/archives/C01GTK53T8Q/p1694660990479979
*/
focusTimeoutRef.current = setTimeout(() => {
textInputRef.current.focus();
textInputRef.current?.focus();
}, CONST.ANIMATED_TRANSITION);
return () => {
if (!focusTimeoutRef.current) {
Expand All @@ -86,19 +77,19 @@ function PDFPasswordForm({isFocused, isPasswordInvalid, shouldShowLoadingIndicat
};
}, [isFocused]);

const updatePassword = (newPassword) => {
onPasswordUpdated(newPassword);
if (!_.isEmpty(newPassword) && validationErrorText) {
const updatePassword = (newPassword: string) => {
onPasswordUpdated?.(newPassword);
if (newPassword && validationErrorText) {
setValidationErrorText('');
}
setPassword(newPassword);
};

const validate = () => {
if (!isPasswordInvalid && !_.isEmpty(password)) {
if (!isPasswordInvalid && password) {
return true;
}
if (_.isEmpty(password)) {
if (!password) {
setValidationErrorText('attachmentView.passwordRequired');
}
return false;
Expand All @@ -108,7 +99,7 @@ function PDFPasswordForm({isFocused, isPasswordInvalid, shouldShowLoadingIndicat
if (!validate()) {
return;
}
onSubmit(password);
onSubmit?.(password);
};

return shouldShowForm ? (
Expand Down Expand Up @@ -136,8 +127,8 @@ function PDFPasswordForm({isFocused, isPasswordInvalid, shouldShowLoadingIndicat
enterKeyHint="done"
onSubmitEditing={submitPassword}
errorText={errorText}
onFocus={() => onPasswordFieldFocused(true)}
onBlur={() => onPasswordFieldFocused(false)}
onFocus={() => onPasswordFieldFocused?.(true)}
onBlur={() => onPasswordFieldFocused?.(false)}
autoFocus
shouldDelayFocus={shouldDelayFocus}
secureTextEntry
Expand All @@ -160,8 +151,6 @@ function PDFPasswordForm({isFocused, isPasswordInvalid, shouldShowLoadingIndicat
);
}

PDFPasswordForm.propTypes = propTypes;
PDFPasswordForm.defaultProps = defaultProps;
PDFPasswordForm.displayName = 'PDFPasswordForm';

export default PDFPasswordForm;
147 changes: 0 additions & 147 deletions src/components/PDFView/index.js

This file was deleted.

Loading
Loading