From d00e03bb614ae95213c2134f99f8a25234d51925 Mon Sep 17 00:00:00 2001 From: Aaron West Date: Thu, 15 Jan 2026 17:20:43 -0600 Subject: [PATCH 1/4] feat: display dynamic character stats in mobile UI - Add getCharacterData helper function for centralized character data access - Update mobile character sheet to use dynamic values from characterState - Add HP percentage calculation for dynamic health bar - Update all stat displays (STR, DEX, CON, INT, WIS, CHA) to use database values - Update Level and HP displays with fallbacks to defaults - Update inventory to dynamically render from database - Maintain fallback values for when character data is unavailable Resolves #128 --- src/App.tsx | 82 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 112b0f1..f5295d7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -130,6 +130,11 @@ function GameMasterHud({ adventure, questSteps, playerChoices, character }: Game // Use character data from database or fallback to defaults const characterName = character?.name || 'Adventurer'; + const characterLevel = character?.level || 1; + const characterHP = { + current: character?.currentHP || 12, + max: character?.maxHP || 12, + }; const stats = { strength: character?.strength || 10, dexterity: character?.dexterity || 12, @@ -264,6 +269,44 @@ function App() { const [playerChoices, setPlayerChoices] = useState([]); const [characterState, setCharacterState] = useState(null); + // Helper to get character display data with fallbacks + const getCharacterData = useCallback(() => { + const stats = { + strength: characterState?.strength || 10, + dexterity: characterState?.dexterity || 12, + constitution: characterState?.constitution || 14, + intelligence: characterState?.intelligence || 16, + wisdom: characterState?.wisdom || 13, + charisma: characterState?.charisma || 11, + }; + + const hp = { + current: characterState?.currentHP || 12, + max: characterState?.maxHP || 12, + percentage: ((characterState?.currentHP || 12) / (characterState?.maxHP || 12)) * 100, + }; + + let inventory: string[] = ['Rusty Sword', 'Leather Armor', '5 Gold']; + if (characterState?.inventory) { + try { + const parsed = typeof characterState.inventory === 'string' + ? JSON.parse(characterState.inventory) + : characterState.inventory; + inventory = Array.isArray(parsed) ? parsed : inventory; + } catch (e) { + console.error('Failed to parse inventory:', e); + } + } + + return { + name: characterState?.name || 'Adventurer', + level: characterState?.level || 1, + stats, + hp, + inventory, + }; + }, [characterState]); + // Personality mode state const [personalityMode, setPersonalityMode] = useState('default'); const effectivePersonality = normalizePersonalityMode(personalityMode); @@ -1790,7 +1833,9 @@ function App() { {/* Expanded Character Sheet Content */} - {mobileCharSheetExpanded && adventureState && ( + {mobileCharSheetExpanded && adventureState && (() => { + const charData = getCharacterData(); + return (
{/* Stats */}
@@ -1798,27 +1843,27 @@ function App() {
STR
-
10
+
{charData.stats.strength}
DEX
-
12
+
{charData.stats.dexterity}
CON
-
14
+
{charData.stats.constitution}
INT
-
16
+
{charData.stats.intelligence}
WIS
-
13
+
{charData.stats.wisdom}
CHA
-
11
+
{charData.stats.charisma}
@@ -1827,15 +1872,15 @@ function App() {
Level - 1 + {charData.level}
HP - 12 / 12 + {charData.hp.current} / {charData.hp.max}
-
+
@@ -1844,19 +1889,16 @@ function App() {

Inventory

-
- • Rusty Sword -
-
- • Leather Armor -
-
- • 5 Gold -
+ {charData.inventory.map((item, index) => ( +
+ • {item} +
+ ))}
- )} + ); + })()} From 7c41a7f5629d60e7985c256a2db19e04344d46ca Mon Sep 17 00:00:00 2001 From: Aaron West Date: Thu, 15 Jan 2026 17:48:17 -0600 Subject: [PATCH 2/4] fix: prevent duplicate character creation and ensure persistence - Change character lookup from adventureId to conversationId for persistence - Add ref-based lock to prevent race condition duplicate creations - Ensure exactly ONE character per conversation (not per adventure) - Characters now persist across page refreshes - Add comprehensive debug logging for character lifecycle - Add render logging for GameMasterHud component Fixes issue where 4+ characters were created on each new conversation and on every refresh --- src/App.tsx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index f5295d7..8962b3e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -125,6 +125,7 @@ interface GameMasterHudProps { } function GameMasterHud({ adventure, questSteps, playerChoices, character }: GameMasterHudProps) { + console.log('🎯 GameMasterHud rendering with character:', character); const latestStep = questSteps.slice(-1)[0]; void playerChoices; @@ -268,9 +269,11 @@ function App() { const [questSteps, setQuestSteps] = useState([]); const [playerChoices, setPlayerChoices] = useState([]); const [characterState, setCharacterState] = useState(null); + const characterCreationLock = useRef(false); // Helper to get character display data with fallbacks const getCharacterData = useCallback(() => { + console.log('🔍 getCharacterData called, characterState:', characterState); const stats = { strength: characterState?.strength || 10, dexterity: characterState?.dexterity || 12, @@ -368,6 +371,7 @@ function App() { } if (adventure) { setAdventureState(adventure); + console.log('🎮 Adventure state set:', adventure.id, adventure.title); } return adventure; } catch (error) { @@ -377,9 +381,16 @@ function App() { }, [effectivePersonality]); const fetchCharacter = useCallback(async (adventureId: string) => { + // Prevent duplicate creation with ref-based lock + if (characterCreationLock.current) { + console.log('⏸️ Character creation already in progress, skipping...'); + return; + } + try { + // Look up character by conversationId instead of adventureId to ensure persistence across refreshes const { data } = await dataClient.models.GameMasterCharacter.list({ - filter: { adventureId: { eq: adventureId } }, + filter: { conversationId: { eq: conversationId } }, limit: 1 }); @@ -387,6 +398,7 @@ function App() { setCharacterState(data[0] as CharacterRecord); console.log('✅ Loaded existing character:', data[0].id); } else { + characterCreationLock.current = true; console.log('📝 Creating default character for adventure:', adventureId); try { const created = await dataClient.models.GameMasterCharacter.create({ @@ -416,15 +428,19 @@ function App() { if (created.data) { setCharacterState(created.data as CharacterRecord); console.log('✅ Created default character:', created.data.id); + console.log('📊 Character data set in state:', created.data); } else { console.error('❌ Character creation returned no data. Errors:', JSON.stringify(created.errors, null, 2)); } } catch (createError) { console.error('❌ Error during character creation:', createError); + } finally { + characterCreationLock.current = false; } } } catch (error) { console.error('❌ Error loading character:', error); + characterCreationLock.current = false; } }, [conversationId]); From 99ef4628ac402e76e5b996960d9e7c712d7dc245 Mon Sep 17 00:00:00 2001 From: Aaron West Date: Fri, 16 Jan 2026 08:23:48 -0600 Subject: [PATCH 3/4] fix: ensure single character per conversation with proper persistence - Decouple character from adventure - use conversationId as primary lookup key - Add explicit owner field to GameMasterAdventure schema - Add authMode: 'userPool' to database queries for proper authorization - Add early return in fetchCharacter when character is found - Increase propagation delay to 1000ms to ensure database writes complete - Remove dependency on conversationId from fetchCharacter callback - Add comprehensive debug logging for character and adventure lookups - Fix character creation to happen only once per conversation - Characters now persist correctly across page refreshes Resolves duplicate character creation bug where 5+ characters were created per conversation --- amplify/data/resource.ts | 1 + consol-log.txt | 17 ---- src/App.tsx | 181 +++++++++++++++++++++++---------------- 3 files changed, 107 insertions(+), 92 deletions(-) delete mode 100644 consol-log.txt diff --git a/amplify/data/resource.ts b/amplify/data/resource.ts index 0663f33..663266f 100644 --- a/amplify/data/resource.ts +++ b/amplify/data/resource.ts @@ -60,6 +60,7 @@ const schema = a.schema({ lastStepId: a.string().default(''), questSteps: a.hasMany('GameMasterQuestStep', 'adventureId'), character: a.hasOne('GameMasterCharacter', 'adventureId'), + owner: a.string(), createdAt: a.date(), updatedAt: a.date(), }).authorization(allow => [allow.owner(), allow.groups(['Admins'])]), diff --git a/consol-log.txt b/consol-log.txt deleted file mode 100644 index 59978a0..0000000 --- a/consol-log.txt +++ /dev/null @@ -1,17 +0,0 @@ -[Log] Creating new conversation with user: – "044884d8-e011-7042-12a9-de2d851aba9b" – "mode:" – "game_master" (App.tsx, line 1042) -[Log] ✅ Created new conversation: – "9269dc79-4505-4545-ac94-749fb0c37862" (App.tsx, line 1057) -[Log] 💾 Saved conversation to localStorage: – "9269dc79-4505-4545-ac94-749fb0c37862" (App.tsx, line 607) -[Log] Setting up subscription for conversation: – "9269dc79-4505-4545-ac94-749fb0c37862" (App.tsx, line 737) -[Log] Setting up raw subscription without filters (App.tsx, line 739) -[Log] 📝 Creating default character for adventure: – "2c3d581e-a932-4bc5-b4f8-b96e3d4b4844" (App.tsx, line 436) -[Log] 📋 Create result: – {data: null, errors: Array} (App.tsx, line 459) -{data: null, errors: Array}Object -[Error] ❌ Character creation returned no data. Errors: – [Object] (1) -[Object]Array (1) - (anonymous function) (App.tsx:464) -[Log] 📝 Creating default character for adventure: – "1815ba8e-772a-45d8-a9fb-61bf41b950de" (App.tsx, line 436) -[Log] 📋 Create result: – {data: null, errors: Array} (App.tsx, line 459) -{data: null, errors: Array}Object -[Error] ❌ Character creation returned no data. Errors: – [Object] (1) -[Object]Array (1) - (anonymous function) (App.tsx:464) diff --git a/src/App.tsx b/src/App.tsx index 8962b3e..029cb01 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -270,6 +270,7 @@ function App() { const [playerChoices, setPlayerChoices] = useState([]); const [characterState, setCharacterState] = useState(null); const characterCreationLock = useRef(false); + const adventureFetchLock = useRef(null); // Helper to get character display data with fallbacks const getCharacterData = useCallback(() => { @@ -353,12 +354,16 @@ function App() { const activeMode = normalizePersonalityMode(modeOverride ?? effectivePersonality); if (activeMode !== 'game_master') return null; try { + console.log('🔍 Looking for existing adventure for conversationId:', convId); const { data } = await dataClient.models.GameMasterAdventure.list({ filter: { conversationId: { eq: convId } }, limit: 1, + authMode: 'userPool', }); + console.log('📋 Adventure lookup result:', data); let adventure: AdventureRecord | null = data?.[0] ? (data[0] as AdventureRecord) : null; if (!adventure) { + console.log('📝 No existing adventure found, creating new one for:', convId); const created = await dataClient.models.GameMasterAdventure.create({ conversationId: convId, title: 'The Shadowed Forest', @@ -368,6 +373,8 @@ function App() { safetyLevel: 'User Directed', }); adventure = created.data ? (created.data as AdventureRecord) : null; + } else { + console.log('✅ Found existing adventure:', adventure.id); } if (adventure) { setAdventureState(adventure); @@ -380,7 +387,7 @@ function App() { } }, [effectivePersonality]); - const fetchCharacter = useCallback(async (adventureId: string) => { + const fetchCharacter = useCallback(async (convId: string) => { // Prevent duplicate creation with ref-based lock if (characterCreationLock.current) { console.log('⏸️ Character creation already in progress, skipping...'); @@ -388,97 +395,121 @@ function App() { } try { - // Look up character by conversationId instead of adventureId to ensure persistence across refreshes - const { data } = await dataClient.models.GameMasterCharacter.list({ - filter: { conversationId: { eq: conversationId } }, - limit: 1 + console.log('🔍 Looking for existing character for conversationId:', convId); + // Look up character by conversationId - completely independent of adventure + const { data, errors } = await dataClient.models.GameMasterCharacter.list({ + filter: { conversationId: { eq: convId } }, + limit: 1, + authMode: 'userPool', }); - if (data && data[0]) { + console.log('📋 Character lookup result:', data, 'errors:', errors); + + if (data && data.length > 0 && data[0]) { setCharacterState(data[0] as CharacterRecord); console.log('✅ Loaded existing character:', data[0].id); - } else { - characterCreationLock.current = true; - console.log('📝 Creating default character for adventure:', adventureId); - try { - const created = await dataClient.models.GameMasterCharacter.create({ - adventureId, - conversationId, - name: 'Adventurer', - race: 'Human', - characterClass: 'Wanderer', - level: 1, - experience: 0, - strength: 10, - dexterity: 12, - constitution: 14, - intelligence: 16, - wisdom: 13, - charisma: 11, - maxHP: 12, - currentHP: 12, - armorClass: 10, - inventory: JSON.stringify(['Rusty Sword', 'Leather Armor', '5 Gold']), - skills: JSON.stringify({}), - statusEffects: JSON.stringify([]), - version: 1, - }); - - console.log('📋 Create result:', created); - if (created.data) { - setCharacterState(created.data as CharacterRecord); - console.log('✅ Created default character:', created.data.id); - console.log('📊 Character data set in state:', created.data); - } else { - console.error('❌ Character creation returned no data. Errors:', JSON.stringify(created.errors, null, 2)); - } - } catch (createError) { - console.error('❌ Error during character creation:', createError); - } finally { - characterCreationLock.current = false; + return; // Early return - character found, don't create + } + + // Only create if no character exists for this conversation + characterCreationLock.current = true; + console.log('📝 Creating default character for conversation:', convId); + try { + const created = await dataClient.models.GameMasterCharacter.create({ + adventureId: 'placeholder', // Adventure ID doesn't matter anymore + conversationId: convId, + name: 'Adventurer', + race: 'Human', + characterClass: 'Wanderer', + level: 1, + experience: 0, + strength: 10, + dexterity: 12, + constitution: 14, + intelligence: 16, + wisdom: 13, + charisma: 11, + maxHP: 12, + currentHP: 12, + armorClass: 10, + inventory: JSON.stringify(['Rusty Sword', 'Leather Armor', '5 Gold']), + skills: JSON.stringify({}), + statusEffects: JSON.stringify([]), + version: 1, + }); + + console.log('📋 Create result:', created); + if (created.data) { + setCharacterState(created.data as CharacterRecord); + console.log('✅ Created default character:', created.data.id); + console.log('📊 Character data set in state:', created.data); + // Small delay to ensure database write propagates before releasing lock + await new Promise(resolve => setTimeout(resolve, 1000)); + } else { + console.error('❌ Character creation returned no data. Errors:', JSON.stringify(created.errors, null, 2)); } + } catch (createError) { + console.error('❌ Error during character creation:', createError); + } finally { + characterCreationLock.current = false; } } catch (error) { console.error('❌ Error loading character:', error); characterCreationLock.current = false; } - }, [conversationId]); + }, []); const fetchAdventureBundle = useCallback(async (convId: string, modeOverride?: string) => { - const activeMode = normalizePersonalityMode(modeOverride ?? effectivePersonality); - if (activeMode !== 'game_master') { - setAdventureState(null); - setQuestSteps([]); - setPlayerChoices([]); - setCharacterState(null); + // Prevent duplicate fetches for the same conversation + if (adventureFetchLock.current === convId) { + console.log('⏸️ Adventure bundle fetch already in progress for:', convId); return; } - const adventure = await ensureAdventureState(convId, activeMode); - if (!adventure || !adventure.id) return; - const adventureId = adventure.id as string; - // Fetch character when adventure is loaded - await fetchCharacter(adventureId); + adventureFetchLock.current = convId; try { - const [stepsRes, choicesRes] = await Promise.all([ - dataClient.models.GameMasterQuestStep.list({ - filter: { adventureId: { eq: adventureId } }, - limit: 200, - }), - dataClient.models.GameMasterPlayerChoice.list({ - filter: { conversationId: { eq: convId } }, - limit: 200, - }), - ]); - const steps = ((stepsRes.data ?? []).filter(Boolean) as QuestStepRecord[]) - .sort((a, b) => ((a?.createdAt ?? '') < (b?.createdAt ?? '') ? -1 : 1)); - const choices = ((choicesRes.data ?? []).filter(Boolean) as PlayerChoiceRecord[]) - .sort((a, b) => ((a?.createdAt ?? '') < (b?.createdAt ?? '') ? -1 : 1)); - setQuestSteps(steps); - setPlayerChoices(choices); - } catch (error) { - console.error('Error loading Game Master data:', error); + const activeMode = normalizePersonalityMode(modeOverride ?? effectivePersonality); + if (activeMode !== 'game_master') { + setAdventureState(null); + setQuestSteps([]); + setPlayerChoices([]); + setCharacterState(null); + adventureFetchLock.current = null; + return; + } + const adventure = await ensureAdventureState(convId, activeMode); + if (!adventure || !adventure.id) { + adventureFetchLock.current = null; + return; + } + const adventureId = adventure.id as string; + + // Fetch character when adventure is loaded - pass conversationId instead + await fetchCharacter(convId); + + try { + const [stepsRes, choicesRes] = await Promise.all([ + dataClient.models.GameMasterQuestStep.list({ + filter: { adventureId: { eq: adventureId } }, + limit: 200, + }), + dataClient.models.GameMasterPlayerChoice.list({ + filter: { conversationId: { eq: convId } }, + limit: 200, + }), + ]); + const steps = ((stepsRes.data ?? []).filter(Boolean) as QuestStepRecord[]) + .sort((a, b) => ((a?.createdAt ?? '') < (b?.createdAt ?? '') ? -1 : 1)); + const choices = ((choicesRes.data ?? []).filter(Boolean) as PlayerChoiceRecord[]) + .sort((a, b) => ((a?.createdAt ?? '') < (b?.createdAt ?? '') ? -1 : 1)); + setQuestSteps(steps); + setPlayerChoices(choices); + } catch (error) { + console.error('Error loading Game Master data:', error); + } + } finally { + adventureFetchLock.current = null; } }, [effectivePersonality, ensureAdventureState, fetchCharacter]); From 8b5b7ed174c019fadd3c0a3e8515b263bc964271 Mon Sep 17 00:00:00 2001 From: Aaron West Date: Fri, 16 Jan 2026 08:26:15 -0600 Subject: [PATCH 4/4] chore: remove debug logging for production readiness - Remove verbose character and adventure creation logs - Remove subscription and message flow debug logs - Remove user authentication and conversation loading logs - Keep only essential error logging for debugging issues - Retain test mode logs for development debugging - Clean up console output for production deployment --- src/App.tsx | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 029cb01..588044e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -125,7 +125,6 @@ interface GameMasterHudProps { } function GameMasterHud({ adventure, questSteps, playerChoices, character }: GameMasterHudProps) { - console.log('🎯 GameMasterHud rendering with character:', character); const latestStep = questSteps.slice(-1)[0]; void playerChoices; @@ -274,7 +273,6 @@ function App() { // Helper to get character display data with fallbacks const getCharacterData = useCallback(() => { - console.log('🔍 getCharacterData called, characterState:', characterState); const stats = { strength: characterState?.strength || 10, dexterity: characterState?.dexterity || 12, @@ -354,16 +352,13 @@ function App() { const activeMode = normalizePersonalityMode(modeOverride ?? effectivePersonality); if (activeMode !== 'game_master') return null; try { - console.log('🔍 Looking for existing adventure for conversationId:', convId); const { data } = await dataClient.models.GameMasterAdventure.list({ filter: { conversationId: { eq: convId } }, limit: 1, authMode: 'userPool', }); - console.log('📋 Adventure lookup result:', data); let adventure: AdventureRecord | null = data?.[0] ? (data[0] as AdventureRecord) : null; if (!adventure) { - console.log('📝 No existing adventure found, creating new one for:', convId); const created = await dataClient.models.GameMasterAdventure.create({ conversationId: convId, title: 'The Shadowed Forest', @@ -373,12 +368,9 @@ function App() { safetyLevel: 'User Directed', }); adventure = created.data ? (created.data as AdventureRecord) : null; - } else { - console.log('✅ Found existing adventure:', adventure.id); } if (adventure) { setAdventureState(adventure); - console.log('🎮 Adventure state set:', adventure.id, adventure.title); } return adventure; } catch (error) { @@ -390,30 +382,27 @@ function App() { const fetchCharacter = useCallback(async (convId: string) => { // Prevent duplicate creation with ref-based lock if (characterCreationLock.current) { - console.log('⏸️ Character creation already in progress, skipping...'); return; } try { - console.log('🔍 Looking for existing character for conversationId:', convId); - // Look up character by conversationId - completely independent of adventure const { data, errors } = await dataClient.models.GameMasterCharacter.list({ filter: { conversationId: { eq: convId } }, limit: 1, authMode: 'userPool', }); - console.log('📋 Character lookup result:', data, 'errors:', errors); + if (errors && errors.length > 0) { + console.error('Error fetching character:', errors); + } if (data && data.length > 0 && data[0]) { setCharacterState(data[0] as CharacterRecord); - console.log('✅ Loaded existing character:', data[0].id); - return; // Early return - character found, don't create + return; } // Only create if no character exists for this conversation characterCreationLock.current = true; - console.log('📝 Creating default character for conversation:', convId); try { const created = await dataClient.models.GameMasterCharacter.create({ adventureId: 'placeholder', // Adventure ID doesn't matter anymore @@ -438,15 +427,12 @@ function App() { version: 1, }); - console.log('📋 Create result:', created); if (created.data) { setCharacterState(created.data as CharacterRecord); - console.log('✅ Created default character:', created.data.id); - console.log('📊 Character data set in state:', created.data); - // Small delay to ensure database write propagates before releasing lock + // Small delay to ensure database write propagates await new Promise(resolve => setTimeout(resolve, 1000)); - } else { - console.error('❌ Character creation returned no data. Errors:', JSON.stringify(created.errors, null, 2)); + } else if (created.errors) { + console.error('Character creation failed:', created.errors); } } catch (createError) { console.error('❌ Error during character creation:', createError); @@ -462,7 +448,6 @@ function App() { const fetchAdventureBundle = useCallback(async (convId: string, modeOverride?: string) => { // Prevent duplicate fetches for the same conversation if (adventureFetchLock.current === convId) { - console.log('⏸️ Adventure bundle fetch already in progress for:', convId); return; } @@ -618,7 +603,6 @@ function App() { const attributes = await fetchUserAttributes(); setUserAttributes(attributes); - console.log('👤 Logged-in user:', attributes); setIsLoading(false); } catch (error) { console.error('❌ Error fetching user attributes:', error); @@ -632,7 +616,6 @@ function App() { useEffect(() => { if (conversationId) { localStorage.setItem('lastConversationId', conversationId); - console.log('💾 Saved conversation to localStorage:', conversationId); } }, [conversationId]); @@ -642,7 +625,6 @@ function App() { if (!userAttributes || conversationId) return; // Don't run if already have conversation or no user try { - console.log('🔄 Auto-loading conversation...'); // For test mode, auto-select test conversation or create new one const urlParams = new URLSearchParams(window.location.search); @@ -660,16 +642,13 @@ function App() { // Check for last conversation ID in localStorage const lastConversationId = localStorage.getItem('lastConversationId'); if (lastConversationId) { - console.log('💾 Found last conversation in localStorage:', lastConversationId); try { // Verify the conversation still exists const { data: conversation } = await dataClient.models.Conversation.get({ id: lastConversationId }); if (conversation) { - console.log('✅ Restoring last conversation'); await handleSelectConversation(lastConversationId); return; } else { - console.log('⚠️ Last conversation no longer exists, clearing localStorage'); localStorage.removeItem('lastConversationId'); } } catch (error) { @@ -690,11 +669,9 @@ function App() { }); const mostRecentConversation = sortedConversations[0]; - console.log('✅ Auto-loaded most recent conversation:', mostRecentConversation.id); await handleSelectConversation(mostRecentConversation.id!); } else { // No conversations exist, create a new one - console.log('📝 No conversations found, creating new one...'); await handleNewConversation(); } } catch (error) { @@ -1019,7 +996,6 @@ function App() { await recordPlayerChoice(savedMessage.id, content); } - console.log('Message saved to backend:', savedMessage); } catch (error) { console.error('Error sending message to backend:', error); setIsWaitingForResponse(false); @@ -1032,7 +1008,6 @@ function App() { // If no conversation exists, create one first if (!conversationId) { - console.log('🔄 No conversation exists, creating one...'); await handleNewConversation(); // Wait a bit for the conversation to be created await new Promise(resolve => setTimeout(resolve, 100)); @@ -1097,7 +1072,6 @@ function App() { setPlayerChoices([]); setCharacterState(null); } - console.log('📌 Loaded personality mode:', normalizedMode); } const { data: conversationMessages } = await dataClient.models.Message.list({ @@ -1139,7 +1113,6 @@ function App() { } else { // This message has no response yet - mark as pending hasPendingMessage = true; - console.log('⏳ Found pending message:', msg.id); } }); @@ -1153,7 +1126,6 @@ function App() { // Set waiting state based on whether there's a pending message if (hasPendingMessage) { - console.log('🔒 Blocking input - pending message detected after load'); setIsWaitingForResponse(true); } else { setIsWaitingForResponse(false);