mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-24 18:56:32 -05:00
refactor: extract shortcuts from help modal
Co-authored-by: Erik Michelson <github@erik.michelson.eu> Signed-off-by: Erik Michelson <github@erik.michelson.eu> Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
ae37bd36f9
commit
ff004a5a63
11 changed files with 254 additions and 252 deletions
|
@ -234,35 +234,6 @@
|
||||||
"untitledNote": "Untitled",
|
"untitledNote": "Untitled",
|
||||||
"placeholder": "← Start by entering a title here\n===\nVisit {{host}}features if you don't know what to do.\nHappy hacking :)",
|
"placeholder": "← Start by entering a title here\n===\nVisit {{host}}features if you don't know what to do.\nHappy hacking :)",
|
||||||
"infoToc": "Structure your note with headings to see a table-of-contents here.",
|
"infoToc": "Structure your note with headings to see a table-of-contents here.",
|
||||||
"help": {
|
|
||||||
"shortcuts": {
|
|
||||||
"title": "Shortcuts",
|
|
||||||
"bold": "Make selection bold",
|
|
||||||
"italic": "Make selection italic",
|
|
||||||
"underline": "Underline selection",
|
|
||||||
"strikethrough": "Strike selection through",
|
|
||||||
"mark": "Mark selection",
|
|
||||||
"link": "Add link around selection",
|
|
||||||
"view": "Show only View",
|
|
||||||
"both": "Show View and Edit",
|
|
||||||
"edit": "Show only Edit"
|
|
||||||
},
|
|
||||||
"links": {
|
|
||||||
"title": "Links"
|
|
||||||
},
|
|
||||||
"contacts": {
|
|
||||||
"title": "Contacts",
|
|
||||||
"community": "Join the community",
|
|
||||||
"meetUsOn": "Meet us on {{service}}",
|
|
||||||
"helpTranslating": "Help us translating",
|
|
||||||
"reportIssue": "Report an issue"
|
|
||||||
},
|
|
||||||
"documents": {
|
|
||||||
"title": "Documents",
|
|
||||||
"yamlMetadata": "YAML Metadata",
|
|
||||||
"slideExample": "Slide Example"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"onlineStatus": {
|
"onlineStatus": {
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
"you": "(You)"
|
"you": "(You)"
|
||||||
|
@ -513,6 +484,15 @@
|
||||||
"editNote": "Edit this note"
|
"editNote": "Edit this note"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"appbar": {
|
||||||
|
"help": {
|
||||||
|
"help": {
|
||||||
|
"header": "Help",
|
||||||
|
"shortcuts": "Shortcuts",
|
||||||
|
"cheatsheet": "Cheatsheet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"yes": "Yes",
|
"yes": "Yes",
|
||||||
"no": "No",
|
"no": "No",
|
||||||
|
@ -643,6 +623,24 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"shortcuts": {
|
||||||
|
"title": "Shortcuts",
|
||||||
|
"editor": {
|
||||||
|
"header": "Editor",
|
||||||
|
"bold": "Make selection bold",
|
||||||
|
"italic": "Make selection italic",
|
||||||
|
"underline": "Underline selection",
|
||||||
|
"strikethrough": "Strike selection through",
|
||||||
|
"mark": "Mark selection",
|
||||||
|
"link": "Add link around selection"
|
||||||
|
},
|
||||||
|
"viewMode": {
|
||||||
|
"header": "View Mode",
|
||||||
|
"view": "Show only View",
|
||||||
|
"both": "Show View and Edit",
|
||||||
|
"edit": "Show only Edit"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cheatsheet": {
|
"cheatsheet": {
|
||||||
"button": "Open Cheatsheet",
|
"button": "Open Cheatsheet",
|
||||||
"search": "Search for Cheatsheets",
|
"search": "Search for Cheatsheets",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
@ -8,13 +8,13 @@ import { useTranslatedText } from '../../../../hooks/common/use-translated-text'
|
||||||
import { useOutlineButtonVariant } from '../../../../hooks/dark-mode/use-outline-button-variant'
|
import { useOutlineButtonVariant } from '../../../../hooks/dark-mode/use-outline-button-variant'
|
||||||
import { cypressId } from '../../../../utils/cypress-attribute'
|
import { cypressId } from '../../../../utils/cypress-attribute'
|
||||||
import { IconButton } from '../../../common/icon-button/icon-button'
|
import { IconButton } from '../../../common/icon-button/icon-button'
|
||||||
import { HelpModal } from './help-modal'
|
import { ShortcutsModal } from '../../../global-dialogs/shortcuts-modal/shortcuts-modal'
|
||||||
import React, { Fragment } from 'react'
|
import React, { Fragment } from 'react'
|
||||||
import { QuestionCircle as IconQuestionCircle } from 'react-bootstrap-icons'
|
import { QuestionCircle as IconQuestionCircle } from 'react-bootstrap-icons'
|
||||||
import { Trans } from 'react-i18next'
|
import { Trans } from 'react-i18next'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the button to open the {@link HelpModal}.
|
* Renders the button to open the shortcuts modal.
|
||||||
*/
|
*/
|
||||||
export const HelpButton: React.FC = () => {
|
export const HelpButton: React.FC = () => {
|
||||||
const [modalVisibility, showModal, closeModal] = useBooleanState()
|
const [modalVisibility, showModal, closeModal] = useBooleanState()
|
||||||
|
@ -33,7 +33,7 @@ export const HelpButton: React.FC = () => {
|
||||||
onClick={showModal}>
|
onClick={showModal}>
|
||||||
<Trans i18nKey={'editor.documentBar.help'} />
|
<Trans i18nKey={'editor.documentBar.help'} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<HelpModal show={modalVisibility} onHide={closeModal} />
|
<ShortcutsModal show={modalVisibility} onHide={closeModal} />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
import type { ModalVisibilityProps } from '../../../common/modals/common-modal'
|
|
||||||
import { CommonModal } from '../../../common/modals/common-modal'
|
|
||||||
import { LinksTabContent } from './links-tab-content'
|
|
||||||
import { ShortcutTabContent } from './shortcuts-tab-content'
|
|
||||||
import React, { useMemo, useState } from 'react'
|
|
||||||
import { Button, Modal } from 'react-bootstrap'
|
|
||||||
import { QuestionCircle as IconQuestionCircle } from 'react-bootstrap-icons'
|
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
|
||||||
|
|
||||||
export enum HelpTabStatus {
|
|
||||||
Shortcuts = 'shortcuts.title',
|
|
||||||
Links = 'links.title'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the help modal.
|
|
||||||
* This modal shows the user the markdown cheatsheet, shortcuts and different links with further help.
|
|
||||||
*
|
|
||||||
* @see CheatsheetTabContent
|
|
||||||
* @see ShortcutTabContent
|
|
||||||
* @see LinksTabContent
|
|
||||||
*
|
|
||||||
* @param show If the modal should be shown
|
|
||||||
* @param onHide A callback when the modal should be closed again
|
|
||||||
*/
|
|
||||||
export const HelpModal: React.FC<ModalVisibilityProps> = ({ show, onHide }) => {
|
|
||||||
const [tab, setTab] = useState<HelpTabStatus>(HelpTabStatus.Shortcuts)
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const tabContent = useMemo(() => {
|
|
||||||
switch (tab) {
|
|
||||||
case HelpTabStatus.Shortcuts:
|
|
||||||
return <ShortcutTabContent />
|
|
||||||
case HelpTabStatus.Links:
|
|
||||||
return <LinksTabContent />
|
|
||||||
}
|
|
||||||
}, [tab])
|
|
||||||
|
|
||||||
const modalTitle = useMemo(() => t('editor.documentBar.help') + ' - ' + t(`editor.help.${tab}`), [t, tab])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CommonModal modalSize={'xl'} titleIcon={IconQuestionCircle} show={show} onHide={onHide} title={modalTitle}>
|
|
||||||
<Modal.Body>
|
|
||||||
<nav className='nav nav-tabs'>
|
|
||||||
<Button
|
|
||||||
variant={'light'}
|
|
||||||
className={`nav-link nav-item ${tab === HelpTabStatus.Shortcuts ? 'active' : ''}`}
|
|
||||||
onClick={() => setTab(HelpTabStatus.Shortcuts)}>
|
|
||||||
<Trans i18nKey={'editor.help.shortcuts.title'} />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant={'light'}
|
|
||||||
className={`nav-link nav-item ${tab === HelpTabStatus.Links ? 'active' : ''}`}
|
|
||||||
onClick={() => setTab(HelpTabStatus.Links)}>
|
|
||||||
<Trans i18nKey={'editor.help.links.title'} />
|
|
||||||
</Button>
|
|
||||||
</nav>
|
|
||||||
{tabContent}
|
|
||||||
</Modal.Body>
|
|
||||||
</CommonModal>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
import links from '../../../../links.json'
|
|
||||||
import { IconMatrixOrg } from '../../../common/icons/additional/icon-matrix-org'
|
|
||||||
import { TranslatedExternalLink } from '../../../common/links/translated-external-link'
|
|
||||||
import { TranslatedInternalLink } from '../../../common/links/translated-internal-link'
|
|
||||||
import React from 'react'
|
|
||||||
import { Col, Row } from 'react-bootstrap'
|
|
||||||
import { Dot as IconDot, Flag as IconFlag, PeopleFill as IconPeopleFill, Tag as IconTag } from 'react-bootstrap-icons'
|
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders a bunch of links, where further help can be requested.
|
|
||||||
*/
|
|
||||||
export const LinksTabContent: React.FC = () => {
|
|
||||||
useTranslation()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Row className={'justify-content-center pt-4'}>
|
|
||||||
<Col lg={4}>
|
|
||||||
<h3>
|
|
||||||
<Trans i18nKey='editor.help.contacts.title' />
|
|
||||||
</h3>
|
|
||||||
<div>
|
|
||||||
<ul className='list-unstyled'>
|
|
||||||
<li>
|
|
||||||
<TranslatedExternalLink
|
|
||||||
i18nKey='editor.help.contacts.community'
|
|
||||||
href={links.community}
|
|
||||||
icon={IconPeopleFill}
|
|
||||||
className='text-primary'
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<TranslatedExternalLink
|
|
||||||
i18nKey='editor.help.contacts.meetUsOn'
|
|
||||||
i18nOption={{ service: 'Matrix' }}
|
|
||||||
href={links.chat}
|
|
||||||
icon={IconMatrixOrg}
|
|
||||||
className='text-primary'
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<TranslatedExternalLink
|
|
||||||
i18nKey='editor.help.contacts.reportIssue'
|
|
||||||
href={links.issues}
|
|
||||||
icon={IconTag}
|
|
||||||
className='text-primary'
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<TranslatedExternalLink
|
|
||||||
i18nKey='editor.help.contacts.helpTranslating'
|
|
||||||
href={links.translate}
|
|
||||||
icon={IconFlag}
|
|
||||||
className='text-primary'
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
<Col lg={4}>
|
|
||||||
<h3>
|
|
||||||
<Trans i18nKey='editor.help.documents.title' />
|
|
||||||
</h3>
|
|
||||||
<div>
|
|
||||||
<ul className='list-unstyled'>
|
|
||||||
<li>
|
|
||||||
<TranslatedInternalLink
|
|
||||||
i18nKey='editor.help.documents.yamlMetadata'
|
|
||||||
href='/n/yaml-metadata'
|
|
||||||
icon={IconDot}
|
|
||||||
className='text-primary'
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<TranslatedInternalLink
|
|
||||||
i18nKey='editor.help.documents.slideExample'
|
|
||||||
href='/n/slide-example'
|
|
||||||
icon={IconDot}
|
|
||||||
className='text-primary'
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
import { isMac } from '../../utils'
|
|
||||||
import React, { Fragment, useMemo } from 'react'
|
|
||||||
import { Card, ListGroup, Row } from 'react-bootstrap'
|
|
||||||
import { Trans } from 'react-i18next'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders a list of shortcuts usable in HedgeDoc.
|
|
||||||
*/
|
|
||||||
export const ShortcutTabContent: React.FC = () => {
|
|
||||||
const modifierKey = useMemo(() => (isMac() ? <kbd>⌘</kbd> : <kbd>Ctrl</kbd>), [])
|
|
||||||
const altKey = useMemo(() => (isMac() ? <kbd>⌥</kbd> : <kbd>Alt</kbd>), [])
|
|
||||||
|
|
||||||
const shortcutMap: { [category: string]: { [functionName: string]: JSX.Element[] } } = {
|
|
||||||
'View Mode': {
|
|
||||||
'editor.help.shortcuts.view': [<kbd key={'ctrl'}>Ctrl</kbd>, <> + </>, altKey, <> + </>, <kbd key={'v'}>V</kbd>],
|
|
||||||
'editor.help.shortcuts.both': [<kbd key={'ctrl'}>Ctrl</kbd>, <> + </>, altKey, <> + </>, <kbd key={'b'}>B</kbd>],
|
|
||||||
'editor.help.shortcuts.edit': [<kbd key={'ctrl'}>Ctrl</kbd>, <> + </>, altKey, <> + </>, <kbd key={'e'}>E</kbd>]
|
|
||||||
},
|
|
||||||
Editor: {
|
|
||||||
'editor.help.shortcuts.bold': [modifierKey, <> + </>, <kbd key={'b'}>B</kbd>],
|
|
||||||
'editor.help.shortcuts.italic': [modifierKey, <> + </>, <kbd key={'i'}>I</kbd>],
|
|
||||||
'editor.help.shortcuts.underline': [modifierKey, <> + </>, <kbd key={'u'}>U</kbd>],
|
|
||||||
'editor.help.shortcuts.strikethrough': [modifierKey, <> + </>, <kbd key={'d'}>D</kbd>],
|
|
||||||
'editor.help.shortcuts.mark': [modifierKey, <> + </>, <kbd key={'m'}>M</kbd>],
|
|
||||||
'editor.help.shortcuts.link': [modifierKey, <> + </>, <kbd key={'k'}>K</kbd>]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Row className={'justify-content-center pt-4'}>
|
|
||||||
{Object.keys(shortcutMap).map((category) => {
|
|
||||||
return (
|
|
||||||
<Card key={category} className={'m-2 w-50'}>
|
|
||||||
<Card.Header>{category}</Card.Header>
|
|
||||||
<ListGroup variant='flush'>
|
|
||||||
{Object.entries(shortcutMap[category]).map(([functionName, shortcuts]) => {
|
|
||||||
return (
|
|
||||||
<ListGroup.Item key={functionName} className={'d-flex justify-content-between'}>
|
|
||||||
<span>
|
|
||||||
<Trans i18nKey={functionName} />
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
{shortcuts.map((shortcut, shortcutIndex) => (
|
|
||||||
<Fragment key={shortcutIndex}>{shortcut}</Fragment>
|
|
||||||
))}
|
|
||||||
</span>
|
|
||||||
</ListGroup.Item>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</ListGroup>
|
|
||||||
</Card>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Row>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import { isMac } from '../../editor-page/utils'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a keyboard alt/option key hint depending on if the browser is running on macOS or not.
|
||||||
|
*/
|
||||||
|
export const AltKey: React.FC = () => {
|
||||||
|
return isMac() ? <kbd>⌥</kbd> : <kbd>Alt</kbd>
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import type { PropsWithChildren } from 'react'
|
||||||
|
import React from 'react'
|
||||||
|
import { Card, ListGroup } from 'react-bootstrap'
|
||||||
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
interface CategoryProps extends PropsWithChildren {
|
||||||
|
headerI18nKey: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a group of shortcut lines
|
||||||
|
*
|
||||||
|
* @param headerI18nKey The i18n key of the header
|
||||||
|
* @param children The lines to include
|
||||||
|
*/
|
||||||
|
export const CategoryCard: React.FC<CategoryProps> = ({ headerI18nKey, children }) => {
|
||||||
|
useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card key={headerI18nKey} className={'mb-4'}>
|
||||||
|
<Card.Header>
|
||||||
|
<Trans i18nKey={headerI18nKey} />
|
||||||
|
</Card.Header>
|
||||||
|
<ListGroup variant='flush'>{children}</ListGroup>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import { isMac } from '../../editor-page/utils'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a keyboard control/command key hint depending on if the browser is running on macOS or not.
|
||||||
|
*/
|
||||||
|
export const ModifierKey: React.FC = () => {
|
||||||
|
return isMac() ? <kbd>⌘</kbd> : <kbd>Ctrl</kbd>
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import { ShowIf } from '../../common/show-if/show-if'
|
||||||
|
import { AltKey } from './alt-key'
|
||||||
|
import { ModifierKey } from './modifier-key'
|
||||||
|
import React from 'react'
|
||||||
|
import { ListGroup } from 'react-bootstrap'
|
||||||
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
interface ShortcutLineProps {
|
||||||
|
functionNameI18nKey: string
|
||||||
|
showModifierKey: boolean
|
||||||
|
showAltKey: boolean
|
||||||
|
functionKeyCode: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders one shortcut hint for the modal
|
||||||
|
*
|
||||||
|
* @param functionNameI18nKey The i18n key of the function name that is associated to the shortcut
|
||||||
|
* @param showAltKey Defines if the shortcut requires the alt/option key
|
||||||
|
* @param showModifierKey Defines if the shortcut requires the control/command key
|
||||||
|
* @param functionKeyCode The actual key of the shortcut
|
||||||
|
*/
|
||||||
|
export const ShortcutLine: React.FC<ShortcutLineProps> = ({
|
||||||
|
functionNameI18nKey,
|
||||||
|
showAltKey,
|
||||||
|
showModifierKey,
|
||||||
|
functionKeyCode
|
||||||
|
}) => {
|
||||||
|
useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ListGroup.Item className={'d-flex justify-content-between'}>
|
||||||
|
<span>
|
||||||
|
<Trans i18nKey={functionNameI18nKey} />
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<ShowIf condition={showModifierKey}>
|
||||||
|
<ModifierKey />
|
||||||
|
<span> + </span>
|
||||||
|
</ShowIf>
|
||||||
|
|
||||||
|
<ShowIf condition={showAltKey}>
|
||||||
|
<AltKey />
|
||||||
|
<span> + </span>
|
||||||
|
</ShowIf>
|
||||||
|
|
||||||
|
<kbd>{functionKeyCode.toUpperCase()}</kbd>
|
||||||
|
</span>
|
||||||
|
</ListGroup.Item>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import { CategoryCard } from './category-card'
|
||||||
|
import { ShortcutLine } from './shortcut-line'
|
||||||
|
import React from 'react'
|
||||||
|
import { Container } from 'react-bootstrap'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a list of shortcuts usable in HedgeDoc.
|
||||||
|
*/
|
||||||
|
export const ShortcutsContent: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<CategoryCard headerI18nKey={'shortcuts.viewMode.header'}>
|
||||||
|
<ShortcutLine
|
||||||
|
functionNameI18nKey={'shortcuts.viewMode.view'}
|
||||||
|
showModifierKey={true}
|
||||||
|
showAltKey={true}
|
||||||
|
functionKeyCode={'v'}
|
||||||
|
/>
|
||||||
|
<ShortcutLine
|
||||||
|
functionNameI18nKey={'shortcuts.viewMode.both'}
|
||||||
|
showModifierKey={true}
|
||||||
|
showAltKey={true}
|
||||||
|
functionKeyCode={'b'}
|
||||||
|
/>
|
||||||
|
<ShortcutLine
|
||||||
|
functionNameI18nKey={'shortcuts.viewMode.edit'}
|
||||||
|
showModifierKey={true}
|
||||||
|
showAltKey={true}
|
||||||
|
functionKeyCode={'e'}
|
||||||
|
/>
|
||||||
|
</CategoryCard>
|
||||||
|
|
||||||
|
<CategoryCard headerI18nKey={'shortcuts.editor.header'}>
|
||||||
|
<ShortcutLine
|
||||||
|
functionNameI18nKey={'shortcuts.editor.bold'}
|
||||||
|
showModifierKey={true}
|
||||||
|
showAltKey={false}
|
||||||
|
functionKeyCode={'b'}
|
||||||
|
/>
|
||||||
|
<ShortcutLine
|
||||||
|
functionNameI18nKey={'shortcuts.editor.italic'}
|
||||||
|
showModifierKey={true}
|
||||||
|
showAltKey={false}
|
||||||
|
functionKeyCode={'i'}
|
||||||
|
/>
|
||||||
|
<ShortcutLine
|
||||||
|
functionNameI18nKey={'shortcuts.editor.underline'}
|
||||||
|
showModifierKey={true}
|
||||||
|
showAltKey={false}
|
||||||
|
functionKeyCode={'u'}
|
||||||
|
/>
|
||||||
|
<ShortcutLine
|
||||||
|
functionNameI18nKey={'shortcuts.editor.strikethrough'}
|
||||||
|
showModifierKey={true}
|
||||||
|
showAltKey={false}
|
||||||
|
functionKeyCode={'d'}
|
||||||
|
/>
|
||||||
|
<ShortcutLine
|
||||||
|
functionNameI18nKey={'shortcuts.editor.mark'}
|
||||||
|
showModifierKey={true}
|
||||||
|
showAltKey={false}
|
||||||
|
functionKeyCode={'m'}
|
||||||
|
/>
|
||||||
|
<ShortcutLine
|
||||||
|
functionNameI18nKey={'shortcuts.editor.link'}
|
||||||
|
showModifierKey={true}
|
||||||
|
showAltKey={false}
|
||||||
|
functionKeyCode={'k'}
|
||||||
|
/>
|
||||||
|
</CategoryCard>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import { useTranslatedText } from '../../../hooks/common/use-translated-text'
|
||||||
|
import type { ModalVisibilityProps } from '../../common/modals/common-modal'
|
||||||
|
import { CommonModal } from '../../common/modals/common-modal'
|
||||||
|
import { ShortcutsContent } from './shortcuts-content'
|
||||||
|
import React from 'react'
|
||||||
|
import { Modal } from 'react-bootstrap'
|
||||||
|
import { QuestionCircle as IconQuestionCircle } from 'react-bootstrap-icons'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the keyboard shortcuts overview modal.
|
||||||
|
* @param show True when the modal should be shown
|
||||||
|
* @param onHide Callback when the modal should be hidden
|
||||||
|
*/
|
||||||
|
export const ShortcutsModal: React.FC<ModalVisibilityProps> = ({ show, onHide }) => {
|
||||||
|
const title = useTranslatedText('shortcuts.title')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CommonModal titleIcon={IconQuestionCircle} show={show} onHide={onHide} showCloseButton={true} title={title}>
|
||||||
|
<Modal.Body>
|
||||||
|
<ShortcutsContent />
|
||||||
|
</Modal.Body>
|
||||||
|
</CommonModal>
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in a new issue