<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>出題者ページ</title>
<link rel="stylesheet" href="host.css">
<style>
.answer-buttons, .teams-section { margin-top: 15px; border-top: 1px solid #ccc; padding-top: 15px; }
.answer-buttons button { font-size: 1.1em; padding: 8px 16px; cursor: pointer; border-radius: 5px; }
#correctBtn { background-color: #28a745; color: white; border: 1px solid #28a745; }
#incorrectBtn { background-color: #dc3545; color: white; border: 1px solid #dc3545; }
/* 非活性化されたボタンのスタイル */
.answer-buttons button:disabled { background-color: #6c757d; border-color: #6c757d; cursor: not-allowed; }
#announce { white-space: pre-wrap; }
#teamsTable { width: 100%; border-collapse: collapse; margin-top: 10px; }
#teamsTable th, #teamsTable td { border: 1px solid #ddd; padding: 8px; text-align: left; vertical-align: top; }
#teamsTable th { background-color: #f2f2f2; }
#teamsTable td:last-child { min-height: 1.5em; }
</style>
</head>
<body>
<h1>出題者ページ</h1>
<p id="currentSong">現在の曲: 未選択</p>
<div class="button-group">
<button id="prevBtn">前の曲</button>
<button id="nextBtn">🎶 次の曲</button>
<button id="playBtn">▶ 再生</button>
<button id="pauseBtn">⏸ 一時停止</button>
<button id="stopBtn">⏹ 停止</button>
<button id="resetBtn">🔁 挙手リセット</button>
</div>
<pre id="announce">誰も挙手していません</pre>
<div class="answer-buttons">
<button id="correctBtn">⭕ 正解</button>
<button id="incorrectBtn">❌ 不正解</button>
</div>
<div class="teams-section">
<h2>参加チーム一覧</h2>
<table id="teamsTable">
<thead>
<tr>
<th style="width: 15%;">グループ</th>
<!-- ▼▼▼【変更】ポイント列を追加 ▼▼▼ -->
<th style="width: 15%;">ポイント</th>
<th>参加メンバー</th>
</tr>
</thead>
<tbody>
<!-- ▼▼▼【変更】ポイント表示用のセルを追加 ▼▼▼ -->
<tr><td>1班</td><td id="points-1">0</td><td id="members-1">(まだ誰もいません)</td></tr>
<tr><td>2班</td><td id="points-2">0</td><td id="members-2">(まだ誰もいません)</td></tr>
<tr><td>3班</td><td id="points-3">0</td><td id="members-3">(まだ誰もいません)</td></tr>
<tr><td>4班</td><td id="points-4">0</td><td id="members-4">(まだ誰もいません)</td></tr>
<tr><td>5班</td><td id="points-5">0</td><td id="members-5">(まだ誰もいません)</td></tr>
</tbody>
</table>
</div>
<script>
const songLabel = document.getElementById("currentSong");
const playBtn = document.getElementById("playBtn");
const pauseBtn = document.getElementById("pauseBtn");
const stopBtn = document.getElementById("stopBtn");
const announce = document.getElementById("announce");
const resetBtn = document.getElementById("resetBtn");
const prevBtn = document.getElementById("prevBtn");
const nextBtn = document.getElementById("nextBtn");
const correctBtn = document.getElementById("correctBtn");
const incorrectBtn = document.getElementById("incorrectBtn");
let musicFiles = [];
let currentIndex = -1;
// ▼▼▼【追加】初期状態では正解・不正解ボタンを無効化 ▼▼▼
correctBtn.disabled = true;
incorrectBtn.disabled = true;
fetch(`http://192.168.0.145:8890/music_list.json`)
.then(res => res.json())
.then(data => {
musicFiles = data.files.sort((a, b) => (parseInt(a.match(/^\d+/), 10) || 0) - (parseInt(b.match(/^\d+/), 10) || 0));
});
const conn = new WebSocket(`ws://${location.hostname}:8888`);
// --- ボタンのイベントリスナーは変更なし ---
playBtn.addEventListener("click", () => { if (currentIndex === -1) return; conn.send(JSON.stringify({ type: "play" })); });
pauseBtn.addEventListener("click", () => conn.send(JSON.stringify({ type: "pause" })));
stopBtn.addEventListener("click", () => conn.send(JSON.stringify({ type: "stop" })));
resetBtn.addEventListener("click", () => conn.send(JSON.stringify({ type: "reset" })));
prevBtn.addEventListener("click", () => { /* ... */ });
nextBtn.addEventListener("click", () => { /* ... */ });
correctBtn.addEventListener("click", () => {
if (currentIndex === -1) return;
conn.send(JSON.stringify({ type: "correct", answer: musicFiles[currentIndex] }));
});
incorrectBtn.addEventListener("click", () => conn.send(JSON.stringify({ type: "incorrect" })));
// prev/nextの省略部分(変更なしなので)
prevBtn.addEventListener("click", () => { if (musicFiles.length === 0) return; currentIndex = (currentIndex - 1 + musicFiles.length) % musicFiles.length; const file = musicFiles[currentIndex]; songLabel.textContent = `現在の曲: ${file}`; conn.send(JSON.stringify({ type: "select", file: file })); });
nextBtn.addEventListener("click", () => { if (musicFiles.length === 0) return; currentIndex = (currentIndex + 1) % musicFiles.length; const file = musicFiles[currentIndex]; songLabel.textContent = `現在の曲: ${file}`; conn.send(JSON.stringify({ type: "select", file: file })); });
conn.onmessage = ev => {
let msg;
try { msg = JSON.parse(ev.data); } catch { return; }
switch (msg.type) {
case "select":
announce.textContent = "曲選択完了、待機中...";
break;
case "announce":
const queue = msg.queue || [];
if (queue.length === 0) {
announce.textContent = "誰も挙手していません";
// ▼▼▼【変更】ボタンの有効/無効を切り替え ▼▼▼
correctBtn.disabled = true;
incorrectBtn.disabled = true;
} else {
announce.textContent = queue.map((p, i) => `${i + 1}. ${p.group} - ${p.name} さん`).join("\n");
// ▼▼▼【変更】ボタンの有効/無効を切り替え ▼▼▼
correctBtn.disabled = false;
incorrectBtn.disabled = false;
}
break;
case "update_teams":
const participants = msg.teams || [];
const points = msg.points || {};
const teamMembers = { '1班': [], '2班': [], '3班': [], '4班': [], '5班': [] };
participants.forEach(p => {
if (teamMembers[p.group]) {
teamMembers[p.group].push(p.name);
}
});
for (let i = 1; i <= 5; i++) {
const groupName = `${i}班`;
const memberCell = document.getElementById(`members-${i}`);
const members = teamMembers[groupName];
if (members.length > 0) {
memberCell.innerHTML = members.join('<br>');
} else {
memberCell.textContent = '(まだ誰もいません)';
}
// ▼▼▼【変更】ポイント表示を更新 ▼▼▼
const pointsCell = document.getElementById(`points-${i}`);
pointsCell.textContent = points[groupName] || 0;
}
break;
}
};
conn.onopen = () => console.log("WebSocket 接続成功!");
conn.onerror = (e) => console.error("WebSocket エラー:", e);
conn.onclose = () => { console.log("WebSocket 切断"); songLabel.textContent = "サーバーとの接続が切れました。"; };
</script>
</body>
</html>