mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Improve handling of doc:saved events (#12522)
GitOrigin-RevId: 0ebf198548f6aeecb356405b0c582d3fd64db391
This commit is contained in:
parent
a8ed6b65e1
commit
39df55787c
5 changed files with 62 additions and 12 deletions
|
@ -20,7 +20,11 @@ export const startCompileKeypress = event => {
|
|||
}
|
||||
}
|
||||
|
||||
export default function useCompileTriggers(startCompile, setChangedAt) {
|
||||
export default function useCompileTriggers(
|
||||
startCompile,
|
||||
setChangedAt,
|
||||
setSavedAt
|
||||
) {
|
||||
const handleKeyDown = useCallback(
|
||||
event => {
|
||||
if (startCompileKeypress(event)) {
|
||||
|
@ -54,5 +58,16 @@ export default function useCompileTriggers(startCompile, setChangedAt) {
|
|||
setOrTriggerChangedAt(Date.now())
|
||||
}, [setOrTriggerChangedAt])
|
||||
useEventListener('doc:changed', setChangedAtHandler)
|
||||
useEventListener('doc:saved', setChangedAtHandler) // TODO: store this separately?
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ export default class DocumentCompiler {
|
|||
projectId,
|
||||
rootDocId,
|
||||
setChangedAt,
|
||||
setSavedAt,
|
||||
setCompiling,
|
||||
setData,
|
||||
setFirstRenderDone,
|
||||
|
@ -32,6 +33,7 @@ export default class DocumentCompiler {
|
|||
this.projectId = projectId
|
||||
this.rootDocId = rootDocId
|
||||
this.setChangedAt = setChangedAt
|
||||
this.setSavedAt = setSavedAt
|
||||
this.setCompiling = setCompiling
|
||||
this.setData = setData
|
||||
this.setFirstRenderDone = setFirstRenderDone
|
||||
|
@ -83,6 +85,7 @@ export default class DocumentCompiler {
|
|||
try {
|
||||
// reset values
|
||||
this.setChangedAt(0) // TODO: wait for doc:saved?
|
||||
this.setSavedAt(0)
|
||||
this.validationIssues = undefined
|
||||
|
||||
window.dispatchEvent(new CustomEvent('flush-changes')) // TODO: wait for this?
|
||||
|
|
|
@ -56,7 +56,8 @@ function useCodeMirrorScope(view: EditorView) {
|
|||
|
||||
// set up scope listeners
|
||||
|
||||
const { logEntryAnnotations, uncompiled, compiling } = useCompileContext()
|
||||
const { logEntryAnnotations, editedSinceCompileStarted, compiling } =
|
||||
useCompileContext()
|
||||
|
||||
const [loadingThreads] = useScopeValue<boolean>('loadingThreads')
|
||||
|
||||
|
@ -394,7 +395,7 @@ function useCodeMirrorScope(view: EditorView) {
|
|||
// the project "changed at" date is reset at the start of the compile, i.e. "the project hasn't changed",
|
||||
// but we don't want to display the compile log diagnostics from the previous compile.
|
||||
const enableCompileLogLinter =
|
||||
!syntaxValidation || (!uncompiled && !compiling)
|
||||
!syntaxValidation || (!editedSinceCompileStarted && !compiling)
|
||||
|
||||
// store enableCompileLogLinter in a ref for use in useEffect
|
||||
const enableCompileLogLinterRef = useRef(enableCompileLogLinter)
|
||||
|
|
|
@ -30,6 +30,7 @@ export function DetachCompileProvider({ children }) {
|
|||
compiling: _compiling,
|
||||
deliveryLatencies: _deliveryLatencies,
|
||||
draft: _draft,
|
||||
editedSinceCompileStarted: _editedSinceCompileStarted,
|
||||
error: _error,
|
||||
fileList: _fileList,
|
||||
forceNewDomainVariant: _forceNewDomainVariant,
|
||||
|
@ -69,6 +70,7 @@ export function DetachCompileProvider({ children }) {
|
|||
startCompile: _startCompile,
|
||||
stopCompile: _stopCompile,
|
||||
setChangedAt: _setChangedAt,
|
||||
setSavedAt: _setSavedAt,
|
||||
clearCache: _clearCache,
|
||||
} = localCompileContext
|
||||
|
||||
|
@ -224,6 +226,12 @@ export function DetachCompileProvider({ children }) {
|
|||
'detacher',
|
||||
'detached'
|
||||
)
|
||||
const [editedSinceCompileStarted] = useDetachStateWatcher(
|
||||
'editedSinceCompileStarted',
|
||||
_editedSinceCompileStarted,
|
||||
'detacher',
|
||||
'detached'
|
||||
)
|
||||
const [validationIssues] = useDetachStateWatcher(
|
||||
'validationIssues',
|
||||
_validationIssues,
|
||||
|
@ -345,6 +353,12 @@ export function DetachCompileProvider({ children }) {
|
|||
'detached',
|
||||
'detacher'
|
||||
)
|
||||
const setSavedAt = useDetachAction(
|
||||
'setSavedAt',
|
||||
_setSavedAt,
|
||||
'detached',
|
||||
'detacher'
|
||||
)
|
||||
const clearCache = useDetachAction(
|
||||
'clearCache',
|
||||
_clearCache,
|
||||
|
@ -352,7 +366,7 @@ export function DetachCompileProvider({ children }) {
|
|||
'detacher'
|
||||
)
|
||||
|
||||
useCompileTriggers(startCompile, setChangedAt)
|
||||
useCompileTriggers(startCompile, setChangedAt, setSavedAt)
|
||||
useEffect(() => {
|
||||
// Sync the split test variant across the editor and pdf-detach.
|
||||
const variants = getMeta('ol-splitTestVariants') || {}
|
||||
|
@ -370,6 +384,7 @@ export function DetachCompileProvider({ children }) {
|
|||
compiling,
|
||||
deliveryLatencies,
|
||||
draft,
|
||||
editedSinceCompileStarted,
|
||||
error,
|
||||
fileList,
|
||||
forceNewDomainVariant,
|
||||
|
@ -423,6 +438,7 @@ export function DetachCompileProvider({ children }) {
|
|||
deliveryLatencies,
|
||||
draft,
|
||||
error,
|
||||
editedSinceCompileStarted,
|
||||
fileList,
|
||||
forceNewDomainVariant,
|
||||
hasChanges,
|
||||
|
|
|
@ -123,9 +123,13 @@ export function LocalCompileProvider({ children }) {
|
|||
setPdfUrl(pdfFile?.pdfUrl)
|
||||
}, [pdfFile, setPdfDownloadUrl, setPdfUrl])
|
||||
|
||||
// the project is considered to be "uncompiled" if a doc has changed since the last compile started
|
||||
// the project is considered to be "uncompiled" if a doc has changed, or finished saving, since the last compile started.
|
||||
const [uncompiled, setUncompiled] = useScopeValue('pdf.uncompiled')
|
||||
|
||||
// whether a doc has been edited since the last compile started
|
||||
const [editedSinceCompileStarted, setEditedSinceCompileStarted] =
|
||||
useState(false)
|
||||
|
||||
// the id of the CLSI server which ran the compile
|
||||
const [clsiServerId, setClsiServerId] = useState()
|
||||
|
||||
|
@ -223,9 +227,12 @@ export function LocalCompileProvider({ children }) {
|
|||
// whether syntax validation is enabled globally
|
||||
const [syntaxValidation] = useScopeValue('settings.syntaxValidation')
|
||||
|
||||
// the timestamp that a doc was last changed or saved
|
||||
// the timestamp that a doc was last changed
|
||||
const [changedAt, setChangedAt] = useState(0)
|
||||
|
||||
// the timestamp that a doc was last saved
|
||||
const [savedAt, setSavedAt] = useState(0)
|
||||
|
||||
const { signal } = useAbortController()
|
||||
|
||||
const cleanupCompileResult = useCallback(() => {
|
||||
|
@ -246,6 +253,7 @@ export function LocalCompileProvider({ children }) {
|
|||
projectId,
|
||||
rootDocId,
|
||||
setChangedAt,
|
||||
setSavedAt,
|
||||
setCompiling,
|
||||
setData,
|
||||
setFirstRenderDone,
|
||||
|
@ -272,10 +280,13 @@ export function LocalCompileProvider({ children }) {
|
|||
compiler.setOption('stopOnFirstError', stopOnFirstError)
|
||||
}, [compiler, stopOnFirstError])
|
||||
|
||||
// pass the "uncompiled" value up into the scope for use outside this context provider
|
||||
useEffect(() => {
|
||||
setUncompiled(changedAt > 0)
|
||||
}, [setUncompiled, changedAt])
|
||||
setUncompiled(changedAt > 0 || savedAt > 0)
|
||||
}, [setUncompiled, changedAt, savedAt])
|
||||
|
||||
useEffect(() => {
|
||||
setEditedSinceCompileStarted(changedAt > 0)
|
||||
}, [setEditedSinceCompileStarted, changedAt])
|
||||
|
||||
// always compile the PDF once after opening the project, after the doc has loaded
|
||||
useEffect(() => {
|
||||
|
@ -468,13 +479,13 @@ export function LocalCompileProvider({ children }) {
|
|||
// call the debounced autocompile function if the project is available for auto-compiling and it has changed
|
||||
useEffect(() => {
|
||||
if (canAutoCompile) {
|
||||
if (changedAt > 0) {
|
||||
if (changedAt > 0 || savedAt > 0) {
|
||||
compiler.debouncedAutoCompile()
|
||||
}
|
||||
} else {
|
||||
compiler.debouncedAutoCompile.cancel()
|
||||
}
|
||||
}, [compiler, canAutoCompile, changedAt])
|
||||
}, [compiler, canAutoCompile, changedAt, savedAt])
|
||||
|
||||
// cancel debounced recompile on unmount
|
||||
useEffect(() => {
|
||||
|
@ -533,6 +544,7 @@ export function LocalCompileProvider({ children }) {
|
|||
compiling,
|
||||
deliveryLatencies,
|
||||
draft,
|
||||
editedSinceCompileStarted,
|
||||
error,
|
||||
fileList,
|
||||
forceNewDomainVariant,
|
||||
|
@ -573,6 +585,7 @@ export function LocalCompileProvider({ children }) {
|
|||
validationIssues,
|
||||
firstRenderDone,
|
||||
setChangedAt,
|
||||
setSavedAt,
|
||||
cleanupCompileResult,
|
||||
}),
|
||||
[
|
||||
|
@ -585,6 +598,7 @@ export function LocalCompileProvider({ children }) {
|
|||
compiling,
|
||||
deliveryLatencies,
|
||||
draft,
|
||||
editedSinceCompileStarted,
|
||||
error,
|
||||
fileList,
|
||||
forceNewDomainVariant,
|
||||
|
@ -620,6 +634,7 @@ export function LocalCompileProvider({ children }) {
|
|||
validationIssues,
|
||||
firstRenderDone,
|
||||
setChangedAt,
|
||||
setSavedAt,
|
||||
cleanupCompileResult,
|
||||
setShowLogs,
|
||||
toggleLogs,
|
||||
|
|
Loading…
Reference in a new issue