Open NeuralNet chats before history loads
mindflux-ci / build (push) Successful in 24s

This commit is contained in:
AliceDarkest
2026-07-14 16:19:52 +02:00
parent fb487be037
commit f9e6516124
4 changed files with 20 additions and 8 deletions
+3
View File
@@ -7,6 +7,9 @@ Versionierung [semantisch](https://semver.org/lang/de/).
## [Unreleased] – 2026-07-14 · SysnaptiK Neural Rebrand
### Marke & Plattform
- **NeuralNet-Chat öffnet sofort:** Der Klick auf eine Verbindung schaltet das
Gespräch samt Eingabefeld nun unabhängig vom anschließenden Verlaufsabruf frei;
Chat-Aktionen sind explizit als Buttons markiert.
- **NeuralNet-Chat repariert:** Leere, erfolgreiche API-Antworten werden nicht mehr
fälschlich als JSON gelesen. Kontaktaktionen aktualisieren die Oberfläche wieder
zuverlässig und bestätigte Verbindungen lassen sich direkt im Chat öffnen.
+1
View File
@@ -489,6 +489,7 @@ Der Verdacht „Profilbutton fehlt / Einstellungen nicht im Profil / irgendwas i
> ✅ **MVP-Stand 2026-07-14:** Opt-in, Kontaktanfragen (annehmen, ablehnen,
> zurückziehen) und private Nachrichten nach bestätigter Verbindung sind umgesetzt.
> Leere Erfolgsantworten des API-Backends werden im Client robust verarbeitet.
> Der Gesprächsbereich öffnet unmittelbar beim Auswählen einer bestätigten Verbindung.
> Blockieren, Melden/Moderation, Duelle und Lernlobby bleiben die nächsten Ausbauschritte.
> Ersetzt den `/soziales`-Platzhalter („Straßen? Wo wir hingehen, brauchen wir keine Straßen!"). Ziel: User können sich befreunden, intern miteinander schreiben, gemeinsam lernen und Achievements vergleichen – **vollständig selbst gehostet, ohne einen einzigen externen Dienst**, und DSGVO-konform von Grund auf.
+15 -7
View File
@@ -28,13 +28,13 @@
}
function render(data) {
q('[data-nn-incoming]').innerHTML = data.incoming.length ? data.incoming.map(function (name) {
return item(name, '<button data-action="accept" data-user="' + esc(name) + '">Annehmen</button><button data-action="decline" data-user="' + esc(name) + '">Ablehnen</button>');
return item(name, '<button type="button" data-action="accept" data-user="' + esc(name) + '">Annehmen</button><button type="button" data-action="decline" data-user="' + esc(name) + '">Ablehnen</button>');
}).join('') : '<span class="mf-small-hint">Keine offenen Anfragen.</span>';
q('[data-nn-outgoing]').innerHTML = data.outgoing.length ? data.outgoing.map(function (name) {
return item(name, '<button data-action="cancel" data-user="' + esc(name) + '">Zurückziehen</button>');
return item(name, '<button type="button" data-action="cancel" data-user="' + esc(name) + '">Zurückziehen</button>');
}).join('') : '<span class="mf-small-hint">Keine gesendeten Anfragen.</span>';
q('[data-nn-connections]').innerHTML = data.connections.length ? data.connections.map(function (name) {
return item(name, '<button data-action="chat" data-user="' + esc(name) + '" class="' + (selected === name ? 'active' : '') + '">Chat</button>');
return item(name, '<button type="button" data-action="chat" data-user="' + esc(name) + '" class="' + (selected === name ? 'active' : '') + '">Chat</button>');
}).join('') : '<span class="mf-small-hint">Noch keine Verbindungen.</span>';
}
async function refresh() {
@@ -47,15 +47,19 @@
async function loadChat() {
if (!selected) return;
var rows = await api('/messages/' + encodeURIComponent(selected));
q('[data-nn-empty]').hidden = true;
q('[data-nn-conversation]').hidden = false;
q('[data-nn-partner]').textContent = selected;
q('[data-nn-messages]').innerHTML = rows.map(function (message) {
return '<article class="nn-message ' + (message.sender === me ? 'mine' : '') + '">' + esc(message.body) + '<small>' + esc(message.sender) + ' · ' + new Date(message.sentAt).toLocaleString('de-DE', { dateStyle: 'short', timeStyle: 'short' }) + '</small></article>';
}).join('');
var box = q('[data-nn-messages]');
box.scrollTop = box.scrollHeight;
}
function openChat(user) {
selected = user;
q('[data-nn-empty]').hidden = true;
q('[data-nn-conversation]').hidden = false;
q('[data-nn-partner]').textContent = user;
q('[data-nn-messages]').innerHTML = '<p class="mf-small-hint">Nachrichten werden geladen …</p>';
}
function message(text) {
var hint = q('.nn-head p');
hint.textContent = text;
@@ -77,7 +81,11 @@
if (!button) return;
var user = button.dataset.user, action = button.dataset.action;
try {
if (action === 'chat') { selected = user; await refresh(); await loadChat(); return; }
if (action === 'chat') {
openChat(user);
try { await loadChat(); } catch (error) { message(error.message); }
return;
}
if (action === 'accept') await api('/requests/' + encodeURIComponent(user) + '/accept', 'POST');
if (action === 'decline') await api('/requests/' + encodeURIComponent(user) + '/decline', 'POST');
if (action === 'cancel') await api('/requests/' + encodeURIComponent(user), 'DELETE');
+1 -1
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NeuralNet – SysnaptiK Neural</title>
<link rel="stylesheet" href="/css/theme.css?v=3"><link rel="stylesheet" href="/css/neuralnet.css?v=1">
<script src="/js/theme.js?v=3"></script><script src="/js/neuralnet.js?v=2" defer></script>
<script src="/js/theme.js?v=3"></script><script src="/js/neuralnet.js?v=3" defer></script>
</head>
<body>
<div class="mf-theme-float"><button class="mf-theme"></button></div>