mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 06:33:55 +01:00
Use tracked changes and comments from the snapshot (#26267)
GitOrigin-RevId: c2bf0c9c9a5ab4f8837b8712ca549119a31cf067
This commit is contained in:
@@ -29,6 +29,10 @@ import {
|
||||
import { ThreadId } from '../../../../../types/review-panel/review-panel'
|
||||
import getMeta from '@/utils/meta'
|
||||
import OError from '@overleaf/o-error'
|
||||
import {
|
||||
HistoryOTShareDoc,
|
||||
ShareLatexOTShareDoc,
|
||||
} from '../../../../../types/share-doc'
|
||||
|
||||
const MAX_PENDING_OP_SIZE = 64
|
||||
|
||||
@@ -121,6 +125,27 @@ export class DocumentContainer extends EventEmitter {
|
||||
this.bindToSocketEvents()
|
||||
}
|
||||
|
||||
get shareDoc() {
|
||||
if (!this.doc) {
|
||||
throw new Error('Missing ShareJSDoc')
|
||||
}
|
||||
if (!this.doc._doc) {
|
||||
throw new Error('Missing ShareJS Doc')
|
||||
}
|
||||
return this.doc._doc as HistoryOTShareDoc | ShareLatexOTShareDoc
|
||||
}
|
||||
|
||||
isHistoryOT() {
|
||||
return this.shareDoc.otType === 'history-ot'
|
||||
}
|
||||
|
||||
get historyOTShareDoc() {
|
||||
if (!this.isHistoryOT()) {
|
||||
throw new Error('shareDoc is not historyOT')
|
||||
}
|
||||
return this.shareDoc as HistoryOTShareDoc
|
||||
}
|
||||
|
||||
attachToCM6(cm6: EditorFacade) {
|
||||
this.cm6 = cm6
|
||||
if (this.doc) {
|
||||
@@ -613,6 +638,9 @@ export class DocumentContainer extends EventEmitter {
|
||||
this.trigger('op:timeout')
|
||||
return this.onError(new Error('op timed out'))
|
||||
})
|
||||
this.doc.on('ranges:dirty', (...args) => {
|
||||
return this.trigger('ranges:dirty', ...args)
|
||||
})
|
||||
|
||||
let docChangedTimeout: number | null = null
|
||||
this.doc.on(
|
||||
|
||||
@@ -22,11 +22,13 @@ import {
|
||||
StringFileData,
|
||||
TrackedChangeList,
|
||||
EditOperationBuilder,
|
||||
CommentList,
|
||||
} from 'overleaf-editor-core'
|
||||
import {
|
||||
StringFileRawData,
|
||||
RawEditOperation,
|
||||
} from 'overleaf-editor-core/lib/types'
|
||||
import { HistoryOTShareDoc } from '../../../../../types/share-doc'
|
||||
|
||||
// All times below are in milliseconds
|
||||
const SINGLE_USER_FLUSH_DELAY = 2000
|
||||
@@ -267,11 +269,26 @@ export class ShareJsDoc extends EventEmitter {
|
||||
processUpdateFromServer(message: Message) {
|
||||
try {
|
||||
if (this.type === 'history-ot' && message.op != null) {
|
||||
const shareDoc = this._doc as HistoryOTShareDoc
|
||||
const trackedChangesBefore = shareDoc.snapshot.getTrackedChanges()
|
||||
const commentsBefore = shareDoc.snapshot.getComments()
|
||||
|
||||
const ops = message.op as RawEditOperation[]
|
||||
this._doc._onMessage({
|
||||
...message,
|
||||
op: ops.map(EditOperationBuilder.fromJSON),
|
||||
})
|
||||
|
||||
if (
|
||||
this.rangesUpdated(
|
||||
trackedChangesBefore,
|
||||
commentsBefore,
|
||||
shareDoc.snapshot.getTrackedChanges(),
|
||||
shareDoc.snapshot.getComments()
|
||||
)
|
||||
) {
|
||||
this.trigger('ranges:dirty')
|
||||
}
|
||||
} else {
|
||||
this._doc._onMessage(message)
|
||||
}
|
||||
@@ -471,6 +488,29 @@ export class ShareJsDoc extends EventEmitter {
|
||||
doc.pendingCallbacks.push(() => {
|
||||
return this.trigger('op:acknowledged', op)
|
||||
})
|
||||
|
||||
// history-ot: submit the op and detect whether tracked changes or comments have updated
|
||||
if (this.type === 'history-ot') {
|
||||
const shareDoc = doc as HistoryOTShareDoc
|
||||
const trackedChangesBefore = shareDoc.snapshot.getTrackedChanges()
|
||||
const commentsBefore = shareDoc.snapshot.getComments()
|
||||
const result = submitOp.call(doc, op, callback)
|
||||
|
||||
if (
|
||||
this.rangesUpdated(
|
||||
trackedChangesBefore,
|
||||
commentsBefore,
|
||||
shareDoc.snapshot.getTrackedChanges(),
|
||||
shareDoc.snapshot.getComments()
|
||||
)
|
||||
) {
|
||||
this.trigger('ranges:dirty')
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// non-history-ot: just submit the op
|
||||
return submitOp.call(doc, op, callback)
|
||||
}
|
||||
|
||||
@@ -480,4 +520,31 @@ export class ShareJsDoc extends EventEmitter {
|
||||
return flush.call(doc)
|
||||
}
|
||||
}
|
||||
|
||||
private rangesUpdated(
|
||||
trackedChangesBefore: TrackedChangeList,
|
||||
commentsBefore: CommentList,
|
||||
trackedChangesAfter: TrackedChangeList,
|
||||
commentsAfter: CommentList
|
||||
) {
|
||||
return (
|
||||
// quick length comparison first
|
||||
trackedChangesBefore.length !== trackedChangesAfter.length ||
|
||||
commentsBefore.length !== commentsAfter.length ||
|
||||
// then compare each item by identity
|
||||
this.itemsChanged(
|
||||
trackedChangesBefore.asSorted(),
|
||||
trackedChangesAfter.asSorted()
|
||||
) ||
|
||||
this.itemsChanged(commentsBefore.toArray(), commentsAfter.toArray())
|
||||
)
|
||||
}
|
||||
|
||||
private itemsChanged(before: readonly any[], after: readonly any[]) {
|
||||
for (let i = 0; i < before.length; i++) {
|
||||
if (before[i] !== after[i]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user