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">
|
@close="onDialogClose" width="75vw" height="75vh" name="MultiChatDialog" icon="multichat24.png">
|
||||||
<div class="dialog-widget-content">
|
<div class="dialog-widget-content">
|
||||||
<div class="multi-chat-top">
|
<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>
|
<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="right-controls">
|
||||||
<div class="status" :class="statusType">
|
<div class="status" :class="statusType">
|
||||||
<span class="dot"></span>
|
<span class="dot"></span>
|
||||||
@@ -31,7 +36,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!showColorPicker" class="multi-chat-body">
|
<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">
|
@mouseleave="mouseOverOutput = false">
|
||||||
<div v-for="msg in messages" :key="msg.id" class="chat-message">
|
<div v-for="msg in messages" :key="msg.id" class="chat-message">
|
||||||
<template v-if="msg.type === 'scream'">
|
<template v-if="msg.type === 'scream'">
|
||||||
@@ -53,6 +58,71 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
||||||
<div class="user-list-header">Teilnehmer ({{ usersInRoom.length }})</div>
|
<div class="user-list-header">Teilnehmer ({{ usersInRoom.length }})</div>
|
||||||
<div class="user-list-items">
|
<div class="user-list-items">
|
||||||
@@ -168,10 +238,23 @@ export default {
|
|||||||
token: null,
|
token: null,
|
||||||
announcedRoomEnter: false,
|
announcedRoomEnter: false,
|
||||||
showColorPicker: false,
|
showColorPicker: false,
|
||||||
|
showRoomCreatePanel: false,
|
||||||
selectedColor: '#000000',
|
selectedColor: '#000000',
|
||||||
lastColor: '#000000',
|
lastColor: '#000000',
|
||||||
hexInput: '#000000',
|
hexInput: '#000000',
|
||||||
hexInvalid: false,
|
hexInvalid: false,
|
||||||
|
roomCreateForm: {
|
||||||
|
roomName: '',
|
||||||
|
visibility: '',
|
||||||
|
publicFlag: '',
|
||||||
|
gender: '',
|
||||||
|
minAge: null,
|
||||||
|
maxAge: null,
|
||||||
|
password: '',
|
||||||
|
friendsOnly: false,
|
||||||
|
rightId: null,
|
||||||
|
typeId: null
|
||||||
|
},
|
||||||
// Palette state
|
// Palette state
|
||||||
paletteWidth: 420,
|
paletteWidth: 420,
|
||||||
paletteHeight: 220,
|
paletteHeight: 220,
|
||||||
@@ -224,6 +307,85 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
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) {
|
selectTargetUser(name) {
|
||||||
if (this.selectedTargetUser === name) {
|
if (this.selectedTargetUser === name) {
|
||||||
this.selectedTargetUser = null; // toggle off
|
this.selectedTargetUser = null; // toggle off
|
||||||
@@ -319,6 +481,7 @@ export default {
|
|||||||
this.selectedTargetUser = null;
|
this.selectedTargetUser = null;
|
||||||
this.input = '';
|
this.input = '';
|
||||||
this.showOptions = false;
|
this.showOptions = false;
|
||||||
|
this.showRoomCreatePanel = false;
|
||||||
this.announcedRoomEnter = false;
|
this.announcedRoomEnter = false;
|
||||||
this.$refs.dialog.open();
|
this.$refs.dialog.open();
|
||||||
// Stelle die WS-Verbindung her, wenn der Dialog geöffnet wird
|
// Stelle die WS-Verbindung her, wenn der Dialog geöffnet wird
|
||||||
@@ -1481,10 +1644,24 @@ export default {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.room-left-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
.room-select {
|
.room-select {
|
||||||
min-width: 10em;
|
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 {
|
.right-controls {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -1591,6 +1768,64 @@ export default {
|
|||||||
border: 1px solid #222;
|
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 {
|
.chat-message {
|
||||||
margin-bottom: 0.3em;
|
margin-bottom: 0.3em;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user