collab-toggle
This commit is contained in:
parent
83c660235a
commit
5c7f810c5f
|
@ -1,9 +1,14 @@
|
|||
import { HocuspocusProvider } from '@hocuspocus/provider'
|
||||
import { useMatch, useNavigate } from '@solidjs/router'
|
||||
import { Editor } from '@tiptap/core'
|
||||
import Collaboration from '@tiptap/extension-collaboration'
|
||||
import CollaborationCursor from '@tiptap/extension-collaboration-cursor'
|
||||
import type { JSX } from 'solid-js'
|
||||
import { Accessor, createContext, createSignal, onCleanup, useContext } from 'solid-js'
|
||||
import { Accessor, createContext, createEffect, createSignal, on, onCleanup, useContext } from 'solid-js'
|
||||
import { SetStoreFunction, createStore } from 'solid-js/store'
|
||||
import { debounce } from 'throttle-debounce'
|
||||
import uniqolor from 'uniqolor'
|
||||
import { Doc } from 'yjs'
|
||||
import { useSnackbar } from '~/context/ui'
|
||||
import deleteShoutQuery from '~/graphql/mutation/core/article-delete'
|
||||
import updateShoutQuery from '~/graphql/mutation/core/article-update'
|
||||
|
@ -14,6 +19,8 @@ import { useLocalize } from './localize'
|
|||
import { useSession } from './session'
|
||||
|
||||
export const AUTO_SAVE_DELAY = 3000
|
||||
const yDocs: Record<string, Doc> = {}
|
||||
const providers: Record<string, HocuspocusProvider> = {}
|
||||
|
||||
export type WordCounter = {
|
||||
characters: number
|
||||
|
@ -98,7 +105,7 @@ export const EditorProvider = (props: { children: JSX.Element }) => {
|
|||
const navigate = useNavigate()
|
||||
const matchEdit = useMatch(() => '/edit')
|
||||
const matchEditSettings = useMatch(() => '/editSettings')
|
||||
const { client } = useSession()
|
||||
const { client, session } = useSession()
|
||||
const { addFeed } = useFeed()
|
||||
const snackbar = useSnackbar()
|
||||
const [isEditorPanelVisible, setIsEditorPanelVisible] = createSignal<boolean>(false)
|
||||
|
@ -251,7 +258,7 @@ export const EditorProvider = (props: { children: JSX.Element }) => {
|
|||
}
|
||||
} catch (error) {
|
||||
console.error('[publishShoutById]', error)
|
||||
snackbar?.showSnackbar({ type: 'error', body: localize?.t('Error') })
|
||||
snackbar?.showSnackbar({ type: 'error', body: localize?.t('Error') || '' })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,6 +285,63 @@ export const EditorProvider = (props: { children: JSX.Element }) => {
|
|||
})
|
||||
onCleanup(debouncedAutoSave.cancel)
|
||||
|
||||
createEffect(
|
||||
on(
|
||||
isCollabMode,
|
||||
(x?: boolean) => () => {
|
||||
const editorInstance = editing()
|
||||
if (!editorInstance) return
|
||||
try {
|
||||
const docName = `shout-${form.shoutId}`
|
||||
const token = session()?.access_token || ''
|
||||
const profile = session()?.user?.app_data?.profile
|
||||
|
||||
if (!(token && profile)) {
|
||||
throw new Error('Missing authentication data')
|
||||
}
|
||||
|
||||
if (!yDocs[docName]) {
|
||||
yDocs[docName] = new Doc()
|
||||
}
|
||||
|
||||
if (!providers[docName]) {
|
||||
providers[docName] = new HocuspocusProvider({
|
||||
url: 'wss://hocuspocus.discours.io',
|
||||
name: docName,
|
||||
document: yDocs[docName],
|
||||
token
|
||||
})
|
||||
console.log(`[collab mode] HocuspocusProvider connected for ${docName}`)
|
||||
}
|
||||
if (x) {
|
||||
const newExtensions = [
|
||||
Collaboration.configure({ document: yDocs[docName] }),
|
||||
CollaborationCursor.configure({
|
||||
provider: providers[docName],
|
||||
user: { name: profile.name, color: uniqolor(profile.slug).color }
|
||||
})
|
||||
]
|
||||
const extensions = editing()?.options.extensions.concat(newExtensions)
|
||||
editorInstance.setOptions({ ...editorInstance.options, extensions })
|
||||
providers[docName].connect()
|
||||
} else if (editorInstance) {
|
||||
providers[docName].disconnect()
|
||||
const updatedExtensions = editorInstance.options.extensions.filter(
|
||||
(ext) => ext.name !== 'collaboration' && ext.name !== 'collaborationCursor'
|
||||
)
|
||||
editorInstance.setOptions({
|
||||
...editorInstance.options,
|
||||
extensions: updatedExtensions
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[collab mode] error', error)
|
||||
}
|
||||
},
|
||||
{ defer: true }
|
||||
)
|
||||
)
|
||||
|
||||
const handleInputChange = (key: keyof ShoutForm, value: string) => {
|
||||
console.log(`[handleInputChange] ${key}: ${value}`)
|
||||
setForm(key, value)
|
||||
|
|
Loading…
Reference in New Issue
Block a user