feat: success show cursor position

This commit is contained in:
cudr 2019-10-12 08:02:37 +03:00
parent 2a4d64b074
commit 4efc8db60e
6 changed files with 109 additions and 58 deletions

View File

@ -40,10 +40,18 @@ class Connection {
}
private saveDoc = throttle(pathname => {
if (this.options.onDocumentSave) {
const doc = this.docSet.getDoc(pathname)
try {
if (this.options.onDocumentSave) {
const doc = this.docSet.getDoc(pathname)
this.options.onDocumentSave(pathname, toJS(doc))
const data = toJS(doc)
delete data.cursors
this.options.onDocumentSave(pathname, data)
}
} catch (e) {
console.log(e)
}
}, (this.options && this.options.saveTreshold) || 2000)

View File

@ -1,17 +1,17 @@
import { Operation, SyncDoc } from '../model'
export const addAnnotation = (doc: SyncDoc, op: Operation): SyncDoc => {
console.log('addAnnotation!!!', op)
console.log('addAnnotation!!!', op.toJS())
return doc
}
export const removeAnnotation = (doc: SyncDoc, op: Operation): SyncDoc => {
console.log('removeAnnotation!!!', op)
console.log('removeAnnotation!!!', op.toJS())
return doc
}
export const setAnnotation = (doc: SyncDoc, op: Operation): SyncDoc => {
console.log('setAnnotation!!!', op)
console.log('setAnnotation!!!', op.toJS())
return doc
}

View File

@ -3,43 +3,19 @@ import { Operation, Operations, SyncDoc } from '../model'
import node from './node'
import mark from './mark'
import text from './text'
import selection from './selection'
import annotation from './annotation'
const setSelection = (doc, op, { id, selection }) => {
console.log('selection', selection.toJSON())
if (!doc.cursors) {
doc.cursors = {}
}
// console.log('setSelection', op.toJSON(), id)
const operation = op.toJSON()
if (!doc.cursors[id]) {
doc.cursors[id] = {
key: id,
type: 'collaborative_selection'
}
}
const cursor = doc.cursors[id]
const { focus, anchor } = operation.newProperties
if (focus) cursor.focus = focus
if (anchor) cursor.anchor = anchor
return doc
}
const setValue = (doc, op) => doc
const setSelection = doc => doc
const setValue = doc => doc
const opType: any = {
...text,
...annotation,
...node,
...mark,
set_selection: setSelection,
set_value: setValue
...selection
// set_value: setValue
}
export const applyOperation = meta => (
@ -49,7 +25,7 @@ export const applyOperation = meta => (
try {
const applyOp = opType[op.type]
if (!applyOp) throw new TypeError('Invalid operation type!')
if (!applyOp) throw new TypeError('Unsupported operation type!')
return applyOp(doc, op, meta)
} catch (e) {

View File

@ -0,0 +1,35 @@
import { toJS } from '../utils'
const setSelection = (doc, op, { id, selection, annotationType }) => {
if (!doc.cursors) {
doc.cursors = {}
}
const operation = op.toJS()
if (!doc.cursors[id]) {
doc.cursors[id] = {
key: id,
type: annotationType,
data: {}
}
}
const cursor = doc.cursors[id]
const { focus, anchor } = operation.newProperties
if (focus) cursor.focus = focus
if (anchor) cursor.anchor = anchor
const cursorPath = (anchor && anchor.path) || (focus && focus.path)
if (cursorPath) cursor.data.cursorPath = toJS(cursorPath)
cursor.data.isBackward = selection.isBackward
return doc
}
export default {
set_selection: setSelection
}

View File

@ -87,29 +87,23 @@ class Connection {
setCursors = cursors => {
if (!cursors) return
// console.log('setCursors', cursors)
const {
value: { annotations }
} = this.editor
const keyMap = {}
console.log('cursors', cursors)
this.editor.withoutSaving(() => {
annotations.forEach(anno => {
// if (cursors[anno.key]) {
// console.log('set cursor', anno, )
// this.editor.setAnnotation(anno, cursors[anno.key])
// keyMap[anno.key] = true
// } else {
// this.editor.removeAnnotation(anno)
// }
this.editor.removeAnnotation(anno)
})
Object.keys(cursors).forEach(key => {
if (key !== this.socket.id && !keyMap[key]) {
this.editor.addAnnotation(cursors[key])
this.editor.addAnnotation(toJS(cursors[key]))
}
})
})
@ -121,11 +115,42 @@ class Connection {
if (!doc) return
const selectionOps = operations.filter(op => op.type === 'set_selection')
console.log('hasSelectionOps', selectionOps.size)
const { value } = this.editor
const { selection } = value
const meta = {
id: this.socket.id,
selection,
annotationType: 'collaborative_selection'
}
const cursor = doc.cursors[meta.id]
const cursorOffset = cursor && cursor.anchor && cursor.anchor.offset
if (!selectionOps.size && selection.start.offset !== cursorOffset) {
const opData = {
type: 'set_selection',
properties: {},
newProperties: {
anchor: selection.start,
focus: selection.end
}
}
const op = Operation.fromJSON(opData)
operations = operations.push(op)
}
console.log('operations', operations.toJSON())
const changed = Automerge.change(doc, message, (d: any) =>
applySlateOps(d, operations, {
id: this.socket.id,
selection: this.editor.value.selection
})
applySlateOps(d, operations, meta)
)
this.docSet.setDoc(this.docId, changed)

View File

@ -15,23 +15,30 @@ const cursorStyleBase = {
} as any
const renderAnnotation = (props, editor, next) => {
const { children, annotation, attributes } = props
const { children, annotation, attributes, node } = props
const isLeft = annotation.focus.offset >= annotation.anchor.offset
const isBackward = annotation.data.get('isBackward')
const cursorPath = annotation.data.get('cursorPath')
console.log('isLeft', isLeft)
const cursorStyles = { ...cursorStyleBase, left: isBackward ? '0%' : '100%' }
const cursorStyles = { ...cursorStyleBase, left: isLeft ? '0%' : '100%' }
const { document } = editor.value
console.log('renderAnnotation', annotation.toJSON())
const targetNode = document.getNode(cursorPath)
const isTarget = targetNode && targetNode.key === node.key
const showCursor = isTarget
switch (annotation.type) {
case 'collaborative_selection':
return (
<span {...attributes} style={wrapStyles}>
<span contentEditable={false} style={cursorStyles}>
{annotation.key}
</span>
{showCursor ? (
<span contentEditable={false} style={cursorStyles}>
{annotation.key}
</span>
) : null}
{children}
</span>
)