Compare commits

...

7 Commits

Author SHA1 Message Date
admin 2b5cd19012 Erweitere Roman auf tausend Seiten 2025-11-06 14:44:31 +01:00
admin 7e8b0a2955 Merge pull request #16 from metacube2/codex/add-3d-traceroute-visualization-app
Improve 3D traceroute viewport resilience
2025-11-04 19:23:11 +01:00
admin 7328420bad Merge branch 'main' into codex/add-3d-traceroute-visualization-app 2025-11-04 19:22:52 +01:00
admin 5593d97e8e Fix 3D traceroute viewport sizing 2025-11-04 19:21:44 +01:00
admin 2bbbf7a7ea Merge pull request #15 from metacube2/codex/fix-verbindungsprobleme-in-chat.php-lboftv
Improve user list resilience and logout handling
2025-11-04 10:53:17 +01:00
admin c01dd3dfc4 Improve user list resilience and logout handling 2025-11-04 10:53:04 +01:00
admin 971ea73553 Merge pull request #14 from metacube2/codex/fix-verbindungsprobleme-in-chat.php
Make chat filters optional and improve fallback connectivity
2025-11-04 10:21:11 +01:00
2 changed files with 3185 additions and 18 deletions
+74 -18
View File
@@ -3193,6 +3193,14 @@ if (isset($_GET['stream']) && $_GET['stream'] === 'events') {
color: #c2410c; color: #c2410c;
} }
.user-list-error-banner {
margin: 12px 16px;
border-radius: 10px;
background: rgba(255, 237, 213, 0.85);
border: 1px solid rgba(251, 146, 60, 0.35);
padding: 12px 14px;
}
.chat-state-message.hidden { .chat-state-message.hidden {
display: none; display: none;
} }
@@ -4359,9 +4367,42 @@ async function loadUsers() {
} catch (error) { } catch (error) {
console.error('Nutzerliste konnte nicht geladen werden:', error); console.error('Nutzerliste konnte nicht geladen werden:', error);
state.isLoadingUsers = false; state.isLoadingUsers = false;
if (userListEl) {
userListEl.innerHTML = '<div class="error-state">Nutzerliste konnte nicht geladen werden.</div>'; const message = (error && error.message) ? error.message : 'Nutzerliste konnte nicht geladen werden.';
if (/nicht\s+eingeloggt/i.test(message) || /sitzung/i.test(message)) {
window.location.href = basePath;
return;
} }
if (userListEl) {
if (!Array.isArray(state.users) || state.users.length === 0) {
userListEl.innerHTML = '';
const errorBox = document.createElement('div');
errorBox.className = 'error-state user-list-error-banner';
errorBox.textContent = message;
userListEl.appendChild(errorBox);
} else {
const existingBanner = userListEl.querySelector('.user-list-error-banner');
if (existingBanner) {
existingBanner.remove();
}
const banner = document.createElement('div');
banner.className = 'error-state user-list-error-banner';
banner.textContent = message;
userListEl.prepend(banner);
setTimeout(() => {
if (banner.parentNode) {
banner.remove();
}
}, 5000);
}
}
setTimeout(() => {
if (!state.isLoadingUsers) {
loadUsers();
}
}, 5000);
} }
} }
@@ -4390,27 +4431,29 @@ function renderUserList() {
return; return;
} }
const offlineLimit = 5; const prioritizedUsers = filtered.slice();
const onlineUsers = [];
const offlineUsers = [];
filtered.forEach(user => { if (state.selectedUserId && !prioritizedUsers.some(user => Number(user.id) === Number(state.selectedUserId))) {
if (user.is_online) { const selectedUser = users.find(user => Number(user.id) === Number(state.selectedUserId));
onlineUsers.push(user); if (selectedUser && selectedUser.display_name.toLowerCase().includes(searchTerm)) {
} else { prioritizedUsers.push(selectedUser);
offlineUsers.push(user); }
} }
});
const limitedUsers = onlineUsers.concat(offlineUsers.slice(0, offlineLimit));
const seen = new Set();
const fragment = document.createDocumentFragment(); const fragment = document.createDocumentFragment();
limitedUsers.forEach(user => { prioritizedUsers.forEach(user => {
const userId = Number(user.id);
if (seen.has(userId)) {
return;
}
seen.add(userId);
const item = document.createElement('button'); const item = document.createElement('button');
item.type = 'button'; item.type = 'button';
item.className = 'user-item' + (Number(user.id) === Number(state.selectedUserId) ? ' active' : ''); item.className = 'user-item' + (userId === Number(state.selectedUserId) ? ' active' : '');
item.dataset.userId = String(user.id); item.dataset.userId = String(userId);
item.dataset.displayName = user.display_name; item.dataset.displayName = user.display_name;
const avatar = document.createElement('div'); const avatar = document.createElement('div');
@@ -4918,8 +4961,21 @@ userSearchInput?.addEventListener('input', () => renderUserList());
document.getElementById('logoutBtn')?.addEventListener('click', async () => { document.getElementById('logoutBtn')?.addEventListener('click', async () => {
const formData = new FormData(); const formData = new FormData();
formData.append('action', 'logout'); formData.append('action', 'logout');
await postFormData(formData);
window.location.reload(); try {
const response = await postFormData(formData);
const contentType = response.headers.get('content-type') || '';
if (contentType.includes('application/json')) {
const result = await response.json().catch(() => null);
if (result && result.success === false) {
throw new Error(result.error || 'Logout fehlgeschlagen.');
}
}
} catch (error) {
console.error('Logout fehlgeschlagen:', error);
} finally {
window.location.href = basePath;
}
}); });
chatInputEl?.addEventListener('input', function() { chatInputEl?.addEventListener('input', function() {
+3111
View File
File diff suppressed because it is too large Load Diff