improved button
This commit is contained in:
parent
fd50466e61
commit
db052845c6
4 changed files with 50 additions and 26 deletions
|
|
@ -178,7 +178,7 @@
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!roomId){ alert('roomId manquant dans l\'URL'); }
|
if(!roomId){ showToast('roomId manquant dans l\'URL', { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
|
|
||||||
function connectAndJoin(){
|
function connectAndJoin(){
|
||||||
socket = io();
|
socket = io();
|
||||||
|
|
@ -408,8 +408,8 @@
|
||||||
try{ log('recv mine:detonated:private', evt); /* could show owner-specific UI later */ }catch(e){}
|
try{ log('recv mine:detonated:private', evt); /* could show owner-specific UI later */ }catch(e){}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.emit('room:join', { roomId, playerId }, (resp)=>{
|
socket.emit('room:join', { roomId, playerId }, (resp)=>{
|
||||||
if(resp && resp.error){ log('join error', resp); alert(resp.message || resp.error); return; }
|
if(resp && resp.error){ log('join error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); return; }
|
||||||
log('Rejoint room', resp);
|
log('Rejoint room', resp);
|
||||||
// remember assigned id/color from server
|
// remember assigned id/color from server
|
||||||
if(resp.playerId){
|
if(resp.playerId){
|
||||||
|
|
@ -698,7 +698,7 @@
|
||||||
if(!occ || occ.color === myShort){ log('select an enemy piece (second)'); return; }
|
if(!occ || occ.color === myShort){ log('select an enemy piece (second)'); return; }
|
||||||
// emit swap payload: sourceSquare + targetSquare
|
// emit swap payload: sourceSquare + targetSquare
|
||||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { sourceSquare: pendingCard.firstTarget, targetSquare: square } }, (resp)=>{
|
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { sourceSquare: pendingCard.firstTarget, targetSquare: square } }, (resp)=>{
|
||||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.message || resp.error); }
|
if(resp && resp.error){ log('card:play error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('inversion played', resp); }
|
else { log('inversion played', resp); }
|
||||||
});
|
});
|
||||||
// cleanup visuals
|
// cleanup visuals
|
||||||
|
|
@ -710,7 +710,7 @@
|
||||||
if(occupied){ log('square not empty for mine placement'); return; }
|
if(occupied){ log('square not empty for mine placement'); return; }
|
||||||
// send mine placement
|
// send mine placement
|
||||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
||||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.message || resp.error); }
|
if(resp && resp.error){ log('card:play error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('card played with target', resp); }
|
else { log('card played with target', resp); }
|
||||||
});
|
});
|
||||||
pendingCard = null; clearTargetHighlights(); return;
|
pendingCard = null; clearTargetHighlights(); return;
|
||||||
|
|
@ -719,7 +719,7 @@
|
||||||
if(!piece || piece.color !== myShort){ log('select one of your pieces'); return; }
|
if(!piece || piece.color !== myShort){ log('select one of your pieces'); return; }
|
||||||
if(piece.type && piece.type.toLowerCase() === 'k'){ log('cannot select king'); return; }
|
if(piece.type && piece.type.toLowerCase() === 'k'){ log('cannot select king'); return; }
|
||||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
||||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.message || resp.error); }
|
if(resp && resp.error){ log('card:play error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('card played with target', resp); }
|
else { log('card played with target', resp); }
|
||||||
});
|
});
|
||||||
pendingCard = null; clearTargetHighlights(); return;
|
pendingCard = null; clearTargetHighlights(); return;
|
||||||
|
|
@ -736,7 +736,7 @@
|
||||||
pendingCard = null; clearTargetHighlights(); return;
|
pendingCard = null; clearTargetHighlights(); return;
|
||||||
}
|
}
|
||||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square, promotion: promotionChoice } }, (resp)=>{
|
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square, promotion: promotionChoice } }, (resp)=>{
|
||||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.message || resp.error); }
|
if(resp && resp.error){ log('card:play error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('card played with promotion', resp); }
|
else { log('card played with promotion', resp); }
|
||||||
});
|
});
|
||||||
pendingCard = null; clearTargetHighlights();
|
pendingCard = null; clearTargetHighlights();
|
||||||
|
|
@ -747,7 +747,7 @@
|
||||||
if(!occ || occ.color === myShort){ log('select an enemy piece'); return; }
|
if(!occ || occ.color === myShort){ log('select an enemy piece'); return; }
|
||||||
if(occ.type && occ.type.toLowerCase() === 'k'){ log('cannot select king'); return; }
|
if(occ.type && occ.type.toLowerCase() === 'k'){ log('cannot select king'); return; }
|
||||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
||||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.message || resp.error); }
|
if(resp && resp.error){ log('card:play error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('card played with target', resp);
|
else { log('card played with target', resp);
|
||||||
// after server applied the card effect, request legal moves for the selected piece so the client
|
// after server applied the card effect, request legal moves for the selected piece so the client
|
||||||
// will receive the updated legal moves (including teleport to empty squares)
|
// will receive the updated legal moves (including teleport to empty squares)
|
||||||
|
|
@ -761,7 +761,7 @@
|
||||||
const occ = currentBoardState && Array.isArray(currentBoardState.pieces) && currentBoardState.pieces.find(p => p.square === square);
|
const occ = currentBoardState && Array.isArray(currentBoardState.pieces) && currentBoardState.pieces.find(p => p.square === square);
|
||||||
if(!occ || occ.color === myShort || !occ.type || occ.type.toLowerCase() !== 'q'){ log('select an enemy queen'); return; }
|
if(!occ || occ.color === myShort || !occ.type || occ.type.toLowerCase() !== 'q'){ log('select an enemy queen'); return; }
|
||||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
||||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.message || resp.error); }
|
if(resp && resp.error){ log('card:play error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('card played with target', resp);
|
else { log('card played with target', resp);
|
||||||
try{ setSelection(square); }catch(_){ }
|
try{ setSelection(square); }catch(_){ }
|
||||||
}
|
}
|
||||||
|
|
@ -773,7 +773,7 @@
|
||||||
if(!occ){ log('select a piece'); return; }
|
if(!occ){ log('select a piece'); return; }
|
||||||
if(occ.type && occ.type.toLowerCase() === 'k'){ log('cannot select king'); return; }
|
if(occ.type && occ.type.toLowerCase() === 'k'){ log('cannot select king'); return; }
|
||||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: pendingCard.cardId, payload: { targetSquare: square } }, (resp)=>{
|
||||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.error); }
|
if(resp && resp.error){ log('card:play error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('card played with target', resp); }
|
else { log('card played with target', resp); }
|
||||||
});
|
});
|
||||||
pendingCard = null; clearTargetHighlights(); return;
|
pendingCard = null; clearTargetHighlights(); return;
|
||||||
|
|
@ -795,7 +795,7 @@
|
||||||
const myShort = (myColor && myColor[0]) || '';
|
const myShort = (myColor && myColor[0]) || '';
|
||||||
if(!currentBoardState || currentBoardState.turn !== myShort){ log('not your turn'); return; }
|
if(!currentBoardState || currentBoardState.turn !== myShort){ log('not your turn'); return; }
|
||||||
socket.emit('game:move', { roomId, from, to }, (resp)=>{
|
socket.emit('game:move', { roomId, from, to }, (resp)=>{
|
||||||
if(resp && resp.error){ log('move error', resp); alert(resp.message || resp.error); }
|
if(resp && resp.error){ log('move error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('move sent', resp); }
|
else { log('move sent', resp); }
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|
@ -1136,16 +1136,16 @@
|
||||||
if(opponents.length === 1){
|
if(opponents.length === 1){
|
||||||
const targetPlayerId = opponents[0];
|
const targetPlayerId = opponents[0];
|
||||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: cid, payload: { targetPlayerId } }, (resp)=>{
|
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: cid, payload: { targetPlayerId } }, (resp)=>{
|
||||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.message || resp.error); }
|
if(resp && resp.error){ log('card:play error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('card played (steal card)', resp); }
|
else { log('card played (steal card)', resp); }
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// show modal to pick which player to steal from
|
// show modal to pick which player to steal from
|
||||||
showStealModal(handCounts, (targetPlayerId)=>{
|
showStealModal(handCounts, (targetPlayerId)=>{
|
||||||
if(!targetPlayerId) return; // canceled
|
if(!targetPlayerId) return; // canceled
|
||||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: cid, payload: { targetPlayerId } }, (resp)=>{
|
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: cid, payload: { targetPlayerId } }, (resp)=>{
|
||||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.message || resp.error); }
|
if(resp && resp.error){ log('card:play error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('card played (steal card)', resp); }
|
else { log('card played (steal card)', resp); }
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -1159,8 +1159,8 @@
|
||||||
}
|
}
|
||||||
// immediate-play card (no target required)
|
// immediate-play card (no target required)
|
||||||
const payload = {};
|
const payload = {};
|
||||||
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: cid, payload }, (resp)=>{
|
socket.emit('card:play', { roomId, playerId: myPlayerId, cardId: cid, payload }, (resp)=>{
|
||||||
if(resp && resp.error){ log('card:play error', resp); alert(resp.message || resp.error); }
|
if(resp && resp.error){ log('card:play error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
else { log('card played', resp); }
|
else { log('card played', resp); }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1184,7 +1184,7 @@
|
||||||
if(!socket) return;
|
if(!socket) return;
|
||||||
drawBtn.disabled = true;
|
drawBtn.disabled = true;
|
||||||
socket.emit('player:draw', { roomId }, (resp)=>{
|
socket.emit('player:draw', { roomId }, (resp)=>{
|
||||||
if(resp && resp.error){ log('player:draw error', resp); alert(resp.message || resp.error); drawBtn.disabled = false; return; }
|
if(resp && resp.error){ log('player:draw error', resp); showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); drawBtn.disabled = false; return; }
|
||||||
log('player:draw ok', resp);
|
log('player:draw ok', resp);
|
||||||
// server will send room:update which will hide/disable the button as needed
|
// server will send room:update which will hide/disable the button as needed
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
|
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
|
||||||
|
<script src="/toast.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function log(...args){ console.log(...args); }
|
function log(...args){ console.log(...args); }
|
||||||
|
|
||||||
|
|
@ -63,17 +64,17 @@
|
||||||
|
|
||||||
document.getElementById('join').addEventListener('click', async ()=>{
|
document.getElementById('join').addEventListener('click', async ()=>{
|
||||||
const roomId = document.getElementById('roomId').value.trim();
|
const roomId = document.getElementById('roomId').value.trim();
|
||||||
if(!roomId){ alert('Entrez roomId'); return; }
|
if(!roomId){ showToast('Entrez roomId', { background: 'rgba(200,60,60,0.95)' }); return; }
|
||||||
// verify room exists before redirecting
|
// verify room exists before redirecting
|
||||||
try{
|
try{
|
||||||
const resp = await fetch(`/rooms/${encodeURIComponent(roomId)}`);
|
const resp = await fetch(`/rooms/${encodeURIComponent(roomId)}`);
|
||||||
if(!resp.ok){
|
if(!resp.ok){
|
||||||
const j = await resp.json().catch(()=>({ error: 'room not found' }));
|
const j = await resp.json().catch(()=>({ error: 'room not found' }));
|
||||||
alert(j.error || 'room not found');
|
showToast(j.error || 'room not found', { background: 'rgba(200,60,60,0.95)' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}catch(e){
|
}catch(e){
|
||||||
alert('Erreur de connexion au serveur');
|
showToast('Erreur de connexion au serveur', { background: 'rgba(200,60,60,0.95)' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
22
public/toast.js
Normal file
22
public/toast.js
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Lightweight non-blocking toast used across pages
|
||||||
|
function showToast(message, opts){
|
||||||
|
try{
|
||||||
|
opts = opts || {};
|
||||||
|
const wrap = document.createElement('div');
|
||||||
|
wrap.className = 'cn-toast';
|
||||||
|
wrap.textContent = message || '';
|
||||||
|
wrap.style.position = 'fixed';
|
||||||
|
wrap.style.left = '50%';
|
||||||
|
wrap.style.transform = 'translateX(-50%)';
|
||||||
|
wrap.style.top = opts.top || '18px';
|
||||||
|
wrap.style.background = opts.background || 'rgba(0,0,0,0.8)';
|
||||||
|
wrap.style.color = opts.color || '#fff';
|
||||||
|
wrap.style.padding = '8px 12px';
|
||||||
|
wrap.style.borderRadius = '6px';
|
||||||
|
wrap.style.zIndex = 99999;
|
||||||
|
wrap.style.fontSize = '14px';
|
||||||
|
wrap.style.boxShadow = '0 6px 18px rgba(0,0,0,0.25)';
|
||||||
|
document.body.appendChild(wrap);
|
||||||
|
setTimeout(()=>{ try{ wrap.style.transition = 'opacity 300ms ease'; wrap.style.opacity = '0'; setTimeout(()=>{ try{ wrap.remove(); }catch(_){ } }, 320); }catch(_){ } }, opts.duration || 3500);
|
||||||
|
}catch(_){ }
|
||||||
|
}
|
||||||
|
|
@ -69,6 +69,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
|
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
|
||||||
|
<script src="/toast.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function qs(name){ const url = new URL(window.location.href); return url.searchParams.get(name); }
|
function qs(name){ const url = new URL(window.location.href); return url.searchParams.get(name); }
|
||||||
const roomId = qs('roomId');
|
const roomId = qs('roomId');
|
||||||
|
|
@ -98,7 +99,7 @@
|
||||||
|
|
||||||
function log(...args){ console.log(...args); }
|
function log(...args){ console.log(...args); }
|
||||||
|
|
||||||
if(!roomId){ alert('roomId manquant dans l\'URL'); }
|
if(!roomId){ showToast('roomId manquant dans l\'URL', { background: 'rgba(200,60,60,0.95)' }); }
|
||||||
|
|
||||||
function connectAndJoin(){
|
function connectAndJoin(){
|
||||||
socket = io();
|
socket = io();
|
||||||
|
|
@ -270,7 +271,7 @@
|
||||||
document.getElementById('startBtn').addEventListener('click', ()=>{
|
document.getElementById('startBtn').addEventListener('click', ()=>{
|
||||||
if(!socket) return;
|
if(!socket) return;
|
||||||
socket.emit('game:start', { roomId }, (resp)=>{
|
socket.emit('game:start', { roomId }, (resp)=>{
|
||||||
if(resp && resp.error){ log('start error', resp); alert(resp.error); return; }
|
if(resp && resp.error){ log('start error', resp); showToast(resp.error || resp.message || 'Erreur', { background: 'rgba(200,60,60,0.95)' }); return; }
|
||||||
log('game:start acknowledged');
|
log('game:start acknowledged');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -281,7 +282,7 @@
|
||||||
if(!socket) return;
|
if(!socket) return;
|
||||||
const enabled = !!autoDrawToggleEl.checked;
|
const enabled = !!autoDrawToggleEl.checked;
|
||||||
socket.emit('room:auto_draw:set', { roomId, enabled }, (resp)=>{
|
socket.emit('room:auto_draw:set', { roomId, enabled }, (resp)=>{
|
||||||
if(resp && resp.error){ log('auto-draw error', resp); alert(resp.error); return; }
|
if(resp && resp.error){ log('auto-draw error', resp); showToast(resp.error || resp.message || 'Erreur', { background: 'rgba(200,60,60,0.95)' }); return; }
|
||||||
log('auto-draw updated', resp);
|
log('auto-draw updated', resp);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -293,7 +294,7 @@
|
||||||
if(!socket) return;
|
if(!socket) return;
|
||||||
const enabled = !!noRemiseToggleEl.checked;
|
const enabled = !!noRemiseToggleEl.checked;
|
||||||
socket.emit('room:no_remise:set', { roomId, enabled }, (resp)=>{
|
socket.emit('room:no_remise:set', { roomId, enabled }, (resp)=>{
|
||||||
if(resp && resp.error){ log('no-remise error', resp); alert(resp.error); return; }
|
if(resp && resp.error){ log('no-remise error', resp); showToast(resp.error || resp.message || 'Erreur', { background: 'rgba(200,60,60,0.95)' }); return; }
|
||||||
log('no-remise updated', resp);
|
log('no-remise updated', resp);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -411,7 +412,7 @@
|
||||||
const link = `${window.location.origin}/waiting.html?roomId=${encodeURIComponent(roomId)}`;
|
const link = `${window.location.origin}/waiting.html?roomId=${encodeURIComponent(roomId)}`;
|
||||||
try{
|
try{
|
||||||
await navigator.clipboard.writeText(link);
|
await navigator.clipboard.writeText(link);
|
||||||
alert('Lien d\'invitation copié dans le presse-papier');
|
showToast('Lien d\'invitation copié dans le presse-papier', { background: 'rgba(40,160,40,0.95)' });
|
||||||
}catch(e){
|
}catch(e){
|
||||||
// fallback
|
// fallback
|
||||||
window.prompt('Copie le lien ci-dessous', link);
|
window.prompt('Copie le lien ci-dessous', link);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue