import React from "react" import { CustomMainMenu } from "./CustomMainMenu" import { CustomToolbar } from "./CustomToolbar" import { CustomContextMenu } from "./CustomContextMenu" import { FocusLockIndicator } from "./FocusLockIndicator" import { MycelialIntelligenceBar } from "./MycelialIntelligenceBar" import { CommandPalette } from "./CommandPalette" import { DefaultKeyboardShortcutsDialog, DefaultKeyboardShortcutsDialogContent, TLComponents, TldrawUiMenuItem, useTools, useActions, useEditor, useValue, } from "tldraw" import { SlidesPanel } from "@/slides/SlidesPanel" import { DeletedShapesOverlay } from "@/components/DeletedShapesOverlay" // Custom People Menu component for showing connected users function CustomPeopleMenu() { const editor = useEditor() const [showDropdown, setShowDropdown] = React.useState(false) // Get current user info const myUserColor = useValue('myColor', () => editor.user.getColor(), [editor]) const myUserName = useValue('myName', () => editor.user.getName() || 'You', [editor]) // Get all collaborators (other users in the session) const collaborators = useValue('collaborators', () => editor.getCollaborators(), [editor]) const totalUsers = collaborators.length + 1 return (
{/* Clickable avatar stack */} {/* Dropdown with user names */} {showDropdown && (
Participants ({totalUsers})
{/* Current user */}
{myUserName.charAt(0).toUpperCase()}
{myUserName} (you)
{/* Other users */} {collaborators.map((presence) => (
{(presence.userName || 'A').charAt(0).toUpperCase()}
{presence.userName || 'Anonymous'}
))}
)} {/* Click outside to close */} {showDropdown && (
setShowDropdown(false)} /> )}
) } // Custom SharePanel that shows the people menu function CustomSharePanel() { return (
) } // Combined InFrontOfCanvas component for floating UI elements function CustomInFrontOfCanvas() { return ( <> ) } export const components: TLComponents = { Toolbar: CustomToolbar, MainMenu: CustomMainMenu, ContextMenu: CustomContextMenu, HelperButtons: SlidesPanel, SharePanel: CustomSharePanel, InFrontOfTheCanvas: CustomInFrontOfCanvas, KeyboardShortcutsDialog: (props: any) => { const tools = useTools() const actions = useActions() // Get all custom tools with keyboard shortcuts const customTools = [ tools["VideoChat"], tools["ChatBox"], tools["Embed"], tools["Slide"], tools["Markdown"], tools["MycrozineTemplate"], tools["Prompt"], tools["ObsidianNote"], tools["Transcription"], tools["Holon"], tools["FathomMeetings"], tools["ImageGen"], tools["VideoGen"], tools["Multmux"], // MycelialIntelligence moved to permanent floating bar ].filter(tool => tool && tool.kbd) // Get all custom actions with keyboard shortcuts const customActions = [ actions["zoom-in"], actions["zoom-out"], actions["zoom-to-selection"], actions["copy-link-to-current-view"], actions["copy-focus-link"], actions["unlock-camera-focus"], actions["revert-camera"], actions["lock-element"], actions["save-to-pdf"], actions["search-shapes"], actions["llm"], actions["open-obsidian-browser"], ].filter(action => action && action.kbd) return ( {/* Custom Tools */} {customTools.map(tool => ( ))} {/* Custom Actions */} {customActions.map(action => ( ))} {/* Default content (includes standard TLDraw shortcuts) */} ) }, }