import { Editor, uniqueId, useEditor } from '@bigbluebutton/editor' import { createContext, useCallback, useContext, useState } from 'react' import { useUiEvents } from './useEventsProvider' /** @public */ export interface TLUiDialogProps { onClose: () => void } /** @public */ export interface TLUiDialog { id: string onClose?: () => void component: (props: TLUiDialogProps) => any } /** @public */ export type TLUiDialogsContextType = { addDialog: (dialog: Omit & { id?: string }) => string removeDialog: (id: string) => string updateDialog: (id: string, newDialogData: Partial) => string clearDialogs: () => void dialogs: TLUiDialog[] } /** @internal */ export const DialogsContext = createContext({} as TLUiDialogsContextType) /** @internal */ export type DialogsProviderProps = { overrides?: (editor: Editor) => TLUiDialogsContextType children: any } /** @internal */ export function DialogsProvider({ children }: DialogsProviderProps) { const editor = useEditor() const trackEvent = useUiEvents() const [dialogs, setDialogs] = useState([]) const addDialog = useCallback( (dialog: Omit & { id?: string }) => { const id = dialog.id ?? uniqueId() setDialogs((d) => { return [...d.filter((m) => m.id !== dialog.id), { ...dialog, id }] }) trackEvent('open-menu', { source: 'dialog', id }) editor.addOpenMenu(id) return id }, [editor, trackEvent] ) const updateDialog = useCallback( (id: string, newDialogData: Partial) => { setDialogs((d) => d.map((m) => { if (m.id === id) { return { ...m, ...newDialogData, } } return m }) ) trackEvent('open-menu', { source: 'dialog', id }) editor.addOpenMenu(id) return id }, [editor, trackEvent] ) const removeDialog = useCallback( (id: string) => { setDialogs((d) => d.filter((m) => { if (m.id === id) { m.onClose?.() return false } return true }) ) trackEvent('close-menu', { source: 'dialog', id }) editor.deleteOpenMenu(id) return id }, [editor, trackEvent] ) const clearDialogs = useCallback(() => { setDialogs((d) => { d.forEach((m) => { m.onClose?.() trackEvent('close-menu', { source: 'dialog', id: m.id }) editor.deleteOpenMenu(m.id) }) return [] }) }, [editor, trackEvent]) return ( {children} ) } /** @public */ export function useDialogs() { const ctx = useContext(DialogsContext) if (!ctx) { throw new Error('useDialogs must be used within a DialogsProvider') } return ctx }