asd
This commit is contained in:
parent
ef045f9353
commit
ff5d6ab91d
7 changed files with 388 additions and 84 deletions
|
|
@ -136,6 +136,73 @@
|
|||
background: rgba(255,255,255,.15);
|
||||
}
|
||||
|
||||
.lobby-list-wrap {
|
||||
margin-top: 16px;
|
||||
text-align: left;
|
||||
}
|
||||
.lobby-list-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.lobby-list-title {
|
||||
font-size: .72rem;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
color: rgba(255,255,255,.55);
|
||||
}
|
||||
.btn-refresh-lobbies {
|
||||
background: rgba(255,255,255,.1);
|
||||
border: 1px solid rgba(255,255,255,.18);
|
||||
color: rgba(255,255,255,.85);
|
||||
border-radius: 8px;
|
||||
padding: 5px 9px;
|
||||
font-size: .72rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-refresh-lobbies:hover { background: rgba(255,255,255,.18); }
|
||||
#lobby-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
max-height: 210px;
|
||||
overflow-y: auto;
|
||||
padding-right: 2px;
|
||||
}
|
||||
.lobby-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
background: rgba(255,255,255,.06);
|
||||
border: 1px solid rgba(255,255,255,.12);
|
||||
border-radius: 10px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
.lobby-id { font-family: ui-monospace, Menlo, Consolas, monospace; color: var(--gold); font-size: .86rem; }
|
||||
.lobby-meta { font-size: .72rem; color: rgba(255,255,255,.6); margin-top: 2px; }
|
||||
.btn-join-lobby {
|
||||
background: var(--gold);
|
||||
color: #1a1a1a;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 7px 10px;
|
||||
font-size: .78rem;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-join-lobby:hover { opacity: .9; }
|
||||
.lobby-empty {
|
||||
font-size: .78rem;
|
||||
color: rgba(255,255,255,.55);
|
||||
background: rgba(255,255,255,.04);
|
||||
border: 1px dashed rgba(255,255,255,.15);
|
||||
border-radius: 10px;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ══════════════════════════════
|
||||
TABLE LAYOUT
|
||||
══════════════════════════════ */
|
||||
|
|
@ -957,6 +1024,14 @@
|
|||
<div class="invite-id" id="invite-id-text" onclick="copyCode()" title="Klikni pro zkopírování"></div>
|
||||
<div class="invite-hint">Klikni na kód pro zkopírování · Čekáme na další hráče…</div>
|
||||
</div>
|
||||
|
||||
<div class="lobby-list-wrap">
|
||||
<div class="lobby-list-head">
|
||||
<div class="lobby-list-title">Veřejné lobby</div>
|
||||
<button class="btn-refresh-lobbies" onclick="loadLobbies()">Obnovit</button>
|
||||
</div>
|
||||
<div id="lobby-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -1128,6 +1203,7 @@ let restartFallbackTimer = null;
|
|||
let joinPending = false;
|
||||
let tableVisible = false;
|
||||
let currentScriptOpen = false;
|
||||
let lobbyPollTimer = null;
|
||||
|
||||
const SUIT_ICONS = { hearts:'♥', diamonds:'♦', spades:'♠', clubs:'♣' };
|
||||
const SUIT_NAMES = { hearts:'Srdce', diamonds:'Kára', spades:'Piky', clubs:'Kříže' };
|
||||
|
|
@ -1206,12 +1282,21 @@ function joinExisting() {
|
|||
sendJoin();
|
||||
}
|
||||
|
||||
function joinLobby(id) {
|
||||
myName = document.getElementById('player-name').value.trim() || 'Hráč';
|
||||
gameId = String(id || '').toLowerCase();
|
||||
if (!gameId) return;
|
||||
document.getElementById('game-id-input').value = gameId.toUpperCase();
|
||||
sendJoin();
|
||||
}
|
||||
|
||||
function sendJoin() {
|
||||
joinPending = true;
|
||||
ws.send(JSON.stringify({ type:'join', player_id:myId, player_name:myName, game_id:gameId }));
|
||||
}
|
||||
|
||||
function switchToTable() {
|
||||
stopLobbyPolling();
|
||||
document.getElementById('lobby').style.display = 'none';
|
||||
document.getElementById('table').style.display = 'flex';
|
||||
document.getElementById('topbar-id').textContent = gameId.toUpperCase();
|
||||
|
|
@ -1222,6 +1307,50 @@ function copyCode() {
|
|||
navigator.clipboard.writeText(gameId.toUpperCase()).then(() => toast('Kód zkopírován: ' + gameId.toUpperCase()));
|
||||
}
|
||||
|
||||
async function loadLobbies() {
|
||||
const list = document.getElementById('lobby-list');
|
||||
if (!list) return;
|
||||
try {
|
||||
const resp = await fetch('/api/lobbies');
|
||||
if (!resp.ok) throw new Error(resp.statusText);
|
||||
const data = await resp.json();
|
||||
const lobbies = data.lobbies || [];
|
||||
if (lobbies.length === 0) {
|
||||
list.innerHTML = `<div class="lobby-empty">Zatím žádné čekající hry</div>`;
|
||||
return;
|
||||
}
|
||||
list.innerHTML = lobbies.map((l) => {
|
||||
const players = (l.players || []).map(escHtml).join(', ');
|
||||
const rules = l.has_rules ? ' · vlastní pravidla' : '';
|
||||
const safeID = escHtml(String(l.game_id || '').toUpperCase());
|
||||
const onclickID = String(l.game_id || '').replace(/'/g, "\\'");
|
||||
return `
|
||||
<div class="lobby-item">
|
||||
<div>
|
||||
<div class="lobby-id">${safeID}</div>
|
||||
<div class="lobby-meta">${l.player_count || 0}/4 hráči${rules}${players ? ` · ${players}` : ''}</div>
|
||||
</div>
|
||||
<button class="btn-join-lobby" onclick="joinLobby('${onclickID}')">Připojit</button>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
} catch (err) {
|
||||
list.innerHTML = `<div class="lobby-empty">Nelze načíst lobby (${escHtml(err.message)})</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
function startLobbyPolling() {
|
||||
stopLobbyPolling();
|
||||
loadLobbies();
|
||||
lobbyPollTimer = setInterval(loadLobbies, 5000);
|
||||
}
|
||||
|
||||
function stopLobbyPolling() {
|
||||
if (!lobbyPollTimer) return;
|
||||
clearInterval(lobbyPollTimer);
|
||||
lobbyPollTimer = null;
|
||||
}
|
||||
|
||||
// ── Game actions ───────────────────────────────────────────────────────
|
||||
function startGame() {
|
||||
ws.send(JSON.stringify({ type:'start', game_id:gameId }));
|
||||
|
|
@ -1836,7 +1965,11 @@ function highlight(code) {
|
|||
function checkUrlJoin() {
|
||||
const params = new URLSearchParams(location.search);
|
||||
const code = params.get('game');
|
||||
if (code) document.getElementById('game-id-input').value = code.toLowerCase();
|
||||
if (code) {
|
||||
document.getElementById('game-id-input').value = code.toLowerCase();
|
||||
} else {
|
||||
startLobbyPolling();
|
||||
}
|
||||
}
|
||||
|
||||
connect();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue