✨(frontend) introduce a shortcut settings tab
Work adapted from PR #859 and partially extracted to ship as a smaller, focused PR. This allows users to view the full list of available shortcuts. An editor to customize these shortcuts may be introduced later.
This commit is contained in:
@@ -17,6 +17,7 @@ and this project adheres to
|
|||||||
- ♻️(frontend) replace custom reactions toolbar with react aria popover #985
|
- ♻️(frontend) replace custom reactions toolbar with react aria popover #985
|
||||||
- 🔒️(frontend) uninstall curl from the frontend production image #987
|
- 🔒️(frontend) uninstall curl from the frontend production image #987
|
||||||
- 💄(frontend) add focus ring to reaction emoji buttons
|
- 💄(frontend) add focus ring to reaction emoji buttons
|
||||||
|
- ✨(frontend) introduce a shortcut settings tab #975
|
||||||
|
|
||||||
## [1.8.0] - 2026-02-20
|
## [1.8.0] - 2026-02-20
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
RiSpeakerLine,
|
RiSpeakerLine,
|
||||||
RiVideoOnLine,
|
RiVideoOnLine,
|
||||||
RiEyeLine,
|
RiEyeLine,
|
||||||
|
RiKeyboardBoxLine,
|
||||||
} from '@remixicon/react'
|
} from '@remixicon/react'
|
||||||
import { AccountTab } from './tabs/AccountTab'
|
import { AccountTab } from './tabs/AccountTab'
|
||||||
import { NotificationsTab } from './tabs/NotificationsTab'
|
import { NotificationsTab } from './tabs/NotificationsTab'
|
||||||
@@ -19,11 +20,12 @@ import { GeneralTab } from './tabs/GeneralTab'
|
|||||||
import { AudioTab } from './tabs/AudioTab'
|
import { AudioTab } from './tabs/AudioTab'
|
||||||
import { VideoTab } from './tabs/VideoTab'
|
import { VideoTab } from './tabs/VideoTab'
|
||||||
import { TranscriptionTab } from './tabs/TranscriptionTab'
|
import { TranscriptionTab } from './tabs/TranscriptionTab'
|
||||||
|
import { ShortcutTab } from './tabs/ShortcutTab'
|
||||||
import { useRef } from 'react'
|
import { useRef } from 'react'
|
||||||
import { useMediaQuery } from '@/features/rooms/livekit/hooks/useMediaQuery'
|
import { useMediaQuery } from '@/features/rooms/livekit/hooks/useMediaQuery'
|
||||||
import { SettingsDialogExtendedKey } from '@/features/settings/type'
|
import { SettingsDialogExtendedKey } from '@/features/settings/type'
|
||||||
import { useIsAdminOrOwner } from '@/features/rooms/livekit/hooks/useIsAdminOrOwner'
|
import { useIsAdminOrOwner } from '@/features/rooms/livekit/hooks/useIsAdminOrOwner'
|
||||||
import AccessibilityTab from './tabs/AccessibilityTab'
|
import { AccessibilityTab } from './tabs/AccessibilityTab'
|
||||||
|
|
||||||
const tabsStyle = css({
|
const tabsStyle = css({
|
||||||
maxHeight: '40.625rem', // fixme size copied from meet settings modal
|
maxHeight: '40.625rem', // fixme size copied from meet settings modal
|
||||||
@@ -107,6 +109,10 @@ export const SettingsDialogExtended = (props: SettingsDialogExtended) => {
|
|||||||
{isWideScreen &&
|
{isWideScreen &&
|
||||||
t(`tabs.${SettingsDialogExtendedKey.NOTIFICATIONS}`)}
|
t(`tabs.${SettingsDialogExtendedKey.NOTIFICATIONS}`)}
|
||||||
</Tab>
|
</Tab>
|
||||||
|
<Tab icon highlight id={SettingsDialogExtendedKey.SHORTCUTS}>
|
||||||
|
<RiKeyboardBoxLine />
|
||||||
|
{isWideScreen && t(`tabs.${SettingsDialogExtendedKey.SHORTCUTS}`)}
|
||||||
|
</Tab>
|
||||||
{isAdminOrOwner && (
|
{isAdminOrOwner && (
|
||||||
<Tab icon highlight id={SettingsDialogExtendedKey.TRANSCRIPTION}>
|
<Tab icon highlight id={SettingsDialogExtendedKey.TRANSCRIPTION}>
|
||||||
<Icon type="symbols" name="speech_to_text" />
|
<Icon type="symbols" name="speech_to_text" />
|
||||||
@@ -130,6 +136,7 @@ export const SettingsDialogExtended = (props: SettingsDialogExtended) => {
|
|||||||
<VideoTab id={SettingsDialogExtendedKey.VIDEO} />
|
<VideoTab id={SettingsDialogExtendedKey.VIDEO} />
|
||||||
<GeneralTab id={SettingsDialogExtendedKey.GENERAL} />
|
<GeneralTab id={SettingsDialogExtendedKey.GENERAL} />
|
||||||
<NotificationsTab id={SettingsDialogExtendedKey.NOTIFICATIONS} />
|
<NotificationsTab id={SettingsDialogExtendedKey.NOTIFICATIONS} />
|
||||||
|
<ShortcutTab id={SettingsDialogExtendedKey.SHORTCUTS} />
|
||||||
{/* Transcription tab won't be accessible if the tab is not active in the tab list */}
|
{/* Transcription tab won't be accessible if the tab is not active in the tab list */}
|
||||||
<TranscriptionTab id={SettingsDialogExtendedKey.TRANSCRIPTION} />
|
<TranscriptionTab id={SettingsDialogExtendedKey.TRANSCRIPTION} />
|
||||||
<AccessibilityTab id={SettingsDialogExtendedKey.ACCESSIBILITY} />
|
<AccessibilityTab id={SettingsDialogExtendedKey.ACCESSIBILITY} />
|
||||||
|
|||||||
@@ -36,5 +36,3 @@ export const AccessibilityTab = ({ id }: AccessibilityTabProps) => {
|
|||||||
</TabPanel>
|
</TabPanel>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AccessibilityTab
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import { shortcutCatalog } from '@/features/shortcuts/catalog'
|
||||||
|
import { ShortcutRow } from '@/features/shortcuts/components/ShortcutRow'
|
||||||
|
import { css } from '@/styled-system/css'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { TabPanel, type TabPanelProps } from '@/primitives/Tabs'
|
||||||
|
import { H } from '@/primitives'
|
||||||
|
|
||||||
|
const tableStyle = css({
|
||||||
|
width: '100%',
|
||||||
|
borderCollapse: 'collapse',
|
||||||
|
overflowY: 'auto',
|
||||||
|
'& th, & td': {
|
||||||
|
padding: '0.65rem 0',
|
||||||
|
textAlign: 'left',
|
||||||
|
},
|
||||||
|
'& tbody tr': {
|
||||||
|
borderBottom: '1px solid rgba(255,255,255,0.08)',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const ShortcutTab = ({ id }: Pick<TabPanelProps, 'id'>) => {
|
||||||
|
const { t } = useTranslation(['settings', 'rooms'])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TabPanel
|
||||||
|
id={id}
|
||||||
|
padding="md"
|
||||||
|
flex
|
||||||
|
className={css({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '0.75rem',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<H lvl={2}>{t('shortcuts.listLabel')}</H>
|
||||||
|
<table className={tableStyle}>
|
||||||
|
<thead className="sr-only">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">{t('shortcuts.columnAction')}</th>
|
||||||
|
<th scope="col">{t('shortcuts.columnShortcut')}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{shortcutCatalog.map((item) => (
|
||||||
|
<ShortcutRow key={item?.id} descriptor={item} />
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</TabPanel>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -5,5 +5,6 @@ export enum SettingsDialogExtendedKey {
|
|||||||
GENERAL = 'general',
|
GENERAL = 'general',
|
||||||
NOTIFICATIONS = 'notifications',
|
NOTIFICATIONS = 'notifications',
|
||||||
TRANSCRIPTION = 'transcription',
|
TRANSCRIPTION = 'transcription',
|
||||||
|
SHORTCUTS = 'shortcuts',
|
||||||
ACCESSIBILITY = 'accessibility',
|
ACCESSIBILITY = 'accessibility',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { css, cx } from '@/styled-system/css'
|
||||||
|
|
||||||
|
type ShortcutBadgeProps = {
|
||||||
|
visualLabel: string
|
||||||
|
srLabel?: string
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const badgeStyle = css({
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
backgroundColor: 'rgba(255,255,255,0.12)',
|
||||||
|
paddingInline: '0.4rem',
|
||||||
|
paddingBlock: '0.2rem',
|
||||||
|
borderRadius: '6px',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
minWidth: '5.5rem',
|
||||||
|
textAlign: 'center',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const ShortcutBadge: React.FC<ShortcutBadgeProps> = ({
|
||||||
|
visualLabel,
|
||||||
|
srLabel,
|
||||||
|
className,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={cx(badgeStyle, className)} aria-hidden="true">
|
||||||
|
<span>{visualLabel}</span>
|
||||||
|
</div>
|
||||||
|
{srLabel && <span className="sr-only">{srLabel}</span>}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { css } from '@/styled-system/css'
|
||||||
|
import { text } from '@/primitives/Text'
|
||||||
|
import { ShortcutDescriptor } from '../catalog'
|
||||||
|
import { ShortcutBadge } from './ShortcutBadge'
|
||||||
|
import { useShortcutFormatting } from '../hooks/useShortcutFormatting'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
type ShortcutRowProps = {
|
||||||
|
descriptor: ShortcutDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
const shortcutCellStyle = css({
|
||||||
|
textAlign: 'right',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const ShortcutRow: React.FC<ShortcutRowProps> = ({ descriptor }) => {
|
||||||
|
const { t } = useTranslation('rooms', { keyPrefix: 'shortcutsPanel' })
|
||||||
|
const { formatVisual, formatForSR } = useShortcutFormatting()
|
||||||
|
|
||||||
|
const visualShortcut = formatVisual(
|
||||||
|
descriptor.shortcut,
|
||||||
|
descriptor.code,
|
||||||
|
descriptor.kind
|
||||||
|
)
|
||||||
|
const srShortcut = formatForSR(
|
||||||
|
descriptor.shortcut,
|
||||||
|
descriptor.code,
|
||||||
|
descriptor.kind
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr>
|
||||||
|
<td className={text({ variant: 'body' })}>
|
||||||
|
{t(`actions.${descriptor.id}`)}
|
||||||
|
</td>
|
||||||
|
<td className={shortcutCellStyle}>
|
||||||
|
<ShortcutBadge visualLabel={visualShortcut} srLabel={srShortcut} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
}
|
||||||
61
src/frontend/src/features/shortcuts/formatLabels.ts
Normal file
61
src/frontend/src/features/shortcuts/formatLabels.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { Shortcut } from './types'
|
||||||
|
import { isMacintosh } from '@/utils/livekit'
|
||||||
|
|
||||||
|
// Visible label for a shortcut (uses ⌘/Ctrl prefix when needed).
|
||||||
|
export const formatShortcutLabel = (shortcut?: Shortcut) => {
|
||||||
|
if (!shortcut) return '—'
|
||||||
|
const key = shortcut.key?.toUpperCase()
|
||||||
|
if (!key) return '—'
|
||||||
|
const parts: string[] = []
|
||||||
|
if (shortcut.ctrlKey) parts.push(isMacintosh() ? '⌘' : 'Ctrl')
|
||||||
|
if (shortcut.altKey) parts.push(isMacintosh() ? '⌥' : 'Alt')
|
||||||
|
if (shortcut.shiftKey) parts.push('Shift')
|
||||||
|
parts.push(key)
|
||||||
|
return parts.join('+')
|
||||||
|
}
|
||||||
|
|
||||||
|
// SR-friendly label for a shortcut (reads “Control plus D”).
|
||||||
|
export const formatShortcutLabelForSR = (
|
||||||
|
shortcut: Shortcut | undefined,
|
||||||
|
{
|
||||||
|
controlLabel,
|
||||||
|
commandLabel,
|
||||||
|
plusLabel,
|
||||||
|
noShortcutLabel,
|
||||||
|
}: {
|
||||||
|
controlLabel: string
|
||||||
|
commandLabel: string
|
||||||
|
plusLabel: string
|
||||||
|
noShortcutLabel: string
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
if (!shortcut) return noShortcutLabel
|
||||||
|
const key = shortcut.key?.toUpperCase()
|
||||||
|
if (!key) return noShortcutLabel
|
||||||
|
const ctrlWord = isMacintosh() ? commandLabel : controlLabel
|
||||||
|
const parts: string[] = []
|
||||||
|
if (shortcut.ctrlKey) parts.push(ctrlWord)
|
||||||
|
if (shortcut.altKey) parts.push('Alt')
|
||||||
|
if (shortcut.shiftKey) parts.push('Shift')
|
||||||
|
parts.push(key)
|
||||||
|
return parts.join(` ${plusLabel} `)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract displayable key name from KeyboardEvent.code (ex: KeyV -> V).
|
||||||
|
export const getKeyLabelFromCode = (code?: string) => {
|
||||||
|
if (!code) return ''
|
||||||
|
if (code.startsWith('Key') && code.length === 4) return code.slice(3)
|
||||||
|
if (code.startsWith('Digit') && code.length === 6) return code.slice(5)
|
||||||
|
if (code === 'Space') return '␣'
|
||||||
|
if (code.startsWith('Arrow')) return code.slice(5) // Up, Down, Left, Right
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
|
// Long-press label (visual or SR), e.g. “Hold V”.
|
||||||
|
export const formatLongPressLabel = (
|
||||||
|
codeLabel: string,
|
||||||
|
holdTemplate: string
|
||||||
|
) => {
|
||||||
|
if (!codeLabel) return holdTemplate.replace('{{key}}', '?')
|
||||||
|
return holdTemplate.replace('{{key}}', codeLabel)
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import { useCallback } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { Shortcut } from '../types'
|
||||||
|
import {
|
||||||
|
formatShortcutLabel,
|
||||||
|
formatShortcutLabelForSR,
|
||||||
|
formatLongPressLabel,
|
||||||
|
getKeyLabelFromCode,
|
||||||
|
} from '../formatLabels'
|
||||||
|
|
||||||
|
export const useShortcutFormatting = () => {
|
||||||
|
const { t } = useTranslation('rooms')
|
||||||
|
|
||||||
|
const formatVisual = useCallback(
|
||||||
|
(shortcut?: Shortcut, code?: string, kind?: string) => {
|
||||||
|
if (code && kind === 'longPress') {
|
||||||
|
const label = getKeyLabelFromCode(code)
|
||||||
|
return formatLongPressLabel(
|
||||||
|
label,
|
||||||
|
t('shortcutsPanel.visual.hold', { key: '{{key}}' })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return formatShortcutLabel(shortcut)
|
||||||
|
},
|
||||||
|
[t]
|
||||||
|
)
|
||||||
|
|
||||||
|
const formatForSR = useCallback(
|
||||||
|
(shortcut?: Shortcut, code?: string, kind?: string) => {
|
||||||
|
if (code && kind === 'longPress') {
|
||||||
|
const label = getKeyLabelFromCode(code)
|
||||||
|
return formatLongPressLabel(
|
||||||
|
label,
|
||||||
|
t('shortcutsPanel.sr.hold', { key: '{{key}}' })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return formatShortcutLabelForSR(shortcut, {
|
||||||
|
controlLabel: t('shortcutsPanel.sr.control'),
|
||||||
|
commandLabel: t('shortcutsPanel.sr.command'),
|
||||||
|
plusLabel: t('shortcutsPanel.sr.plus'),
|
||||||
|
noShortcutLabel: t('shortcutsPanel.sr.noShortcut'),
|
||||||
|
})
|
||||||
|
},
|
||||||
|
[t]
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
formatVisual,
|
||||||
|
formatForSR,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -595,6 +595,38 @@
|
|||||||
"muteParticipant": "{{name}} stummschalten",
|
"muteParticipant": "{{name}} stummschalten",
|
||||||
"fullScreen": "Vollbild"
|
"fullScreen": "Vollbild"
|
||||||
},
|
},
|
||||||
|
"shortcutsPanel": {
|
||||||
|
"title": "Tastenkombinationen",
|
||||||
|
"categories": {
|
||||||
|
"navigation": "Navigation",
|
||||||
|
"media": "Medien",
|
||||||
|
"interaction": "Interaktion"
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"open-shortcuts": "Tastenkürzel-Hilfe öffnen",
|
||||||
|
"focus-toolbar": "Fokus auf die untere Symbolleiste",
|
||||||
|
"toggle-microphone": "Mikrofon umschalten",
|
||||||
|
"toggle-camera": "Kamera umschalten",
|
||||||
|
"push-to-talk": "Push-to-talk (gedrückt halten zum Einschalten)",
|
||||||
|
"reaction": "Reaktionspanel",
|
||||||
|
"fullscreen": "Vollbild umschalten",
|
||||||
|
"recording": "Aufnahmepanel umschalten",
|
||||||
|
"raise-hand": "Hand heben oder senken",
|
||||||
|
"toggle-chat": "Chat anzeigen/ausblenden",
|
||||||
|
"toggle-participants": "Teilnehmer anzeigen/ausblenden",
|
||||||
|
"open-shortcuts-settings": "Tastenkürzel-Einstellungen öffnen"
|
||||||
|
},
|
||||||
|
"sr": {
|
||||||
|
"control": "Steuerung",
|
||||||
|
"command": "Befehl",
|
||||||
|
"plus": "plus",
|
||||||
|
"hold": "Halte {{key}} gedrückt",
|
||||||
|
"noShortcut": "Kein Tastenkürzel"
|
||||||
|
},
|
||||||
|
"visual": {
|
||||||
|
"hold": "Halte {{key}} gedrückt"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fullScreenWarning": {
|
"fullScreenWarning": {
|
||||||
"message": "Um eine Endlosschleife zu vermeiden, teile nicht deinen gesamten Bildschirm. Teile stattdessen einen Tab oder ein anderes Fenster.",
|
"message": "Um eine Endlosschleife zu vermeiden, teile nicht deinen gesamten Bildschirm. Teile stattdessen einen Tab oder ein anderes Fenster.",
|
||||||
"stop": "Präsentation beenden",
|
"stop": "Präsentation beenden",
|
||||||
|
|||||||
@@ -100,6 +100,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"shortcuts": {
|
||||||
|
"listLabel": "Tastenkürzel",
|
||||||
|
"columnAction": "Aktion",
|
||||||
|
"columnShortcut": "Tastenkürzel"
|
||||||
|
},
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"heading": "Einstellungen"
|
"heading": "Einstellungen"
|
||||||
},
|
},
|
||||||
@@ -120,6 +125,7 @@
|
|||||||
"general": "Allgemein",
|
"general": "Allgemein",
|
||||||
"notifications": "Benachrichtigungen",
|
"notifications": "Benachrichtigungen",
|
||||||
"accessibility": "Barrierefreiheit",
|
"accessibility": "Barrierefreiheit",
|
||||||
"transcription": "Transkription"
|
"transcription": "Transkription",
|
||||||
|
"shortcuts": "Tastenkürzel"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -595,6 +595,38 @@
|
|||||||
"muteParticipant": "Mute {{name}}",
|
"muteParticipant": "Mute {{name}}",
|
||||||
"fullScreen": "Full screen"
|
"fullScreen": "Full screen"
|
||||||
},
|
},
|
||||||
|
"shortcutsPanel": {
|
||||||
|
"title": "Keyboard shortcuts",
|
||||||
|
"categories": {
|
||||||
|
"navigation": "Navigation",
|
||||||
|
"media": "Media",
|
||||||
|
"interaction": "Interaction"
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"open-shortcuts": "Open shortcuts help",
|
||||||
|
"focus-toolbar": "Focus bottom toolbar",
|
||||||
|
"toggle-microphone": "Toggle microphone",
|
||||||
|
"toggle-camera": "Toggle camera",
|
||||||
|
"push-to-talk": "Push-to-talk (hold to unmute)",
|
||||||
|
"reaction": "Emoji reaction panel",
|
||||||
|
"fullscreen": "Toggle fullscreen",
|
||||||
|
"recording": "Toggle recording panel",
|
||||||
|
"raise-hand": "Raise or lower hand",
|
||||||
|
"toggle-chat": "Toggle chat",
|
||||||
|
"toggle-participants": "Toggle participants",
|
||||||
|
"open-shortcuts-settings": "Open shortcuts settings"
|
||||||
|
},
|
||||||
|
"sr": {
|
||||||
|
"control": "Control",
|
||||||
|
"command": "Command",
|
||||||
|
"plus": "plus",
|
||||||
|
"hold": "Hold {{key}}",
|
||||||
|
"noShortcut": "No shortcut"
|
||||||
|
},
|
||||||
|
"visual": {
|
||||||
|
"hold": "Hold {{key}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fullScreenWarning": {
|
"fullScreenWarning": {
|
||||||
"message": "To avoid infinite loop display, do not share your entire screen. Instead, share a tab or another window.",
|
"message": "To avoid infinite loop display, do not share your entire screen. Instead, share a tab or another window.",
|
||||||
"stop": "Stop presenting",
|
"stop": "Stop presenting",
|
||||||
|
|||||||
@@ -100,6 +100,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"shortcuts": {
|
||||||
|
"listLabel": "Keyboard shortcuts",
|
||||||
|
"columnAction": "Action",
|
||||||
|
"columnShortcut": "Shortcut"
|
||||||
|
},
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"heading": "Settings"
|
"heading": "Settings"
|
||||||
},
|
},
|
||||||
@@ -120,6 +125,7 @@
|
|||||||
"general": "General",
|
"general": "General",
|
||||||
"notifications": "Notifications",
|
"notifications": "Notifications",
|
||||||
"accessibility": "Accessibility",
|
"accessibility": "Accessibility",
|
||||||
"transcription": "Transcription"
|
"transcription": "Transcription",
|
||||||
|
"shortcuts": "Shortcuts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -595,6 +595,38 @@
|
|||||||
"muteParticipant": "Couper le micro de {{name}}",
|
"muteParticipant": "Couper le micro de {{name}}",
|
||||||
"fullScreen": "Plein écran"
|
"fullScreen": "Plein écran"
|
||||||
},
|
},
|
||||||
|
"shortcutsPanel": {
|
||||||
|
"title": "Raccourcis clavier",
|
||||||
|
"categories": {
|
||||||
|
"navigation": "Navigation",
|
||||||
|
"media": "Média",
|
||||||
|
"interaction": "Interaction"
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"open-shortcuts": "Ouvrir l’aide des raccourcis",
|
||||||
|
"focus-toolbar": "Mettre le focus sur la barre d’outils du bas",
|
||||||
|
"toggle-microphone": "Activer ou désactiver le micro",
|
||||||
|
"toggle-camera": "Activer ou désactiver la caméra",
|
||||||
|
"push-to-talk": "Appuyer pour parler (maintenir pour réactiver)",
|
||||||
|
"reaction": "Panneau des réactions",
|
||||||
|
"fullscreen": "Basculer en plein écran",
|
||||||
|
"recording": "Basculer le panneau d’enregistrement",
|
||||||
|
"raise-hand": "Lever ou baisser la main",
|
||||||
|
"toggle-chat": "Afficher/Masquer le chat",
|
||||||
|
"toggle-participants": "Afficher/Masquer les participants",
|
||||||
|
"open-shortcuts-settings": "Ouvrir les réglages des raccourcis"
|
||||||
|
},
|
||||||
|
"sr": {
|
||||||
|
"control": "Contrôle",
|
||||||
|
"command": "Commande",
|
||||||
|
"plus": "plus",
|
||||||
|
"hold": "Maintenir {{key}}",
|
||||||
|
"noShortcut": "Aucun raccourci"
|
||||||
|
},
|
||||||
|
"visual": {
|
||||||
|
"hold": "Maintenir {{key}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fullScreenWarning": {
|
"fullScreenWarning": {
|
||||||
"message": "Pour éviter l'affichage en boucle infinie, ne partagez pas l'intégralité de votre écran. Partagez plutôt un onglet ou une autre fenêtre.",
|
"message": "Pour éviter l'affichage en boucle infinie, ne partagez pas l'intégralité de votre écran. Partagez plutôt un onglet ou une autre fenêtre.",
|
||||||
"stop": "Arrêter la présentation",
|
"stop": "Arrêter la présentation",
|
||||||
|
|||||||
@@ -100,6 +100,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"shortcuts": {
|
||||||
|
"listLabel": "Liste des raccourcis clavier",
|
||||||
|
"columnAction": "Action",
|
||||||
|
"columnShortcut": "Raccourci"
|
||||||
|
},
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"heading": "Paramètres"
|
"heading": "Paramètres"
|
||||||
},
|
},
|
||||||
@@ -120,6 +125,7 @@
|
|||||||
"general": "Général",
|
"general": "Général",
|
||||||
"notifications": "Notifications",
|
"notifications": "Notifications",
|
||||||
"accessibility": "Accessibilité",
|
"accessibility": "Accessibilité",
|
||||||
"transcription": "Transcription"
|
"transcription": "Transcription",
|
||||||
|
"shortcuts": "Raccourcis"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -595,6 +595,38 @@
|
|||||||
"muteParticipant": "Demp {{name}}",
|
"muteParticipant": "Demp {{name}}",
|
||||||
"fullScreen": "Volledig scherm"
|
"fullScreen": "Volledig scherm"
|
||||||
},
|
},
|
||||||
|
"shortcutsPanel": {
|
||||||
|
"title": "Sneltoetsen",
|
||||||
|
"categories": {
|
||||||
|
"navigation": "Navigatie",
|
||||||
|
"media": "Media",
|
||||||
|
"interaction": "Interactie"
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"open-shortcuts": "Sneltoetsenhulp openen",
|
||||||
|
"focus-toolbar": "Focus op de onderste werkbalk",
|
||||||
|
"toggle-microphone": "Microfoon aan/uit",
|
||||||
|
"toggle-camera": "Camera aan/uit",
|
||||||
|
"push-to-talk": "Push-to-talk (ingedrukt houden om te activeren)",
|
||||||
|
"reaction": "Reactiepaneel",
|
||||||
|
"fullscreen": "Volledig scherm wisselen",
|
||||||
|
"recording": "Opnamepaneel wisselen",
|
||||||
|
"raise-hand": "Hand opsteken of laten zakken",
|
||||||
|
"toggle-chat": "Chat tonen/verbergen",
|
||||||
|
"toggle-participants": "Deelnemers tonen/verbergen",
|
||||||
|
"open-shortcuts-settings": "Sneltoets-instellingen openen"
|
||||||
|
},
|
||||||
|
"sr": {
|
||||||
|
"control": "Control",
|
||||||
|
"command": "Command",
|
||||||
|
"plus": "plus",
|
||||||
|
"hold": "Houd {{key}} ingedrukt",
|
||||||
|
"noShortcut": "Geen sneltoets"
|
||||||
|
},
|
||||||
|
"visual": {
|
||||||
|
"hold": "Houd {{key}} ingedrukt"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fullScreenWarning": {
|
"fullScreenWarning": {
|
||||||
"message": "Om niet oneindige uw scherm in zichzelf te delen, kunt u beter niet het hele scherm delen. Deel in plaats daarvan een tab of een ander venster.",
|
"message": "Om niet oneindige uw scherm in zichzelf te delen, kunt u beter niet het hele scherm delen. Deel in plaats daarvan een tab of een ander venster.",
|
||||||
"stop": "Stop met presenteren",
|
"stop": "Stop met presenteren",
|
||||||
|
|||||||
@@ -100,6 +100,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"shortcuts": {
|
||||||
|
"listLabel": "Sneltoetsen",
|
||||||
|
"columnAction": "Actie",
|
||||||
|
"columnShortcut": "Sneltoets"
|
||||||
|
},
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"heading": "Instellingen"
|
"heading": "Instellingen"
|
||||||
},
|
},
|
||||||
@@ -114,6 +119,7 @@
|
|||||||
"video": "Video",
|
"video": "Video",
|
||||||
"general": "Algemeen",
|
"general": "Algemeen",
|
||||||
"notifications": "Meldingen",
|
"notifications": "Meldingen",
|
||||||
"transcription": "Transcriptie"
|
"transcription": "Transcriptie",
|
||||||
|
"shortcuts": "Sneltoetsen"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user