From e2c5720a0d573e71d991bafe35b2210bfe0f2ce8 Mon Sep 17 00:00:00 2001 From: Hans Pagel Date: Mon, 30 Nov 2020 13:35:49 +0100 Subject: [PATCH] refactor the collaboration extensions --- .../Examples/CollaborativeEditing/index.vue | 40 ++++++------------- .../src/index.ts | 37 +++++++++++------ packages/extension-collaboration/src/index.ts | 8 ++-- 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/docs/src/demos/Examples/CollaborativeEditing/index.vue b/docs/src/demos/Examples/CollaborativeEditing/index.vue index 493bbca7..5b5f11c0 100644 --- a/docs/src/demos/Examples/CollaborativeEditing/index.vue +++ b/docs/src/demos/Examples/CollaborativeEditing/index.vue @@ -87,7 +87,7 @@ class="collaboration-users__item" :style="`background-color: ${user.color}`" v-for="user in users" - :key="user.id" + :key="user.clientId" > {{ user.name }} @@ -112,12 +112,9 @@ export default { data() { return { - documentName: 'tiptap-collaboration-example', name: this.getRandomName(), color: this.getRandomColor(), - ydoc: null, provider: null, - type: null, indexdb: null, editor: null, users: [], @@ -125,28 +122,28 @@ export default { }, mounted() { - this.ydoc = new Y.Doc() - this.type = this.ydoc.getXmlFragment('prosemirror') - this.indexdb = new IndexeddbPersistence(this.documentName, this.ydoc) - - this.provider = new WebrtcProvider(this.documentName, this.ydoc) - this.provider.awareness.on('change', this.updateState) + const ydoc = new Y.Doc() + this.provider = new WebrtcProvider('tiptap-collaboration-example', ydoc) + this.indexdb = new IndexeddbPersistence('tiptap-collaboration-example', ydoc) this.editor = new Editor({ extensions: [ ...defaultExtensions(), Collaboration.configure({ - type: this.type, + provider: this.provider, }), CollaborationCursor.configure({ provider: this.provider, - name: this.name, - color: this.color, + user: { + name: this.name, + color: this.color, + }, + onUpdate: users => { + this.users = users + }, }), ], }) - - this.updateState() }, methods: { @@ -175,7 +172,7 @@ export default { color: this.color, }).run() - this.updateState() + // this.updateState() }, getRandomColor() { @@ -200,17 +197,6 @@ export default { getRandomElement(list) { return list[Math.floor(Math.random() * list.length)] }, - - updateState() { - const { states } = this.provider.awareness - - this.users = Array.from(states.entries()).map(state => { - return { - id: state[0], - ...state[1].user, - } - }) - }, }, beforeDestroy() { diff --git a/packages/extension-collaboration-cursor/src/index.ts b/packages/extension-collaboration-cursor/src/index.ts index ae88704c..fb97257e 100644 --- a/packages/extension-collaboration-cursor/src/index.ts +++ b/packages/extension-collaboration-cursor/src/index.ts @@ -2,17 +2,28 @@ import { Extension, Command } from '@tiptap/core' import { yCursorPlugin } from 'y-prosemirror' export interface CollaborationCursorOptions { - name: string, - color: string, provider: any, - render (user: { name: string, color: string }): HTMLElement, + user: { [key: string]: any }, + render (user: { [key: string]: any }): HTMLElement, + onUpdate: (users: { clientId: string, [key: string]: any }[]) => null, +} + +const awarenessStatesToArray = (states: Map) => { + return Array.from(states.entries()).map(([key, value]) => { + return { + clientId: key, + ...value.user, + } + }) } const CollaborationCursor = Extension.create({ defaultOptions: { provider: null, - name: 'Someone', - color: '#cccccc', + user: { + name: null, + color: null, + }, render: user => { const cursor = document.createElement('span') cursor.classList.add('collaboration-cursor__caret') @@ -26,6 +37,7 @@ const CollaborationCursor = Extension.create({ return cursor }, + onUpdate: () => null, }, addCommands() { @@ -33,11 +45,9 @@ const CollaborationCursor = Extension.create({ /** * Update details of the current user */ - user: (attributes: { - name: string, - color: string, - }): Command => () => { + user: (attributes: { [key: string]: any }): Command => () => { this.options.provider.awareness.setLocalStateField('user', attributes) + this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states)) return true }, @@ -47,11 +57,14 @@ const CollaborationCursor = Extension.create({ addProseMirrorPlugins() { return [ yCursorPlugin((() => { - this.options.provider.awareness.setLocalStateField('user', { - name: this.options.name, - color: this.options.color, + this.options.provider.awareness.setLocalStateField('user', this.options.user) + + this.options.provider.awareness.on('change', () => { + this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states)) }) + this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states)) + return this.options.provider.awareness })(), // @ts-ignore diff --git a/packages/extension-collaboration/src/index.ts b/packages/extension-collaboration/src/index.ts index d0e686c0..0bf64d4c 100644 --- a/packages/extension-collaboration/src/index.ts +++ b/packages/extension-collaboration/src/index.ts @@ -7,17 +7,19 @@ import { } from 'y-prosemirror' export interface CollaborationOptions { - type: any, + provider: any, } const Collaboration = Extension.create({ defaultOptions: { - type: null, + provider: null, }, addProseMirrorPlugins() { return [ - ySyncPlugin(this.options.type), + ySyncPlugin( + this.options.provider.doc.getXmlFragment('prosemirror'), + ), yUndoPlugin(), ] },