Weiter gebaut
Some checks failed
Host-Based Deploy (Java 21 Fix) / build-and-run (push) Has been cancelled

This commit is contained in:
2026-04-25 16:56:35 +02:00
parent e4b762f905
commit 4f2048bdc8
242 changed files with 14108 additions and 1770 deletions

View File

@@ -69,13 +69,36 @@
.card-field:last-child { margin-bottom: 0; }
.card-field > label { font-size: 0.8rem; color: #aaa; margin: 0 0 0.5rem 0; display: block; }
.check-group { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.check-group--two-col { display: grid; grid-template-columns: 1fr 1fr; }
.check-item { display: inline-flex; align-items: flex-start; gap: 0.45rem; background: var(--color-secondary); border: 1px solid transparent; border-radius: 6px; padding: 0.4rem 0.7rem; cursor: pointer; transition: border-color 0.15s; user-select: none; }
.check-group--two-col { display: grid; grid-template-columns: repeat(auto-fill, minmax(145px, 1fr)); }
.check-item { display: inline-flex; align-items: flex-start; gap: 0.45rem; background: var(--color-secondary); border: 1px solid transparent; border-radius: 6px; padding: 0.4rem 0.7rem; cursor: pointer; transition: border-color 0.15s; user-select: none; position: relative; }
.check-item.is-checked { border-color: var(--color-primary); }
.check-item.is-disabled { opacity: 0.5; pointer-events: none; cursor: default; }
.check-item input { accent-color: var(--color-primary); width: auto; margin-top: 0.15rem; cursor: pointer; flex-shrink: 0; }
.check-item-label { font-size: 0.88rem; color: var(--color-text); line-height: 1.3; }
.check-item-desc { display: block; font-size: 0.72rem; color: var(--color-muted); margin-top: 0.1rem; }
.check-item-label { font-size: 0.88rem; color: var(--color-text); line-height: 1.3; display: flex; align-items: center; gap: 0.2rem; flex-wrap: wrap; }
.check-item-desc { display: none; }
.check-item-tooltip {
display: none; position: absolute; bottom: calc(100% + 6px); left: 0;
background: var(--color-card); border: 1px solid var(--color-secondary);
border-radius: 6px; padding: 0.4rem 0.65rem;
font-size: 0.78rem; color: var(--color-muted); line-height: 1.4;
width: max-content; max-width: 210px;
z-index: 50; pointer-events: none;
box-shadow: 0 4px 12px rgba(0,0,0,0.35);
}
.check-item:hover .check-item-tooltip { display: block; }
.check-item-info-btn {
display: none; background: none; border: 1px solid var(--color-muted);
border-radius: 50%; width: 1.1rem; height: 1.1rem; font-size: 0.62rem;
color: var(--color-muted); cursor: pointer; padding: 0; line-height: 1;
flex-shrink: 0; font-style: normal; font-weight: normal;
align-items: center; justify-content: center;
}
.check-item-info-btn.active { border-color: var(--color-primary); color: var(--color-primary); }
.check-item-desc-mobile { display: none; font-size: 0.72rem; color: var(--color-muted); margin-top: 0.25rem; line-height: 1.4; }
@media (max-width: 679px) {
.check-item:hover .check-item-tooltip { display: none; }
.check-item-info-btn { display: inline-flex; }
}
.field-error { font-size: 0.78rem; color: var(--color-primary); margin-top: 0.3rem; display: none; }
.add-player-btn { width: 100%; background: transparent; border: 1px dashed var(--color-secondary); color: var(--color-muted); padding: 0.7rem; border-radius: 8px; font-size: 0.88rem; font-weight: normal; cursor: pointer; transition: border-color 0.15s, color 0.15s; margin-top: 0.5rem; }
.add-player-btn:hover { border-color: var(--color-primary); color: var(--color-text); background: transparent; }
@@ -163,7 +186,6 @@
<div class="main" id="setupView" style="display:none;">
<div class="content">
<h1>Vanilla Game Session einrichten</h1>
<p id="pageSubtitle" style="margin-bottom:1.5rem;">Session einrichten</p>
<!-- Accordion 1: Grundeinstellungen -->
<div class="acc-item">
@@ -191,7 +213,7 @@
<div class="acc-body" id="acc-aufgaben-body">
<div id="guestAufgabenHint" class="guest-hint" style="display:none;">Aufgaben werden vom Host festgelegt nur zur Ansicht.</div>
<p style="font-size:0.85rem;color:var(--color-muted);margin-bottom:0.75rem;">
Gruppen verwalten: <a href="/games/vanilla/aufgaben.html" style="color:var(--color-primary);">Aufgaben-Verwaltung (Vanilla)</a>
Gruppen verwalten: <a href="/games/vanilla/aufgaben.html" target="_blank" style="color:var(--color-primary);">Aufgaben-Verwaltung (Vanilla)</a>
</p>
<div id="sectionOwn">
<div class="aufgaben-section-label"><label class="select-all-label"><input type="checkbox" class="select-all-cb" data-list="listOwn"> Eigene Gruppen</label></div>
@@ -262,11 +284,11 @@
DIVERS: ['MUND','ANUS','UMSCHNALLDILDO'],
};
const WERKZEUGE = [
{ value: 'MUND', label: 'Mund', desc: 'Gewillt den Mund einzusetzen' },
{ value: 'VAGINA', label: 'Vagina', desc: 'Verfügt über eine Vagina und setzt sie ein' },
{ value: 'PENIS', label: 'Penis', desc: 'Verfügt über einen Penis und setzt ihn ein' },
{ value: 'ANUS', label: 'Anus', desc: 'Gewillt den Anus einzusetzen' },
{ value: 'UMSCHNALLDILDO', label: 'Umschnall-Dildo', desc: 'Verfügt über einen Umschnall-Dildo' },
{ value: 'VAGINA', label: 'Vagina', desc: 'Verfügt über eine Vagina' },
{ value: 'PENIS', label: 'Penis', desc: 'Verfügt über einen Penis' },
{ value: 'UMSCHNALLDILDO', label: 'Umschnall-Dildo', desc: 'Verfügt über einen Umschnall-Dildo' },
{ value: 'MUND', label: 'Oral', desc: 'Ist für aktiven Oral-Verkehr' },
{ value: 'ANUS', label: 'Anal', desc: 'Ist Bereit passiv Anal-Verkehr zu haben ' },
];
const ROLE_LABELS = {
AUFGABE_AKTIV: 'Aufgabe Aktiv', AUFGABE_PASSIV: 'Aufgabe Passiv',
@@ -370,10 +392,19 @@
return items.map(({ value, label, desc }) => `
<label class="check-item${disabled ? ' is-disabled' : ''}">
<input type="${type}" name="${name}" value="${value}"${disabled ? ' disabled' : ''}>
<span><span class="check-item-label">${label}</span>${desc ? `<span class="check-item-desc">${desc}</span>` : ''}</span>
<span><span class="check-item-label">${label}${desc ? `<button type="button" class="check-item-info-btn" onclick="event.stopPropagation();toggleCheckDesc(this);">ⓘ</button>` : ''}</span>${desc ? `<span class="check-item-tooltip">${desc}</span><span class="check-item-desc-mobile">${desc}</span>` : ''}</span>
</label>`).join('');
}
function toggleCheckDesc(btn) {
const mobile = btn.closest('.check-item')?.querySelector('.check-item-desc-mobile');
if (!mobile) return;
const isVisible = mobile.style.display === 'block';
document.querySelectorAll('.check-item-desc-mobile').forEach(el => { el.style.display = 'none'; });
document.querySelectorAll('.check-item-info-btn').forEach(el => el.classList.remove('active'));
if (!isVisible) { mobile.style.display = 'block'; btn.classList.add('active'); }
}
function buildPlayerBody(id, nameValue, nameReadOnly = false, genderDisabled = false, allDisabled = false) {
const nameHtml = nameReadOnly
? `<input type="text" id="p${id}-name" value="${nameValue}" readonly style="background:transparent;cursor:default;color:var(--color-muted);">`
@@ -574,14 +605,14 @@
);
if (!filtered.length) {
ul.innerHTML = '<li class="empty-hint">Keine Gruppen vorhanden.</li>';
if (selectAllWrap) selectAllWrap.style.visibility = 'hidden'; return;
if (selectAllWrap) { const cb = selectAllWrap.querySelector('input'); if (cb) cb.disabled = true; selectAllWrap.style.pointerEvents = 'none'; selectAllWrap.style.opacity = '0.4'; } return;
}
ul.innerHTML = filtered.map(g => {
const checked = savedGruppen.has(g.gruppenId);
return `<li><label class="gruppe-item${checked ? ' is-checked' : ''}">
<input type="checkbox" value="${g.gruppenId}"${checked ? ' checked' : ''}>
<span><span class="gruppe-item-name">${g.name}</span>${g.beschreibung ? `<span class="gruppe-item-desc">${g.beschreibung}</span>` : ''}</span>
${g.bild ? `<img class="item-img" src="data:image/png;base64,${g.bild}" alt="">` : ''}
<span><span class="gruppe-item-name">${g.name}</span>${g.beschreibung ? `<span class="gruppe-item-desc">${g.beschreibung}</span>` : ''}</span>
</label></li>`;
}).join('');
updateSelectAll(ul);
@@ -905,8 +936,7 @@
const name = document.getElementById(`p${id}-name`)?.value.trim() || '';
const werkzeuge = getChecked(`p${id}-werkzeuge`);
setFieldError(`p${id}-name-err`, !name);
setFieldError(`p${id}-werkzeuge-err`, werkzeuge.length === 0);
if (!name || !werkzeuge.length) valid = false;
if (!name) valid = false;
return { name, geschlecht: null, spieltMit: [], rollen: [], werkzeuge,
userId: inv ? inv.inviteeId : (id === selfPlayerId ? myUserId : null),
eigenesGeraet: false };
@@ -1035,10 +1065,6 @@
async function bereitMachen() {
const id = guestOwnPlayerId; if (!id) return;
const werkzeuge = getChecked(`p${id}-werkzeuge`);
setFieldError(`p${id}-werkzeuge-err`, werkzeuge.length === 0);
if (!werkzeuge.length) {
showMessage('Bitte mindestens ein Werkzeug auswählen.', 'error'); return;
}
try {
const res = await fetch(`/vanilla/einladung/${guestEinladungId}/spielerdaten`, {
method: 'PUT', headers: { 'Content-Type': 'application/json' },
@@ -1338,6 +1364,13 @@
}
init();
const _sessBc = new BroadcastChannel('vanilla-gruppen-updated');
_sessBc.onmessage = () => {
document.querySelectorAll('.gruppe-list input[type="checkbox"]:checked').forEach(cb => savedGruppen.add(cb.value));
document.querySelectorAll('.gruppe-list input[type="checkbox"]:not(:checked)').forEach(cb => savedGruppen.delete(cb.value));
ladeGruppenListen();
};
</script>
</body>
</html>