Weiter gebaut
Some checks failed
Host-Based Deploy (Java 21 Fix) / build-and-run (push) Has been cancelled
Some checks failed
Host-Based Deploy (Java 21 Fix) / build-and-run (push) Has been cancelled
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/img/icon.png" type="image/png">
|
||||
<meta http-equiv="refresh" content="0;url=/games/aufgaben/aufgaben.html">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Aufgaben – BDSM – xXx Sphere</title>
|
||||
<link rel="stylesheet" href="/css/variables.css">
|
||||
@@ -96,6 +97,7 @@
|
||||
.gruppe-badge-private { background: rgba(233,69,96,0.15); color: var(--color-primary); }
|
||||
.gruppe-badge-public { background: rgba(46,204,113,0.15); color: var(--color-success); }
|
||||
.gruppe-badge-vanilla { background: #e8f5e9; color: #2e7d32; border: 1px solid #a5d6a7; }
|
||||
.gruppe-badge-chastity { background: rgba(155,89,182,0.15); color: #9b59b6; border: 1px solid rgba(155,89,182,0.4); }
|
||||
.gruppe-toggle { font-size: 0.75rem; color: var(--color-muted); flex-shrink: 0; transition: transform 0.2s; }
|
||||
.gruppe-card.open .gruppe-toggle { transform: rotate(90deg); }
|
||||
|
||||
@@ -368,12 +370,14 @@
|
||||
Gruppe veröffentlichen (für alle sichtbar)
|
||||
</span>
|
||||
</label>
|
||||
<label>
|
||||
<span class="modal-check">
|
||||
<input type="checkbox" id="gVanilla">
|
||||
Auch für Vanilla-Game verfügbar
|
||||
</span>
|
||||
</label>
|
||||
<div style="margin-top:0.5rem;">
|
||||
<label for="gAvailableIn" style="font-size:0.85rem;display:block;margin-bottom:0.3rem;">Verfügbar in</label>
|
||||
<select id="gAvailableIn" style="width:100%;padding:0.5rem 0.75rem;border-radius:6px;border:1px solid var(--color-secondary);background:var(--color-secondary);color:var(--color-text);font-size:0.9rem;">
|
||||
<option value="BDSM_ONLY">Nur BDSM</option>
|
||||
<option value="BDSM_AND_VANILLA">BDSM & Vanilla</option>
|
||||
<option value="CHASTITY_ONLY">Nur Chastity</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="modal-error" id="modalError"></div>
|
||||
<div class="modal-actions">
|
||||
<button class="btn-cancel" id="cancelBtn">Abbrechen</button>
|
||||
@@ -636,8 +640,13 @@
|
||||
.then(user => { if (!user) return; loadUserGruppen(); loadAboGruppen(); loadSystemGruppen(); })
|
||||
.catch(() => { window.location.href = '/login.html'; });
|
||||
|
||||
// ── Cross-tab notification ──
|
||||
let _notifyOnLoad = false;
|
||||
const gruppenBc = new BroadcastChannel('bdsm-gruppen-updated');
|
||||
|
||||
// ── Load ──
|
||||
function loadUserGruppen() {
|
||||
if (_notifyOnLoad) { _notifyOnLoad = false; try { gruppenBc.postMessage(1); } catch (_) {} }
|
||||
resetSelection();
|
||||
document.getElementById('userLoading').style.display = 'block';
|
||||
fetch(apiUrl(`/gruppe/list/user`) + `?page=${userPage}&size=${PAGE_SIZE}`)
|
||||
@@ -722,7 +731,8 @@
|
||||
if (g.privateGruppe) badges.push(`<span class="gruppe-badge gruppe-badge-private">Privat</span>`);
|
||||
else badges.push(`<span class="gruppe-badge gruppe-badge-public">Öffentlich</span>`);
|
||||
if (type === 'user' && g.subscriberCount > 0) badges.push(`<span class="gruppe-badge">♥ ${g.subscriberCount} Abo${g.subscriberCount !== 1 ? 's' : ''}</span>`);
|
||||
if (g.vanillaAvailable) badges.push(`<span class="gruppe-badge gruppe-badge-vanilla">Vanilla</span>`);
|
||||
if (g.availableIn === 'BDSM_AND_VANILLA') badges.push(`<span class="gruppe-badge gruppe-badge-vanilla">Vanilla</span>`);
|
||||
if (g.availableIn === 'CHASTITY_ONLY') badges.push(`<span class="gruppe-badge gruppe-badge-chastity">Chastity</span>`);
|
||||
|
||||
return `
|
||||
<div class="gruppe-card" id="gruppe-${esc(g.gruppenId)}">
|
||||
@@ -936,7 +946,7 @@
|
||||
openItemId = null;
|
||||
pendingExpandId = gruppenId;
|
||||
pendingExpandType = 'user';
|
||||
loadUserGruppen();
|
||||
_notifyOnLoad = true; loadUserGruppen();
|
||||
} else {
|
||||
document.getElementById('userActionError').textContent = 'Fehler beim Löschen (HTTP ' + r.status + ').';
|
||||
}
|
||||
@@ -1077,7 +1087,7 @@
|
||||
pubCb.checked = !g.privateGruppe;
|
||||
pubCb.disabled = g.privateGruppe; // Veröffentlichen nur über den Veröffentlichen-Button
|
||||
document.getElementById('gPublicLabel').style.display = 'block';
|
||||
document.getElementById('gVanilla').checked = g.vanillaAvailable || false;
|
||||
document.getElementById('gAvailableIn').value = g.availableIn || 'BDSM_ONLY';
|
||||
const imgWrap = document.getElementById('gCurrentImgWrap');
|
||||
if (g.bild) {
|
||||
document.getElementById('gCurrentImg').src = 'data:image/png;base64,' + g.bild;
|
||||
@@ -1095,7 +1105,7 @@
|
||||
document.getElementById('gDesc').value = '';
|
||||
document.getElementById('gPublic').checked = false;
|
||||
document.getElementById('gPublicLabel').style.display = 'none';
|
||||
document.getElementById('gVanilla').checked = false;
|
||||
document.getElementById('gAvailableIn').value = 'BDSM_ONLY';
|
||||
document.getElementById('gCurrentImgWrap').style.display = 'none';
|
||||
gruppeModal.classList.add('open');
|
||||
document.getElementById('gName').focus();
|
||||
@@ -1129,7 +1139,7 @@
|
||||
name,
|
||||
beschreibung: document.getElementById('gDesc').value.trim() || null,
|
||||
privateGruppe: isEdit ? !document.getElementById('gPublic').checked : true,
|
||||
vanillaAvailable: document.getElementById('gVanilla').checked,
|
||||
availableIn: document.getElementById('gAvailableIn').value,
|
||||
bild: bildBase64
|
||||
};
|
||||
|
||||
@@ -1146,7 +1156,7 @@
|
||||
pendingExpandType = 'user';
|
||||
}
|
||||
userPage = 0;
|
||||
loadUserGruppen();
|
||||
_notifyOnLoad = true; loadUserGruppen();
|
||||
} else if (r.status === 409) {
|
||||
showModalError('Limit erreicht: maximal 10 eigene Aufgabengruppen möglich.');
|
||||
} else {
|
||||
@@ -1172,7 +1182,7 @@
|
||||
.then(r => {
|
||||
if (r.ok || r.status === 202) {
|
||||
userPage = 0;
|
||||
loadUserGruppen();
|
||||
_notifyOnLoad = true; loadUserGruppen();
|
||||
} else if (r.status === 403) {
|
||||
document.getElementById('userActionError').textContent = 'Keine Berechtigung.';
|
||||
btn.disabled = false;
|
||||
@@ -1194,7 +1204,7 @@
|
||||
.then(r => {
|
||||
if (r.ok || r.status === 201) {
|
||||
userPage = 0;
|
||||
loadUserGruppen();
|
||||
_notifyOnLoad = true; loadUserGruppen();
|
||||
document.getElementById('systemActionError').textContent = '';
|
||||
} else {
|
||||
document.getElementById('systemActionError').textContent = 'Fehler beim Kopieren (HTTP ' + r.status + ').';
|
||||
@@ -1213,7 +1223,7 @@
|
||||
.then(r => {
|
||||
if (r.ok || r.status === 201) {
|
||||
userPage = 0;
|
||||
loadUserGruppen();
|
||||
_notifyOnLoad = true; loadUserGruppen();
|
||||
document.getElementById('aboActionError').textContent = '';
|
||||
} else if (r.status === 409) {
|
||||
document.getElementById('aboActionError').textContent = 'Limit erreicht: maximal 10 eigene Aufgabengruppen möglich.';
|
||||
@@ -1643,7 +1653,7 @@
|
||||
pendingExpandId = currentItemGruppeId;
|
||||
pendingExpandType = 'user';
|
||||
userPage = 0;
|
||||
loadUserGruppen();
|
||||
_notifyOnLoad = true; loadUserGruppen();
|
||||
} else if (r.status === 409) {
|
||||
showItemError('Limit erreicht: maximal 100 Einträge pro Gruppe möglich.');
|
||||
} else {
|
||||
@@ -1739,7 +1749,7 @@
|
||||
pendingExpandId = selectedGruppeId;
|
||||
pendingExpandType = 'user';
|
||||
userPage = 0;
|
||||
loadUserGruppen();
|
||||
_notifyOnLoad = true; loadUserGruppen();
|
||||
} else {
|
||||
const errEl = document.getElementById('publishError');
|
||||
errEl.textContent = 'Fehler beim Veröffentlichen (HTTP ' + r.status + ').';
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/img/icon.png" type="image/png">
|
||||
<meta http-equiv="refresh" content="0;url=/games/aufgaben/entdecken.html">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Entdecken – xXx Sphere</title>
|
||||
<link rel="stylesheet" href="/css/variables.css">
|
||||
|
||||
@@ -67,13 +67,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; }
|
||||
@@ -160,8 +183,7 @@
|
||||
|
||||
<div class="main" id="setupView" style="display:none;">
|
||||
<div class="content">
|
||||
<h1>BDSM Game</h1>
|
||||
<p id="pageSubtitle" style="margin-bottom:1.5rem;">Session einrichten</p>
|
||||
<h1>BDSM Game - Session einrichten</h1>
|
||||
|
||||
<!-- Accordion 1: Grundeinstellungen -->
|
||||
<div class="acc-item">
|
||||
@@ -212,6 +234,9 @@
|
||||
</button>
|
||||
<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/bdsm/aufgaben.html" target="_blank" style="color:var(--color-primary);">Aufgaben-Verwaltung (BDSM)</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>
|
||||
<ul class="gruppe-list" id="listOwn"><li class="empty-hint">Wird geladen…</li></ul>
|
||||
@@ -281,11 +306,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: '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',
|
||||
@@ -417,10 +442,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 globalDefault = document.getElementById('chkZeitstrafen')?.checked ?? true;
|
||||
const isCheckedCls = globalDefault ? ' is-checked' : '';
|
||||
@@ -650,15 +684,15 @@
|
||||
const selectAllWrap = section?.querySelector('.select-all-label');
|
||||
if (!gruppen.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 = gruppen.map(g => {
|
||||
const checked = savedGruppen.has(g.gruppenId);
|
||||
const vanillaBadge = g.vanillaAvailable ? '<span class="vanilla-badge">Vanilla</span>' : '';
|
||||
const vanillaBadge = g.availableIn === 'BDSM_AND_VANILLA' ? '<span class="vanilla-badge">Vanilla</span>' : '';
|
||||
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}${vanillaBadge}</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}${vanillaBadge}</span>${g.beschreibung ? `<span class="gruppe-item-desc">${g.beschreibung}</span>` : ''}</span>
|
||||
</label></li>`;
|
||||
}).join('');
|
||||
updateSelectAll(ul);
|
||||
@@ -1033,8 +1067,7 @@
|
||||
setFieldError(`p${id}-geschlecht-err`, geschlecht.length === 0);
|
||||
setFieldError(`p${id}-spieltmit-err`, spieltMit.length === 0);
|
||||
setFieldError(`p${id}-rollen-err`, rollen.length === 0);
|
||||
setFieldError(`p${id}-werkzeuge-err`, werkzeuge.length === 0);
|
||||
if (!name || !geschlecht.length || !spieltMit.length || !rollen.length || !werkzeuge.length) valid = false;
|
||||
if (!name || !geschlecht.length || !spieltMit.length || !rollen.length) valid = false;
|
||||
const sperre = document.getElementById(`p${id}-sperrenAufloesen`);
|
||||
return { name, geschlecht: geschlecht[0] || null, spieltMit, rollen, werkzeuge,
|
||||
userId: inv ? inv.inviteeId : (id === selfPlayerId ? myUserId : null),
|
||||
@@ -1196,8 +1229,7 @@
|
||||
setFieldError(`p${id}-geschlecht-err`, geschlecht.length === 0);
|
||||
setFieldError(`p${id}-spieltmit-err`, spieltMit.length === 0);
|
||||
setFieldError(`p${id}-rollen-err`, rollen.length === 0);
|
||||
setFieldError(`p${id}-werkzeuge-err`, werkzeuge.length === 0);
|
||||
if (!geschlecht.length || !spieltMit.length || !rollen.length || !werkzeuge.length) {
|
||||
if (!geschlecht.length || !spieltMit.length || !rollen.length) {
|
||||
showMessage('Bitte alle Felder ausfüllen.', 'error'); return;
|
||||
}
|
||||
const sperre = document.getElementById(`p${id}-sperrenAufloesen`);
|
||||
@@ -1482,6 +1514,13 @@
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
const _sessBc = new BroadcastChannel('bdsm-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>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/img/icon.png" type="image/png">
|
||||
<meta http-equiv="refresh" content="0;url=/games/aufgaben/toys.html">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Toys – xXx Sphere</title>
|
||||
<link rel="stylesheet" href="/css/variables.css">
|
||||
|
||||
Reference in New Issue
Block a user