MVP - Phase One Complete

This commit is contained in:
Aodhan Collins
2025-10-11 22:48:35 +01:00
parent eccd456c59
commit a1c8ae5f5b
7 changed files with 1221 additions and 46 deletions

View File

@@ -5,11 +5,13 @@ const WS_URL = 'ws://localhost:8000';
function StorytellerView({ sessionId }) {
const [characters, setCharacters] = useState({});
const [publicMessages, setPublicMessages] = useState([]);
const [selectedCharacter, setSelectedCharacter] = useState(null);
const [responseText, setResponseText] = useState('');
const [sceneText, setSceneText] = useState('');
const [currentScene, setCurrentScene] = useState('');
const [isConnected, setIsConnected] = useState(false);
const [isGeneratingSuggestion, setIsGeneratingSuggestion] = useState(false);
const wsRef = useRef(null);
useEffect(() => {
@@ -27,6 +29,7 @@ function StorytellerView({ sessionId }) {
if (data.type === 'session_state') {
setCharacters(data.characters || {});
setCurrentScene(data.current_scene || '');
setPublicMessages(data.public_messages || []);
} else if (data.type === 'character_message') {
// Update character with new message
setCharacters(prev => ({
@@ -110,6 +113,30 @@ function StorytellerView({ sessionId }) {
setSceneText('');
};
const getSuggestion = async () => {
if (!selectedCharacter || isGeneratingSuggestion) return;
setIsGeneratingSuggestion(true);
try {
const response = await fetch(
`${API_URL}/sessions/${sessionId}/generate_suggestion?character_id=${selectedCharacter}`,
{ method: 'POST' }
);
if (!response.ok) {
throw new Error('Failed to generate suggestion');
}
const data = await response.json();
setResponseText(data.suggestion);
} catch (error) {
console.error('Error generating suggestion:', error);
alert('Failed to generate AI suggestion. Please try again.');
} finally {
setIsGeneratingSuggestion(false);
}
};
const selectedChar = selectedCharacter ? characters[selectedCharacter] : null;
const pendingCount = Object.values(characters).filter(c => c.pending_response).length;
@@ -150,6 +177,24 @@ function StorytellerView({ sessionId }) {
Narrate Scene
</button>
</div>
{publicMessages.length > 0 && (
<div className="public-feed">
<h4>📢 Public Actions Feed ({publicMessages.length})</h4>
<div className="public-messages-list">
{publicMessages.slice(-5).map((msg, idx) => (
<div key={idx} className="public-message-item">
<span className="public-msg-content">
{msg.visibility === 'mixed' && msg.public_content ? msg.public_content : msg.content}
</span>
<span className="public-msg-time">
{new Date(msg.timestamp).toLocaleTimeString()}
</span>
</div>
))}
</div>
</div>
)}
</div>
<div className="storyteller-content">
@@ -223,9 +268,18 @@ function StorytellerView({ sessionId }) {
onChange={(e) => setResponseText(e.target.value)}
rows="4"
/>
<button className="btn-primary" onClick={sendResponse} disabled={!isConnected}>
Send Private Response
</button>
<div className="response-buttons">
<button
className="btn-secondary"
onClick={getSuggestion}
disabled={!isConnected || isGeneratingSuggestion}
>
{isGeneratingSuggestion ? '⏳ Generating...' : '✨ AI Suggest'}
</button>
<button className="btn-primary" onClick={sendResponse} disabled={!isConnected}>
Send Private Response
</button>
</div>
</div>
</>
) : (