import { useDialogueStore } from '../../store/dialogueStore'; import { makeNodeId } from '../../utils/idGen'; import { DialogueNode, NodeType } from '../../types/dialogue'; import { MAIN_CHARACTER } from '../../constants/characters'; import styles from './GraphToolbar.module.css'; const NODE_DEFAULTS: Record Omit> = { Line: () => ({ type: 'Line', speaker: MAIN_CHARACTER, portrait: 'resources/dialogue/portrait_hero_neutral.png', text: '', next: '', }), Choice: () => ({ type: 'Choice', speaker: MAIN_CHARACTER, portrait: 'resources/dialogue/portrait_hero_neutral.png', text: '', choices: [], }), Condition: () => ({ type: 'Condition', conditions: [], trueNext: '', falseNext: '', }), SetFlag: () => ({ type: 'SetFlag', effects: [], next: '', }), CutsceneStart: () => ({ type: 'CutsceneStart', cutsceneId: '', next: '', }), End: () => ({ type: 'End' }), }; export function GraphToolbar() { const { file, selectedDialogueId, selectedNodeId, addNode, applyAutoLayout, startPlay, setDialogueMobileMode, persistentFlags, resetFlags } = useDialogueStore(); const dialogue = file?.dialogues.find(d => d.id === selectedDialogueId); if (!dialogue) return null; function handleAddNode(type: NodeType) { if (!selectedDialogueId || !dialogue) return; const existingIds = new Set(dialogue.nodes.map(n => n.id)); const id = makeNodeId(type, existingIds); const node = { id, ...NODE_DEFAULTS[type]() } as DialogueNode; addNode(selectedDialogueId, node, selectedNodeId ?? undefined); } return (
Add: {(['Line', 'Choice', 'Condition', 'SetFlag', 'CutsceneStart', 'End'] as NodeType[]).map(type => ( ))}
{dialogue.mobileMode && (
Mobile mode — portraits will be overridden on export
)} {Object.keys(persistentFlags).length > 0 && ( <>
🚩 Flags: {Object.entries(persistentFlags).map(([k, v]) => ( {k}={v} ))}
)}
); }