2020-05-10 13:50:12 +00:00
|
|
|
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
|
|
|
|
2019-10-13 16:37:56 +00:00
|
|
|
import randomColor from 'randomcolor'
|
2019-10-05 08:44:49 +00:00
|
|
|
|
|
|
|
import styled from '@emotion/styled'
|
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
import { withIOCollaboration, useCursor } from '@slate-collaborative/client'
|
|
|
|
|
2020-05-11 06:21:49 +00:00
|
|
|
import { Instance, Title, H4, Button } from './Components'
|
2019-10-05 08:44:49 +00:00
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
import EditorFrame from './EditorFrame'
|
2019-10-05 08:44:49 +00:00
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
const defaultValue: Node[] = [
|
|
|
|
{
|
|
|
|
type: 'paragraph',
|
|
|
|
children: [
|
|
|
|
{
|
|
|
|
text: ''
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
2019-10-05 08:44:49 +00:00
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
interface ClientProps {
|
2019-10-05 08:44:49 +00:00
|
|
|
name: string
|
|
|
|
id: string
|
|
|
|
slug: string
|
|
|
|
removeUser: (id: any) => void
|
|
|
|
}
|
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
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
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
const color = useMemo(
|
|
|
|
() =>
|
|
|
|
randomColor({
|
|
|
|
luminosity: 'dark',
|
|
|
|
format: 'rgba',
|
|
|
|
alpha: 1
|
|
|
|
}),
|
|
|
|
[]
|
|
|
|
)
|
2019-10-05 08:44:49 +00:00
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
const editor = useMemo(() => {
|
|
|
|
const slateEditor = withReact(withHistory(createEditor()))
|
2019-10-13 16:37:56 +00:00
|
|
|
|
2019-10-27 20:50:01 +00:00
|
|
|
const origin =
|
|
|
|
process.env.NODE_ENV === 'production'
|
|
|
|
? window.location.origin
|
|
|
|
: 'http://localhost:9000'
|
|
|
|
|
2019-10-13 16:37:56 +00:00
|
|
|
const options = {
|
2020-05-10 13:50:12 +00:00
|
|
|
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: {
|
2020-05-10 13:50:12 +00:00
|
|
|
name,
|
|
|
|
token: id,
|
|
|
|
slug
|
2019-10-05 08:44:49 +00:00
|
|
|
}
|
|
|
|
},
|
2020-05-10 13:50:12 +00:00
|
|
|
onConnect: () => setOnlineState(true),
|
|
|
|
onDisconnect: () => setOnlineState(false)
|
2019-10-13 16:37:56 +00:00
|
|
|
}
|
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
return withIOCollaboration(slateEditor, options)
|
|
|
|
}, [])
|
2019-10-05 08:44:49 +00:00
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
useEffect(() => {
|
|
|
|
editor.connect()
|
2019-10-05 08:44:49 +00:00
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
return editor.destroy
|
|
|
|
}, [])
|
2019-10-05 08:44:49 +00:00
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
const { decorate } = useCursor(editor)
|
2019-10-05 08:44:49 +00:00
|
|
|
|
2020-05-10 13:50:12 +00:00
|
|
|
const toggleOnline = () => {
|
|
|
|
const { connect, disconnect } = editor
|
2019-10-05 08:44:49 +00:00
|
|
|
isOnline ? disconnect() : connect()
|
|
|
|
}
|
2020-05-10 13:50:12 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
`
|