Skip to content

Commit

Permalink
Merge pull request Expensify#29284 from VickyStash/ts-migration/useEn…
Browse files Browse the repository at this point in the history
…vironment-hook
  • Loading branch information
francoisl authored Oct 25, 2023
2 parents cfccd42 + c1a3297 commit bb8f28b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
import React, {createContext, useState, useEffect, forwardRef, useContext, useMemo} from 'react';
import PropTypes from 'prop-types';
import React, {ComponentType, RefAttributes, ReactNode, ForwardedRef, ReactElement, createContext, useState, useEffect, forwardRef, useContext, useMemo} from 'react';
import {ValueOf} from 'type-fest';
import * as Environment from '../libs/Environment/Environment';
import CONST from '../CONST';
import getComponentDisplayName from '../libs/getComponentDisplayName';

const EnvironmentContext = createContext(null);
type EnvironmentProviderProps = {
/** Actual content wrapped by this component */
children: ReactNode;
};

type EnvironmentValue = ValueOf<typeof CONST.ENVIRONMENT>;

const environmentPropTypes = {
type EnvironmentContextValue = {
/** The string value representing the current environment */
environment: PropTypes.string.isRequired,
environment: EnvironmentValue;

/** The string value representing the URL of the current environment */
environmentURL: PropTypes.string.isRequired,
environmentURL: string;
};

function EnvironmentProvider({children}) {
const [environment, setEnvironment] = useState(CONST.ENVIRONMENT.PRODUCTION);
const EnvironmentContext = createContext<EnvironmentContextValue | null>(null);

function EnvironmentProvider({children}: EnvironmentProviderProps): ReactElement {
const [environment, setEnvironment] = useState<EnvironmentValue>(CONST.ENVIRONMENT.PRODUCTION);
const [environmentURL, setEnvironmentURL] = useState(CONST.NEW_EXPENSIFY_URL);

useEffect(() => {
Expand All @@ -24,7 +31,7 @@ function EnvironmentProvider({children}) {
}, []);

const contextValue = useMemo(
() => ({
(): EnvironmentContextValue => ({
environment,
environmentURL,
}),
Expand All @@ -35,28 +42,27 @@ function EnvironmentProvider({children}) {
}

EnvironmentProvider.displayName = 'EnvironmentProvider';
EnvironmentProvider.propTypes = {
/** Actual content wrapped by this component */
children: PropTypes.node.isRequired,
};

export default function withEnvironment(WrappedComponent) {
const WithEnvironment = forwardRef((props, ref) => {
const {environment, environmentURL} = useContext(EnvironmentContext);
export default function withEnvironment<TProps extends EnvironmentContextValue, TRef>(
WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>,
): (props: Omit<TProps, keyof EnvironmentContextValue> & React.RefAttributes<TRef>) => ReactElement | null {
function WithEnvironment(props: Omit<TProps, keyof EnvironmentContextValue>, ref: ForwardedRef<TRef>): ReactElement {
const {environment, environmentURL} = useContext(EnvironmentContext) ?? {};
return (
<WrappedComponent
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
{...(props as TProps)}
ref={ref}
environment={environment}
environmentURL={environmentURL}
/>
);
});
}

WithEnvironment.displayName = `withEnvironment(${getComponentDisplayName(WrappedComponent)})`;

return WithEnvironment;
return forwardRef(WithEnvironment);
}

export {EnvironmentContext, environmentPropTypes, EnvironmentProvider};
export {EnvironmentContext, EnvironmentProvider};
export type {EnvironmentContextValue};
10 changes: 8 additions & 2 deletions src/hooks/useEnvironment.js → src/hooks/useEnvironment.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import {useContext} from 'react';
import CONST from '../CONST';
import {EnvironmentContext} from '../components/withEnvironment';
import type {EnvironmentContextValue} from '../components/withEnvironment';

export default function useEnvironment() {
const {environment, environmentURL} = useContext(EnvironmentContext);
type UseEnvironment = Partial<EnvironmentContextValue> & {
isProduction: boolean;
isDevelopment: boolean;
};

export default function useEnvironment(): UseEnvironment {
const {environment, environmentURL} = useContext(EnvironmentContext) ?? {};
return {
environment,
environmentURL,
Expand Down
7 changes: 5 additions & 2 deletions src/pages/ShareCodePage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import {View, ScrollView} from 'react-native';
import _ from 'underscore';
import PropTypes from 'prop-types';
import ScreenWrapper from '../components/ScreenWrapper';
import HeaderWithBackButton from '../components/HeaderWithBackButton';
import Navigation from '../libs/Navigation/Navigation';
Expand All @@ -20,16 +21,18 @@ import CONST from '../CONST';
import ContextMenuItem from '../components/ContextMenuItem';
import * as UserUtils from '../libs/UserUtils';
import ROUTES from '../ROUTES';
import withEnvironment, {environmentPropTypes} from '../components/withEnvironment';
import withEnvironment from '../components/withEnvironment';
import * as Url from '../libs/Url';

const propTypes = {
/** The report currently being looked at */
report: reportPropTypes,

/** The string value representing the URL of the current environment */
environmentURL: PropTypes.string.isRequired,

...withLocalizePropTypes,
...withCurrentUserPersonalDetailsPropTypes,
...environmentPropTypes,
};

const defaultProps = {
Expand Down

0 comments on commit bb8f28b

Please sign in to comment.