import { createShapeId, DebugFlag, debugFlags, Editor, featureFlags, hardResetEditor, TLShapePartial, track, uniqueId, useEditor, useValue, } from '@bigbluebutton/editor' import * as React from 'react' import { useDialogs } from '../hooks/useDialogsProvider' import { useToasts } from '../hooks/useToastsProvider' import { untranslated, useTranslation } from '../hooks/useTranslation/useTranslation' import { Button } from './primitives/Button' import * as Dialog from './primitives/Dialog' import * as DropdownMenu from './primitives/DropdownMenu' let t = 0 function createNShapes(editor: Editor, n: number) { const shapesToCreate: TLShapePartial[] = Array(n) const cols = Math.floor(Math.sqrt(n)) for (let i = 0; i < n; i++) { t++ shapesToCreate[i] = { id: createShapeId('box' + t), type: 'geo', x: (i % cols) * 132, y: Math.floor(i / cols) * 132, } } editor.batch(() => { editor.createShapes(shapesToCreate).setSelectedShapes(shapesToCreate.map((s) => s.id)) }) } /** @internal */ export const DebugPanel = React.memo(function DebugPanel({ renderDebugMenuItems, }: { renderDebugMenuItems: (() => React.ReactNode) | null }) { const msg = useTranslation() return (
) }) const CurrentState = track(function CurrentState() { const editor = useEditor() return
{editor.getPath()}
}) const ShapeCount = function ShapeCount() { const editor = useEditor() const count = useValue('rendering shapes count', () => editor.getRenderingShapes().length, [ editor, ]) return
{count} Shapes
} const DebugMenuContent = track(function DebugMenuContent({ renderDebugMenuItems, }: { renderDebugMenuItems: (() => React.ReactNode) | null }) { const editor = useEditor() const { addToast } = useToasts() const { addDialog } = useDialogs() const [error, setError] = React.useState(false) return ( <> { addToast({ id: uniqueId(), title: 'Something happened', description: 'Hey, attend to this thing over here. It might be important!', keepOpen: true, // icon?: string // title?: string // description?: string // actions?: TLUiToastAction[] }) addToast({ id: uniqueId(), title: 'Something happened', description: 'Hey, attend to this thing over here. It might be important!', keepOpen: true, actions: [ { label: 'Primary', type: 'primary', onClick: () => { void null }, }, { label: 'Normal', type: 'normal', onClick: () => { void null }, }, { label: 'Danger', type: 'danger', onClick: () => { void null }, }, ], // icon?: string // title?: string // description?: string // actions?: TLUiToastAction[] }) addToast({ id: uniqueId(), title: 'Something happened', description: 'Hey, attend to this thing over here. It might be important!', keepOpen: true, icon: 'twitter', actions: [ { label: 'Primary', type: 'primary', onClick: () => { void null }, }, { label: 'Normal', type: 'normal', onClick: () => { void null }, }, { label: 'Danger', type: 'danger', onClick: () => { void null }, }, ], }) }} label={untranslated('Show toast')} /> { addDialog({ component: ({ onClose }) => ( { onClose() }} onContinue={() => { onClose() }} /> ), onClose: () => { void null }, }) }} label={untranslated('Show dialog')} /> createNShapes(editor, 100)} label={untranslated('Create 100 shapes')} /> { function countDescendants({ children }: HTMLElement) { let count = 0 if (!children.length) return 0 for (const el of [...(children as any)]) { count++ count += countDescendants(el) } return count } const selectedShapes = editor.getSelectedShapes() const shapes = selectedShapes.length === 0 ? editor.getRenderingShapes() : selectedShapes const elms = shapes.map( (shape) => (document.getElementById(shape.id) as HTMLElement)!.parentElement! ) let descendants = elms.length for (const elm of elms) { descendants += countDescendants(elm) } window.alert(`Shapes ${shapes.length}, DOM nodes:${descendants}`) }} label={untranslated('Count shapes / nodes')} /> {(() => { if (error) throw Error('oh no!') })()} { setError(true) }} label={untranslated('Throw error')} /> { hardResetEditor() }} label={untranslated('Hard reset')} /> {Object.values(featureFlags).map((flag) => { return })} {renderDebugMenuItems?.()} ) }) function Toggle({ label, value, onChange, }: { label: string value: boolean onChange: (newValue: boolean) => void }) { return ( onChange(!value)} > {label} ) } const DebugFlagToggle = track(function DebugFlagToggle({ flag, onChange, }: { flag: DebugFlag onChange?: (newValue: boolean) => void }) { return ( `${m[0]} ${m[1].toLowerCase()}`) .replace(/^[a-z]/, (m) => m.toUpperCase())} value={flag.get()} onChange={(newValue) => { flag.set(newValue) onChange?.(newValue) }} /> ) }) function ExampleDialog({ title = 'title', body = 'hello hello hello', cancel = 'Cancel', confirm = 'Continue', displayDontShowAgain = false, onCancel, onContinue, }: { title?: string body?: string cancel?: string confirm?: string displayDontShowAgain?: boolean onCancel: () => void onContinue: () => void }) { const [dontShowAgain, setDontShowAgain] = React.useState(false) return ( <> {title} {body} {displayDontShowAgain && ( )} ) }