overleaf/services/web/frontend/js/features/pdf-preview/hooks/use-compile-triggers.js
Alf Eaton e320473d05 Allow compile to be triggered with Ctrl/Cmd-s when Caps Lock is enabled (#14547)
GitOrigin-RevId: f78bd433e6862a49f353e3f994c90024a06e2b3f
2023-09-04 08:04:31 +00:00

83 lines
2.1 KiB
JavaScript

import { useCallback, useEffect } from 'react'
import useEventListener from '../../../shared/hooks/use-event-listener'
import useDetachAction from '../../../shared/hooks/use-detach-action'
export const startCompileKeypress = event => {
if (event.shiftKey || event.altKey) {
return false
}
if (event.ctrlKey) {
// Ctrl+s / Ctrl+Enter / Ctrl+.
if (event.key === 's' || event.key === 'Enter' || event.key === '.') {
return true
}
// Ctrl+s with Caps-Lock on
if (event.key === 'S' && !event.shiftKey) {
return true
}
} else if (event.metaKey) {
// Cmd+s / Cmd+Enter
if (event.key === 's' || event.key === 'Enter') {
return true
}
// Cmd+s with Caps-Lock on
if (event.key === 'S' && !event.shiftKey) {
return true
}
}
}
export default function useCompileTriggers(
startCompile,
setChangedAt,
setSavedAt
) {
const handleKeyDown = useCallback(
event => {
if (startCompileKeypress(event)) {
event.preventDefault()
startCompile()
}
},
[startCompile]
)
const handleStartCompile = useCallback(() => {
startCompile()
}, [startCompile])
useEventListener('pdf:recompile', handleStartCompile)
useEffect(() => {
document.body.addEventListener('keydown', handleKeyDown)
return () => {
document.body.removeEventListener('keydown', handleKeyDown)
}
}, [handleKeyDown])
// record doc changes when notified by the editor
const setOrTriggerChangedAt = useDetachAction(
'set-changed-at',
setChangedAt,
'detacher',
'detached'
)
const setChangedAtHandler = useCallback(() => {
setOrTriggerChangedAt(Date.now())
}, [setOrTriggerChangedAt])
useEventListener('doc:changed', setChangedAtHandler)
// record when the server acknowledges saving changes
const setOrTriggerSavedAt = useDetachAction(
'set-saved-at',
setSavedAt,
'detacher',
'detached'
)
const setSavedAtHandler = useCallback(() => {
setOrTriggerSavedAt(Date.now())
}, [setOrTriggerSavedAt])
useEventListener('doc:saved', setSavedAtHandler)
}