Locations können nun auch Posten - bugfixes im Feed
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:
@@ -19,6 +19,14 @@
|
||||
.car-next{right:0.3rem}
|
||||
.car-indicator{text-align:center;font-size:0.75rem;color:var(--color-muted);margin-top:0.25rem}
|
||||
|
||||
/* ── Bilder-Grid (nur im Feed) ── */
|
||||
.post-img-grid{display:grid;gap:2px;margin:0.5rem auto 0;border-radius:6px;overflow:hidden;flex-shrink:0}
|
||||
.pig-item{position:relative;overflow:hidden;min-width:0;min-height:0}
|
||||
.pig-item img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
|
||||
.pig-contain img{object-fit:contain}
|
||||
.pig-dark{background:#111}.pig-dark .pig-item{background:#111}
|
||||
.pig-more{position:absolute;inset:0;background:rgba(0,0,0,0.55);display:flex;align-items:center;justify-content:center;font-size:1.8rem;font-weight:700;color:#fff;pointer-events:none}
|
||||
|
||||
/* ── Like / Löschen-Buttons ── */
|
||||
.btn-like{background:none;border:1px solid rgba(255,255,255,0.15);border-radius:20px;padding:0.2rem 0.65rem;color:var(--color-muted);font-size:0.78rem;cursor:pointer;display:inline-flex;align-items:center;gap:0.3rem;margin:0;width:auto;transition:border-color 0.15s,color 0.15s}
|
||||
.btn-like:hover,.btn-like.liked{border-color:var(--color-primary);color:var(--color-primary)}
|
||||
@@ -110,21 +118,117 @@ document.addEventListener('click', e => {
|
||||
}
|
||||
});
|
||||
|
||||
// ── Bild-Karussell ────────────────────────────────────────────────────────────
|
||||
// ── Bild-Karussell (Lightbox/Detail-Ansicht) ─────────────────────────────────
|
||||
function bilderCarousel(bilder) {
|
||||
if (!bilder || bilder.length === 0) return '';
|
||||
if (bilder.length === 1) {
|
||||
return `<div style="margin-top:0.5rem;"><img class="post-bild" src="data:image/jpeg;base64,${bilder[0]}" alt=""></div>`;
|
||||
}
|
||||
const slides = bilder.map((b, i) =>
|
||||
`<div class="car-slide${i === 0 ? ' active' : ''}"><img class="post-bild" src="data:image/jpeg;base64,${b}" alt=""></div>`
|
||||
).join('');
|
||||
return `<div class="post-carousel">
|
||||
${slides}
|
||||
<button class="car-btn car-prev" onclick="event.stopPropagation();carNav(this,-1)">‹</button>
|
||||
<button class="car-btn car-next" onclick="event.stopPropagation();carNav(this,1)">›</button>
|
||||
<div class="car-indicator"><span class="car-cur">1</span>/${bilder.length}</div>
|
||||
</div>`;
|
||||
const nav = bilder.length > 1
|
||||
? `<button class="car-btn car-prev" onclick="event.stopPropagation();carNav(this,-1)">‹</button>
|
||||
<button class="car-btn car-next" onclick="event.stopPropagation();carNav(this,1)">›</button>
|
||||
<div class="car-indicator"><span class="car-cur">1</span> / ${bilder.length}</div>`
|
||||
: '';
|
||||
return `<div class="post-carousel">${slides}${nav}</div>`;
|
||||
}
|
||||
|
||||
/** Richtet die Lightbox-Inhalte ein:
|
||||
* – View-Area bekommt Flex-Layout damit das Bild den Platz füllt
|
||||
* – Bild-Container bekommt lb-ic-Klasse + Carousel (für alle Bildanzahlen)
|
||||
* – Post-Text bekommt scrollbare Höhenbegrenzung
|
||||
*/
|
||||
function _lbSetupContent(postId, prefix, bilder) {
|
||||
const body = document.getElementById('lbPostBody');
|
||||
const va = body.querySelector(`#${prefix}va-${postId}`);
|
||||
if (va) va.classList.add('lb-va');
|
||||
const hasImages = bilder && bilder.length > 0;
|
||||
const pbi = body.querySelector(`#${prefix}bi-${postId}`);
|
||||
if (pbi) {
|
||||
if (hasImages) {
|
||||
pbi.classList.add('lb-ic');
|
||||
pbi.innerHTML = bilderCarousel(bilder);
|
||||
} else {
|
||||
pbi.style.display = 'none';
|
||||
}
|
||||
}
|
||||
if (va) va.querySelector('.post-text')?.classList.add('lb-text');
|
||||
|
||||
// Text-only layout: kein Bild → Kommentare unterhalb, volle Breite
|
||||
const layout = document.querySelector('#postLightbox .lb-layout');
|
||||
if (layout) layout.classList.toggle('lb-text-only', !hasImages);
|
||||
}
|
||||
|
||||
// ── Bilder-Grid (Feed-Karten, orientierungsabhängig) ──────────────────────────
|
||||
const POST_IMG_SIZE = 500; // px — Breite und Höhe des Bild-Containers
|
||||
let _pigSeq = 0;
|
||||
const _pigStore = new Map(); // id → bilder[]
|
||||
|
||||
function bilderGrid(bilder) {
|
||||
if (!bilder || bilder.length === 0) return '';
|
||||
const S = POST_IMG_SIZE;
|
||||
const id = 'pig-' + (++_pigSeq);
|
||||
|
||||
if (bilder.length === 1) {
|
||||
// Längere Seite = S, kürzere letterboxed
|
||||
return `<div class="post-img-grid pig-contain" id="${id}" style="width:${S}px;height:${S}px;grid-template-columns:1fr;grid-template-rows:1fr;">
|
||||
<div class="pig-item pig-contain"><img src="data:image/jpeg;base64,${bilder[0]}" alt=""></div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// 2+ Bilder: Orientierung des ersten Bilds bestimmt das Layout → deferred init
|
||||
_pigStore.set(id, bilder);
|
||||
return `<div class="post-img-grid" id="${id}" style="width:${S}px;height:${S}px;">` +
|
||||
`<img src="data:image/jpeg;base64,${bilder[0]}" style="display:none;position:absolute;" alt="" onload="_pigInit('${id}',this)">` +
|
||||
`</div>`;
|
||||
}
|
||||
|
||||
function _pigInit(id, probe) {
|
||||
const bilder = _pigStore.get(id);
|
||||
if (!bilder) return;
|
||||
_pigStore.delete(id);
|
||||
const grid = document.getElementById(id);
|
||||
if (!grid) return;
|
||||
const land = probe.naturalWidth >= probe.naturalHeight; // quer = landscape
|
||||
const n = bilder.length;
|
||||
const extra = n - 3;
|
||||
const moreHtml = extra > 0 ? `<div class="pig-more">+${extra}</div>` : '';
|
||||
|
||||
grid.innerHTML = ''; // Probe-Bild entfernen
|
||||
|
||||
// Fraktionale Werte → Browser berücksichtigt gap automatisch, Trennstrich immer genau in der Mitte
|
||||
if (n === 2) {
|
||||
if (land) {
|
||||
// Quer-erstes Bild → beide übereinander (Trennstrich horizontal in der Mitte)
|
||||
grid.style.gridTemplateColumns = '1fr';
|
||||
grid.style.gridTemplateRows = '1fr 1fr';
|
||||
} else {
|
||||
// Hochkant-erstes Bild → beide nebeneinander (Trennstrich vertikal in der Mitte)
|
||||
grid.style.gridTemplateColumns = '1fr 1fr';
|
||||
grid.style.gridTemplateRows = '1fr';
|
||||
}
|
||||
grid.insertAdjacentHTML('beforeend',
|
||||
`<div class="pig-item"><img src="data:image/jpeg;base64,${bilder[0]}" alt=""></div>` +
|
||||
`<div class="pig-item"><img src="data:image/jpeg;base64,${bilder[1]}" alt=""></div>`);
|
||||
} else {
|
||||
// 3+ Bilder (ab 4 gleiche Darstellung wie bei 3, +N-Overlay auf Zelle 3)
|
||||
// Dunkler Hintergrund nur hier, damit der Spalt zwischen den Zellen nicht auffällt
|
||||
grid.classList.add('pig-dark');
|
||||
grid.style.gridTemplateColumns = '1fr 1fr';
|
||||
grid.style.gridTemplateRows = '1fr 1fr';
|
||||
if (land) {
|
||||
// Quer → Bild 1 oben (volle Breite), Bilder 2+3 nebeneinander unten
|
||||
grid.insertAdjacentHTML('beforeend',
|
||||
`<div class="pig-item" style="grid-column:1/3"><img src="data:image/jpeg;base64,${bilder[0]}" alt=""></div>` +
|
||||
`<div class="pig-item"><img src="data:image/jpeg;base64,${bilder[1]}" alt=""></div>` +
|
||||
`<div class="pig-item"><img src="data:image/jpeg;base64,${bilder[2]}" alt="">${moreHtml}</div>`);
|
||||
} else {
|
||||
// Hochkant → Bild 1 links (volle Höhe), Bilder 2+3 übereinander rechts
|
||||
grid.insertAdjacentHTML('beforeend',
|
||||
`<div class="pig-item" style="grid-row:1/3"><img src="data:image/jpeg;base64,${bilder[0]}" alt=""></div>` +
|
||||
`<div class="pig-item"><img src="data:image/jpeg;base64,${bilder[1]}" alt=""></div>` +
|
||||
`<div class="pig-item"><img src="data:image/jpeg;base64,${bilder[2]}" alt="">${moreHtml}</div>`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function carNav(btn, dir) {
|
||||
@@ -209,6 +313,7 @@ async function loadReplies(kommentarId) {
|
||||
const res = await fetch(`/social/kommentare?targetType=KOMMENTAR&targetId=${kommentarId}`);
|
||||
const replies = await res.json();
|
||||
const section = document.getElementById('replies-' + kommentarId);
|
||||
replies.reverse();
|
||||
section.innerHTML = (replies.length === 0
|
||||
? '<p style="color:var(--color-muted);font-size:0.78rem;margin-bottom:0.35rem;">Noch keine Antworten.</p>'
|
||||
: replies.map(r => renderReplyHtml(r, kommentarId)).join(''))
|
||||
@@ -235,3 +340,237 @@ async function deleteReply(replyId, parentId) {
|
||||
await fetch('/social/kommentare/' + replyId, { method: 'DELETE' });
|
||||
await loadReplies(parentId);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Gemeinsame Lightbox (standardisierte IDs: #postLightbox, #lbPostBody,
|
||||
// #lbCommentsList, #lbCommentInput – auf allen Feed-Seiten gleich)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
let _lbMyUserId = null;
|
||||
let _lbPostId = null;
|
||||
let _lbPostType = null;
|
||||
|
||||
/** Muss nach dem Login mit der eigenen userId aufgerufen werden. */
|
||||
function initLb(userId) { _lbMyUserId = userId; }
|
||||
|
||||
function closeLb() {
|
||||
document.getElementById('postLightbox')?.classList.remove('open');
|
||||
document.body.style.overflow = '';
|
||||
_lbPostId = null; _lbPostType = null;
|
||||
}
|
||||
|
||||
// Escape schließt, Pfeiltasten navigieren das Karussell
|
||||
document.addEventListener('keydown', e => {
|
||||
const lb = document.getElementById('postLightbox');
|
||||
if (!lb?.classList.contains('open')) return;
|
||||
if (e.key === 'Escape') { closeLb(); return; }
|
||||
if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return;
|
||||
const car = lb.querySelector('.post-carousel');
|
||||
if (!car) return;
|
||||
const slides = Array.from(car.querySelectorAll('.car-slide'));
|
||||
if (slides.length <= 1) return;
|
||||
const cur = slides.findIndex(s => s.classList.contains('active'));
|
||||
const next = (cur + (e.key === 'ArrowLeft' ? -1 : 1) + slides.length) % slides.length;
|
||||
slides[cur].classList.remove('active');
|
||||
slides[next].classList.add('active');
|
||||
const ind = car.querySelector('.car-cur');
|
||||
if (ind) ind.textContent = next + 1;
|
||||
});
|
||||
|
||||
async function loadLbComments(postId, postType) {
|
||||
_lbPostId = postId; _lbPostType = postType;
|
||||
const targetType = postType === 'GROUP' ? 'GROUP_POST' : 'FEED_POST';
|
||||
try {
|
||||
const res = await fetch(`/social/kommentare?targetType=${targetType}&targetId=${postId}`);
|
||||
const comments = await res.json();
|
||||
comments.reverse();
|
||||
document.getElementById('lbCommentsList').innerHTML = comments.length === 0
|
||||
? '<p style="color:var(--color-muted);font-size:0.82rem;margin:0.4rem;">Noch keine Kommentare.</p>'
|
||||
: comments.map(k => renderKommentarHtml(k, targetType, postId, { myUserId: _lbMyUserId })).join('');
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
async function postLbComment() {
|
||||
if (!_lbPostId) return;
|
||||
const input = document.getElementById('lbCommentInput');
|
||||
const text = input.value.trim();
|
||||
if (!text) return;
|
||||
const targetType = _lbPostType === 'GROUP' ? 'GROUP_POST' : 'FEED_POST';
|
||||
await fetch('/social/kommentare', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ targetType, targetId: _lbPostId, text })
|
||||
});
|
||||
input.value = '';
|
||||
await loadLbComments(_lbPostId, _lbPostType);
|
||||
const kcEl = document.getElementById('kc-' + _lbPostId) || document.getElementById('hkc-' + _lbPostId);
|
||||
if (kcEl) kcEl.textContent = parseInt(kcEl.textContent || '0') + 1;
|
||||
}
|
||||
|
||||
async function deleteKommentar(kommentarId, targetType, targetId) {
|
||||
await fetch('/social/kommentare/' + kommentarId, { method: 'DELETE' });
|
||||
await loadLbComments(targetId, _lbPostType);
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Bild-Verarbeitung (Compose & Edit)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/** Liest eine Bilddatei, skaliert auf max. 1024px, komprimiert auf JPEG 85 %
|
||||
* und hängt den Base64-String an bilderArr an, dann ruft renderFn() auf. */
|
||||
function processImageFile(file, bilderArr, renderFn) {
|
||||
if (!file || !file.type.startsWith('image/')) return;
|
||||
const reader = new FileReader();
|
||||
reader.onload = e => {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
const MAX = 1024, canvas = document.createElement('canvas');
|
||||
const s = Math.min(MAX / img.width, MAX / img.height, 1);
|
||||
canvas.width = Math.round(img.width * s); canvas.height = Math.round(img.height * s);
|
||||
canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height);
|
||||
bilderArr.push(canvas.toDataURL('image/jpeg', 0.85).split(',')[1]);
|
||||
renderFn();
|
||||
};
|
||||
img.src = e.target.result;
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
/** Rendert Vorschau-Thumbnails in containerId; rmCallback(idx) wird beim ✕ aufgerufen. */
|
||||
function renderBilderThumbs(bilderArr, containerId, rmCallback) {
|
||||
const c = document.getElementById(containerId);
|
||||
if (!c) return;
|
||||
c.innerHTML = '';
|
||||
bilderArr.forEach((b, i) => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'compose-thumb';
|
||||
const img = document.createElement('img');
|
||||
img.src = `data:image/jpeg;base64,${b}`;
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'compose-thumb-remove';
|
||||
btn.textContent = '✕'; btn.title = 'Entfernen';
|
||||
btn.onclick = ev => { ev.stopPropagation(); rmCallback(i); };
|
||||
div.appendChild(img); div.appendChild(btn);
|
||||
c.appendChild(div);
|
||||
});
|
||||
c.style.display = bilderArr.length > 0 ? 'flex' : 'none';
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Post-Bearbeitung (gemeinsam, über Präfix parametrisiert)
|
||||
// Präfixe: 'p' (feed), 'hp' (userhome), 'gp' (gruppe)
|
||||
// IDs-Muster: ${prefix}va-, ${prefix}bi-, ${prefix}ea-, ${prefix}um-,
|
||||
// ${prefix}m-, ${prefix}et-, ${prefix}et-tb-, ${prefix}eo-, ${prefix}mc-
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* cfg: { postId, prefix, data, editBilderMap,
|
||||
* saveFn, cancelFn, addImgFn, addOptionFn, rmImgFn }
|
||||
* Alle Fn-Namen sind Strings (globale Funktionsnamen auf der jeweiligen Seite).
|
||||
*/
|
||||
function startPostEdit(cfg) {
|
||||
const { postId, prefix, data, editBilderMap, saveFn, cancelFn, addImgFn, addOptionFn, rmImgFn } = cfg;
|
||||
editBilderMap.set(postId, [...(data.bilder || [])]);
|
||||
document.getElementById(`${prefix}va-${postId}`).style.display = 'none';
|
||||
document.getElementById(`${prefix}um-${postId}`).style.display = 'none';
|
||||
|
||||
const isUmfrage = data.beitragTyp === 'UMFRAGE';
|
||||
const optionenHtml = isUmfrage
|
||||
? `<div id="${prefix}eo-${postId}" style="margin-top:0.5rem;">${(data.optionen || []).map(o =>
|
||||
`<div class="umfrage-option-row">
|
||||
<input type="text" value="${esc(o.text)}" maxlength="200" data-option-id="${o.optionId}"
|
||||
style="flex:1;padding:0.4rem 0.6rem;border:1px solid var(--color-secondary);border-radius:6px;background:var(--color-secondary);color:var(--color-text);font-size:0.9rem;"
|
||||
onmousedown="event.stopPropagation()" onclick="event.stopPropagation()" onkeydown="event.stopPropagation()">
|
||||
<button onmousedown="event.stopPropagation()" onclick="event.stopPropagation();this.closest('.umfrage-option-row').remove()" style="width:auto;margin:0;padding:0.3rem 0.6rem;font-size:0.8rem;">✕</button>
|
||||
</div>`).join('')}
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-top:0.3rem;" onclick="event.stopPropagation()">
|
||||
<button onmousedown="event.stopPropagation()" onclick="event.stopPropagation();${addOptionFn}('${postId}')" style="width:auto;margin:0;padding:0.3rem 0.75rem;font-size:0.8rem;">+ Option</button>
|
||||
<label class="multi-toggle" onmousedown="event.stopPropagation()" onclick="event.stopPropagation()">
|
||||
<input type="checkbox" id="${prefix}mc-${postId}" ${data.multiChoice ? 'checked' : ''}> Mehrfachauswahl möglich
|
||||
</label>
|
||||
</div>
|
||||
</div>`
|
||||
: '';
|
||||
|
||||
const actionRow = `<div style="display:flex;gap:0.5rem;align-items:center;margin-top:0.5rem;" onclick="event.stopPropagation()">
|
||||
<label class="compose-action-btn" title="Fotos hinzufügen">📷
|
||||
<input type="file" accept="image/*" multiple style="display:none;" onchange="event.stopPropagation();${addImgFn}(this,'${postId}')">
|
||||
</label>
|
||||
<button onclick="event.stopPropagation();${saveFn}('${postId}')" style="width:auto;margin:0;">Speichern</button>
|
||||
<button onclick="event.stopPropagation();${cancelFn}('${postId}')" style="width:auto;margin:0;background:var(--color-secondary);color:var(--color-text);">Abbrechen</button>
|
||||
</div>`;
|
||||
|
||||
const ea = document.getElementById(`${prefix}ea-${postId}`);
|
||||
ea.style.display = ''; ea.onclick = e => e.stopPropagation();
|
||||
ea.innerHTML = `<textarea id="${prefix}et-${postId}" style="width:100%;box-sizing:border-box;padding:0.6rem;border:1px solid var(--color-secondary);border-radius:6px;background:var(--color-secondary);color:var(--color-text);font-size:0.95rem;resize:vertical;min-height:70px;" onclick="event.stopPropagation()" onkeydown="event.stopPropagation()">${esc(data.text || '')}</textarea>
|
||||
<div class="compose-thumbs" id="${prefix}et-tb-${postId}" style="margin-top:0.4rem;"></div>
|
||||
${optionenHtml}${actionRow}`;
|
||||
_renderEditThumbs(editBilderMap, postId, prefix, rmImgFn);
|
||||
}
|
||||
|
||||
function cancelPostEdit(postId, prefix, editBilderMap) {
|
||||
document.getElementById(`${prefix}va-${postId}`).style.display = '';
|
||||
document.getElementById(`${prefix}um-${postId}`).style.display = '';
|
||||
document.getElementById(`${prefix}ea-${postId}`).style.display = 'none';
|
||||
editBilderMap.delete(postId);
|
||||
}
|
||||
|
||||
function _renderEditThumbs(editBilderMap, postId, prefix, rmFn) {
|
||||
const bilder = editBilderMap.get(postId) || [];
|
||||
const c = document.getElementById(`${prefix}et-tb-${postId}`);
|
||||
if (!c) return;
|
||||
c.innerHTML = bilder.map((b, i) =>
|
||||
`<div class="compose-thumb"><img src="data:image/jpeg;base64,${b}" alt="">
|
||||
<button class="compose-thumb-remove" onclick="event.stopPropagation();${rmFn}('${postId}',${i})">✕</button></div>`
|
||||
).join('');
|
||||
c.style.display = bilder.length > 0 ? 'flex' : 'none';
|
||||
}
|
||||
|
||||
function editAddOptionRow(containerId) {
|
||||
const container = document.getElementById(containerId);
|
||||
if (!container) return;
|
||||
const count = container.querySelectorAll('input[type=text]').length;
|
||||
const row = document.createElement('div');
|
||||
row.className = 'umfrage-option-row';
|
||||
row.innerHTML = `<input type="text" placeholder="Option ${count + 1}" maxlength="200"
|
||||
style="flex:1;padding:0.4rem 0.6rem;border:1px solid var(--color-secondary);border-radius:6px;background:var(--color-secondary);color:var(--color-text);font-size:0.9rem;"
|
||||
onmousedown="event.stopPropagation()" onclick="event.stopPropagation()" onkeydown="event.stopPropagation()">
|
||||
<button onmousedown="event.stopPropagation()" onclick="event.stopPropagation();this.closest('.umfrage-option-row').remove()" style="width:auto;margin:0;padding:0.3rem 0.6rem;font-size:0.8rem;">✕</button>`;
|
||||
container.insertBefore(row, container.querySelector('div:last-child'));
|
||||
}
|
||||
|
||||
/**
|
||||
* cfg: { postId, prefix, endpoint, isUmfrage, editBilderMap, onSuccess }
|
||||
* onSuccess(updated) – Seite aktualisiert Cache und DOM.
|
||||
*/
|
||||
async function savePostEdit(cfg) {
|
||||
const { postId, prefix, endpoint, isUmfrage, editBilderMap, onSuccess } = cfg;
|
||||
const text = document.getElementById(`${prefix}et-${postId}`).value.trim();
|
||||
if (!text) return;
|
||||
const bilder = editBilderMap.get(postId) || [];
|
||||
const optionen = isUmfrage
|
||||
? Array.from(document.querySelectorAll(`#${prefix}eo-${postId} input[type=text]`))
|
||||
.map(inp => ({ optionId: inp.dataset.optionId || null, text: inp.value.trim() }))
|
||||
.filter(o => o.text)
|
||||
: null;
|
||||
const multiChoice = isUmfrage ? (document.getElementById(`${prefix}mc-${postId}`)?.checked ?? false) : null;
|
||||
const res = await fetch(endpoint, {
|
||||
method: 'PUT', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ text, bilder, optionen, multiChoice })
|
||||
});
|
||||
if (!res.ok) return;
|
||||
editBilderMap.delete(postId);
|
||||
onSuccess(await res.json());
|
||||
}
|
||||
|
||||
/** Aktualisiert Text, Bilder, Edit-Area, Umfrage und (bearbeitet)-Label im DOM. */
|
||||
function applyPostEditDom(postId, prefix, updated, umfrageHtml) {
|
||||
document.getElementById(`${prefix}va-${postId}`).querySelector('.post-text').innerHTML = renderTextWithHashtags(updated.text);
|
||||
document.getElementById(`${prefix}bi-${postId}`).innerHTML = bilderGrid(updated.bilder);
|
||||
document.getElementById(`${prefix}va-${postId}`).style.display = '';
|
||||
document.getElementById(`${prefix}ea-${postId}`).style.display = 'none';
|
||||
const pum = document.getElementById(`${prefix}um-${postId}`);
|
||||
if (pum) { pum.innerHTML = umfrageHtml || ''; pum.style.display = ''; }
|
||||
const meta = document.getElementById(`${prefix}m-${postId}`);
|
||||
if (meta && !meta.querySelector('.edited-label')) {
|
||||
meta.insertAdjacentHTML('beforeend', ' <span class="edited-label" style="font-size:0.75rem;color:var(--color-muted);">(bearbeitet)</span>');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user