Skip to content

Commit 7b0adef

Browse files
committed
Fix duel UI round recovery orchestration
1 parent f202a93 commit 7b0adef

File tree

1 file changed

+35
-18
lines changed

1 file changed

+35
-18
lines changed

app/js/ui/screens/duel.js

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ var DuelScreen = (function() {
2727
strategySecret: null,
2828
strategyRound: 0,
2929
roundResults: [],
30+
revealRoundNumber: 0,
31+
lastSeenResolvedRound: 0,
3032
challengeData: null,
3133
autoMode: false,
3234
pendingAction: '',
@@ -119,23 +121,16 @@ var DuelScreen = (function() {
119121
var data = JSON.parse(saved);
120122
if (!data || !data.secret || !data.secret.hash) return;
121123

122-
var shouldRestore = false;
123-
124124
// Restore only for an already identified duel after reload.
125125
// For fresh outgoing duels without combatRef, stale secrets must not lock UI.
126-
if (duelState.combatRef && data.combatRef === duelState.combatRef) {
127-
shouldRestore = true;
128-
}
129-
130-
if (!shouldRestore) {
126+
if (!duelState.combatRef || data.combatRef !== duelState.combatRef) {
131127
return;
132128
}
133129

134130
duelState.strategySecret = data.secret;
135131
duelState.strategyRound = data.round || 1;
136132
duelState.selectedIntent = data.secret.intent;
137133
duelState.currentRound = data.round || 1;
138-
duelState.phase = 'waiting';
139134
console.log('Duel secret restored from localStorage for combat', duelState.combatRef, 'round', data.round || 1);
140135
} catch(e) {
141136
console.log('Could not restore duel secret:', e);
@@ -599,7 +594,8 @@ var DuelScreen = (function() {
599594
SoundManager.play('seals_break');
600595
SoundManager.vibrate('reveal');
601596

602-
var roundLabel = t('duel_round', { round: duelState.currentRound, total: duelState.totalRounds });
597+
var revealRound = duelState.revealRoundNumber || duelState.roundResults.length || duelState.currentRound;
598+
var roundLabel = t('duel_round', { round: revealRound, total: duelState.totalRounds });
603599
var resultClass = iWon ? 'round-won' : (isDraw ? 'round-draw' : 'round-lost');
604600
var resultText = iWon ? t('duel_round_won') : (isDraw ? t('duel_round_draw') : t('duel_round_lost'));
605601

@@ -673,6 +669,9 @@ var DuelScreen = (function() {
673669
var finishBtn = Helpers.$('btn-duel-finish');
674670
if (finishBtn) {
675671
finishBtn.addEventListener('click', function() {
672+
duelState.lastSeenResolvedRound = Math.max(duelState.lastSeenResolvedRound, duelState.revealRoundNumber || duelState.roundResults.length);
673+
duelState.revealRoundNumber = 0;
674+
_clearPersistedSecret();
676675
duelState.phase = 'result';
677676
duelState.finalWinsMe = winsMe;
678677
duelState.finalWinsOpp = winsOpp;
@@ -683,13 +682,16 @@ var DuelScreen = (function() {
683682
var nextBtn = Helpers.$('btn-duel-next');
684683
if (nextBtn) {
685684
nextBtn.addEventListener('click', function() {
686-
duelState.currentRound++;
685+
duelState.lastSeenResolvedRound = Math.max(duelState.lastSeenResolvedRound, duelState.revealRoundNumber || duelState.roundResults.length);
686+
duelState.revealRoundNumber = 0;
687+
duelState.currentRound = Math.max(duelState.currentRound + 1, duelState.lastSeenResolvedRound + 1);
687688
duelState.selectedIntent = null;
688689
duelState.strategySecret = null;
689690
duelState.strategyRound = 0;
690691
duelState.opponentCommitted = false;
691692
duelState.opponentRevealedIntent = '';
692693
duelState.myRevealedIntent = '';
694+
_clearPersistedSecret();
693695
duelState.phase = 'seal';
694696
render();
695697
});
@@ -823,14 +825,13 @@ var DuelScreen = (function() {
823825
duelState.myRevealedIntent = latest.myIntent;
824826
duelState.opponentRevealedIntent = latest.oppIntent;
825827
if (duel.status === 'completed') {
828+
duelState.revealRoundNumber = duel.roundResults.length;
826829
duelState.phase = 'result';
827830
duelState.finalWinsMe = _countWinsForUser(duel.roundResults, user);
828831
duelState.finalWinsOpp = _countLossesForUser(duel.roundResults, user);
829-
} else if ((duelState.phase === 'waiting' || duelState.phase === 'seal') &&
830-
duelState.currentRound <= duel.roundResults.length) {
831-
// Only stay on reveal for the most recently resolved round.
832-
// Once the player has advanced to the next round, do not
833-
// force the UI back into the prior round's reveal screen.
832+
_clearPersistedSecret();
833+
} else if (duel.roundResults.length > (duelState.lastSeenResolvedRound || 0)) {
834+
duelState.revealRoundNumber = duel.roundResults.length;
834835
duelState.phase = 'reveal';
835836
}
836837
}
@@ -850,11 +851,27 @@ var DuelScreen = (function() {
850851
}
851852
}
852853
if (duel.status === 'active') {
854+
var activeRound = duel.currentRound || duelState.currentRound || 1;
855+
var hasCurrentCommit = _hasCurrentUserCommitted(duel, user, activeRound);
853856
var canReveal = _canRevealCurrentRound(duel);
857+
854858
duelState.waitingMessageKey = canReveal ? 'duel_waiting_reveal_chain' : 'duel_waiting_commit_chain';
855-
if (duelState.phase === 'pre') {
856-
duelState.phase = canReveal ? 'seal' : 'waiting';
859+
860+
if (duelState.strategySecret && duelState.strategyRound !== activeRound) {
861+
duelState.strategySecret = null;
862+
duelState.strategyRound = 0;
863+
duelState.selectedIntent = null;
864+
_clearPersistedSecret();
857865
}
866+
867+
if (duelState.phase !== 'reveal' && duelState.phase !== 'result') {
868+
if (!hasCurrentCommit) {
869+
duelState.phase = 'seal';
870+
} else {
871+
duelState.phase = 'waiting';
872+
}
873+
}
874+
858875
if (canReveal) {
859876
_maybeAutoRevealCurrentRound(duel);
860877
}
@@ -1272,4 +1289,4 @@ var DuelScreen = (function() {
12721289
render: render,
12731290
startDuel: startDuel
12741291
};
1275-
})();
1292+
})();

0 commit comments

Comments
 (0)