Merge branch 'main' of github.com:ueberdosis/tiptap

This commit is contained in:
Hans Pagel 2021-10-29 17:49:04 +02:00
commit 51aa314034
6 changed files with 55 additions and 39 deletions

View File

@ -65,7 +65,6 @@ const getInitialUser = () => {
export default () => {
const [status, setStatus] = useState('connecting')
const [users, setUsers] = useState([])
const [currentUser, setCurrentUser] = useState(getInitialUser)
const editor = useEditor({
@ -84,9 +83,6 @@ export default () => {
}),
CollaborationCursor.configure({
provider: websocketProvider,
onUpdate: updatedUsers => {
setUsers(updatedUsers)
},
}),
],
})
@ -96,7 +92,7 @@ export default () => {
const indexeddbProvider = new IndexeddbPersistence(room, ydoc)
indexeddbProvider.on('synced', () => {
console.log('Loaded content from database …')
console.log('Loaded content from database …')
})
// Update status changes
@ -109,7 +105,7 @@ export default () => {
useEffect(() => {
if (editor && currentUser) {
localStorage.setItem('currentUser', JSON.stringify(currentUser))
editor.chain().focus().user(currentUser).run()
editor.chain().focus().updateUser(currentUser).run()
}
}, [editor, currentUser])
@ -128,7 +124,7 @@ export default () => {
<div className="editor__footer">
<div className={`editor__status editor__status--${status}`}>
{status === 'connected'
? `${users.length} user${users.length === 1 ? '' : 's'} online in ${room}`
? `${editor.storage.collaborationCursor.users.length} user${editor.storage.collaborationCursor.users.length === 1 ? '' : 's'} online in ${room}`
: 'offline'}
</div>
<div className="editor__name">

View File

@ -5,7 +5,7 @@
<div class="editor__footer">
<div :class="`editor__status editor__status--${status}`">
<template v-if="status === 'connected'">
{{ users.length }} user{{ users.length === 1 ? '' : 's' }} online in {{ room }}
{{ editor.storage.collaborationCursor.users.length }} user{{ editor.storage.collaborationCursor.users.length === 1 ? '' : 's' }} online in {{ room }}
</template>
<template v-else>
offline
@ -61,7 +61,6 @@ export default {
provider: null,
indexdb: null,
editor: null,
users: [],
status: 'connecting',
room: getRandomRoom(),
}
@ -74,8 +73,6 @@ export default {
this.status = event.status
})
window.ydoc = ydoc
this.indexdb = new IndexeddbPersistence(this.room, ydoc)
this.editor = new Editor({
@ -92,9 +89,6 @@ export default {
CollaborationCursor.configure({
provider: this.provider,
user: this.currentUser,
onUpdate: users => {
this.users = users
},
}),
CharacterCount.configure({
limit: 10000,
@ -120,7 +114,7 @@ export default {
updateCurrentUser(attributes) {
this.currentUser = { ...this.currentUser, ...attributes }
this.editor.chain().focus().user(this.currentUser).run()
this.editor.chain().focus().updateUser(this.currentUser).run()
localStorage.setItem('currentUser', JSON.stringify(this.currentUser))
},

View File

@ -43,11 +43,15 @@ A render function for the cursor, look at [the extension source code](https://gi
## Commands
### user()
An object with the attributes of the current user. It expects a `name` and a `color`, but you can add additional fields, too.
### updateUser()
Pass an object with updated attributes of the current user. It expects a `name` and a `color`, but you can add additional fields, too.
```js
editor.commands.user({ name: 'Philipp Kühn', color: '#000000' })
editor.commands.updateUser({
name: 'Philipp Kühn',
color: '#000000',
avatar: 'https://unavatar.io/github/philippkuehn',
})
```
## Source code

View File

@ -7,7 +7,7 @@ tableOfContents: true
## Introduction
The whole Tiptap is code base is written in TypeScript. If you havent heard of it or never used it, no worries. You dont have to.
TypeScript extends JavaScript by adding types (hence the name). It adds new syntax, which doesnt exist in Vanilla JavaScript. Its actually removed before running in the browser, but this step the compilation is important to find bugs early. It checks if you passe the right types of data to functions. For a big and complex project, thats very valuable. It means well get notified of lot of bugs, before shipping code to you.
TypeScript extends JavaScript by adding types (hence the name). It adds new syntax, which doesnt exist in Vanilla JavaScript. Its actually removed before running in the browser, but this step the compilation is important to find bugs early. It checks if you pass the right types of data to functions. For a big and complex project, thats very valuable. It means well get notified of lot of bugs, before shipping code to you.
**Anyway, if you dont use TypeScript in your project, thats fine.** You will still be able to use Tiptap and nevertheless get a nice autocomplete for the Tiptap API (if your editor supports it, but most do).

View File

@ -1,13 +1,13 @@
# Jobs
Some great companies are looking for developers right now. If youre looking for a job to work with Tiptap and/or Hocuspocus, consider applying:
You enjoy to work with Tiptap? You are not alone. Some amazing companies are looking for developers with some Tiptap and/or [Hocuspocus](https://hocuspocus.dev) experience.
**[Software Engineer](https://gamma.app/docs/Software-Engineer-6s0e0grm9zk9w5s) @ Gamma**<br>
- **[Software Engineer](https://gamma.app/docs/Software-Engineer-6s0e0grm9zk9w5s) @ Gamma**<br>
React · Tiptap · San Francisco, CA
**[Frontend Engineer](https://birdeatsbug.recruitee.com/o/frontend-engineer-vuejs-graphql-browser-extension) @ Bird Eats Bug**<br>
- **[Javascript Engineer, Software Engineer, …](https://birdeatsbug.recruitee.com/) @ Bird Eats Bug**<br>
Vue.js · Tiptap · Remote · Berlin, Germany
**[Frontend Developer](https://bitcrowd.net/jobs) @ bitcrowd**<br>
- **[Frontend Developer](https://bitcrowd.net/jobs) @ bitcrowd**<br>
Tiptap · Remote · Berlin, Germany
Is your company hiring, too? We have more than 200,000 page views/month from people who love to work with Tiptap. Maybe we can find someone for you. Reach out to [humans@tiptap.dev](mailto:humans@tiptap.dev) with a link to your job description!
Is your company hiring, too? We have [200,000 page views/month](https://plausible.io/tiptap.dev?period=30d) from people who love to work with Tiptap. Maybe we can help you find the right person. Reach out to [humans@tiptap.dev](mailto:humans@tiptap.dev) with a link to your job description!

View File

@ -1,10 +1,17 @@
import { Extension } from '@tiptap/core'
import { yCursorPlugin } from 'y-prosemirror'
type CollaborationCursorStorage = {
users: { clientId: number, [key: string]: any }[],
}
export interface CollaborationCursorOptions {
provider: any,
user: Record<string, any>,
render (user: Record<string, any>): HTMLElement,
/**
* @deprecated The "onUpdate" option is deprecated. Please use `editor.storage.collaborationCursor.users` instead. Read more: https://tiptap.dev/api/extensions/collaboration-cursor
*/
onUpdate: (users: { clientId: number, [key: string]: any }[]) => null,
}
@ -14,6 +21,12 @@ declare module '@tiptap/core' {
/**
* Update details of the current user
*/
updateUser: (attributes: Record<string, any>) => ReturnType,
/**
* Update details of the current user
*
* @deprecated The "user" command is deprecated. Please use "updateUser" instead. Read more: https://tiptap.dev/api/extensions/collaboration-cursor
*/
user: (attributes: Record<string, any>) => ReturnType,
}
}
@ -28,7 +41,9 @@ const awarenessStatesToArray = (states: Map<number, Record<string, any>>) => {
})
}
export const CollaborationCursor = Extension.create<CollaborationCursorOptions>({
const defaultOnUpdate = () => null
export const CollaborationCursor = Extension.create<CollaborationCursorOptions, CollaborationCursorStorage>({
name: 'collaborationCursor',
addOptions() {
@ -51,19 +66,36 @@ export const CollaborationCursor = Extension.create<CollaborationCursorOptions>(
return cursor
},
onUpdate: () => null,
onUpdate: defaultOnUpdate,
}
},
onCreate() {
if (this.options.onUpdate !== defaultOnUpdate) {
console.warn('[tiptap warn]: DEPRECATED: The "onUpdate" option is deprecated. Please use `editor.storage.collaborationCursor.users` instead. Read more: https://tiptap.dev/api/extensions/collaboration-cursor')
}
},
addStorage() {
return {
users: [],
}
},
addCommands() {
return {
user: attributes => () => {
updateUser: attributes => () => {
this.options.user = attributes
this.options.provider.awareness.setLocalStateField('user', this.options.user)
return true
},
user: attributes => ({ editor }) => {
console.warn('[tiptap warn]: DEPRECATED: The "user" command is deprecated. Please use "updateUser" instead. Read more: https://tiptap.dev/api/extensions/collaboration-cursor')
return editor.commands.updateUser(attributes)
},
}
},
@ -72,22 +104,12 @@ export const CollaborationCursor = Extension.create<CollaborationCursorOptions>(
yCursorPlugin((() => {
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.storage.users = awarenessStatesToArray(this.options.provider.awareness.states)
this.options.provider.awareness.on('update', () => {
this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states))
this.storage.users = awarenessStatesToArray(this.options.provider.awareness.states)
})
this.options.provider.on('status', (event: { status: string }) => {
if (event.status === 'connected') {
this.options.provider.awareness.setLocalStateField('user', this.options.user)
}
})
this.options.onUpdate(awarenessStatesToArray(this.options.provider.awareness.states))
return this.options.provider.awareness
})(),
// @ts-ignore