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) */}
)
},
}