Global API init indicator (#2438)

This commit is contained in:
Jaco Greeff 2020-03-23 08:47:26 +01:00 committed by GitHub
parent a4a13a9a7c
commit 114966882a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 15 deletions

View File

@ -2,11 +2,13 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import React, { Suspense, useContext } from 'react';
import { Route } from '@polkadot/apps-routing/types';
import React, { Suspense, useContext, useMemo } from 'react';
import { useLocation } from 'react-router-dom';
import styled from 'styled-components';
import routing from '@polkadot/apps-routing';
import { ErrorBoundary, StatusContext } from '@polkadot/react-components';
import { ErrorBoundary, Spinner, StatusContext } from '@polkadot/react-components';
import { useApi } from '@polkadot/react-hooks';
import Status from './Status';
@ -17,11 +19,15 @@ interface Props {
className?: string;
}
const unknown = {
const NOT_FOUND: Route = {
Component: NotFound,
display: {
needsApi: undefined
},
i18n: {
defaultValue: 'Unknown'
},
icon: 'cancel',
isIgnored: false,
name: ''
};
@ -31,15 +37,24 @@ function Content ({ className }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { isApiConnected, isApiReady } = useApi();
const { queueAction, stqueue, txqueue } = useContext(StatusContext);
const app = location.pathname.slice(1) || '';
const { Component, display: { needsApi }, name } = routing.routes.find((route): boolean =>
!!(route && app.startsWith(route.name))
) || unknown;
const { Component, display: { needsApi }, name } = useMemo(
(): Route => {
const app = location.pathname.slice(1) || '';
const found = routing.routes.find((route) => !!(route && app.startsWith(route.name)));
return found || NOT_FOUND;
},
[location]
);
return (
<div className={className}>
{needsApi && (!isApiReady || !isApiConnected)
? <div className='connecting'>{t('Waiting for API to be connected and ready.')}</div>
? (
<div className='connecting'>
<Spinner label={t('Waiting for API to be connected and ready')} />
</div>
)
: (
<>
<Suspense fallback='...'>
@ -80,6 +95,6 @@ export default React.memo(styled(Content)`
}
.connecting {
padding: 1rem 0;
padding: 3.5rem 0;
}
`);

View File

@ -2,29 +2,44 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import React from 'react';
import React, { useMemo } from 'react';
import styled from 'styled-components';
import { useTranslation } from './translate';
interface Props {
className?: string;
label?: React.ReactNode;
variant?: 'app' | 'push' | 'mini';
}
function Spinner ({ className, variant = 'app' }: Props): React.ReactElement<Props> | null {
function Spinner ({ className, label, variant = 'app' }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const strokeWidth = variant === 'app' ? 2 : 4;
const strokeWidth = useMemo(
() => variant === 'app' ? 2 : 4,
[variant]
);
return (
<div className={`${className} ui--Spinner ${variant}`}>
<div className='loader'>
<svg className='circular ui--highlight--stroke' viewBox='25 25 50 50'>
<circle className='path' cx='50' cy='50' r='20' fill='none' strokeWidth={strokeWidth} strokeMiterlimit='10' />
<svg
className='circular ui--highlight--stroke'
viewBox='25 25 50 50'
>
<circle
className='path'
cx='50'
cy='50'
r='20'
fill='none'
strokeWidth={strokeWidth}
strokeMiterlimit='10'
/>
</svg>
</div>
{variant === 'app' && (
<div className='text'>{t('Retrieving data')}</div>
<div className='text'>{label || t('Retrieving data')}</div>
)}
</div>
);