Remove deprecated scripts for adding head-matter to wt_config.xml, including Python and Bash implementations, to streamline configuration management.

This commit is contained in:
Torsten Schulz (local)
2025-12-04 16:34:45 +01:00
parent 4b674c7c60
commit 6e9116e819
13187 changed files with 1493219 additions and 337 deletions

648
client/src/stores/chat.js Normal file
View File

@@ -0,0 +1,648 @@
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 remainingSecondsToTimeout = ref(1800);
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('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':
if (currentConversation.value === data.from) {
messages.value.push({
from: data.from,
message: data.message,
timestamp: data.timestamp,
self: false,
isImage: data.isImage || false,
imageType: data.imageType || null
});
}
// 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.message,
timestamp: msg.timestamp,
self: msg.from === userName.value,
isImage: msg.isImage || false,
imageType: msg.imageType || null
}));
break;
case 'searchResults':
searchResults.value = data.results;
break;
case 'inboxResults':
inboxResults.value = data.results;
break;
case 'historyResults':
historyResults.value = data.results;
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) {
if (!socket.value || !socket.value.connected) {
console.error('Socket.IO nicht verbunden');
return;
}
const messageId = Date.now().toString();
socket.value.emit('message', {
toUserName,
message,
messageId
});
// Lokal hinzufügen
messages.value.push({
from: userName.value,
message,
timestamp: new Date().toISOString(),
self: true
});
// Timeout zurücksetzen bei Aktivität
resetTimeoutTimer();
}
function sendImage(toUserName, imageData, imageType) {
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: imageData, // Base64-kodiertes Bild
messageId,
isImage: true,
imageType: imageType
});
// Lokal hinzufügen
messages.value.push({
from: userName.value,
message: imageData,
timestamp: new Date().toISOString(),
self: true,
isImage: true,
imageType: imageType
});
// 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 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 = [];
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,
searchData,
// Computed
currentConversationWith,
// Actions
connectWebSocket,
login,
sendMessage,
sendImage,
requestConversation,
userSearch,
requestHistory,
requestOpenConversations,
setView,
logout,
restoreSession
};
});