Update chat configuration and remove MultiChat component: Change chat port to 1236 in chatBridge.json, update WebSocket URL in .env.local, and delete the MultiChat.vue component to streamline chat functionality.

This commit is contained in:
Torsten Schulz (local)
2026-03-04 17:24:15 +01:00
parent a2652c983f
commit 407c3b359b
4 changed files with 43 additions and 167 deletions

View File

@@ -1,4 +1,4 @@
{
"host": "localhost",
"port": 1235
"port": 1236
}

View File

@@ -1,4 +1,4 @@
VITE_API_BASE_URL=http://localhost:3001
VITE_TINYMCE_API_KEY=xjqnfymt2wd5q95onkkwgblzexams6l6naqjs01x72ftzryg
VITE_DAEMON_SOCKET=ws://localhost:4551
VITE_CHAT_WS_URL=ws://localhost.de:1235
VITE_CHAT_WS_URL=ws://127.0.0.1:1235

View File

@@ -1,148 +0,0 @@
<template>
<DialogWidget ref="dialog" :title="$t('chat.multichat.title')" :modal="true" width="40em" height="32em" name="MultiChat">
<div class="multi-chat-top">
<select v-model="selectedRoom" class="room-select">
<option v-for="room in rooms" :key="room.id" :value="room.id">{{ room.title }}</option>
</select>
<div class="options-popdown">
<label>
<input type="checkbox" v-model="autoscroll" />
{{ $t('chat.multichat.autoscroll') }}
</label>
<!-- Weitere Optionen können hier ergänzt werden -->
</div>
</div>
<div class="multi-chat-output" ref="output" @mouseenter="mouseOverOutput = true" @mouseleave="mouseOverOutput = false">
<div v-for="msg in messages" :key="msg.id" class="chat-message">
<span class="user">{{ msg.user }}:</span> <span class="text">{{ msg.text }}</span>
</div>
</div>
<div class="multi-chat-input">
<input v-model="input" @keyup.enter="sendMessage" class="chat-input" :placeholder="$t('chat.multichat.placeholder')" />
<button @click="sendMessage" class="send-btn">{{ $t('chat.multichat.send') }}</button>
<button @click="shout" class="mini-btn">{{ $t('chat.multichat.shout') }}</button>
<button @click="action" class="mini-btn">{{ $t('chat.multichat.action') }}</button>
<button @click="roll" class="mini-btn">{{ $t('chat.multichat.roll') }}</button>
</div>
</DialogWidget>
</template>
<script>
import DialogWidget from '@/components/DialogWidget.vue';
export default {
name: 'MultiChat',
components: { DialogWidget },
data() {
return {
rooms: [],
selectedRoom: null,
autoscroll: true,
mouseOverOutput: false,
messages: [],
input: ''
};
},
watch: {
messages() {
this.$nextTick(this.handleAutoscroll);
},
autoscroll(val) {
if (val) this.handleAutoscroll();
}
},
methods: {
open(rooms = []) {
this.rooms = rooms;
this.selectedRoom = rooms.length ? rooms[0].id : null;
this.autoscroll = true;
this.messages = [];
this.input = '';
this.$refs.dialog.open();
},
handleAutoscroll() {
if (this.autoscroll && !this.mouseOverOutput) {
const out = this.$refs.output;
if (out) out.scrollTop = out.scrollHeight;
}
},
sendMessage() {
if (!this.input.trim()) return;
this.messages.push({ id: Date.now(), user: 'Ich', text: this.input });
this.input = '';
},
shout() {
// Schreien-Logik
},
action() {
// Aktion-Logik
},
roll() {
// Würfeln-Logik
}
}
};
</script>
<style scoped>
.multi-chat-top {
display: flex;
align-items: center;
gap: 1em;
margin-bottom: 0.5em;
}
.room-select {
min-width: 10em;
}
.options-popdown {
background: #f5f5f5;
border-radius: 4px;
padding: 0.3em 0.8em;
font-size: 0.95em;
}
.multi-chat-output {
background: #222;
color: #fff;
height: 16em;
overflow-y: auto;
margin-bottom: 0.5em;
padding: 0.7em;
border-radius: 4px;
font-size: 1em;
}
.chat-message {
margin-bottom: 0.3em;
}
.user {
font-weight: bold;
color: #90caf9;
}
.multi-chat-input {
display: flex;
align-items: center;
gap: 0.5em;
}
.chat-input {
flex: 1;
padding: 0.4em 0.7em;
border-radius: 3px;
border: 1px solid #bbb;
}
.send-btn {
padding: 0.3em 1.1em;
border-radius: 3px;
background: #1976d2;
color: #fff;
border: none;
cursor: pointer;
}
.mini-btn {
padding: 0.2em 0.7em;
font-size: 0.95em;
border-radius: 3px;
background: #eee;
color: #333;
border: 1px solid #bbb;
cursor: pointer;
}
</style>

View File

@@ -216,7 +216,7 @@ export default {
selectedRoom(newVal, oldVal) {
if (newVal && this.transportConnected) {
const room = this.getSelectedRoomName();
if (room) this.sendWithToken({ type: 'join', room, name: this.user?.username || '' });
if (room) this.sendWithToken({ type: 'join', room, password: '' });
this.messages = [];
this.usersInRoom = [];
this.selectedTargetUser = null;
@@ -301,14 +301,9 @@ export default {
async reloadRoomsAdmin() {
if (!this.isAdmin) return;
try {
const current = this.selectedRoom;
const data = await fetchPublicRooms();
const rooms = Array.isArray(data) ? data : [];
this.rooms = rooms;
if (!rooms.find(r => r.id === current)) {
this.selectedRoom = rooms.length ? rooms[0].id : null;
}
this.messages.push({ id: Date.now(), user: 'System', text: 'Raumliste aktualisiert.' });
this.sendWithToken({ type: 'reload_rooms' });
this.sendWithToken({ type: 'rooms' });
this.messages.push({ id: Date.now(), user: 'System', text: 'Raum-Reload angefordert.' });
} catch (e) {
console.error('Fehler beim Neuladen der Räume', e);
this.messages.push({ id: Date.now(), user: 'System', text: 'Fehler beim Neuladen der Raumliste.' });
@@ -446,7 +441,7 @@ export default {
// Drop references to losers so GC can collect
this.pendingWs = [];
// Prepare handshake like before
const init = { type: 'init', name: this.user?.username || '', room: this.getSelectedRoomName() || '' };
const init = { type: 'init', name: this.user?.username || '', room: this.getSelectedRoomName() || '', password: '' };
if (this.debug) console.log('[Chat WS >>]', init);
this.wsSend(init);
if (this.connectAttemptTimeout) clearTimeout(this.connectAttemptTimeout);
@@ -543,7 +538,7 @@ export default {
this.transportConnected = true;
const dt = Date.now() - (this.wsStartAt || Date.now());
console.log('[Chat WS] open in', dt, 'ms', '| protocol:', ws.protocol || '(none)', '| url:', url);
const init = { type: 'init', name: this.user?.username || '', room: this.getSelectedRoomName() || '' };
const init = { type: 'init', name: this.user?.username || '', room: this.getSelectedRoomName() || '', password: '' };
if (this.debug) console.log('[Chat WS >>]', init);
this.wsSend(init);
if (this.connectOpenTimer) { clearTimeout(this.connectOpenTimer); this.connectOpenTimer = null; }
@@ -661,9 +656,8 @@ export default {
}
try {
// Send a ping message to keep connection alive
this.wsSend({ type: 'ping' });
console.log('[Chat WS] Heartbeat sent');
// Keepalive via supported protocol command
if (this.token) this.wsSend({ type: 'userlist', token: this.token });
} catch (error) {
console.warn('[Chat WS] Heartbeat failed:', error);
this.stopHeartbeat();
@@ -823,7 +817,7 @@ export default {
action() {
if (!this.input.trim()) return;
if (!this.selectedTargetUser) return; // Nur mit Auswahl
const payload = { type: 'do', value: this.input, to: this.selectedTargetUser };
const payload = { type: 'do', message: `${this.input} ${this.selectedTargetUser}`.trim() };
if (this.debug) console.log('[Chat WS >>]', payload);
this.sendWithToken(payload);
this.input = '';
@@ -1053,6 +1047,12 @@ export default {
},
onWsObject(obj) {
if (!obj) return;
if (obj.type === 'error') {
const text = obj.message || 'chat_error';
this.setStatus('error');
this.messages.push({ id: Date.now(), user: 'System', text: `Fehler: ${text}` });
return;
}
// Token handshake: only when explicitly marked as token-type
if (obj.type === 'token' || obj.type === 1) {
let tok = obj.token;
@@ -1062,6 +1062,8 @@ export default {
}
if (tok) {
this.token = tok;
this.sendWithToken({ type: 'rooms' });
this.sendWithToken({ type: 'userlist' });
// No extra join here; we already sent init with room
if (this.joinFallbackTimer) { clearTimeout(this.joinFallbackTimer); this.joinFallbackTimer = null; }
this.flushPending();
@@ -1136,11 +1138,33 @@ export default {
return;
}
if (obj.type === 3 && Array.isArray(obj.message)) {
const names = obj.message.map(r => r.name).filter(Boolean).join(', ');
this.handleIncoming({ type: 'system', text: names ? `Rooms: ${names}` : 'Rooms updated' });
const mapped = obj.message
.filter(r => r && r.name)
.map((r, index) => ({
id: r.name || index + 1,
title: r.name,
name: r.name,
users: Number(r.users || 0)
}));
if (mapped.length > 0) {
const currentName = this.getSelectedRoomName();
this.rooms = mapped;
if (currentName) {
const existing = mapped.find(r => r.name === currentName);
this.selectedRoom = existing ? existing.id : mapped[0].id;
} else if (!this.selectedRoom) {
this.selectedRoom = mapped[0].id;
}
}
return;
}
if (obj.type === 5) {
if (obj.message === 'room_entered') {
const to = obj.to || obj.room || this.getSelectedRoomName();
this.handleIncoming({ type: 'system', code: 'room_entered', tr: 'room_entered', to });
this.sendWithToken({ type: 'userlist' });
return;
}
const msg = obj.message;
if (typeof msg === 'string') {
// Some servers send a JSON-encoded string here; parse if it looks like JSON