feat: add test annotations

This commit is contained in:
cudr
2019-10-10 22:45:31 +03:00
parent ab3b8c4ee3
commit 2a4d64b074
10 changed files with 153 additions and 24 deletions

View File

@@ -5,7 +5,12 @@ import io from 'socket.io-client'
import { Value, Operation } from 'slate'
import { ConnectionModel } from './model'
import { applySlateOps, toSlateOp, toJS } from '@slate-collaborative/bridge'
import {
applySlateOps,
toSlateOp,
hexGen,
toJS
} from '@slate-collaborative/bridge'
class Connection {
url: string
@@ -15,6 +20,7 @@ class Connection {
socket: SocketIOClient.Socket
editor: any
connectOpts: any
selection: any
onConnect?: () => void
onDisconnect?: () => void
@@ -68,13 +74,47 @@ class Connection {
})
})
setTimeout(() => (this.editor.remote = false), 5)
await Promise.resolve()
this.editor.remote = false
this.setCursors(docNew.cursors)
}
} catch (e) {
console.error(e)
}
}
setCursors = cursors => {
if (!cursors) return
// console.log('setCursors', cursors)
const {
value: { annotations }
} = this.editor
const keyMap = {}
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])
}
})
})
}
receiveSlateOps = (operations: Immutable.List<Operation>) => {
const doc = this.docSet.getDoc(this.docId)
const message = `change from ${this.socket.id}`
@@ -82,7 +122,10 @@ class Connection {
if (!doc) return
const changed = Automerge.change(doc, message, (d: any) =>
applySlateOps(d, operations)
applySlateOps(d, operations, {
id: this.socket.id,
selection: this.editor.value.selection
})
)
this.docSet.setDoc(this.docId, changed)

View File

@@ -2,6 +2,7 @@ import { ReactNode } from 'react'
import onChange from './onChange'
import renderEditor from './renderEditor'
import renderAnnotation from './renderAnnotation'
import Connection from './Connection'
@@ -22,7 +23,8 @@ const plugin = (opts: PluginOptions = {}) => {
return {
onChange: onChange(options),
renderEditor: renderEditor(options)
renderEditor: renderEditor(options),
renderAnnotation
}
}

View File

@@ -1,7 +1,7 @@
import { ExtendedEditor } from './model'
const onChange = opts => (editor: ExtendedEditor, next: () => void) => {
if (!editor.remote) {
if (editor.connection && !editor.remote) {
const operations: any = editor.operations
editor.connection.receiveSlateOps(operations)

View File

@@ -0,0 +1,43 @@
import React from 'react'
const wrapStyles = { backgroundColor: '#e91e63', position: 'relative' }
const cursorStyleBase = {
position: 'absolute',
top: 0,
pointerEvents: 'none',
userSelect: 'none',
transform: 'translateY(-100%)',
fontSize: '10px',
color: 'white',
background: 'palevioletred',
whiteSpace: 'nowrap'
} as any
const renderAnnotation = (props, editor, next) => {
const { children, annotation, attributes } = props
const isLeft = annotation.focus.offset >= annotation.anchor.offset
console.log('isLeft', isLeft)
const cursorStyles = { ...cursorStyleBase, left: isLeft ? '0%' : '100%' }
console.log('renderAnnotation', annotation.toJSON())
switch (annotation.type) {
case 'collaborative_selection':
return (
<span {...attributes} style={wrapStyles}>
<span contentEditable={false} style={cursorStyles}>
{annotation.key}
</span>
{children}
</span>
)
default:
return next()
}
}
export default renderAnnotation