import React, { Component, ReactElement, Consumer, Provider } from 'react'; import Grid from '@material-ui/core/Grid'; import Loading from '../../components/Loading/Loading'; import DetailContainer from '../../components/DetailContainer/DetailContainer'; import DetailSidebar from '../../components/DetailSidebar/DetailSidebar'; import { callDetailPage } from '../../utils/calls'; import { getRouterPackageName } from '../../utils/package'; import NotFound from '../../components/NotFound'; import { PackageMetaInterface } from '../../../types/packageMeta'; export interface DetailContextProps { packageMeta: PackageMetaInterface; readMe: string; packageName: string; enableLoading: () => void; } export const DetailContext = React.createContext>({}); export interface VersionPageConsumerProps { packageMeta: PackageMetaInterface; readMe: string; packageName: string; enableLoading: () => void; } export const DetailContextProvider: Provider> = DetailContext.Provider; export const DetailContextConsumer: Consumer> = DetailContext.Consumer; interface PropsInterface { match: boolean; } interface StateInterface { readMe: string; packageName: string; packageMeta: PackageMetaInterface | null; isLoading: boolean; notFound: boolean; } class VersionPage extends Component> { constructor(props) { super(props); this.state = { readMe: '', packageName: getRouterPackageName(props.match), packageMeta: null, isLoading: true, notFound: false, }; } public static getDerivedStateFromProps(nextProps, prevState): { packageName?: string; isLoading: boolean; notFound?: boolean } | null { const { match } = nextProps; const packageName = getRouterPackageName(match); if (packageName !== prevState.packageName) { try { return { packageName, isLoading: false, }; } catch (err) { return { notFound: true, isLoading: false, }; } } else { return null; } } public async componentDidMount(): Promise { await this.loadPackageInfo(); } /* eslint no-unused-vars: 0 */ public async componentDidUpdate(nextProps, prevState: StateInterface): Promise { const { packageName } = this.state; if (packageName !== prevState.packageName) { const { readMe, packageMeta } = (await callDetailPage(packageName)) as Partial; this.setState({ readMe, packageMeta, packageName, notFound: false, isLoading: false, }); } } public render(): ReactElement { const { isLoading, packageMeta, readMe, packageName } = this.state; if (isLoading) { return ; } else if (!packageMeta) { return ; } else { return ( {this.renderDetail()} {this.renderSidebar()} ); } } public async loadPackageInfo(): Promise { const { packageName } = this.state; // FIXME: use utility document.title = `Verdaccio - ${packageName}`; this.setState({ readMe: '', }); try { const { readMe, packageMeta } = (await callDetailPage(packageName)) as Partial; this.setState({ readMe, packageMeta, packageName, notFound: false, isLoading: false, }); } catch (err) { this.setState({ notFound: true, packageName, isLoading: false, }); } } public enableLoading = () => { this.setState({ isLoading: true, }); }; public renderDetail(): ReactElement { return ; } public renderSidebar(): ReactElement { return ; } } export default VersionPage;