- Introduced `commandTable` state in chat store to manage command output. - Implemented WebSocket listener for `commandTable` messages. - Enhanced ChatView.vue to display command table with dynamic content and styling. - Added `clearCommandTable` method to reset command table state. - Updated server broadcast logic to send structured command table data for various statistics.
733 lines
24 KiB
JavaScript
733 lines
24 KiB
JavaScript
import { defineStore } from 'pinia';
|
|
import { ref, computed } from 'vue';
|
|
import { io } from 'socket.io-client';
|
|
|
|
export const useChatStore = defineStore('chat', () => {
|
|
// State
|
|
const isLoggedIn = ref(false);
|
|
const userName = ref('');
|
|
const gender = ref('');
|
|
const age = ref(0);
|
|
const country = ref('');
|
|
const isoCountryCode = ref('');
|
|
const sessionId = ref('');
|
|
const socket = ref(null);
|
|
const users = ref([]);
|
|
const currentConversation = ref(null);
|
|
const messages = ref([]);
|
|
const currentView = ref('chat');
|
|
const searchResults = ref([]);
|
|
const inboxResults = ref([]);
|
|
const historyResults = ref([]);
|
|
const unreadChatsCount = ref(0);
|
|
const errorMessage = ref(null);
|
|
const commandTable = ref(null);
|
|
const remainingSecondsToTimeout = ref(1800);
|
|
const awaitingLoginUsername = ref(false);
|
|
const awaitingLoginPassword = ref(false);
|
|
const searchData = ref({
|
|
nameIncludes: '',
|
|
minAge: null,
|
|
maxAge: null,
|
|
genders: [],
|
|
selectedCountries: [], // Übersetzte Namen (für UI)
|
|
selectedCountriesEnglish: [] // Englische Namen (für Server)
|
|
});
|
|
let timeoutTimer = null;
|
|
const TIMEOUT_SECONDS = 1800; // 30 Minuten
|
|
|
|
// Computed
|
|
const currentConversationWith = computed(() => {
|
|
if (!currentConversation.value) return null;
|
|
return currentConversation.value;
|
|
});
|
|
|
|
// Actions
|
|
function connectWebSocket() {
|
|
return new Promise((resolve, reject) => {
|
|
// Schließe alte Verbindung, falls vorhanden
|
|
if (socket.value) {
|
|
try {
|
|
socket.value.disconnect();
|
|
} catch (e) {
|
|
// Ignoriere Fehler beim Schließen
|
|
}
|
|
socket.value = null;
|
|
}
|
|
|
|
let url;
|
|
|
|
if (import.meta.env.DEV) {
|
|
// Socket.IO läuft jetzt auf dem gleichen Port wie Express
|
|
url = 'http://localhost:3300';
|
|
} else {
|
|
// In Production: Socket.IO läuft über den gleichen Host/Port wie die Webseite
|
|
// Apache leitet alles an den Backend-Server weiter
|
|
url = window.location.origin;
|
|
}
|
|
|
|
console.log('=== Socket.IO-Verbindung ===');
|
|
console.log('Versuche Socket.IO-Verbindung zu:', url);
|
|
console.log('Aktuelle Seite:', window.location.href);
|
|
console.log('DEV-Modus:', import.meta.env.DEV);
|
|
|
|
let timeoutId;
|
|
let resolved = false;
|
|
|
|
try {
|
|
const socketInstance = io(url, {
|
|
transports: ['polling'], // Nur Polling verwenden, um WebSocket-Probleme zu vermeiden
|
|
reconnection: true,
|
|
reconnectionAttempts: 5,
|
|
reconnectionDelay: 1000,
|
|
upgrade: false, // Kein Upgrade zu WebSocket
|
|
rememberUpgrade: false,
|
|
withCredentials: true // Wichtig für Cookies/Sessions
|
|
});
|
|
|
|
// Timeout nach 5 Sekunden
|
|
timeoutId = setTimeout(() => {
|
|
if (!resolved) {
|
|
resolved = true;
|
|
socketInstance.disconnect();
|
|
reject(new Error('Socket.IO-Verbindung-Timeout: Server antwortet nicht. Bitte stelle sicher, dass der Server auf Port 3300 läuft.'));
|
|
}
|
|
}, 5000);
|
|
|
|
socketInstance.on('connect', async () => {
|
|
if (!resolved) {
|
|
resolved = true;
|
|
clearTimeout(timeoutId);
|
|
console.log('Socket.IO-Verbindung erfolgreich');
|
|
socket.value = socketInstance;
|
|
|
|
// Hole Express-Session-ID und sende sie an den Server
|
|
try {
|
|
const response = await fetch('/api/session', {
|
|
credentials: 'include'
|
|
});
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
if (data.sessionId) {
|
|
console.log('Socket.IO Connect - Sende Express-Session-ID:', data.sessionId);
|
|
socketInstance.emit('setSessionId', { expressSessionId: data.sessionId });
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Fehler beim Abrufen der Session-ID:', error);
|
|
}
|
|
|
|
resolve(socketInstance);
|
|
}
|
|
});
|
|
|
|
socketInstance.on('connected', (data) => {
|
|
console.log('Connected-Nachricht empfangen:', data);
|
|
sessionId.value = data.sessionId;
|
|
|
|
// Wenn bereits eingeloggt, Login-Status wiederherstellen
|
|
if (data.loggedIn && data.user) {
|
|
isLoggedIn.value = true;
|
|
userName.value = data.user.userName;
|
|
gender.value = data.user.gender;
|
|
age.value = data.user.age;
|
|
country.value = data.user.country;
|
|
isoCountryCode.value = data.user.isoCountryCode;
|
|
startTimeoutTimer();
|
|
}
|
|
});
|
|
|
|
socketInstance.on('disconnect', (reason) => {
|
|
console.log('Socket.IO-Verbindung getrennt:', reason);
|
|
socket.value = null;
|
|
});
|
|
|
|
socketInstance.on('connect_error', (error) => {
|
|
console.error('Socket.IO Verbindungsfehler:', error);
|
|
if (!resolved) {
|
|
resolved = true;
|
|
clearTimeout(timeoutId);
|
|
reject(new Error('Socket.IO-Verbindung fehlgeschlagen: ' + error.message));
|
|
}
|
|
});
|
|
|
|
// Event-Handler für verschiedene Nachrichtentypen
|
|
socketInstance.on('loginSuccess', (data) => {
|
|
handleWebSocketMessage({ type: 'loginSuccess', ...data });
|
|
});
|
|
|
|
socketInstance.on('userList', (data) => {
|
|
handleWebSocketMessage({ type: 'userList', ...data });
|
|
});
|
|
|
|
socketInstance.on('message', (data) => {
|
|
handleWebSocketMessage({ type: 'message', ...data });
|
|
});
|
|
|
|
socketInstance.on('messageSent', (data) => {
|
|
handleWebSocketMessage({ type: 'messageSent', ...data });
|
|
});
|
|
|
|
socketInstance.on('messageSent', (data) => {
|
|
handleWebSocketMessage({ type: 'messageSent', ...data });
|
|
});
|
|
|
|
socketInstance.on('conversation', (data) => {
|
|
handleWebSocketMessage({ type: 'conversation', ...data });
|
|
});
|
|
|
|
socketInstance.on('searchResults', (data) => {
|
|
handleWebSocketMessage({ type: 'searchResults', ...data });
|
|
});
|
|
|
|
socketInstance.on('inboxResults', (data) => {
|
|
handleWebSocketMessage({ type: 'inboxResults', ...data });
|
|
});
|
|
|
|
socketInstance.on('historyResults', (data) => {
|
|
handleWebSocketMessage({ type: 'historyResults', ...data });
|
|
});
|
|
|
|
socketInstance.on('commandResult', (data) => {
|
|
handleWebSocketMessage({ type: 'commandResult', ...data });
|
|
});
|
|
|
|
socketInstance.on('commandTable', (data) => {
|
|
handleWebSocketMessage({ type: 'commandTable', ...data });
|
|
});
|
|
|
|
socketInstance.on('unreadChats', (data) => {
|
|
handleWebSocketMessage({ type: 'unreadChats', ...data });
|
|
});
|
|
|
|
socketInstance.on('error', (data) => {
|
|
handleWebSocketMessage({ type: 'error', ...data });
|
|
});
|
|
|
|
console.log('Socket.IO-Objekt erstellt');
|
|
} catch (error) {
|
|
if (timeoutId) clearTimeout(timeoutId);
|
|
console.error('Fehler beim Erstellen der Socket.IO-Verbindung:', error);
|
|
reject(new Error('Fehler beim Erstellen der Socket.IO-Verbindung: ' + error.message));
|
|
}
|
|
});
|
|
}
|
|
|
|
function handleWebSocketMessage(data) {
|
|
console.log('WebSocket-Nachricht empfangen:', data.type);
|
|
|
|
switch (data.type) {
|
|
case 'connected':
|
|
sessionId.value = data.sessionId;
|
|
break;
|
|
case 'loginSuccess':
|
|
isLoggedIn.value = true;
|
|
userName.value = data.user.userName;
|
|
gender.value = data.user.gender;
|
|
age.value = data.user.age;
|
|
country.value = data.user.country;
|
|
isoCountryCode.value = data.user.isoCountryCode;
|
|
sessionId.value = data.sessionId;
|
|
break;
|
|
case 'userList':
|
|
users.value = data.users;
|
|
// Aktualisiere Suchergebnisse, falls eine Suche aktiv ist
|
|
updateSearchResults();
|
|
break;
|
|
case 'message':
|
|
// Debug-Logging für empfangene Nachrichten
|
|
if (data.isImage) {
|
|
console.log('[Bild empfangen] Von:', data.from, 'URL:', data.imageUrl || data.message);
|
|
}
|
|
|
|
// Sound abspielen bei neuer Nachricht (nur wenn nicht selbst gesendet)
|
|
if (!data.self) {
|
|
try {
|
|
const audio = new Audio('/static/newmessage.mp3');
|
|
audio.play().catch(err => {
|
|
// Ignoriere Fehler (z.B. wenn Browser Auto-Play blockiert)
|
|
console.log('Sound konnte nicht abgespielt werden:', err);
|
|
});
|
|
} catch (error) {
|
|
console.log('Fehler beim Abspielen des Sounds:', error);
|
|
}
|
|
}
|
|
|
|
if (currentConversation.value === data.from) {
|
|
const newMessage = {
|
|
from: data.from,
|
|
message: data.imageUrl || data.message, // Verwende URL für Bilder
|
|
timestamp: data.timestamp,
|
|
self: false,
|
|
isImage: data.isImage || false,
|
|
imageType: data.imageType || null,
|
|
imageUrl: data.imageUrl || null,
|
|
imageCode: data.imageCode || null
|
|
};
|
|
|
|
console.log('[Nachricht hinzugefügt]', newMessage);
|
|
messages.value.push(newMessage);
|
|
} else {
|
|
console.log('[Nachricht ignoriert] Aktuelle Konversation:', currentConversation.value, 'Nachricht von:', data.from);
|
|
}
|
|
// Timeout zurücksetzen bei empfangener Nachricht
|
|
resetTimeoutTimer();
|
|
break;
|
|
case 'messageSent':
|
|
// Bestätigung, dass Nachricht gesendet wurde
|
|
break;
|
|
case 'conversation':
|
|
currentConversation.value = data.with;
|
|
messages.value = data.messages.map(msg => ({
|
|
from: msg.from,
|
|
message: msg.imageUrl || msg.message, // Verwende URL für Bilder
|
|
timestamp: msg.timestamp,
|
|
self: msg.from === userName.value,
|
|
isImage: msg.isImage || false,
|
|
imageType: msg.imageType || null,
|
|
imageUrl: msg.imageUrl || null,
|
|
imageCode: msg.imageCode || null
|
|
}));
|
|
break;
|
|
case 'searchResults':
|
|
searchResults.value = data.results;
|
|
break;
|
|
case 'inboxResults':
|
|
inboxResults.value = data.results;
|
|
break;
|
|
case 'historyResults':
|
|
historyResults.value = data.results;
|
|
break;
|
|
case 'commandResult': {
|
|
const lines = Array.isArray(data.lines) ? data.lines : [];
|
|
const kind = data.kind || 'info';
|
|
|
|
if (kind === 'loginPromptUsername') {
|
|
awaitingLoginUsername.value = true;
|
|
awaitingLoginPassword.value = false;
|
|
} else if (kind === 'loginPromptPassword') {
|
|
awaitingLoginUsername.value = false;
|
|
awaitingLoginPassword.value = true;
|
|
} else if (kind === 'loginSuccess' || kind === 'loginError' || kind === 'loginAbort' || kind === 'loginLogout') {
|
|
awaitingLoginUsername.value = false;
|
|
awaitingLoginPassword.value = false;
|
|
}
|
|
|
|
// Command-Ausgaben immer global anzeigen, nicht im Chatverlauf.
|
|
errorMessage.value = lines.join(' | ');
|
|
setTimeout(() => {
|
|
errorMessage.value = null;
|
|
}, 5000);
|
|
break;
|
|
}
|
|
case 'commandTable': {
|
|
const title = data.title || 'Ausgabe';
|
|
const columns = Array.isArray(data.columns) ? data.columns : [];
|
|
const rows = Array.isArray(data.rows) ? data.rows : [];
|
|
commandTable.value = { title, columns, rows };
|
|
// Tabelle ist persistent; temporäre Fehlermeldung löschen
|
|
errorMessage.value = null;
|
|
break;
|
|
}
|
|
case 'unreadChats':
|
|
unreadChatsCount.value = data.count || 0;
|
|
break;
|
|
case 'error':
|
|
console.error('Server-Fehler:', data.message);
|
|
errorMessage.value = data.message;
|
|
// Fehlermeldung nach 5 Sekunden automatisch entfernen
|
|
setTimeout(() => {
|
|
errorMessage.value = null;
|
|
}, 5000);
|
|
break;
|
|
}
|
|
}
|
|
|
|
async function login(userNameVal, genderVal, ageVal, countryVal) {
|
|
// Stelle sicher, dass Socket.IO verbunden ist
|
|
if (!socket.value || !socket.value.connected) {
|
|
console.log('Socket.IO nicht verbunden, versuche Verbindung herzustellen...');
|
|
try {
|
|
await connectWebSocket();
|
|
// Warte kurz, damit die Verbindung vollständig hergestellt ist
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
} catch (error) {
|
|
console.error('Fehler beim Verbinden mit Socket.IO:', error);
|
|
alert('Verbindung zum Server fehlgeschlagen. Bitte stelle sicher, dass der Server läuft.');
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Prüfe nochmal, ob die Verbindung jetzt besteht
|
|
if (!socket.value || !socket.value.connected) {
|
|
console.error('Socket.IO-Verbindung konnte nicht hergestellt werden');
|
|
alert('Verbindung zum Server fehlgeschlagen. Bitte stelle sicher, dass der Server läuft.');
|
|
return;
|
|
}
|
|
|
|
// Hole Express-Session-ID vom Server
|
|
let expressSessionId = null;
|
|
try {
|
|
const response = await fetch('/api/session', {
|
|
credentials: 'include'
|
|
});
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
expressSessionId = data.sessionId;
|
|
console.log('Login - Express-Session-ID erhalten:', expressSessionId);
|
|
}
|
|
} catch (error) {
|
|
console.error('Fehler beim Abrufen der Session-ID:', error);
|
|
}
|
|
|
|
socket.value.emit('login', {
|
|
userName: userNameVal,
|
|
gender: genderVal,
|
|
age: ageVal,
|
|
country: countryVal,
|
|
expressSessionId: expressSessionId
|
|
});
|
|
}
|
|
|
|
function sendMessage(toUserName, message, options = {}) {
|
|
if (!socket.value || !socket.value.connected) {
|
|
console.error('Socket.IO nicht verbunden');
|
|
return;
|
|
}
|
|
|
|
const messageId = Date.now().toString();
|
|
const trimmed = message.trim();
|
|
const isCommand = trimmed.startsWith('/');
|
|
socket.value.emit('message', {
|
|
toUserName,
|
|
message: trimmed,
|
|
messageId
|
|
});
|
|
|
|
const suppressLocal = !!options.suppressLocal || isCommand || awaitingLoginUsername.value || awaitingLoginPassword.value;
|
|
|
|
// Lokal hinzufügen (außer bei Commands oder sensiblen Eingaben wie Login)
|
|
if (!isCommand && !suppressLocal) {
|
|
messages.value.push({
|
|
from: userName.value,
|
|
message: trimmed,
|
|
timestamp: new Date().toISOString(),
|
|
self: true
|
|
});
|
|
}
|
|
|
|
// Timeout zurücksetzen bei Aktivität
|
|
resetTimeoutTimer();
|
|
}
|
|
|
|
function sendImage(toUserName, imageCode, imageUrl) {
|
|
if (!socket.value || !socket.value.connected) {
|
|
console.error('Socket.IO nicht verbunden');
|
|
return;
|
|
}
|
|
|
|
if (!toUserName) {
|
|
console.error('Empfänger fehlt');
|
|
return;
|
|
}
|
|
|
|
const messageId = Date.now().toString();
|
|
socket.value.emit('message', {
|
|
toUserName,
|
|
message: imageCode, // Nur der Code, nicht das gesamte Bild
|
|
messageId,
|
|
isImage: true,
|
|
imageUrl: imageUrl // URL für das Bild
|
|
});
|
|
|
|
// Lokal hinzufügen (mit URL)
|
|
messages.value.push({
|
|
from: userName.value,
|
|
message: imageUrl, // Verwende URL statt Code für lokale Anzeige
|
|
timestamp: new Date().toISOString(),
|
|
self: true,
|
|
isImage: true,
|
|
imageCode: imageCode
|
|
});
|
|
|
|
// Timeout zurücksetzen bei Aktivität
|
|
resetTimeoutTimer();
|
|
}
|
|
|
|
function requestConversation(withUserName) {
|
|
if (!socket.value || !socket.value.connected) {
|
|
console.error('Socket.IO nicht verbunden');
|
|
errorMessage.value = 'Socket.IO nicht verbunden';
|
|
setTimeout(() => {
|
|
errorMessage.value = null;
|
|
}, 5000);
|
|
return;
|
|
}
|
|
|
|
// Fehlermeldung zurücksetzen
|
|
errorMessage.value = null;
|
|
|
|
socket.value.emit('requestConversation', {
|
|
withUserName
|
|
});
|
|
|
|
currentConversation.value = withUserName;
|
|
currentView.value = 'chat';
|
|
}
|
|
|
|
function userSearch(searchDataPayload) {
|
|
if (!socket.value || !socket.value.connected) {
|
|
console.error('Socket.IO nicht verbunden');
|
|
errorMessage.value = 'Socket.IO nicht verbunden';
|
|
setTimeout(() => {
|
|
errorMessage.value = null;
|
|
}, 5000);
|
|
return;
|
|
}
|
|
|
|
// Fehlermeldung zurücksetzen
|
|
errorMessage.value = null;
|
|
|
|
// Speichere Suchparameter für spätere Aktualisierungen
|
|
// Hinweis: selectedCountries wird in SearchView.vue verwaltet und enthält übersetzte Namen
|
|
// Für updateSearchResults speichern wir auch die englischen Länder-Namen
|
|
searchData.value.nameIncludes = searchDataPayload.nameIncludes || '';
|
|
searchData.value.minAge = searchDataPayload.minAge || null;
|
|
searchData.value.maxAge = searchDataPayload.maxAge || null;
|
|
searchData.value.genders = searchDataPayload.genders || [];
|
|
// Speichere die englischen Länder-Namen für spätere Aktualisierungen
|
|
if (searchDataPayload.countries) {
|
|
searchData.value.selectedCountriesEnglish = searchDataPayload.countries;
|
|
}
|
|
|
|
socket.value.emit('userSearch', searchDataPayload);
|
|
resetTimeoutTimer(); // Aktivität zurücksetzen
|
|
}
|
|
|
|
function updateSearchResults() {
|
|
// Aktualisiere Suchergebnisse nur, wenn eine Suche aktiv ist
|
|
// Prüfe, ob der Benutzer auf der Suchseite ist UND ob es bereits Suchergebnisse gibt
|
|
const hasSearchResults = searchResults.value && searchResults.value.length > 0;
|
|
const hasSearchParams = searchData.value.nameIncludes ||
|
|
searchData.value.minAge ||
|
|
searchData.value.maxAge ||
|
|
(searchData.value.selectedCountries && searchData.value.selectedCountries.length > 0) ||
|
|
(searchData.value.genders && searchData.value.genders.length > 0);
|
|
|
|
// Aktualisiere nur, wenn der Benutzer auf der Suchseite ist UND (Ergebnisse vorhanden ODER Parameter gesetzt)
|
|
if (currentView.value !== 'search' || (!hasSearchResults && !hasSearchParams)) {
|
|
return;
|
|
}
|
|
|
|
// Führe die Suche erneut aus, um aktuelle Ergebnisse zu erhalten
|
|
// Verwende die englischen Länder-Namen, die beim letzten Suchvorgang gespeichert wurden
|
|
const searchPayload = {
|
|
nameIncludes: searchData.value.nameIncludes || null,
|
|
minAge: searchData.value.minAge || null,
|
|
maxAge: searchData.value.maxAge || null,
|
|
countries: searchData.value.selectedCountriesEnglish && searchData.value.selectedCountriesEnglish.length > 0
|
|
? searchData.value.selectedCountriesEnglish
|
|
: null,
|
|
genders: searchData.value.genders && searchData.value.genders.length > 0
|
|
? searchData.value.genders
|
|
: null
|
|
};
|
|
|
|
// Sende Suchanfrage erneut an den Server
|
|
if (socket.value && socket.value.connected) {
|
|
socket.value.emit('userSearch', searchPayload);
|
|
}
|
|
}
|
|
|
|
function requestHistory() {
|
|
if (!socket.value || !socket.value.connected) {
|
|
console.error('Socket.IO nicht verbunden');
|
|
return;
|
|
}
|
|
|
|
socket.value.emit('requestHistory');
|
|
}
|
|
|
|
function requestOpenConversations() {
|
|
if (!socket.value || !socket.value.connected) {
|
|
console.error('Socket.IO nicht verbunden');
|
|
return;
|
|
}
|
|
|
|
socket.value.emit('requestOpenConversations');
|
|
}
|
|
|
|
function clearCommandTable() {
|
|
commandTable.value = null;
|
|
}
|
|
|
|
function setView(view) {
|
|
currentView.value = view;
|
|
|
|
// Search-Ergebnisse NICHT zurücksetzen, damit sie beim Zurückkehren erhalten bleiben
|
|
if (view === 'search') {
|
|
// Wenn zur Suchseite zurückgekehrt wird, aktualisiere die Suchergebnisse
|
|
// falls bereits Suchparameter vorhanden sind
|
|
updateSearchResults();
|
|
} else if (view === 'inbox') {
|
|
requestOpenConversations();
|
|
} else if (view === 'history') {
|
|
requestHistory();
|
|
}
|
|
}
|
|
|
|
function logout() {
|
|
stopTimeoutTimer();
|
|
isLoggedIn.value = false;
|
|
userName.value = '';
|
|
gender.value = '';
|
|
age.value = 0;
|
|
country.value = '';
|
|
isoCountryCode.value = '';
|
|
sessionId.value = '';
|
|
users.value = [];
|
|
currentConversation.value = null;
|
|
messages.value = [];
|
|
currentView.value = 'chat';
|
|
searchResults.value = [];
|
|
inboxResults.value = [];
|
|
historyResults.value = [];
|
|
commandTable.value = null;
|
|
searchData.value = {
|
|
nameIncludes: '',
|
|
minAge: null,
|
|
maxAge: null,
|
|
genders: [],
|
|
selectedCountries: [],
|
|
selectedCountriesEnglish: []
|
|
};
|
|
|
|
if (socket.value) {
|
|
socket.value.disconnect();
|
|
socket.value = null;
|
|
}
|
|
}
|
|
|
|
function startTimeoutTimer() {
|
|
stopTimeoutTimer(); // Stoppe alten Timer, falls vorhanden
|
|
remainingSecondsToTimeout.value = TIMEOUT_SECONDS;
|
|
|
|
timeoutTimer = setInterval(() => {
|
|
remainingSecondsToTimeout.value--;
|
|
|
|
if (remainingSecondsToTimeout.value <= 0) {
|
|
stopTimeoutTimer();
|
|
// Auto-Logout
|
|
console.log('Timeout erreicht - automatischer Logout');
|
|
logout();
|
|
}
|
|
}, 1000); // Jede Sekunde aktualisieren
|
|
}
|
|
|
|
function resetTimeoutTimer() {
|
|
if (isLoggedIn.value && timeoutTimer) {
|
|
remainingSecondsToTimeout.value = TIMEOUT_SECONDS;
|
|
}
|
|
}
|
|
|
|
function stopTimeoutTimer() {
|
|
if (timeoutTimer) {
|
|
clearInterval(timeoutTimer);
|
|
timeoutTimer = null;
|
|
}
|
|
remainingSecondsToTimeout.value = TIMEOUT_SECONDS;
|
|
}
|
|
|
|
async function restoreSession() {
|
|
try {
|
|
console.log('restoreSession: Starte Session-Wiederherstellung...');
|
|
const response = await fetch('/api/session', {
|
|
credentials: 'include' // Wichtig für Cookies
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.log('restoreSession: Response nicht OK:', response.status);
|
|
return false;
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log('restoreSession: Antwort vom Server:', data);
|
|
|
|
if (data.loggedIn && data.user) {
|
|
console.log('restoreSession: Session gefunden, stelle Login-Status wieder her...');
|
|
// Session wiederherstellen
|
|
isLoggedIn.value = true;
|
|
userName.value = data.user.userName;
|
|
gender.value = data.user.gender;
|
|
age.value = data.user.age;
|
|
country.value = data.user.country;
|
|
isoCountryCode.value = data.user.isoCountryCode;
|
|
sessionId.value = data.user.sessionId;
|
|
|
|
console.log('restoreSession: Login-Status wiederhergestellt:', {
|
|
userName: userName.value,
|
|
sessionId: sessionId.value
|
|
});
|
|
|
|
// WebSocket-Verbindung herstellen
|
|
try {
|
|
await connectWebSocket();
|
|
startTimeoutTimer();
|
|
} catch (error) {
|
|
console.error('Fehler beim Wiederherstellen der WebSocket-Verbindung:', error);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
console.log('restoreSession: Keine gültige Session gefunden');
|
|
return false;
|
|
} catch (error) {
|
|
console.error('Fehler beim Wiederherstellen der Session:', error);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return {
|
|
// State
|
|
isLoggedIn,
|
|
userName,
|
|
gender,
|
|
age,
|
|
country,
|
|
isoCountryCode,
|
|
sessionId,
|
|
socket,
|
|
users,
|
|
currentConversation,
|
|
messages,
|
|
currentView,
|
|
searchResults,
|
|
inboxResults,
|
|
historyResults,
|
|
unreadChatsCount,
|
|
remainingSecondsToTimeout,
|
|
errorMessage,
|
|
commandTable,
|
|
searchData,
|
|
awaitingLoginUsername,
|
|
awaitingLoginPassword,
|
|
// Computed
|
|
currentConversationWith,
|
|
// Actions
|
|
connectWebSocket,
|
|
login,
|
|
sendMessage,
|
|
sendImage,
|
|
requestConversation,
|
|
userSearch,
|
|
requestHistory,
|
|
requestOpenConversations,
|
|
clearCommandTable,
|
|
setView,
|
|
logout,
|
|
restoreSession
|
|
};
|
|
});
|
|
|