diff --git a/client/play/geoword/results/packet/html.js b/client/play/geoword/results/packet/html.js index f5c3972e8..420c2ecb9 100644 --- a/client/play/geoword/results/packet/html.js +++ b/client/play/geoword/results/packet/html.js @@ -1,4 +1,4 @@ -import { formatTime, getBuzzTime, getClueAt, hasClueTimes } from './time.js'; +import { formatTime, getBuzzClue, getBuzzTime, hasClueTimes } from './time.js'; import { escapeHTML } from '../../../../../shared/string-utils.js'; /** @@ -10,27 +10,26 @@ export function getCluesHTML (tossup, buzzpoints) { const label = `aria-label="Clues for question ${tossup.questionNumber}"`; if (hasClueTimes(tossup)) { - const counts = tossup.clues.map(() => ({ correct: 0, total: 0 })); + const counts = [...tossup.clues, 'End'].map(() => ({ correct: 0, total: 0 })); if (tossup.duration) { for (const buzz of buzzpoints) { - const time = getBuzzTime(buzz, tossup.duration); - if (time === null) { continue; } - const count = counts[getClueAt(tossup.clipBoundaries, time)]; + const count = counts[getBuzzClue(buzz, tossup)]; count.total++; if (buzz.points > 0) { count.correct++; } } } let html = `
`; - tossup.clues.forEach((clue, index) => { - const start = tossup.clipBoundaries[index]; - const { correct, total } = counts[index]; + counts.forEach(({ correct, total }, index) => { + const isEnd = index === tossup.clues.length; + if (isEnd && total === 0) { return; } + const start = isEnd ? Math.floor(tossup.duration * 1000) / 1000 : tossup.clipBoundaries[index]; const count = total === 0 ? '' : `${correct}/${total}`; html += ` - `; }); @@ -61,7 +60,7 @@ export function getBuzzTableHTML (tossup, buzzpoints) { const time = getBuzzTime(buzz, tossup.duration); data = `data-buzz-time="${time ?? tossup.duration}" tabindex="0"`; if (time !== null) { data += ` data-correct="${buzz.points > 0}"`; } - if (time !== null && hasClueTimes(tossup)) { data += ` data-clue="${getClueAt(tossup.clipBoundaries, time)}"`; } + if (hasClueTimes(tossup)) { data += ` data-clue="${getBuzzClue(buzz, tossup)}"`; } } const who = buzz.isYou ? 'you' : buzz.isTeammate ? 'teammate' : ''; const pointsClass = buzz.points > 0 ? 'text-success' : buzz.points < 0 ? 'text-danger' : 'text-body-secondary'; diff --git a/client/play/geoword/results/packet/index.js b/client/play/geoword/results/packet/index.js index 35b77e2ab..960b7be28 100644 --- a/client/play/geoword/results/packet/index.js +++ b/client/play/geoword/results/packet/index.js @@ -196,7 +196,12 @@ tabContent.addEventListener('click', event => { const section = button.closest('section'); const audio = section.querySelector('audio'); audio.currentTime = parseFloat(button.dataset.start); - audio.play().catch(console.error); + if ('end' in button.dataset) { + audio.pause(); + showPosition(section); + } else { + audio.play().catch(console.error); + } selectBuzz(section, null); scrollTableToClue(section, [...section.querySelectorAll('button[data-start]')].indexOf(button)); }); diff --git a/client/play/geoword/results/packet/time.js b/client/play/geoword/results/packet/time.js index efd97a8cd..16745c5bb 100644 --- a/client/play/geoword/results/packet/time.js +++ b/client/play/geoword/results/packet/time.js @@ -29,3 +29,13 @@ export function getBuzzTime (buzz, duration) { export function getClueAt (starts, time) { return Math.max(0, starts.findLastIndex(start => start <= time)); } + +/** + * @param {object} buzz + * @param {object} tossup - with clue times and a duration + * @returns {number} the buzz's clue, or the number of clues if it came after the audio ended + */ +export function getBuzzClue (buzz, { clipBoundaries, duration }) { + const time = getBuzzTime(buzz, duration); + return time === null ? clipBoundaries.length : getClueAt(clipBoundaries, time); +}