Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/hooks/useTTS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useBusTTSText } from './useBusTTSText';
import { useCachedInitAnonymousUser } from './useCachedAnonymousUser';
import { useCurrentLine } from './useCurrentLine';
import { usePrevious } from './usePrevious';
import { useStoppingState } from './useStoppingState';
import { useTTSText } from './useTTSText';

const BASE64_ALPHABET =
Expand Down Expand Up @@ -70,6 +71,8 @@ export const useTTS = (): void => {
useAtomValue(speechState);
const { arrived, selectedBound } = useAtomValue(stationState);
const currentLine = useCurrentLine();
const stoppingState = useStoppingState();
const prevStoppingState = usePrevious(stoppingState);

const firstSpeechRef = useRef(true);
// 行先選択直後の初回TTSを抑止し、発車後(arrived=false)でのみ解放する
Expand Down Expand Up @@ -506,6 +509,7 @@ export const useTTS = (): void => {
}

if (!textJa || !textEn) {
pendingRef.current = null;
return;
}

Expand All @@ -515,6 +519,7 @@ export const useTTS = (): void => {
firstSpeechRef,
suppressFirstSpeechUntilDepartureRef,
arrived,
stoppingStateChanged: stoppingState !== prevStoppingState,
})
) {
return;
Expand All @@ -536,7 +541,16 @@ export const useTTS = (): void => {
console.error(err);
}
})();
}, [arrived, enabled, prevTextEn, prevTextJa, textEn, textJa]);
}, [
arrived,
enabled,
prevStoppingState,
prevTextEn,
prevTextJa,
stoppingState,
textEn,
textJa,
]);

useEffect(() => {
return () => {
Expand Down
13 changes: 12 additions & 1 deletion src/utils/computeSuppressionDecision.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const createParams = (
firstSpeech: boolean;
suppressFirstSpeechUntilDeparture: boolean;
arrived: boolean;
stoppingStateChanged: boolean;
}> = {}
) => ({
suppressPostFirstSpeechRef: {
Expand All @@ -16,6 +17,7 @@ const createParams = (
current: overrides.suppressFirstSpeechUntilDeparture ?? false,
},
arrived: overrides.arrived ?? false,
stoppingStateChanged: overrides.stoppingStateChanged ?? false,
});

describe('computeSuppressionDecision', () => {
Expand All @@ -25,12 +27,21 @@ describe('computeSuppressionDecision', () => {
});

describe('Post-first-speech 抑制', () => {
it('suppressPostFirstSpeechが有効なら抑制してフラグをクリアする', () => {
it('suppressPostFirstSpeechが有効でstoppingState未変化なら抑制してフラグをクリアする', () => {
const params = createParams({ suppressPostFirstSpeech: true });
expect(computeSuppressionDecision(params)).toBe(true);
expect(params.suppressPostFirstSpeechRef.current).toBe(false);
});

it('suppressPostFirstSpeechが有効でもstoppingStateが変化していれば抑制しない', () => {
const params = createParams({
suppressPostFirstSpeech: true,
stoppingStateChanged: true,
});
expect(computeSuppressionDecision(params)).toBe(false);
expect(params.suppressPostFirstSpeechRef.current).toBe(false);
});

it('他の抑制条件より優先して評価される', () => {
const params = createParams({
suppressPostFirstSpeech: true,
Expand Down
6 changes: 5 additions & 1 deletion src/utils/computeSuppressionDecision.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ export const computeSuppressionDecision = (params: {
firstSpeechRef: { current: boolean };
suppressFirstSpeechUntilDepartureRef: { current: boolean };
arrived: boolean;
stoppingStateChanged: boolean;
}): boolean => {
// 1. Post-first-speech: firstSpeechRef→falseで生じるテキスト変化を1回だけ無視
// ただしstoppingStateが変化した場合は正当なテキスト変化なので抑止しない
if (params.suppressPostFirstSpeechRef.current) {
params.suppressPostFirstSpeechRef.current = false;
return true;
if (!params.stoppingStateChanged) {
return true;
}
}

// 2. Suppress-until-departure
Expand Down