Implement room creation panel in MultiChatDialog: Add functionality for users to create new chat rooms with customizable settings, including visibility, age restrictions, and password protection. Enhance UI with a toggle button and form for room details.
This commit is contained in:
@@ -3,9 +3,14 @@
|
||||
@close="onDialogClose" width="75vw" height="75vh" name="MultiChatDialog" icon="multichat24.png">
|
||||
<div class="dialog-widget-content">
|
||||
<div class="multi-chat-top">
|
||||
<select v-model="selectedRoom" class="room-select">
|
||||
<div class="room-left-controls">
|
||||
<select v-model="selectedRoom" class="room-select">
|
||||
<option v-for="room in rooms" :key="room.id" :value="room.id">{{ room.title }}</option>
|
||||
</select>
|
||||
</select>
|
||||
<button class="create-room-toggle-btn" type="button" @click="toggleRoomCreatePanel">
|
||||
{{ showRoomCreatePanel ? 'Chat anzeigen' : 'Raum anlegen' }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="right-controls">
|
||||
<div class="status" :class="statusType">
|
||||
<span class="dot"></span>
|
||||
@@ -31,7 +36,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!showColorPicker" class="multi-chat-body">
|
||||
<div class="multi-chat-output" ref="output" @mouseenter="mouseOverOutput = true"
|
||||
<div v-if="!showRoomCreatePanel" class="multi-chat-output" ref="output" @mouseenter="mouseOverOutput = true"
|
||||
@mouseleave="mouseOverOutput = false">
|
||||
<div v-for="msg in messages" :key="msg.id" class="chat-message">
|
||||
<template v-if="msg.type === 'scream'">
|
||||
@@ -53,6 +58,71 @@
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="room-create-panel">
|
||||
<div class="room-create-title">Neuen Raum erstellen</div>
|
||||
<div class="room-create-grid">
|
||||
<label>
|
||||
Raumname *
|
||||
<input v-model.trim="roomCreateForm.roomName" type="text" placeholder="z. B. Lounge" />
|
||||
</label>
|
||||
<label>
|
||||
Sichtbarkeit
|
||||
<select v-model="roomCreateForm.visibility">
|
||||
<option value="">(keine)</option>
|
||||
<option value="public">public</option>
|
||||
<option value="private">private</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
public=true|false
|
||||
<select v-model="roomCreateForm.publicFlag">
|
||||
<option value="">(keine)</option>
|
||||
<option value="true">true</option>
|
||||
<option value="false">false</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
gender
|
||||
<select v-model="roomCreateForm.gender">
|
||||
<option value="">(keine)</option>
|
||||
<option value="m">m</option>
|
||||
<option value="f">f</option>
|
||||
<option value="any">any</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
min_age
|
||||
<input v-model.number="roomCreateForm.minAge" type="number" min="0" />
|
||||
</label>
|
||||
<label>
|
||||
max_age
|
||||
<input v-model.number="roomCreateForm.maxAge" type="number" min="0" />
|
||||
</label>
|
||||
<label>
|
||||
Passwort
|
||||
<input v-model.trim="roomCreateForm.password" type="text" placeholder="ohne Leerzeichen" />
|
||||
</label>
|
||||
<label>
|
||||
right_id
|
||||
<input v-model.number="roomCreateForm.rightId" type="number" min="1" />
|
||||
</label>
|
||||
<label>
|
||||
type_id
|
||||
<input v-model.number="roomCreateForm.typeId" type="number" min="1" />
|
||||
</label>
|
||||
<label class="checkbox-label">
|
||||
<input type="checkbox" v-model="roomCreateForm.friendsOnly" />
|
||||
friends_only=true
|
||||
</label>
|
||||
</div>
|
||||
<div class="room-create-actions">
|
||||
<button type="button" class="send-btn" @click="sendCreateRoomCommand">Raum erstellen</button>
|
||||
<button type="button" class="create-room-reset-btn" @click="resetRoomCreateForm">Zurücksetzen</button>
|
||||
</div>
|
||||
<div class="room-create-preview">
|
||||
Kommando: <code>{{ buildRoomCreateCommandPreview() || '/cr <raumname>' }}</code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-list">
|
||||
<div class="user-list-header">Teilnehmer ({{ usersInRoom.length }})</div>
|
||||
<div class="user-list-items">
|
||||
@@ -168,10 +238,23 @@ export default {
|
||||
token: null,
|
||||
announcedRoomEnter: false,
|
||||
showColorPicker: false,
|
||||
showRoomCreatePanel: false,
|
||||
selectedColor: '#000000',
|
||||
lastColor: '#000000',
|
||||
hexInput: '#000000',
|
||||
hexInvalid: false,
|
||||
roomCreateForm: {
|
||||
roomName: '',
|
||||
visibility: '',
|
||||
publicFlag: '',
|
||||
gender: '',
|
||||
minAge: null,
|
||||
maxAge: null,
|
||||
password: '',
|
||||
friendsOnly: false,
|
||||
rightId: null,
|
||||
typeId: null
|
||||
},
|
||||
// Palette state
|
||||
paletteWidth: 420,
|
||||
paletteHeight: 220,
|
||||
@@ -224,6 +307,85 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDefaultRoomCreateForm() {
|
||||
return {
|
||||
roomName: '',
|
||||
visibility: '',
|
||||
publicFlag: '',
|
||||
gender: '',
|
||||
minAge: null,
|
||||
maxAge: null,
|
||||
password: '',
|
||||
friendsOnly: false,
|
||||
rightId: null,
|
||||
typeId: null
|
||||
};
|
||||
},
|
||||
toggleRoomCreatePanel() {
|
||||
this.showRoomCreatePanel = !this.showRoomCreatePanel;
|
||||
if (!this.showRoomCreatePanel) return;
|
||||
this.showColorPicker = false;
|
||||
},
|
||||
resetRoomCreateForm() {
|
||||
this.roomCreateForm = this.getDefaultRoomCreateForm();
|
||||
},
|
||||
buildRoomCreateCommandPreview() {
|
||||
return this.buildRoomCreateCommand();
|
||||
},
|
||||
buildRoomCreateCommand() {
|
||||
const name = (this.roomCreateForm.roomName || '').trim();
|
||||
if (!name) return '';
|
||||
const parts = ['/cr', name];
|
||||
if (this.roomCreateForm.visibility) parts.push(this.roomCreateForm.visibility);
|
||||
if (this.roomCreateForm.publicFlag === 'true' || this.roomCreateForm.publicFlag === 'false') {
|
||||
parts.push(`public=${this.roomCreateForm.publicFlag}`);
|
||||
}
|
||||
if (this.roomCreateForm.gender) parts.push(`gender=${this.roomCreateForm.gender}`);
|
||||
if (Number.isInteger(this.roomCreateForm.minAge) && this.roomCreateForm.minAge >= 0) {
|
||||
parts.push(`min_age=${this.roomCreateForm.minAge}`);
|
||||
}
|
||||
if (Number.isInteger(this.roomCreateForm.maxAge) && this.roomCreateForm.maxAge >= 0) {
|
||||
parts.push(`max_age=${this.roomCreateForm.maxAge}`);
|
||||
}
|
||||
const password = (this.roomCreateForm.password || '').trim();
|
||||
if (password) parts.push(`password=${password}`);
|
||||
if (this.roomCreateForm.friendsOnly) parts.push('friends_only=true');
|
||||
if (Number.isInteger(this.roomCreateForm.rightId) && this.roomCreateForm.rightId > 0) {
|
||||
parts.push(`right_id=${this.roomCreateForm.rightId}`);
|
||||
}
|
||||
if (Number.isInteger(this.roomCreateForm.typeId) && this.roomCreateForm.typeId > 0) {
|
||||
parts.push(`type_id=${this.roomCreateForm.typeId}`);
|
||||
}
|
||||
return parts.join(' ');
|
||||
},
|
||||
requestRoomRefreshAfterCreate() {
|
||||
const requestRooms = () => {
|
||||
if (this.isAdmin) this.sendWithToken({ type: 'reload_rooms' });
|
||||
this.sendWithToken({ type: 'rooms' });
|
||||
};
|
||||
setTimeout(requestRooms, 500);
|
||||
setTimeout(requestRooms, 1800);
|
||||
},
|
||||
sendCreateRoomCommand() {
|
||||
if (!this.transportConnected) {
|
||||
this.messages.push({ id: Date.now(), user: 'System', text: 'Keine Verbindung zum Chat-Server.' });
|
||||
return;
|
||||
}
|
||||
const command = this.buildRoomCreateCommand();
|
||||
if (!command) {
|
||||
this.messages.push({ id: Date.now(), user: 'System', text: 'Bitte einen Raumnamen angeben.' });
|
||||
return;
|
||||
}
|
||||
if ((this.roomCreateForm.password || '').includes(' ')) {
|
||||
this.messages.push({ id: Date.now(), user: 'System', text: 'Passwort darf keine Leerzeichen enthalten.' });
|
||||
return;
|
||||
}
|
||||
const payload = { type: 'message', message: command };
|
||||
if (this.debug) console.log('[Chat WS >>]', payload);
|
||||
this.sendWithToken(payload);
|
||||
this.messages.push({ id: Date.now(), user: 'System', text: `Raum-Erstellung gesendet: ${command}` });
|
||||
this.requestRoomRefreshAfterCreate();
|
||||
},
|
||||
selectTargetUser(name) {
|
||||
if (this.selectedTargetUser === name) {
|
||||
this.selectedTargetUser = null; // toggle off
|
||||
@@ -319,6 +481,7 @@ export default {
|
||||
this.selectedTargetUser = null;
|
||||
this.input = '';
|
||||
this.showOptions = false;
|
||||
this.showRoomCreatePanel = false;
|
||||
this.announcedRoomEnter = false;
|
||||
this.$refs.dialog.open();
|
||||
// Stelle die WS-Verbindung her, wenn der Dialog geöffnet wird
|
||||
@@ -1481,10 +1644,24 @@ export default {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.room-left-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
}
|
||||
|
||||
.room-select {
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
.create-room-toggle-btn {
|
||||
border: 1px solid #bbb;
|
||||
background: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
padding: 0.3em 0.8em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.right-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -1591,6 +1768,64 @@ export default {
|
||||
border: 1px solid #222;
|
||||
}
|
||||
|
||||
.room-create-panel {
|
||||
border: 1px solid #222;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
padding: 0.7em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.room-create-title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.6em;
|
||||
}
|
||||
|
||||
.room-create-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 0.6em;
|
||||
}
|
||||
|
||||
.room-create-grid label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25em;
|
||||
}
|
||||
|
||||
.room-create-grid input,
|
||||
.room-create-grid select {
|
||||
border: 1px solid #bbb;
|
||||
border-radius: 3px;
|
||||
padding: 0.35em 0.5em;
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
flex-direction: row !important;
|
||||
align-items: center;
|
||||
gap: 0.4em !important;
|
||||
}
|
||||
|
||||
.room-create-actions {
|
||||
display: flex;
|
||||
gap: 0.5em;
|
||||
margin-top: 0.8em;
|
||||
}
|
||||
|
||||
.create-room-reset-btn {
|
||||
border: 1px solid #bbb;
|
||||
background: #eee;
|
||||
border-radius: 3px;
|
||||
padding: 0.3em 0.8em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.room-create-preview {
|
||||
margin-top: 0.7em;
|
||||
font-size: 0.9em;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.chat-message {
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user