// ── Timestamp ──
// formatTimestamp() → defined in ui-helpers.js
function _addTimestamp(div, timestamp) {
if (!timestamp) return;
var formatted = formatTimestamp(timestamp);
if (!formatted) return;
var span = document.createElement('span');
span.className = 'msg-timestamp';
span.textContent = formatted;
div.prepend(span);
}
// ── Delete Button ──
function _addDeleteButton(div, messageId, deletedOn) {
if (!messageId) return;
const isDeleted = !!deletedOn;
const btn = document.createElement('button');
btn.className = 'msg-delete-btn icon-btn' + (isDeleted ? ' deleted' : '');
btn.innerHTML = '';
btn.title = isDeleted ? 'Löschung aufheben' : 'Nachricht löschen';
btn.addEventListener('click', async (e) => {
e.stopPropagation();
try {
const result = await apiToggleMessageDelete(messageId);
const nowDeleted = !!result.deletedOn;
btn.classList.toggle('deleted', nowDeleted);
btn.title = nowDeleted ? 'Löschung aufheben' : 'Nachricht löschen';
if (nowDeleted && !isDeletedVisible()) {
// Nachricht ausblenden
div.classList.add('msg-deleted-hidden');
} else {
div.classList.remove('msg-deleted-hidden');
div.classList.toggle('msg-deleted', nowDeleted);
}
} catch (err) {
console.error('Delete toggle failed:', err);
}
});
// Nach dem Reply-Button einfügen
const replyBtn = div.querySelector('.msg-reply-btn');
if (replyBtn) {
replyBtn.after(btn);
} else {
div.prepend(btn);
}
}
function isDeletedVisible() {
return loadSettings().showDeletedMessages === true;
}
// ── Mark Button ──
function _addMarkButton(div, messageId, isMarked) {
if (!messageId) return; // kein DB-Eintrag → kein Button
const btn = document.createElement('button');
btn.className = 'msg-mark-btn icon-btn' + (isMarked ? ' marked' : '');
btn.innerHTML = isMarked ? '' : '';
btn.title = 'Als wichtig markieren';
btn.addEventListener('click', async (e) => {
e.stopPropagation();
try {
const result = await apiToggleMessageMark(messageId);
btn.classList.toggle('marked', result.isMarked);
btn.innerHTML = result.isMarked ? '' : '';
div.classList.toggle('marked', result.isMarked);
} catch (err) {
console.error('Mark toggle failed:', err);
}
});
// Nach dem Delete-Button einfügen (oder nach Reply-Button, oder am Anfang)
const deleteBtn = div.querySelector('.msg-delete-btn');
if (deleteBtn) {
deleteBtn.after(btn);
} else {
const replyBtn = div.querySelector('.msg-reply-btn');
if (replyBtn) {
replyBtn.after(btn);
} else {
div.prepend(btn);
}
}
}
// ── Share Button ──
function _addShareButton(div, messageId) {
if (!messageId) return;
const btn = document.createElement('button');
btn.className = 'msg-share-btn icon-btn';
btn.innerHTML = '';
btn.title = 'Nachricht teilen';
btn.addEventListener('click', async (e) => {
e.stopPropagation();
try {
// Kontextmenü: Einzelnachricht oder mit Kontext?
const mode = await _showShareMenu(btn);
if (!mode) return; // abgebrochen
const result = await apiShareMessage(messageId, mode === 'context');
const url = location.origin + '/#shared/' + result.token;
await navigator.clipboard.writeText(url);
showToast('Link kopiert!', 'success');
} catch (err) {
showToast('Fehler: ' + err.message, 'error');
}
});
// Nach dem Mark-Button einfügen
const markBtn = div.querySelector('.msg-mark-btn');
if (markBtn) {
markBtn.after(btn);
} else {
const deleteBtn = div.querySelector('.msg-delete-btn');
if (deleteBtn) {
deleteBtn.after(btn);
} else {
div.prepend(btn);
}
}
}
function _showShareMenu(anchorBtn) {
return new Promise((resolve) => {
// Wenn schon ein Menü offen, schließen
const existing = document.querySelector('.share-menu');
if (existing) { existing.remove(); resolve(null); return; }
const menu = document.createElement('div');
menu.className = 'share-menu';
menu.innerHTML = `
`;
// Positionierung
const rect = anchorBtn.getBoundingClientRect();
menu.style.top = (rect.bottom + 4) + 'px';
menu.style.left = rect.left + 'px';
document.body.appendChild(menu);
function cleanup() {
menu.remove();
document.removeEventListener('click', outsideClick);
}
function outsideClick(e) {
if (!menu.contains(e.target)) {
cleanup();
resolve(null);
}
}
menu.querySelectorAll('.share-menu-item').forEach(item => {
item.addEventListener('click', (e) => {
e.stopPropagation();
const mode = item.dataset.mode;
cleanup();
resolve(mode);
});
});
// Beim nächsten Klick außerhalb schließen
setTimeout(() => document.addEventListener('click', outsideClick), 10);
});
}
// ── Reply Button ──
function _addReplyButton(div) {
const btn = document.createElement('button');
btn.className = 'msg-reply-btn icon-btn';
btn.innerHTML = '';
btn.title = 'Antworten';
btn.addEventListener('click', (e) => {
e.stopPropagation();
// Nur den eigentlichen Nachrichten-Text holen (ohne Reply-Button-Text)
const clone = div.cloneNode(true);
clone.querySelectorAll('.msg-reply-btn, .attachment-indicator, .reply-quote').forEach(el => el.remove());
const text = clone.textContent.trim();
setReply({
role: div.dataset.role,
timestamp: div.dataset.timestamp || '',
text
});
});
div.prepend(btn);
}