Skip to content

Commit

Permalink
Merge pull request #32253 from software-mansion-labs/ts-migration/blo…
Browse files Browse the repository at this point in the history
…cking-view

[TS migration] Migrate 'BlockingViews' component to TypeScript
  • Loading branch information
Joel Bettner authored Dec 30, 2023
2 parents 924bee7 + ad34368 commit 8cb48e4
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 106 deletions.
Original file line number Diff line number Diff line change
@@ -1,75 +1,75 @@
import PropTypes from 'prop-types';
import React from 'react';
import {View} from 'react-native';
import {ImageSourcePropType, View} from 'react-native';
import {SvgProps} from 'react-native-svg';
import AutoEmailLink from '@components/AutoEmailLink';
import Icon from '@components/Icon';
import sourcePropTypes from '@components/Image/sourcePropTypes';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import variables from '@styles/variables';
import {TranslationPaths} from '@src/languages/types';

const propTypes = {
type BlockingViewProps = {
/** Expensicon for the page */
icon: sourcePropTypes.isRequired,
icon: React.FC<SvgProps> | ImageSourcePropType;

/** Color for the icon (should be from theme) */
iconColor: PropTypes.string,
iconColor?: string;

/** Title message below the icon */
title: PropTypes.string.isRequired,
title: string;

/** Subtitle message below the title */
subtitle: PropTypes.string,
subtitle?: string;

/** Link message below the subtitle */
linkKey: PropTypes.string,
linkKey?: TranslationPaths;

/** Whether we should show a link to navigate elsewhere */
shouldShowLink: PropTypes.bool,
shouldShowLink?: boolean;

/** The custom icon width */
iconWidth: PropTypes.number,
iconWidth?: number;

/** The custom icon height */
iconHeight: PropTypes.number,
iconHeight?: number;

/** Function to call when pressing the navigation link */
onLinkPress: PropTypes.func,
onLinkPress?: () => void;

/** Whether we should embed the link with subtitle */
shouldEmbedLinkWithSubtitle: PropTypes.bool,
shouldEmbedLinkWithSubtitle?: boolean;
};

const defaultProps = {
iconColor: null,
subtitle: '',
shouldShowLink: false,
linkKey: 'notFound.goBackHome',
iconWidth: variables.iconSizeSuperLarge,
iconHeight: variables.iconSizeSuperLarge,
onLinkPress: () => Navigation.dismissModal(),
shouldEmbedLinkWithSubtitle: false,
};

function BlockingView(props) {
function BlockingView({
icon,
iconColor,
title,
subtitle = '',
linkKey = 'notFound.goBackHome',
shouldShowLink = false,
iconWidth = variables.iconSizeSuperLarge,
iconHeight = variables.iconSizeSuperLarge,
onLinkPress = () => Navigation.dismissModal(),
shouldEmbedLinkWithSubtitle = false,
}: BlockingViewProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
function renderContent() {
return (
<>
<AutoEmailLink
style={[styles.textAlignCenter]}
text={props.subtitle}
text={subtitle}
/>
{props.shouldShowLink ? (
{shouldShowLink ? (
<TextLink
onPress={props.onLinkPress}
onPress={onLinkPress}
style={[styles.link, styles.mt2]}
>
{translate(props.linkKey)}
{translate(linkKey)}
</TextLink>
) : null}
</>
Expand All @@ -79,14 +79,14 @@ function BlockingView(props) {
return (
<View style={[styles.flex1, styles.alignItemsCenter, styles.justifyContentCenter, styles.ph10]}>
<Icon
src={props.icon}
fill={props.iconColor}
width={props.iconWidth}
height={props.iconHeight}
src={icon}
fill={iconColor}
width={iconWidth}
height={iconHeight}
/>
<Text style={[styles.notFoundTextHeader]}>{props.title}</Text>
<Text style={[styles.notFoundTextHeader]}>{title}</Text>

{props.shouldEmbedLinkWithSubtitle ? (
{shouldEmbedLinkWithSubtitle ? (
<Text style={[styles.textAlignCenter]}>{renderContent()}</Text>
) : (
<View style={[styles.alignItemsCenter, styles.justifyContentCenter]}>{renderContent()}</View>
Expand All @@ -95,8 +95,6 @@ function BlockingView(props) {
);
}

BlockingView.propTypes = propTypes;
BlockingView.defaultProps = defaultProps;
BlockingView.displayName = 'BlockingView';

export default BlockingView;
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import PropTypes from 'prop-types';
import React from 'react';
import {View} from 'react-native';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
Expand All @@ -7,54 +6,54 @@ import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import variables from '@styles/variables';
import {TranslationPaths} from '@src/languages/types';
import ROUTES from '@src/ROUTES';
import BlockingView from './BlockingView';

const propTypes = {
type FullPageNotFoundViewProps = {
/** Child elements */
children: PropTypes.node,
children?: React.ReactNode;

/** If true, child components are replaced with a blocking "not found" view */
shouldShow: PropTypes.bool,
shouldShow?: boolean;

/** The key in the translations file to use for the title */
titleKey: PropTypes.string,
titleKey?: TranslationPaths;

/** The key in the translations file to use for the subtitle */
subtitleKey: PropTypes.string,
subtitleKey?: TranslationPaths;

/** Whether we should show a link to navigate elsewhere */
shouldShowLink: PropTypes.bool,
shouldShowLink?: boolean;

/** Whether we should show the back button on the header */
shouldShowBackButton: PropTypes.bool,
shouldShowBackButton?: boolean;

/** The key in the translations file to use for the go back link */
linkKey: PropTypes.string,
linkKey?: TranslationPaths;

/** Method to trigger when pressing the back button of the header */
onBackButtonPress: PropTypes.func,
onBackButtonPress: () => void;

/** Function to call when pressing the navigation link */
onLinkPress: PropTypes.func,
};

const defaultProps = {
children: null,
shouldShow: false,
titleKey: 'notFound.notHere',
subtitleKey: 'notFound.pageNotFound',
linkKey: 'notFound.goBackHome',
onBackButtonPress: () => Navigation.goBack(ROUTES.HOME),
shouldShowLink: true,
shouldShowBackButton: true,
onLinkPress: () => Navigation.dismissModal(),
onLinkPress: () => void;
};

// eslint-disable-next-line rulesdir/no-negated-variables
function FullPageNotFoundView({children, shouldShow, titleKey, subtitleKey, linkKey, onBackButtonPress, shouldShowLink, shouldShowBackButton, onLinkPress}) {
function FullPageNotFoundView({
children = null,
shouldShow = false,
titleKey = 'notFound.notHere',
subtitleKey = 'notFound.pageNotFound',
linkKey = 'notFound.goBackHome',
onBackButtonPress = () => Navigation.goBack(ROUTES.HOME),
shouldShowLink = true,
shouldShowBackButton = true,
onLinkPress = () => Navigation.dismissModal(),
}: FullPageNotFoundViewProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();

if (shouldShow) {
return (
<>
Expand All @@ -81,8 +80,6 @@ function FullPageNotFoundView({children, shouldShow, titleKey, subtitleKey, link
return children;
}

FullPageNotFoundView.propTypes = propTypes;
FullPageNotFoundView.defaultProps = defaultProps;
FullPageNotFoundView.displayName = 'FullPageNotFoundView';

export default FullPageNotFoundView;
42 changes: 0 additions & 42 deletions src/components/BlockingViews/FullPageOfflineBlockingView.js

This file was deleted.

31 changes: 31 additions & 0 deletions src/components/BlockingViews/FullPageOfflineBlockingView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import * as Expensicons from '@components/Icon/Expensicons';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useTheme from '@hooks/useTheme';
import ChildrenProps from '@src/types/utils/ChildrenProps';
import BlockingView from './BlockingView';

function FullPageOfflineBlockingView({children}: ChildrenProps) {
const {translate} = useLocalize();
const {isOffline} = useNetwork();

const theme = useTheme();

if (isOffline) {
return (
<BlockingView
icon={Expensicons.OfflineCloud}
iconColor={theme.offline}
title={translate('common.youAppearToBeOffline')}
subtitle={translate('common.thisFeatureRequiresInternet')}
/>
);
}

return children;
}

FullPageOfflineBlockingView.displayName = 'FullPageOfflineBlockingView';

export default FullPageOfflineBlockingView;

0 comments on commit 8cb48e4

Please sign in to comment.