import React, { useState, useRef } from 'react'; import { Statement } from '@/lib/vn-parser'; import { Sprite } from '@/lib/sprite-bank'; interface VNOutlineProps { statements: Statement[]; currentSay: Statement | null; onSelectLine: (line: number) => void; isParsing: boolean; spriteBank: Record; onUpdateSpriteBank: (newBank: Record) => void; onAddSpriteToScript: (char: string, id: string, url: string) => void; } export const VNOutline: React.FC = ({ statements, currentSay, onSelectLine, isParsing, spriteBank, onUpdateSpriteBank, onAddSpriteToScript }) => { const [activeTab, setActiveTab] = useState<'outline' | 'sprites'>('outline'); const [newCharName, setNewCharName] = useState(''); const [uploadingFor, setUploadingFor] = useState(null); const fileInputRef = useRef(null); const addCharacter = () => { if (!newCharName || spriteBank[newCharName]) return; onUpdateSpriteBank({ ...spriteBank, [newCharName]: [] }); setNewCharName(''); }; const removeCharacter = (charName: string) => { const { [charName]: _, ...rest } = spriteBank; onUpdateSpriteBank(rest); }; const addSpriteUrl = (charName: string) => { const id = prompt('Sprite ID (e.g. happy):'); if (!id) return; const url = prompt('Sprite Image URL:'); if (!url) return; onAddSpriteToScript(charName, id, url); }; const handleFileUpload = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file || !uploadingFor) return; const id = prompt('Sprite ID (e.g. happy):'); if (!id) return; const reader = new FileReader(); reader.onload = (e) => { const url = e.target?.result as string; if (url) { onAddSpriteToScript(uploadingFor, id, url); } }; reader.readAsDataURL(file); // Reset file input if (fileInputRef.current) fileInputRef.current.value = ''; setUploadingFor(null); }; const triggerFileUpload = (charName: string) => { setUploadingFor(charName); fileInputRef.current?.click(); }; const removeSprite = (charName: string, spriteId: string) => { const newSprites = spriteBank[charName].filter(s => s.id !== spriteId); onUpdateSpriteBank({ ...spriteBank, [charName]: newSprites }); }; return (
{/* Tabs */}
{activeTab === 'outline' ? (
{statements.map((s, idx) => { if (s.type === 'comment') return null; const isSay = s.type === 'say'; const isActive = isSay && currentSay?.lineNumber === s.lineNumber; return ( ); })}
) : (
{/* Add Character UI */}
setNewCharName(e.target.value)} placeholder="Character Name..." className="flex-1 bg-gray-900 border border-gray-800 rounded px-2 py-1 text-xs outline-none focus:border-cyan-500" />
{Object.entries(spriteBank).map(([charName, sprites]) => (

{charName}

{sprites.map(sprite => (
{sprite.name}
{sprite.id}
))}
))}
)}
); };