feat(frontend): replace forkawesome with bootstrap icons

These icon replace fork awesome. A linter informs the user about the deprecation.

See https://github.com/hedgedoc/hedgedoc/issues/2929

Co-authored-by: Philip Molares <philip.molares@udo.edu>
Co-authored-by: Tilman Vatteroth <git@tilmanvatteroth.de>
Signed-off-by: Philip Molares <philip.molares@udo.edu>
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Philip Molares 2023-02-05 22:05:02 +01:00 committed by Tilman Vatteroth
parent e7246f1484
commit 1c16e25e14
179 changed files with 4974 additions and 1943 deletions

View file

@ -5,9 +5,7 @@ exports[`AbcFrame renders a music sheet 1`] = `
<div
class="m-3 d-flex align-items-center justify-content-center"
>
<i
class="fa fa-spinner fa-spin "
/>
BootstrapIconMock_ArrowRepeat
</div>
</div>
`;
@ -2358,9 +2356,7 @@ exports[`AbcFrame renders an error if abcjs file can't be loaded 1`] = `
<div
class="m-3 d-flex align-items-center justify-content-center"
>
<i
class="fa fa-spinner fa-spin "
/>
BootstrapIconMock_ArrowRepeat
</div>
</div>
`;
@ -2381,9 +2377,7 @@ exports[`AbcFrame renders an error if abcjs render function crashes 1`] = `
<div
class="m-3 d-flex align-items-center justify-content-center"
>
<i
class="fa fa-spinner fa-spin "
/>
BootstrapIconMock_ArrowRepeat
</div>
</div>
`;
@ -2402,9 +2396,7 @@ exports[`AbcFrame renders an error if abcjs render function crashes 2`] = `
<div
class="m-3 d-flex align-items-center justify-content-center"
>
<i
class="fa fa-spinner fa-spin "
/>
BootstrapIconMock_ArrowRepeat
</div>
</div>
</div>

View file

@ -6,6 +6,7 @@
import { ClickShield } from '../../../components/markdown-renderer/replace-components/click-shield/click-shield'
import type { IdProps } from '../../../components/markdown-renderer/replace-components/custom-tag-with-id-component-replacer'
import React from 'react'
import { Play as IconPlay } from 'react-bootstrap-icons'
/**
* Renders an embedding for https://asciinema.org
@ -15,7 +16,7 @@ import React from 'react'
export const AsciinemaFrame: React.FC<IdProps> = ({ id }) => {
return (
<ClickShield
hoverIcon={'play'}
hoverIcon={IconPlay}
targetDescription={'asciinema'}
fallbackPreviewImageUrl={`https://asciinema.org/a/${id}.png`}
fallbackBackgroundColor={'#d40000'}

View file

@ -35,9 +35,7 @@ exports[`blockquote extra tag renders the tag "[color=#abcdef]" correctly 1`] =
class="blockquote-extra"
style="color: rgb(171, 205, 239);"
>
<i
class="fa fa-tag mx-1 "
/>
BootstrapIconMock_Tag
</span>
</p>
@ -52,9 +50,7 @@ exports[`blockquote extra tag renders the tag "[color=#dfe]" correctly 1`] = `
class="blockquote-extra"
style="color: rgb(221, 255, 238);"
>
<i
class="fa fa-tag mx-1 "
/>
BootstrapIconMock_Tag
</span>
</p>
@ -78,9 +74,6 @@ exports[`blockquote extra tag renders the tag "[color=notarealcolor]" correctly
<span
class="blockquote-extra"
>
<i
class="fa fa-tag mx-1 "
/>
notarealcolor
</span>
</p>
@ -96,9 +89,7 @@ exports[`blockquote extra tag renders the tag "[color=white]" correctly 1`] = `
class="blockquote-extra"
style="color: white;"
>
<i
class="fa fa-tag mx-1 "
/>
BootstrapIconMock_Tag
</span>
</p>
@ -142,9 +133,6 @@ exports[`blockquote extra tag renders the tag "[name=giowehg]" correctly 1`] = `
<span
class="blockquote-extra"
>
<i
class="fa fa-user mx-1 "
/>
giowehg
</span>
</p>
@ -169,9 +157,6 @@ exports[`blockquote extra tag renders the tag "[time=tomorrow]" correctly 1`] =
<span
class="blockquote-extra"
>
<i
class="fa fa-clock-o mx-1 "
/>
tomorrow
</span>
</p>

View file

@ -3,7 +3,7 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ForkAwesomeIcon } from '../../../components/common/fork-awesome/fork-awesome-icon'
import { UiIcon } from '../../../components/common/icons/ui-icon'
import type { NodeReplacement } from '../../../components/markdown-renderer/replace-components/component-replacer'
import {
ComponentReplacer,
@ -15,6 +15,7 @@ import { Optional } from '@mrdrogdrog/optional'
import type { Element } from 'domhandler'
import { isText } from 'domhandler'
import type { Text } from 'domhandler/lib/node'
import { Tag as IconTag } from 'react-bootstrap-icons'
/**
* Replaces <blockquote-tag> elements with "color" as label and a valid color as content
@ -35,7 +36,7 @@ export class BlockquoteColorExtraTagReplacer extends ComponentReplacer {
.filter((content) => cssColor.test(content))
.map((color) => (
<span className={'blockquote-extra'} key={1} style={{ color: color }}>
<ForkAwesomeIcon key='icon' className={'mx-1'} icon={'tag'} />
<UiIcon icon={IconTag} key='icon' className={'mx-1'} />
</span>
))
.orElse(DO_NOT_REPLACE)

View file

@ -20,8 +20,8 @@ export class BlockquoteExtraTagMarkdownExtension extends MarkdownRendererExtensi
public configureMarkdownIt(markdownIt: MarkdownIt): void {
new BlockquoteExtraTagMarkdownItPlugin('color', 'tag').registerRule(markdownIt)
new BlockquoteExtraTagMarkdownItPlugin('name', 'user').registerRule(markdownIt)
new BlockquoteExtraTagMarkdownItPlugin('time', 'clock-o').registerRule(markdownIt)
new BlockquoteExtraTagMarkdownItPlugin('name', 'person').registerRule(markdownIt)
new BlockquoteExtraTagMarkdownItPlugin('time', 'clock').registerRule(markdownIt)
}
public buildReplacers(): ComponentReplacer[] {

View file

@ -3,7 +3,7 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { IconName } from '../../../components/common/fork-awesome/types'
import type { BootstrapIconName } from '../../../components/common/icons/bootstrap-icons'
import { BlockquoteExtraTagMarkdownExtension } from './blockquote-extra-tag-markdown-extension'
import { Optional } from '@mrdrogdrog/optional'
import type MarkdownIt from 'markdown-it/lib'
@ -11,12 +11,6 @@ import type { RuleInline } from 'markdown-it/lib/parser_inline'
import type StateInline from 'markdown-it/lib/rules_inline/state_inline'
import type Token from 'markdown-it/lib/token'
export interface BlockquoteTagOptions {
parseSubTags?: boolean
valueRegex?: RegExp
icon?: IconName
}
export interface QuoteExtraTagValues {
labelStartIndex: number
labelEndIndex: number
@ -32,7 +26,7 @@ export interface QuoteExtraTagValues {
export class BlockquoteExtraTagMarkdownItPlugin {
private static readonly BlockquoteExtraTagRuleName = 'blockquote_extra_tag'
constructor(private tagName: string, private icon: IconName) {}
constructor(private tagName: string, private icon: BootstrapIconName) {}
/**
* Registers an inline rule that detects blockquote extra tags and replaces them with blockquote tokens.

View file

@ -3,10 +3,10 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { ForkAwesomeIconProps } from '../../../components/common/fork-awesome/fork-awesome-icon'
import { ForkAwesomeIcon } from '../../../components/common/fork-awesome/fork-awesome-icon'
import { ForkAwesomeIcons } from '../../../components/common/fork-awesome/fork-awesome-icons'
import type { IconName } from '../../../components/common/fork-awesome/types'
import type { BootstrapIconName } from '../../../components/common/icons/bootstrap-icons'
import { isBootstrapIconName } from '../../../components/common/icons/bootstrap-icons'
import type { LazyBootstrapIconProps } from '../../../components/common/icons/lazy-bootstrap-icon'
import { LazyBootstrapIcon } from '../../../components/common/icons/lazy-bootstrap-icon'
import type {
NodeReplacement,
SubNodeTransform
@ -42,15 +42,15 @@ export class BlockquoteExtraTagReplacer extends ComponentReplacer {
}
/**
* Extracts a fork awesome icon name from the node and builds a {@link ForkAwesomeIcon fork awesome icon react element}.
* Extracts an icon name from the node and builds a {@link LazyBootstrapIcon icon react element}.
*
* @param node The node that holds the "data-icon" attribute.
* @return the {@link ForkAwesomeIcon fork awesome icon react element} or {@link undefined} if no icon name was found.
* @return the {@link LazyBootstrapIcon icon react element} or {@link undefined} if no icon name was found.
*/
private buildIconElement(node: Element): ReactElement<ForkAwesomeIconProps> | undefined {
return Optional.ofNullable(node.attribs['data-icon'] as IconName)
.filter((iconName) => ForkAwesomeIcons.includes(iconName))
.map((iconName) => <ForkAwesomeIcon key='icon' className={'mx-1'} icon={iconName} />)
private buildIconElement(node: Element): ReactElement<LazyBootstrapIconProps> | undefined {
return Optional.ofNullable(node.attribs['data-icon'] as BootstrapIconName)
.filter((iconName) => isBootstrapIconName(iconName))
.map((iconName) => <LazyBootstrapIcon key='icon' className={'mx-1'} icon={iconName} />)
.orElse(undefined)
}
}

View file

@ -11,9 +11,9 @@ import { t } from 'i18next'
const forkAwesomeRegex = /<i class=["'][\w\s]*fa-[\w-]+[\w\s-]*["'][^>]*\/?>(?:<\/i>)?/
/**
* Adds support for flow charts to the markdown rendering.
* Adds a linter for the icon html tag.
*/
export class ForkAwesomeAppExtension extends AppExtension {
export class ForkAwesomeHtmlTagAppExtension extends AppExtension {
buildCodeMirrorLinter(): Linter[] {
return [
new SingleLineRegexLinter(

View file

@ -9,6 +9,7 @@ import { cypressId } from '../../../utils/cypress-attribute'
import styles from './gist-frame.module.scss'
import { useResizeGistFrame } from './use-resize-gist-frame'
import React, { useCallback } from 'react'
import { Github as IconGithub } from 'react-bootstrap-icons'
/**
* This component renders a GitHub Gist by placing the gist URL in an {@link HTMLIFrameElement iframe}.
@ -28,7 +29,7 @@ export const GistFrame: React.FC<IdProps> = ({ id }) => {
return (
<ClickShield
fallbackBackgroundColor={'#161b22'}
hoverIcon={'github'}
hoverIcon={IconGithub}
targetDescription={'GitHub Gist'}
data-cypress-id={'click-shield-gist'}>
<iframe

View file

@ -10,7 +10,7 @@ import { AsciinemaAppExtension } from './asciinema/asciinema-app-extension'
import { BlockquoteAppExtension } from './blockquote/blockquote-app-extension'
import { CsvTableAppExtension } from './csv/csv-table-app-extension'
import { FlowchartAppExtension } from './flowchart/flowchart-app-extension'
import { ForkAwesomeAppExtension } from './fork-awesome/fork-awesome-app-extension'
import { ForkAwesomeHtmlTagAppExtension } from './fork-awesome-html-tag/fork-awesome-html-tag-app-extension'
import { GistAppExtension } from './gist/gist-app-extension'
import { GraphvizAppExtension } from './graphviz/graphviz-app-extension'
import { HighlightedCodeFenceAppExtension } from './highlighted-code-fence/highlighted-code-fence-app-extension'
@ -48,5 +48,5 @@ export const optionalAppExtensions: AppExtension[] = [
new YoutubeAppExtension(),
new TaskListCheckboxAppExtension(),
new HighlightedCodeFenceAppExtension(),
new ForkAwesomeAppExtension()
new ForkAwesomeHtmlTagAppExtension()
]

View file

@ -6,6 +6,7 @@
import { ClickShield } from '../../../components/markdown-renderer/replace-components/click-shield/click-shield'
import type { IdProps } from '../../../components/markdown-renderer/replace-components/custom-tag-with-id-component-replacer'
import React, { useCallback } from 'react'
import { Vimeo as IconVimeo } from 'react-bootstrap-icons'
interface VimeoApiResponse {
// Vimeo uses strange names for their fields. ESLint doesn't like that.
@ -38,7 +39,7 @@ export const VimeoFrame: React.FC<IdProps> = ({ id }) => {
return (
<ClickShield
hoverIcon={'vimeo-square'}
hoverIcon={IconVimeo}
targetDescription={'Vimeo'}
onImageFetch={getPreviewImageLink}
fallbackBackgroundColor={'#00adef'}

View file

@ -6,6 +6,7 @@
import { ClickShield } from '../../../components/markdown-renderer/replace-components/click-shield/click-shield'
import type { IdProps } from '../../../components/markdown-renderer/replace-components/custom-tag-with-id-component-replacer'
import React from 'react'
import { Youtube as IconYoutube } from 'react-bootstrap-icons'
/**
* Renders a video player embedding for https://youtube.com
@ -15,7 +16,7 @@ import React from 'react'
export const YouTubeFrame: React.FC<IdProps> = ({ id }) => {
return (
<ClickShield
hoverIcon={'youtube-play'}
hoverIcon={IconYoutube}
targetDescription={'YouTube'}
fallbackPreviewImageUrl={`https://i.ytimg.com/vi/${id}/maxresdefault.jpg`}
fallbackBackgroundColor={'#ff0000'}