fix(circuit): 偶数 set 数休息语音被一半/进度提示吞掉

偶数组数 sets×hold/2 正好压在组练完→休息切换的同一 tick:
_circuitCue 先播 halfway 并占麦 2.6s,导致 _circuitPhase 的
restStart 被静音。修复:atRestBoundary 且 restStart 会播时,
跳过 halfway/last30/last10 让休息语音优先;奇数组数/短组
配置不动,无回归。
This commit is contained in:
2026-08-14 08:52:07 +08:00
parent aa905b1d09
commit 845a1bfd8d
2 changed files with 19 additions and 3 deletions
+13 -3
View File
@@ -354,21 +354,31 @@ Page({
const s = storage.getSettings()
const voiceOn = s.voiceGuide !== false
// Even set counts land a progress threshold (halfway / last30 / last10)
// exactly on a work→rest transition. If that prompt speaks it grabs the
// mic for ~2.6s (see _playProgressVoice) and mutes the "休息一下" line
// fired on the same tick. Yield to rest whenever restStart will actually
// play (chatty + rest≥5); short-set configs keep the progress cue as
// before. Odd set counts never hit this because the halfway point sits
// mid-set, so their progress prompts are unaffected.
const atRestBoundary = t.phaseRemaining <= 0 && t.restPerSet > 0 && t.setIndex < t.sets
const restWillSpeak = this._circuitCfg.holdPerSet >= 10 && this._circuitCfg.restPerSet >= 5
// Same duration gates as _remind(), so short circuits (e.g. 3 sets × 5s)
// don't fire "最后30秒" on the very first tick. `<=` rather than `===`
// survives a skipped second when the app returns from background.
if (total >= 10 && !this._halfwaySignaled && done >= Math.floor(total / 2)) {
this._halfwaySignaled = true
if (voiceOn) this._playProgressVoice('halfway')
if (!(atRestBoundary && restWillSpeak) && voiceOn) this._playProgressVoice('halfway')
this._vibrateOnce(2, 150)
}
if (total > 60 && left <= 30 && !this._last30Signaled) {
this._last30Signaled = true
if (voiceOn) this._playProgressVoice('last30')
if (!(atRestBoundary && restWillSpeak) && voiceOn) this._playProgressVoice('last30')
}
if (total > 20 && left <= 10 && !this._last10Signaled) {
this._last10Signaled = true
if (voiceOn) this._playProgressVoice('last10')
if (!(atRestBoundary && restWillSpeak) && voiceOn) this._playProgressVoice('last10')
}
// Countdown buzz over the last 5s of the FINAL set (the real finish line).