Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00f7334580 | ||
|
|
c5c0fb6b03 |
@@ -2,5 +2,5 @@ apiVersion: v2
|
|||||||
name: ai-spel-frontend
|
name: ai-spel-frontend
|
||||||
description: Static web frontend for the Swedish life simulator
|
description: Static web frontend for the Swedish life simulator
|
||||||
type: application
|
type: application
|
||||||
version: 0.1.37
|
version: 0.1.38
|
||||||
appVersion: "0.1.37"
|
appVersion: "0.1.38"
|
||||||
+1
-1
@@ -219,7 +219,7 @@
|
|||||||
microphone.textContent = listening ? 'Avsluta mikrofon' : 'Starta mikrofon';
|
microphone.textContent = listening ? 'Avsluta mikrofon' : 'Starta mikrofon';
|
||||||
refreshMicrophone();
|
refreshMicrophone();
|
||||||
if (message) setVoiceStatus(message);
|
if (message) setVoiceStatus(message);
|
||||||
if (/Uppläsningen startade inte/.test(message)) showSpeechRecovery(message);
|
if (/Läs senaste repliken/.test(message)) showSpeechRecovery(message);
|
||||||
playVoiceSignal(state === 'IDLE' && /Mikrofonen är avstängd/.test(message) ? 'STOPPED' : state);
|
playVoiceSignal(state === 'IDLE' && /Mikrofonen är avstängd/.test(message) ? 'STOPPED' : state);
|
||||||
},
|
},
|
||||||
onTranscript(text) {
|
onTranscript(text) {
|
||||||
|
|||||||
@@ -165,6 +165,16 @@ test('speech start timeout tells the player how to recover when mobile playback
|
|||||||
assert.equal(h.synthesis.cancelled, cancelledBeforeRetry);
|
assert.equal(h.synthesis.cancelled, cancelledBeforeRetry);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('iOS not-allowed speech error offers an immediate gesture-based retry', () => {
|
||||||
|
const h = makeHarness();
|
||||||
|
h.controller.speak('En replik');
|
||||||
|
h.utterances[0].onerror({error: 'not-allowed'});
|
||||||
|
assert.match(h.states.at(-1).message, /Safari blockerade uppläsningen/);
|
||||||
|
assert.match(h.states.at(-1).message, /Läs senaste repliken/);
|
||||||
|
assert.equal(h.controller.speak('Försök igen'), true);
|
||||||
|
assert.equal(h.synthesis.spoken.at(-1).text, 'Försök igen');
|
||||||
|
});
|
||||||
|
|
||||||
test('character voice identity gives stable distinct masculine, feminine, and neutral timbres', () => {
|
test('character voice identity gives stable distinct masculine, feminine, and neutral timbres', () => {
|
||||||
const profile = GameVoice.characterVoiceProfile;
|
const profile = GameVoice.characterVoiceProfile;
|
||||||
const masculine = profile('masculine', 'character-1');
|
const masculine = profile('masculine', 'character-1');
|
||||||
|
|||||||
@@ -240,7 +240,7 @@
|
|||||||
currentUtterance = null;
|
currentUtterance = null;
|
||||||
setState('IDLE');
|
setState('IDLE');
|
||||||
};
|
};
|
||||||
utterance.onerror = () => {
|
utterance.onerror = event => {
|
||||||
if (token !== generation) return;
|
if (token !== generation) return;
|
||||||
if (speechTimer !== null) win.clearTimeout(speechTimer);
|
if (speechTimer !== null) win.clearTimeout(speechTimer);
|
||||||
if (speechStartTimer !== null) win.clearTimeout(speechStartTimer);
|
if (speechStartTimer !== null) win.clearTimeout(speechStartTimer);
|
||||||
@@ -248,7 +248,11 @@
|
|||||||
speechStartTimer = null;
|
speechStartTimer = null;
|
||||||
currentUtterance = null;
|
currentUtterance = null;
|
||||||
generation += 1;
|
generation += 1;
|
||||||
setState('IDLE', 'Uppläsningen avbröts. Dialogen finns kvar som text.');
|
const blocked = event?.error === 'not-allowed' || event?.error === 'service-not-allowed';
|
||||||
|
const message = blocked
|
||||||
|
? 'Safari blockerade uppläsningen. Tryck på Läs senaste repliken för att starta ljudet.'
|
||||||
|
: 'Uppläsningen avbröts. Tryck på Läs senaste repliken för att försöka igen. Dialogen finns kvar som text.';
|
||||||
|
setState('IDLE', message);
|
||||||
};
|
};
|
||||||
setState('SPEAKING', 'Läser upp dialog.');
|
setState('SPEAKING', 'Läser upp dialog.');
|
||||||
currentUtterance = utterance;
|
currentUtterance = utterance;
|
||||||
|
|||||||
Reference in New Issue
Block a user