feat: implement answer submission and scoring system for guessing game
This commit is contained in:
@@ -38,6 +38,11 @@ export const $leaveRoom = el('leaveRoom');
|
||||
export const $earnToken = el('earnToken');
|
||||
export const $dashboardList = el('dashboardList');
|
||||
export const $toast = el('toast');
|
||||
// Answer form elements
|
||||
export const $answerForm = el('answerForm');
|
||||
export const $guessTitle = el('guessTitle');
|
||||
export const $guessArtist = el('guessArtist');
|
||||
export const $answerResult = el('answerResult');
|
||||
|
||||
export function showLobby() { $lobby.classList.remove('hidden'); $room.classList.add('hidden'); }
|
||||
export function showRoom() { $lobby.classList.add('hidden'); $room.classList.remove('hidden'); }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { $audio, $copyRoomCode, $leaveRoom, $nameDisplay, $nameLobby, $npArtist, $npTitle, $npYear, $pauseBtn, $placeBtn, $readyChk, $roomId, $roomCode, $slotSelect, $startGame, $volumeSlider, $playBtn, $nextBtn, $createRoom, $joinRoom, $lobby, $room, $setNameLobby } from './dom.js';
|
||||
import { $audio, $copyRoomCode, $leaveRoom, $nameDisplay, $nameLobby, $npArtist, $npTitle, $npYear, $pauseBtn, $placeBtn, $readyChk, $roomId, $roomCode, $slotSelect, $startGame, $volumeSlider, $playBtn, $nextBtn, $createRoom, $joinRoom, $lobby, $room, $setNameLobby, $guessTitle, $guessArtist, $answerResult } from './dom.js';
|
||||
import { state } from './state.js';
|
||||
import { connectWS, sendMsg } from './ws.js';
|
||||
import { renderRoom } from './render.js';
|
||||
@@ -44,6 +44,10 @@ function handlePlayTrack(msg) {
|
||||
$npTitle.textContent = '???';
|
||||
$npArtist.textContent = '';
|
||||
$npYear.textContent = '';
|
||||
// reset answer UI
|
||||
if ($guessTitle) $guessTitle.value = '';
|
||||
if ($guessArtist) $guessArtist.value = '';
|
||||
if ($answerResult) { $answerResult.textContent=''; $answerResult.className='mt-1 text-sm'; }
|
||||
try {
|
||||
$audio.preload = 'auto';
|
||||
} catch {}
|
||||
@@ -151,6 +155,25 @@ function onMessage(ev) {
|
||||
case 'game_ended':
|
||||
handleGameEnded(msg);
|
||||
break;
|
||||
case 'answer_result': {
|
||||
if ($answerResult) {
|
||||
if (!msg.ok) {
|
||||
$answerResult.textContent = '⛔ Eingabe ungültig oder gerade nicht möglich';
|
||||
$answerResult.className = 'mt-1 text-sm text-rose-600';
|
||||
} else {
|
||||
const okBoth = !!(msg.correctTitle && msg.correctArtist);
|
||||
const parts = [];
|
||||
parts.push(msg.correctTitle ? 'Titel ✓' : 'Titel ✗');
|
||||
parts.push(msg.correctArtist ? 'Künstler ✓' : 'Künstler ✗');
|
||||
let coin = '';
|
||||
if (msg.awarded) coin = ' +1 Token';
|
||||
else if (msg.alreadyAwarded) coin = ' (bereits erhalten)';
|
||||
$answerResult.textContent = `${parts.join(' · ')}${coin}`;
|
||||
$answerResult.className = okBoth ? 'mt-1 text-sm text-emerald-600' : 'mt-1 text-sm text-amber-600';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -241,6 +264,20 @@ function wireUi() {
|
||||
});
|
||||
$roomId.style.cursor = 'pointer';
|
||||
}
|
||||
// Answer submit
|
||||
const form = document.getElementById('answerForm');
|
||||
if (form) {
|
||||
form.addEventListener('submit', (e) => {
|
||||
e.preventDefault();
|
||||
const title = ($guessTitle?.value || '').trim();
|
||||
const artist = ($guessArtist?.value || '').trim();
|
||||
if (!title || !artist) {
|
||||
if ($answerResult) { $answerResult.textContent = 'Bitte Titel und Künstler eingeben'; $answerResult.className = 'mt-1 text-sm text-amber-600'; }
|
||||
return;
|
||||
}
|
||||
sendMsg({ type: 'submit_answer', guess: { title, artist } });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// boot
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { state } from './state.js';
|
||||
import { badgeColorForYear } from '../utils/colors.js';
|
||||
import { $dashboardList, $guesser, $lobby, $nameDisplay, $nextArea, $np, $placeArea, $readyChk, $revealBanner, $room, $roomId, $slotSelect, $startGame, $status, $timeline, $tokens } from './dom.js';
|
||||
import { $answerForm, $answerResult, $dashboardList, $guesser, $lobby, $nameDisplay, $nextArea, $np, $placeArea, $readyChk, $revealBanner, $room, $roomId, $slotSelect, $startGame, $status, $timeline, $tokens } from './dom.js';
|
||||
|
||||
export function renderRoom(room) {
|
||||
state.room = room; if (!room) { $lobby.classList.remove('hidden'); $room.classList.add('hidden'); return; }
|
||||
@@ -87,6 +87,10 @@ export function renderRoom(room) {
|
||||
if ($revealBanner) { const inReveal = room.state.phase === 'reveal'; if (!inReveal) { $revealBanner.className = 'hidden'; $revealBanner.textContent=''; } }
|
||||
const canNext = room.state.status==='playing' && room.state.phase==='reveal' && (isHost || room.state.currentGuesser===state.playerId);
|
||||
if ($nextArea) $nextArea.classList.toggle('hidden', !canNext);
|
||||
// Answer form visible during guess phase while a track is active
|
||||
const showAnswer = room.state.status==='playing' && room.state.phase==='guess' && !!room.state.currentTrack;
|
||||
if ($answerForm) $answerForm.classList.toggle('hidden', !showAnswer);
|
||||
if ($answerResult && !showAnswer) { $answerResult.textContent=''; $answerResult.className='mt-1 text-sm'; }
|
||||
}
|
||||
|
||||
export function shortName(id) {
|
||||
|
||||
Reference in New Issue
Block a user