mirror of
https://github.com/GoodStartLabs/AI_Diplomacy.git
synced 2026-04-19 12:58:09 +00:00
momentModal styling, making speech search fire and forget
Speech creation was holding up the queue, as the promise only resolved when the speech was returned. Made it fire and forget with a toggle to the gameState.isSpeaking to make sure we wait until the turn ends.
This commit is contained in:
parent
79a2eceef4
commit
fe18f5ee52
4 changed files with 59 additions and 41 deletions
|
|
@ -204,25 +204,6 @@ export function closeMomentModal(immediate: boolean = false): void {
|
|||
function createDialogueOverlay(): HTMLElement {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.id = 'dialogue-overlay';
|
||||
overlay.style.cssText = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
`;
|
||||
|
||||
// Trigger fade in
|
||||
// Trigger fade in with a small timeout
|
||||
setTimeout(() => overlay.style.opacity = '1', 10);
|
||||
|
||||
return overlay;
|
||||
}
|
||||
|
||||
|
|
@ -231,24 +212,11 @@ function createDialogueOverlay(): HTMLElement {
|
|||
*/
|
||||
function createDialogueContainer(power1: string, power2: string, title?: string, moment?: Moment): HTMLElement {
|
||||
const container = document.createElement('div');
|
||||
container.className = 'dialogue-container';
|
||||
container.style.cssText = `
|
||||
background: radial-gradient(ellipse at center, #f7ecd1 0%, #dbc08w8px;
|
||||
box-shadow: 0 0 15px rgba(0,0,0,0.5);
|
||||
width: 90%;
|
||||
height: 85%;
|
||||
position: relative;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
container.className = "dialogue-container"
|
||||
|
||||
// Create header section with title and moment info
|
||||
const headerSection = document.createElement('div');
|
||||
headerSection.style.cssText = `
|
||||
margin-bottom: 15px;
|
||||
text-align: center;
|
||||
`;
|
||||
headerSection.id = "dialogue-header"
|
||||
|
||||
// Add main title
|
||||
const titleElement = document.createElement('h2');
|
||||
|
|
@ -267,7 +235,7 @@ function createDialogueContainer(power1: string, power2: string, title?: string,
|
|||
const momentTypeElement = document.createElement('div');
|
||||
momentTypeElement.textContent = `${moment.category} (Interest: ${moment.interest_score}/10)`;
|
||||
momentTypeElement.style.cssText = `
|
||||
background: rgba(75, 59, 22, 0.8);
|
||||
background: rgba(75, 59, 22);
|
||||
color: #f7ecd1;
|
||||
padding: 5px 15px;
|
||||
border-radius: 15px;
|
||||
|
|
@ -344,7 +312,7 @@ function createDiaryBox(power: PowerENUM, diaryContent: string): HTMLElement {
|
|||
diaryBox.style.cssText = `
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
background: rgba(255, 255, 255);
|
||||
border: 2px solid #8b7355;
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
|
|
@ -363,7 +331,7 @@ function createDiaryBox(power: PowerENUM, diaryContent: string): HTMLElement {
|
|||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
background: rgba(75, 59, 22, 0.1);
|
||||
background: rgba(75, 59, 22, 0.8);
|
||||
border-radius: 4px;
|
||||
border-bottom: 1px solid #8b7355;
|
||||
`;
|
||||
|
|
@ -391,7 +359,7 @@ function createDiaryBox(power: PowerENUM, diaryContent: string): HTMLElement {
|
|||
p.style.cssText = `
|
||||
margin: 0 0 4px 0;
|
||||
padding: 3px;
|
||||
background: ${index % 2 === 0 ? 'rgba(255,255,255,0.2)' : 'transparent'};
|
||||
background: ${index % 2 === 0 ? 'rgba(255,255,255)' : 'transparent'};
|
||||
border-radius: 3px;
|
||||
`;
|
||||
contentArea.appendChild(p);
|
||||
|
|
@ -428,7 +396,7 @@ function createConversationArea(): HTMLElement {
|
|||
padding: 8px;
|
||||
border: 2px solid #8b7355;
|
||||
border-radius: 5px;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ class GameState {
|
|||
boardName: string
|
||||
currentPower!: PowerENUM
|
||||
isPlaying: boolean
|
||||
isSpeaking: boolean
|
||||
audio: GameAudio
|
||||
|
||||
|
||||
|
|
@ -189,6 +190,7 @@ class GameState {
|
|||
this.boardName = boardName
|
||||
this.gameId = 0
|
||||
this.isPlaying = false
|
||||
this.isSpeaking = false
|
||||
this.audio = new GameAudio()
|
||||
|
||||
this.scene = new THREE.Scene()
|
||||
|
|
@ -244,7 +246,7 @@ class GameState {
|
|||
while (true) {
|
||||
let narrator = this.audio.getNarratorPlayer()
|
||||
|
||||
let narratorFinished = (narrator === null) || narrator.ended
|
||||
let narratorFinished = (narrator === null) || narrator.ended || !this.isSpeaking
|
||||
if (this.unitAnimations.length === 0 && narratorFinished) {
|
||||
this.phaseIndex = phaseIdx
|
||||
updateMapOwnership()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { config } from "./config";
|
||||
import { ScheduledEvent } from "./events";
|
||||
import { GamePhase } from "./types/gameState";
|
||||
import { gameState } from "./gameState";
|
||||
// TODO: We need to get these pieces of audio ahead of time, instead of paying for them each time we load the front end
|
||||
// These pieces of audio are predetermined.
|
||||
|
||||
|
|
@ -63,7 +64,18 @@ async function testElevenLabsKey() {
|
|||
|
||||
export function createNarratorAudioEvent(phase: GamePhase): ScheduledEvent {
|
||||
|
||||
return new ScheduledEvent(`narratorSpeech-${phase.name}`, () => speakSummary(phase.summary))
|
||||
return new ScheduledEvent(`narratorSpeech-${phase.name}`, () => {
|
||||
// Immediately set isSpeaking flag and resolve promise
|
||||
gameState.isSpeaking = true;
|
||||
|
||||
// Start audio generation in background (don't wait for it)
|
||||
speakSummary(phase.summary).finally(() => {
|
||||
gameState.isSpeaking = false;
|
||||
});
|
||||
|
||||
// Resolve immediately so event queue can continue
|
||||
return Promise.resolve();
|
||||
})
|
||||
|
||||
}
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -903,3 +903,39 @@
|
|||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------
|
||||
Moment Model
|
||||
----------------- */
|
||||
#dialogue-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1000;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
.dialogue-container {
|
||||
background: radial-gradient(ellipse at center, #f7ecd1 0%, #dbc08c 100%);
|
||||
border: 3px solid #4f3b16;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 15px rgba(0,0,0,0.5);
|
||||
width: 90%;
|
||||
height: 85%;
|
||||
position: relative;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#dialogue-header {
|
||||
|
||||
margin-bottom: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue