Add custom intro page by fetching markdown content from a file (#697)

Signed-off-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
This commit is contained in:
Tilman Vatteroth 2021-02-08 15:03:11 +01:00 committed by GitHub
parent 4b2e2a7c93
commit 7f6e0e53a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 373 additions and 173 deletions

View file

@ -1,7 +1,7 @@
/*
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
SPDX-License-Identifier: AGPL-3.0-only
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import React from 'react'
@ -38,6 +38,7 @@ export const CoverButtons: React.FC = () => {
</ShowIf>
<Link to="/n/features">
<Button
data-cy={ 'features-button' }
className="cover-button"
variant="primary"
size="lg"

View file

@ -13,29 +13,29 @@ import { ForkAwesomeIcon } from '../common/fork-awesome/fork-awesome-icon'
export const FeatureLinks: React.FC = () => {
useTranslation()
return (
<Row className="mb-5">
<Col md={ 4 }>
<Row className="mb-5 d-flex flex-row justify-content-center">
<Col md={ 3 }>
<Link to={ '/n/features#Share-Notes' } className="text-light">
<ForkAwesomeIcon icon="bolt" size="3x"/>
<h5>
<ForkAwesomeIcon icon="bolt" size="2x"/>
<h6>
<Trans i18nKey="landing.intro.features.collaboration"/>
</h5>
</h6>
</Link>
</Col>
<Col md={ 4 }>
<Col md={ 3 }>
<Link to={ '/n/features#MathJax' } className="text-light">
<ForkAwesomeIcon icon="bar-chart" size="3x"/>
<h5>
<ForkAwesomeIcon icon="bar-chart" size="2x"/>
<h6>
<Trans i18nKey="landing.intro.features.katex"/>
</h5>
</h6>
</Link>
</Col>
<Col md={ 4 }>
<Col md={ 3 }>
<Link to={ '/n/features#Slide-Mode' } className="text-light">
<ForkAwesomeIcon icon="television" size="3x"/>
<h5>
<ForkAwesomeIcon icon="television" size="2x"/>
<h6>
<Trans i18nKey="landing.intro.features.slides"/>
</h5>
</h6>
</Link>
</Col>
</Row>

View file

@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { getFrontPageContent } from '../requests'
import { useFrontendBaseUrl } from '../../../hooks/common/use-frontend-base-url'
const MARKDOWN_WHILE_LOADING = ':zzz: {message}'
const MARKDOWN_IF_ERROR = ':::danger\n' +
'{message}\n' +
':::'
export const useIntroPageContent = (): string => {
const { t } = useTranslation()
const [content, setContent] = useState<string>(() => MARKDOWN_WHILE_LOADING.replace('{message}', t('landing.intro.markdownWhileLoading')))
const frontendBaseUrl = useFrontendBaseUrl()
useEffect(() => {
getFrontPageContent(frontendBaseUrl)
.then((content) => setContent(content))
.catch(() => setContent(MARKDOWN_IF_ERROR.replace('{message}', t('landing.intro.markdownLoadingError'))))
}, [frontendBaseUrl, t])
return content
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

View file

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
SPDX-License-Identifier: CC0-1.0

View file

@ -1,37 +1,54 @@
/*
SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
SPDX-License-Identifier: AGPL-3.0-only
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
*SPDX-License-Identifier: AGPL-3.0-only
*/
import React, { Fragment } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import React, { Fragment, useState } from 'react'
import { Trans } from 'react-i18next'
import { Branding } from '../common/branding/branding'
import {
HedgeDocLogoSize,
HedgeDocLogoType,
HedgeDocLogoWithText
} from '../common/hedge-doc-logo/hedge-doc-logo-with-text'
import { RenderIframe } from '../editor-page/renderer-pane/render-iframe'
import { CoverButtons } from './cover-buttons/cover-buttons'
import { FeatureLinks } from './feature-links'
import screenshot from './img/screenshot.png'
import { useIntroPageContent } from './hooks/use-intro-page-content'
import { ShowIf } from '../common/show-if/show-if'
import { ForkAwesomeIcon } from '../common/fork-awesome/fork-awesome-icon'
import { RendererType } from '../render-page/rendering-message'
export const IntroPage: React.FC = () => {
const { t } = useTranslation()
const introPageContent = useIntroPageContent()
const [showSpinner, setShowSpinner] = useState<boolean>(true)
return <Fragment>
<h1 dir='auto' className={ 'align-items-center d-flex justify-content-center flex-column' }>
<HedgeDocLogoWithText logoType={ HedgeDocLogoType.COLOR_VERTICAL } size={ HedgeDocLogoSize.BIG }/>
</h1>
<p className="lead">
<Trans i18nKey="app.slogan"/>
</p>
<div className={ 'mb-5' }>
<Branding delimiter={ false }/>
</div>
<CoverButtons/>
<img alt={ t('landing.intro.screenShotAltText') } src={ screenshot } className="img-fluid mb-5"/>
<FeatureLinks/>
</Fragment>
return (
<Fragment>
<div className={ 'flex-fill mt-3' }>
<h1 dir='auto' className={ 'align-items-center d-flex justify-content-center flex-column' }>
<HedgeDocLogoWithText logoType={ HedgeDocLogoType.COLOR_VERTICAL } size={ HedgeDocLogoSize.BIG }/>
</h1>
<p className="lead">
<Trans i18nKey="app.slogan"/>
</p>
<div className={ 'mb-5' }>
<Branding delimiter={ false }/>
</div>
<CoverButtons/>
<ShowIf condition={ showSpinner }>
<ForkAwesomeIcon icon={ 'spinner' } className={ 'fa-spin' }/>
</ShowIf>
<RenderIframe
frameClasses={ 'w-100 overflow-y-hidden' }
markdownContent={ introPageContent }
disableToc={ true }
onRendererReadyChange={ (rendererReady => setShowSpinner(!rendererReady)) }
rendererType={ RendererType.INTRO }
forcedDarkMode={ true }/>
<hr className={ 'mb-5' }/>
</div>
<FeatureLinks/>
</Fragment>)
}

View file

@ -0,0 +1,17 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { defaultFetchConfig, expectResponseCode } from '../../api/utils'
export const getFrontPageContent = async (baseUrl: string): Promise<string> => {
const response = await fetch(baseUrl + '/intro.md', {
...defaultFetchConfig,
method: 'GET'
})
expectResponseCode(response)
return await response.text()
}