Weitere Fehler im Chastity ingame game behoben
Some checks failed
Host-Based Deploy (Java 21 Fix) / build-and-run (push) Has been cancelled

This commit is contained in:
2026-04-30 22:52:21 +02:00
parent 4bd4635faf
commit c472093f62
32 changed files with 1002 additions and 405 deletions

View File

@@ -405,13 +405,9 @@
<div id="subGameSet" style="display:none;">
<div class="form-row">
<label>Aufgaben-Set (Chastity) <span class="required-star">*</span></label>
<div style="position:relative;">
<input type="text" id="gameSetSearch" placeholder="Name eingeben zum Suchen…"
autocomplete="off" oninput="onGameSetSearch(this.value)" onfocus="onGameSetSearchFocus()">
<div id="gameSetDropdown" class="gs-dropdown"></div>
</div>
<div id="gameSetSelected" class="gs-selected" style="display:none;"></div>
<input type="hidden" id="fGameSetId">
<select id="fGameSetId" onchange="markDirty()">
<option value="">Kein Aufgaben-Set</option>
</select>
<div class="field-error-msg" id="errGameSet" style="display:none;">Bitte ein Aufgaben-Set für Spiel-Karten auswählen.</div>
</div>
<div class="form-row" style="margin-bottom:0;">
@@ -757,8 +753,30 @@
{ label: 'Lang' },
{ label: 'Sehr lang' },
];
let _gameSetSearchTimer = null;
let _gameSetResults = [];
let _gameGroups = [];
async function loadGameGroups() {
try {
const res = await fetch('/lock-game/groups');
if (!res.ok) return;
_gameGroups = await res.json();
populateGameSetSelect();
} catch(e) { console.error(e); }
}
function populateGameSetSelect() {
const sel = document.getElementById('fGameSetId');
if (!sel) return;
const cur = sel.value;
sel.innerHTML = '<option value="">Kein Aufgaben-Set</option>';
_gameGroups.forEach(g => {
const opt = document.createElement('option');
opt.value = g.gruppenId;
opt.textContent = g.name + (g.beschreibung ? ' ' + g.beschreibung : '');
sel.appendChild(opt);
});
sel.value = cur;
}
function checkGameCardSection() {
const minV = parseInt(document.getElementById('min_GAME_CARD')?.value) || 0;
@@ -791,72 +809,6 @@
document.getElementById('valGameSpieldauer').textContent = GAME_SPIELDAUER[+val].label;
}
function onGameSetSearchFocus() {
if (!document.getElementById('fGameSetId').value) onGameSetSearch(document.getElementById('gameSetSearch').value);
}
function onGameSetSearch(value) {
clearTimeout(_gameSetSearchTimer);
if (value.length === 0) {
_gameSetSearchTimer = setTimeout(() => doGameSetSearch(''), 0);
} else if (value.length < 2) {
document.getElementById('gameSetDropdown').style.display = 'none';
} else {
_gameSetSearchTimer = setTimeout(() => doGameSetSearch(value), 300);
}
}
async function doGameSetSearch(search) {
try {
const url = '/gruppe/chastity' + (search ? '?search=' + encodeURIComponent(search) : '');
const res = await fetch(url);
if (!res.ok) return;
const data = await res.json();
_gameSetResults = data.gruppen || [];
renderGameSetDropdown();
} catch(e) { console.error(e); }
}
function renderGameSetDropdown() {
const dd = document.getElementById('gameSetDropdown');
if (!dd) return;
if (!_gameSetResults.length) { dd.style.display = 'none'; return; }
dd.innerHTML = _gameSetResults.map(g => `
<div class="gs-dropdown-item" onclick="selectGameSet('${esc(g.gruppenId)}','${esc(g.name).replace(/'/g, "\\'")}')">
<div class="gs-item-name">${esc(g.name)}</div>
${g.beschreibung ? `<div class="gs-item-desc">${esc(g.beschreibung)}</div>` : ''}
</div>`).join('');
dd.style.display = 'block';
}
function selectGameSet(id, name, suppressDirty = false) {
document.getElementById('fGameSetId').value = id;
document.getElementById('gameSetSearch').value = '';
document.getElementById('gameSetDropdown').style.display = 'none';
document.getElementById('gameSetSelected').innerHTML =
`<span style="flex:1;">${esc(name)}</span>
<button type="button" onclick="clearGameSet()" title="Auswahl entfernen">✕</button>`;
document.getElementById('gameSetSelected').style.display = 'flex';
document.getElementById('errGameSet').style.display = 'none';
if (!suppressDirty) markDirty();
}
function clearGameSet() {
document.getElementById('fGameSetId').value = '';
document.getElementById('gameSetSearch').value = '';
document.getElementById('gameSetSelected').style.display = 'none';
document.getElementById('gameSetSelected').innerHTML = '';
markDirty();
}
document.addEventListener('click', e => {
const search = document.getElementById('gameSetSearch');
const dd = document.getElementById('gameSetDropdown');
if (dd && search && !search.contains(e.target) && !dd.contains(e.target)) {
dd.style.display = 'none';
}
});
// ── Karten-Info ──
function openCardInfo(cardId) {
const c = CARD_DEFS.find(x => x.id === cardId); if (!c) return;
@@ -1300,17 +1252,12 @@
// Task-Karte und Spiel-Karte
checkTaskCardSection();
clearGameSet();
checkGameCardSection();
const gsi = template?.gameSpieldauerIdx ?? 2;
document.getElementById('sldGameSpieldauer').value = gsi;
updateGameSpieldauer(gsi);
if (template?.gameSetId) {
fetch(`/gruppe/${template.gameSetId}`)
.then(r => r.ok ? r.json() : null)
.then(g => { if (g?.name) selectGameSet(template.gameSetId, g.name, true); })
.catch(() => {});
}
populateGameSetSelect();
document.getElementById('fGameSetId').value = template?.gameSetId || '';
}
if (type === 'TIMELOCK') {
@@ -1664,6 +1611,7 @@
document.getElementById('templateList').innerHTML = '';
document.getElementById('listEmpty').style.display = 'none';
await loadTaskSets();
await loadGameGroups();
loadNextPage();
loadSubscribedTemplates();
}