fix: mobile fight playback — prevent sprite loading hangs, TTS stalls, unlock audio from gesture
- Unified speakAsync/speakAsyncWithRate into _speakAsyncCore with: - 500ms startup check: bail immediately if speech won't start (mobile/no gesture) - 8s safety timeout (down from 15s) to prevent blocking - iOS-safe keepalive: only do Chrome pause/resume workaround on desktop Chrome - Immediate bail when no voices loaded - Sprite loading: 5s timeout per sprite prevents mobile hangs from stuck Image decodes - Scene creation: 10s timeout in FightViewer so overlay/voice flow continues even if canvas fails on mobile - playRound: bail gracefully if fighter sprites missing instead of crashing - Global audio unlock: first touch/click on site unlocks AudioContext + SpeechSynthesis - Practice button pre-unlocks audio while still in user gesture context Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
9287fd1783
commit
6561ef5d15
@@ -4,6 +4,7 @@ import { useRouter } from 'vue-router'
|
||||
import { useNostr } from '../composables/useNostr'
|
||||
import { useWallet } from '../composables/useWallet'
|
||||
import SpritePreview from '../components/SpritePreview.vue'
|
||||
import { ensureAudioContext } from '../game/sounds'
|
||||
import HumanPreview from '../components/HumanPreview.vue'
|
||||
import WalletConnect from '../components/WalletConnect.vue'
|
||||
|
||||
@@ -384,6 +385,8 @@ async function practice() {
|
||||
if (!bot.value || isJoiningPractice.value) return
|
||||
isJoiningPractice.value = true
|
||||
error.value = ''
|
||||
// Unlock audio/speech NOW while we're in user gesture context (lost after async navigation)
|
||||
ensureAudioContext()
|
||||
try {
|
||||
const res = await fetch(`/api/fights/practice/${bot.value.id}`, { method: 'POST' })
|
||||
if (res.ok) {
|
||||
|
||||
Reference in New Issue
Block a user