cudr_slate-collaborative/packages/example/src/Client.tsx

119 lines
2.5 KiB
TypeScript
Raw Normal View History

import React, { useState, useEffect, useMemo } from 'react'
import { createEditor, Node } from 'slate'
import { withHistory } from 'slate-history'
import { withReact } from 'slate-react'
2019-10-05 08:44:49 +00:00
import randomColor from 'randomcolor'
2019-10-05 08:44:49 +00:00
import styled from '@emotion/styled'
import { withIOCollaboration, useCursor } from '@slate-collaborative/client'
import { Instance, Title, H4, Button } from './Components'
2019-10-05 08:44:49 +00:00
import EditorFrame from './EditorFrame'
2019-10-05 08:44:49 +00:00
const defaultValue: Node[] = [
{
type: 'paragraph',
children: [
{
text: ''
}
]
}
]
2019-10-05 08:44:49 +00:00
interface ClientProps {
2019-10-05 08:44:49 +00:00
name: string
id: string
slug: string
removeUser: (id: any) => void
}
const Client: React.FC<ClientProps> = ({ id, name, slug, removeUser }) => {
const [value, setValue] = useState<Node[]>(defaultValue)
const [isOnline, setOnlineState] = useState<boolean>(false)
2019-10-05 08:44:49 +00:00
const color = useMemo(
() =>
randomColor({
luminosity: 'dark',
format: 'rgba',
alpha: 1
}),
[]
)
2019-10-05 08:44:49 +00:00
const editor = useMemo(() => {
const slateEditor = withReact(withHistory(createEditor()))
2019-10-27 20:50:01 +00:00
const origin =
process.env.NODE_ENV === 'production'
? window.location.origin
: 'http://localhost:9000'
const options = {
docId: '/' + slug,
cursorData: {
name,
color,
alphaColor: color.slice(0, -2) + '0.2)'
},
url: `${origin}/${slug}`,
2019-10-05 08:44:49 +00:00
connectOpts: {
query: {
name,
token: id,
slug
2019-10-05 08:44:49 +00:00
}
},
onConnect: () => setOnlineState(true),
onDisconnect: () => setOnlineState(false)
}
return withIOCollaboration(slateEditor, options)
}, [])
2019-10-05 08:44:49 +00:00
useEffect(() => {
editor.connect()
2019-10-05 08:44:49 +00:00
return editor.destroy
}, [])
2019-10-05 08:44:49 +00:00
const { decorate } = useCursor(editor)
2019-10-05 08:44:49 +00:00
const toggleOnline = () => {
const { connect, disconnect } = editor
2019-10-05 08:44:49 +00:00
isOnline ? disconnect() : connect()
}
return (
<Instance online={isOnline}>
<Title>
<Head>Editor: {name}</Head>
<Button type="button" onClick={toggleOnline}>
Go {isOnline ? 'offline' : 'online'}
</Button>
<Button type="button" onClick={() => removeUser(id)}>
Remove
</Button>
</Title>
<EditorFrame
editor={editor}
value={value}
decorate={decorate}
onChange={(value: Node[]) => setValue(value)}
/>
</Instance>
)
2019-10-05 08:44:49 +00:00
}
export default Client
const Head = styled(H4)`
margin-right: auto;
`