selection fonctionnelle
This commit is contained in:
parent
db052845c6
commit
4cf1aca7e4
2 changed files with 90 additions and 3 deletions
|
|
@ -267,11 +267,26 @@
|
|||
|
||||
connectAndJoin();
|
||||
|
||||
// Start button handler (host)
|
||||
// Start button handler (host) — ensure custom deck is applied before starting
|
||||
document.getElementById('startBtn').addEventListener('click', ()=>{
|
||||
if(!socket) return;
|
||||
// If custom draw is enabled and host selected cards, send the deck first
|
||||
try{
|
||||
if(customDrawToggleEl && customDrawToggleEl.checked && selectedCards.size && myPlayerId && roomHostId && myPlayerId === roomHostId){
|
||||
socket.emit('room:deck:set', { roomId, selected: Array.from(selectedCards) }, (deckResp)=>{
|
||||
if(deckResp && deckResp.error){ showToast(deckResp.message || deckResp.error, { background: 'rgba(200,60,60,0.95)' }); return; }
|
||||
// now start the game
|
||||
socket.emit('game:start', { roomId }, (resp)=>{
|
||||
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');
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
}catch(_){ }
|
||||
// fallback: start immediately
|
||||
socket.emit('game:start', { roomId }, (resp)=>{
|
||||
if(resp && resp.error){ log('start error', resp); showToast(resp.error || resp.message || 'Erreur', { background: 'rgba(200,60,60,0.95)' }); 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');
|
||||
});
|
||||
});
|
||||
|
|
@ -311,6 +326,26 @@
|
|||
const checked = !!customDrawToggleEl.checked;
|
||||
log('custom-draw toggled (minimal)', { checked });
|
||||
if(customCardsSection) customCardsSection.style.display = checked ? 'block' : 'none';
|
||||
// When toggling the checkbox, inform server: if unchecked, clear custom deck on server so default deck is used.
|
||||
try{
|
||||
if(socket && socket.connected && myPlayerId && roomHostId && myPlayerId === roomHostId){
|
||||
if(!checked){
|
||||
// inform server to revert to default deck
|
||||
socket.emit('room:deck:set', { roomId, selected: [] }, (resp)=>{
|
||||
if(resp && resp.error) showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' });
|
||||
else showToast('Pioche personnalisée désactivée — pioche par défaut restaurée', { background: 'rgba(40,160,40,0.95)' });
|
||||
});
|
||||
} else {
|
||||
// if checked and we already have a selection, push it to server
|
||||
if(selectedCards.size){
|
||||
socket.emit('room:deck:set', { roomId, selected: Array.from(selectedCards) }, (resp)=>{
|
||||
if(resp && resp.error) showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' });
|
||||
else showToast('Pioche personnalisée activée', { background: 'rgba(40,160,40,0.95)' });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(_){ }
|
||||
if(checked){
|
||||
// fetch card list and render simple names
|
||||
if(customCardsContainer){
|
||||
|
|
@ -379,6 +414,15 @@
|
|||
selectMark.style.display = 'flex';
|
||||
}
|
||||
saveSelection();
|
||||
// if we're the host and connected AND custom-draw is enabled, update the server's custom deck selection
|
||||
try{
|
||||
if(socket && socket.connected && myPlayerId && roomHostId && myPlayerId === roomHostId && customDrawToggleEl && customDrawToggleEl.checked){
|
||||
socket.emit('room:deck:set', { roomId, selected: Array.from(selectedCards) }, (resp)=>{
|
||||
if(resp && resp.error){ showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' }); }
|
||||
else { showToast('Pioche personnalisée mise à jour', { background: 'rgba(40,160,40,0.95)' }); }
|
||||
});
|
||||
}
|
||||
}catch(_){ }
|
||||
});
|
||||
|
||||
grid.appendChild(cardEl);
|
||||
|
|
@ -400,6 +444,15 @@
|
|||
else { selectedCards.delete(id); el.classList.remove('selected'); if(mark) mark.style.display = 'none'; }
|
||||
});
|
||||
saveSelection();
|
||||
// send selection to server if host AND custom-draw enabled
|
||||
try{
|
||||
if(socket && socket.connected && myPlayerId && roomHostId && myPlayerId === roomHostId && customDrawToggleEl && customDrawToggleEl.checked){
|
||||
socket.emit('room:deck:set', { roomId, selected: Array.from(selectedCards) }, (resp)=>{
|
||||
if(resp && resp.error) showToast(resp.message || resp.error, { background: 'rgba(200,60,60,0.95)' });
|
||||
else showToast('Pioche personnalisée mise à jour', { background: 'rgba(40,160,40,0.95)' });
|
||||
});
|
||||
}
|
||||
}catch(_){ }
|
||||
}
|
||||
if(customSelectAllBtn) customSelectAllBtn.addEventListener('click', (e)=>{ e.preventDefault(); setAllVisible(true); });
|
||||
if(customDeselectAllBtn) customDeselectAllBtn.addEventListener('click', (e)=>{ e.preventDefault(); setAllVisible(false); });
|
||||
|
|
|
|||
36
server.js
36
server.js
|
|
@ -303,7 +303,9 @@ function buildDefaultDeck(){
|
|||
let ascii = normalized;
|
||||
try{ ascii = ascii.normalize('NFD').replace(/\p{Diacritic}/gu, ''); }catch(e){ /* ignore if normalize unsupported */ }
|
||||
const cardId = ascii.replace(/[^a-z0-9]+/gi,'_').toLowerCase();
|
||||
return { id: uuidv4().slice(0,8), cardId, title: cap(normalized), description: desc };
|
||||
// Use deterministic id equal to the slug so clients and server agree on identifiers across requests
|
||||
const id = cardId;
|
||||
return { id, cardId, title: cap(normalized), description: desc };
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1251,6 +1253,38 @@ io.on('connection', (socket) => {
|
|||
cb && cb({ ok: true });
|
||||
});
|
||||
|
||||
// Host can set a custom deck for the room (selected list of card ids). Only host may change it.
|
||||
socket.on('room:deck:set', ({ roomId, selected }, cb) => {
|
||||
const room = rooms.get(roomId);
|
||||
if(!room) return cb && cb({ error: 'room not found', message: "Aucune salle trouvée." });
|
||||
const sender = socket.data.playerId;
|
||||
if(!sender) return cb && cb({ error: 'not joined', message: "Vous n'avez pas rejoint la salle." });
|
||||
if(room.hostId !== sender) return cb && cb({ error: 'only host can set deck', message: "Seul l'hôte peut définir la pioche." });
|
||||
try{
|
||||
// selected is expected to be an array of card identifiers (either id or cardId)
|
||||
const sel = Array.isArray(selected) ? selected : [];
|
||||
// Build a lookup from the canonical default deck and current room deck
|
||||
const master = buildDefaultDeck();
|
||||
const pool = (room.deck && Array.isArray(room.deck) && room.deck.length) ? room.deck.concat(master) : master;
|
||||
const byId = {};
|
||||
pool.forEach(c => { if(c && c.id) byId[c.id] = c; if(c && c.cardId) byId[c.cardId] = c; });
|
||||
// Map selected ids to card objects, preserving order. If a selected id is unknown, ignore it.
|
||||
const newDeck = [];
|
||||
sel.forEach(sid => { const c = byId[sid]; if(c) newDeck.push(Object.assign({}, c)); });
|
||||
if(newDeck.length === 0){
|
||||
// empty selection -> revert to default deck
|
||||
room.deck = buildDefaultDeck();
|
||||
} else {
|
||||
room.deck = newDeck;
|
||||
}
|
||||
// reset discard and hands so the new deck applies for the upcoming game
|
||||
room.discard = room.discard || [];
|
||||
// inform players
|
||||
sendRoomUpdate(room);
|
||||
return cb && cb({ ok: true, deckCount: room.deck.length });
|
||||
}catch(err){ console.error('room:deck:set error', err); return cb && cb({ error: 'server_error' }); }
|
||||
});
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
const roomId = socket.data.roomId;
|
||||
if (!roomId) return;
|
||||
|
|
|
|||
Loading…
Reference in a new issue