Skip to content

Commit

Permalink
feat: error boundary message panel (#587)
Browse files Browse the repository at this point in the history
* feat: error boundary message panel

* chore: add isChrome test
  • Loading branch information
zuozhuo authored Apr 23, 2022
1 parent 36449c5 commit 7b0c375
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 2 deletions.
57 changes: 57 additions & 0 deletions packages/kit/src/components/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* eslint-disable react/destructuring-assignment, react/state-in-constructor */
import React from 'react';

import { Box, Button, Typography } from '@onekeyhq/components';
import platformEnv from '@onekeyhq/shared/src/platformEnv';

type ErrorBoundaryProps = {
onError?: (error: Error, componentStack: string | null) => void;
};
type ErrorBoundaryState = { error: Error | null };

class ErrorBoundary extends React.PureComponent<
ErrorBoundaryProps,
ErrorBoundaryState
> {
state: { error: Error | null } = { error: null };

componentDidCatch(
error: Error,
// Loosely typed because it depends on the React version and was
// accidentally excluded in some versions.
errorInfo?: { componentStack?: string | null },
) {
this.props?.onError?.(error, errorInfo?.componentStack || null);
this.setState({ error });
}

render() {
if (platformEnv.isDev && this.state.error) {
return (
// The component has to be unmounted or else it would continue to error
<Box flex="1" bg="background-default" px={4} py={8}>
<Button
onPress={() => {
if (platformEnv.isBrowser) {
window.location.href = '#/';
window.location.reload();
}
}}
>
Back to HOME
</Button>
<Typography.PageHeading>
Error: {this.state.error?.name}
</Typography.PageHeading>
<Typography.Body1Strong>
{this.state.error?.message}
</Typography.Body1Strong>
<Typography.Caption>{this.state.error?.stack}</Typography.Caption>
</Box>
);
}
return this.props.children;
}
}

export { ErrorBoundary };
5 changes: 4 additions & 1 deletion packages/kit/src/provider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import useRemoteConsole from '@onekeyhq/remote-console/src/useRemoteConsole';

import backgroundApiProxy from '../background/instance/backgroundApiProxy';
import { waitForDataLoaded } from '../background/utils';
import { ErrorBoundary } from '../components/ErrorBoundary';
import store from '../store';

import EngineApp from './EngineProvider';
Expand Down Expand Up @@ -83,7 +84,9 @@ const KitProvider: FC = () => {
<ThemeApp>
<WaitBackgroundReady loading={undefined}>
<EngineApp>
<NavigationApp />
<ErrorBoundary>
<NavigationApp />
</ErrorBoundary>
</EngineApp>
</WaitBackgroundReady>
</ThemeApp>
Expand Down
5 changes: 4 additions & 1 deletion packages/kit/src/views/Send/useFeeInfoPayload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { useCallback, useEffect, useState } from 'react';

import { useRoute } from '@react-navigation/core';
import { useIsFocused } from '@react-navigation/native';
import BigNumber from 'bignumber.js';

import { EIP1559Fee } from '@onekeyhq/engine/src/types/network';
Expand Down Expand Up @@ -91,6 +92,7 @@ export function useFeeInfoPayload({
pollingInterval?: number;
fetchAnyway?: boolean;
}) {
const isFocused = useIsFocused();
const { network } = useActiveWalletAccount();
const [feeInfoError, setFeeInfoError] = useState<Error | null>(null);
const { accountId, networkId } = useActiveWalletAccount();
Expand Down Expand Up @@ -243,7 +245,7 @@ export function useFeeInfoPayload({
}, [encodedTx, fetchFeeInfo, setFeeInfoPayload]);
useEffect(() => {
let timer: ReturnType<typeof setInterval>;
if (pollingInterval) {
if (pollingInterval && isFocused) {
timer = setInterval(async () => {
if (loading) {
return;
Expand All @@ -268,6 +270,7 @@ export function useFeeInfoPayload({
fetchFeeInfo,
loading,
pollingInterval,
isFocused,
]);
return {
feeInfoError,
Expand Down
39 changes: 39 additions & 0 deletions packages/shared/src/platformEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type IPlatformEnv = {
isDev?: boolean;
isBrowser?: boolean;
isFirefox?: boolean;
isChrome?: boolean;
isIOS?: boolean;
isAndroid?: boolean;
};
Expand All @@ -45,6 +46,43 @@ export const isBrowser = (): boolean =>
// @ts-ignore
export const isFirefox = (): boolean => typeof InstallTrigger !== 'undefined';

export const isChrome = (): boolean => {
if (!isBrowser()) {
return false;
}
// please note,
// that IE11 now returns undefined again for window.chrome
// and new Opera 30 outputs true for window.chrome
// but needs to check if window.opr is not undefined
// and new IE Edge outputs to true now for window.chrome
// and if not iOS Chrome check
// so use the below updated condition
const isChromium = window.chrome;
const winNav = window.navigator;
const vendorName = winNav.vendor;
// @ts-ignore
const isOpera = typeof window.opr !== 'undefined';
const isIEedge = winNav.userAgent.indexOf('Edg') > -1;
const isIOSChrome = /CriOS/.exec(winNav.userAgent);

if (isIOSChrome) {
// is Google Chrome on IOS
return true;
}
if (
isChromium !== null &&
typeof isChromium !== 'undefined' &&
vendorName === 'Google Inc.' &&
!isOpera &&
!isIEedge
) {
// is Google Chrome
return true;
}
// not Google Chrome
return false;
};

export const isWeb = (): boolean => process.env.ONEKEY_BUILD_TYPE === 'web';

export const isExtension = (): boolean =>
Expand Down Expand Up @@ -138,6 +176,7 @@ const platformEnv: IPlatformEnv = {
isDev: isDev(),
isBrowser: isBrowser(),
isFirefox: isFirefox(),
isChrome: isChrome(),
isIOS: isIOS(),
isAndroid: isAndroid(),
};
Expand Down

0 comments on commit 7b0c375

Please sign in to comment.