collabmode-onoff
This commit is contained in:
parent
0615476dd9
commit
6bd219a2e4
|
@ -32,7 +32,6 @@ export type EditorComponentProps = {
|
|||
shoutId: number
|
||||
initialContent?: string
|
||||
onChange: (text: string) => void
|
||||
disableCollaboration?: boolean
|
||||
}
|
||||
|
||||
const yDocs: Record<string, Doc> = {}
|
||||
|
@ -45,7 +44,7 @@ export const EditorComponent = (props: EditorComponentProps) => {
|
|||
const [isCommonMarkup, setIsCommonMarkup] = createSignal(false)
|
||||
const [shouldShowTextBubbleMenu, setShouldShowTextBubbleMenu] = createSignal(false)
|
||||
const { showSnackbar } = useSnackbar()
|
||||
const { countWords, setEditing } = useEditorContext()
|
||||
const { countWords, setEditing, isCollabMode } = useEditorContext()
|
||||
const [editorOptions, setEditorOptions] = createSignal<Partial<EditorOptions>>({})
|
||||
const [editorElRef, setEditorElRef] = createSignal<HTMLElement | undefined>()
|
||||
const [textBubbleMenuRef, setTextBubbleMenuRef] = createSignal<HTMLDivElement | undefined>()
|
||||
|
@ -154,6 +153,7 @@ export const EditorComponent = (props: EditorComponentProps) => {
|
|||
}
|
||||
console.log(options)
|
||||
setEditorOptions(() => options)
|
||||
return options
|
||||
}
|
||||
|
||||
// stage 1: create editor options when got author profile
|
||||
|
@ -166,19 +166,6 @@ export const EditorComponent = (props: EditorComponentProps) => {
|
|||
})
|
||||
)
|
||||
|
||||
// Перенос всех эффектов, зависящих от editor, внутрь onMount
|
||||
onMount(() => {
|
||||
console.log('Editor component mounted')
|
||||
editorElRef()?.addEventListener('focus', handleFocus)
|
||||
requireAuthentication(() => {
|
||||
setTimeout(() => {
|
||||
setupEditor()
|
||||
createEditorInstance(editorOptions())
|
||||
initializeMenus()
|
||||
}, 1200)
|
||||
}, 'edit')
|
||||
})
|
||||
|
||||
const isFigcaptionActive = createEditorTransaction(editor as Accessor<Editor | undefined>, (e) =>
|
||||
e?.isActive('figcaption')
|
||||
)
|
||||
|
@ -276,38 +263,39 @@ export const EditorComponent = (props: EditorComponentProps) => {
|
|||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const docName = `shout-${props.shoutId}`
|
||||
const token = session()?.access_token || ''
|
||||
const profile = author()
|
||||
setEditorOptions((prev: Partial<EditorOptions>) => {
|
||||
const extensions = [...(prev.extensions || [])]
|
||||
|
||||
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(`HocuspocusProvider установлен для ${docName}`)
|
||||
}
|
||||
|
||||
setEditorOptions((prev: Partial<EditorOptions>) => {
|
||||
const extensions = [...(prev.extensions || [])]
|
||||
if (props.disableCollaboration) {
|
||||
// Remove collaboration extensions if they exist
|
||||
try {
|
||||
if (!isCollabMode()) {
|
||||
// Remove collaboration extensions and return
|
||||
const filteredExtensions = extensions.filter(
|
||||
(ext) => ext.name !== 'collaboration' && ext.name !== 'collaborationCursor'
|
||||
)
|
||||
return { ...prev, extensions: filteredExtensions }
|
||||
}
|
||||
|
||||
const docName = `shout-${props.shoutId}`
|
||||
const token = session()?.access_token || ''
|
||||
const profile = author()
|
||||
|
||||
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(`HocuspocusProvider установлен для ${docName}`)
|
||||
}
|
||||
extensions.push(
|
||||
Collaboration.configure({ document: yDocs[docName] }),
|
||||
CollaborationCursor.configure({
|
||||
|
@ -315,13 +303,14 @@ export const EditorComponent = (props: EditorComponentProps) => {
|
|||
user: { name: profile.name, color: uniqolor(profile.slug).color }
|
||||
})
|
||||
)
|
||||
console.log('collab extensions added:', extensions)
|
||||
return { ...prev, extensions }
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error initializing collaboration:', error)
|
||||
showSnackbar({ body: t('Failed to initialize collaboration') })
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error initializing collaboration:', error)
|
||||
showSnackbar({ body: t('Failed to initialize collaboration') })
|
||||
}
|
||||
console.log('collab extensions added:', extensions)
|
||||
return { ...prev, extensions }
|
||||
})
|
||||
}
|
||||
|
||||
const handleFocus = (event: FocusEvent) => {
|
||||
|
@ -332,13 +321,23 @@ export const EditorComponent = (props: EditorComponentProps) => {
|
|||
}
|
||||
}
|
||||
|
||||
// Инициализируем коллаборацию если необходимо
|
||||
onMount(() => {
|
||||
console.log('Editor component mounted')
|
||||
editorElRef()?.addEventListener('focus', handleFocus)
|
||||
requireAuthentication(() => {
|
||||
setTimeout(() => {
|
||||
const opts = setupEditor()
|
||||
createEditorInstance(opts)
|
||||
initializeMenus()
|
||||
}, 120)
|
||||
}, 'edit')
|
||||
})
|
||||
|
||||
// collab mode on/off
|
||||
createEffect(
|
||||
on(
|
||||
() => props.disableCollaboration,
|
||||
() => {
|
||||
initializeCollaboration()
|
||||
},
|
||||
isCollabMode,
|
||||
(x) => !x && initializeCollaboration(),
|
||||
{ defer: true }
|
||||
)
|
||||
)
|
||||
|
|
|
@ -11,6 +11,7 @@ import { useLocalize } from '~/context/localize'
|
|||
import { useUI } from '~/context/ui'
|
||||
import { useEscKeyDownHandler } from '~/lib/useEscKeyDownHandler'
|
||||
import { useOutsideClickHandler } from '~/lib/useOutsideClickHandler'
|
||||
|
||||
import styles from './Panel.module.scss'
|
||||
|
||||
const typograf = new Typograf({ locale: ['ru', 'en-US'] })
|
||||
|
@ -23,6 +24,7 @@ export const Panel = (props: Props) => {
|
|||
const { t } = useLocalize()
|
||||
const { showModal } = useUI()
|
||||
const {
|
||||
setIsCollabMode,
|
||||
isEditorPanelVisible,
|
||||
wordCounter,
|
||||
form,
|
||||
|
@ -32,13 +34,12 @@ export const Panel = (props: Props) => {
|
|||
publishShout,
|
||||
editing: editor
|
||||
} = useEditorContext()
|
||||
|
||||
let containerRef: HTMLElement | undefined
|
||||
const [containerRef, setAsideContainerRef] = createSignal<HTMLElement | undefined>()
|
||||
const [isShortcutsVisible, setIsShortcutsVisible] = createSignal(false)
|
||||
const [isTypographyFixed, setIsTypographyFixed] = createSignal(false)
|
||||
|
||||
useOutsideClickHandler({
|
||||
containerRef,
|
||||
containerRef: containerRef(),
|
||||
predicate: () => isEditorPanelVisible(),
|
||||
handler: () => toggleEditorPanel()
|
||||
})
|
||||
|
@ -67,7 +68,7 @@ export const Panel = (props: Props) => {
|
|||
|
||||
return (
|
||||
<aside
|
||||
ref={(el) => (containerRef = el)}
|
||||
ref={setAsideContainerRef}
|
||||
class={clsx('col-md-6', styles.Panel, { [styles.hidden]: !isEditorPanelVisible() })}
|
||||
>
|
||||
<Button
|
||||
|
@ -96,6 +97,13 @@ export const Panel = (props: Props) => {
|
|||
{t('Invite co-authors')}
|
||||
</span>
|
||||
</p>
|
||||
{/* TODO: <Show when={coauthorsCount() > 0}> */}
|
||||
<p>
|
||||
<span class={styles.link} onClick={() => setIsCollabMode((x) => !x)}>
|
||||
{t('Collaborative mode')}
|
||||
</span>
|
||||
</p>
|
||||
{/*</Show> */}
|
||||
<p>
|
||||
<A
|
||||
class={styles.link}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { ToolbarControl } from './ToolbarControl'
|
|||
|
||||
import { Popover } from '~/components/_shared/Popover/Popover'
|
||||
import styles from './FullBubbleMenu.module.scss'
|
||||
import { useEditorContext } from '~/context/editor'
|
||||
|
||||
type FullBubbleMenuProps = {
|
||||
editor: () => Editor | undefined
|
||||
|
@ -20,6 +21,7 @@ type FullBubbleMenuProps = {
|
|||
|
||||
export const FullBubbleMenu = (props: FullBubbleMenuProps) => {
|
||||
const { t } = useLocalize()
|
||||
const { isCollabMode, setIsCollabMode } = useEditorContext()
|
||||
|
||||
// SIGNALS
|
||||
const [textSizeBubbleOpen, setTextSizeBubbleOpen] = createSignal(false)
|
||||
|
@ -259,6 +261,18 @@ export const FullBubbleMenu = (props: FullBubbleMenuProps) => {
|
|||
<div style={{ width: '5px' }} />
|
||||
|
||||
<ListDropdown />
|
||||
|
||||
<div class={styles.dropDownHolder}>
|
||||
<Popover content={t('Collaborative mode')}>
|
||||
{(triggerRef: (el: HTMLButtonElement) => void) => (
|
||||
<button ref={triggerRef} type="button" class={styles.actionButton}
|
||||
onClick={() => setIsCollabMode(x => !x)}
|
||||
>
|
||||
<Icon name={`comment${isCollabMode() ? '-hover' : ''}`} />
|
||||
</button>
|
||||
)}
|
||||
</Popover>
|
||||
</div>
|
||||
</Show>
|
||||
</>
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user