mirror of
				https://github.com/cudr/slate-collaborative.git
				synced 2025-06-13 12:54:04 +00:00 
			
		
		
		
	feat: success show cursor position
This commit is contained in:
		
							parent
							
								
									2a4d64b074
								
							
						
					
					
						commit
						4efc8db60e
					
				| @ -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) | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
							
								
								
									
										35
									
								
								packages/bridge/src/apply/selection.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								packages/bridge/src/apply/selection.ts
									
									
									
									
									
										Normal 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 | ||||
| } | ||||
| @ -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) | ||||
|  | ||||
| @ -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> | ||||
|       ) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user