diff --git a/frontend/src/dialogues/chat/MultiChatDialog.vue b/frontend/src/dialogues/chat/MultiChatDialog.vue
index d05a35a..d093421 100644
--- a/frontend/src/dialogues/chat/MultiChatDialog.vue
+++ b/frontend/src/dialogues/chat/MultiChatDialog.vue
@@ -172,6 +172,23 @@
+
+
{{ $t('chat.multichat.password.title') }}
+
+ {{ passwordPromptInvalid ? $t('chat.multichat.password.invalidPrompt', { room: passwordPromptRoom }) : $t('chat.multichat.password.requiredPrompt', { room: passwordPromptRoom }) }}
+
+
+
+
+
+
+
@@ -322,7 +339,10 @@ export default {
pendingRoomCreateAttempts: 0,
pendingRoomCreateTimer: null,
roomPasswords: {},
- passwordPromptActive: false,
+ passwordPromptVisible: false,
+ passwordPromptInvalid: false,
+ passwordPromptRoom: '',
+ passwordPromptValue: '',
// Palette state
paletteWidth: 420,
paletteHeight: 220,
@@ -371,6 +391,10 @@ export default {
this.messages = [];
this.usersInRoom = [];
this.selectedTargetUser = null;
+ this.passwordPromptVisible = false;
+ this.passwordPromptInvalid = false;
+ this.passwordPromptRoom = '';
+ this.passwordPromptValue = '';
}
}
},
@@ -411,38 +435,47 @@ export default {
if (!roomName) return '';
return this.roomPasswords[roomName] || '';
},
- async handleRoomPasswordError(errorCode) {
+ handleRoomPasswordError(errorCode) {
const room = this.getSelectedRoomName();
- if (!room || this.passwordPromptActive) return;
- this.passwordPromptActive = true;
- try {
- const isInvalid = errorCode === 'room_password_invalid';
- const promptText = isInvalid
- ? this.$t('chat.multichat.password.invalidPrompt', { room })
- : this.$t('chat.multichat.password.requiredPrompt', { room });
- const entered = window.prompt(promptText, '');
- if (entered === null) {
- this.messages.push({
- id: Date.now(),
- user: 'System',
- text: this.$t('chat.multichat.password.cancelled', { room })
- });
- return;
- }
- const password = entered.trim();
- if (!password) {
- this.messages.push({
- id: Date.now(),
- user: 'System',
- text: this.$t('chat.multichat.password.empty')
- });
- return;
- }
- this.roomPasswords[room] = password;
- this.sendWithToken({ type: 'join', room, password });
- } finally {
- this.passwordPromptActive = false;
+ if (!room || this.passwordPromptVisible) return;
+ this.passwordPromptRoom = room;
+ this.passwordPromptInvalid = errorCode === 'room_password_invalid';
+ this.passwordPromptValue = '';
+ this.passwordPromptVisible = true;
+ },
+ submitRoomPassword() {
+ const room = this.passwordPromptRoom || this.getSelectedRoomName();
+ if (!room) {
+ this.passwordPromptVisible = false;
+ return;
}
+ const password = (this.passwordPromptValue || '').trim();
+ if (!password) {
+ this.messages.push({
+ id: Date.now(),
+ user: 'System',
+ text: this.$t('chat.multichat.password.empty')
+ });
+ return;
+ }
+ this.roomPasswords[room] = password;
+ this.passwordPromptVisible = false;
+ this.passwordPromptInvalid = false;
+ this.passwordPromptRoom = '';
+ this.passwordPromptValue = '';
+ this.sendWithToken({ type: 'join', room, password });
+ },
+ cancelRoomPassword() {
+ const room = this.passwordPromptRoom || this.getSelectedRoomName();
+ this.passwordPromptVisible = false;
+ this.passwordPromptInvalid = false;
+ this.passwordPromptRoom = '';
+ this.passwordPromptValue = '';
+ this.messages.push({
+ id: Date.now(),
+ user: 'System',
+ text: this.$t('chat.multichat.password.cancelled', { room })
+ });
},
tryConfirmRoomCreateSuccess() {
if (!this.pendingRoomCreateName) return false;
@@ -2162,6 +2195,40 @@ export default {
margin-top: 0.5em;
}
+.room-password-panel {
+ margin-top: 0.6em;
+ margin-bottom: 0.6em;
+ padding: 0.6em;
+ border: 1px solid #d7d7d7;
+ border-radius: 6px;
+ background: #f8f9fb;
+}
+
+.room-password-title {
+ font-weight: bold;
+ margin-bottom: 0.25em;
+}
+
+.room-password-message {
+ font-size: 0.9em;
+ color: #444;
+ margin-bottom: 0.45em;
+}
+
+.room-password-controls {
+ display: flex;
+ align-items: center;
+ gap: 0.45em;
+}
+
+.room-password-input {
+ flex: 1;
+ min-width: 0;
+ border: 1px solid #bbb;
+ border-radius: 3px;
+ padding: 0.35em 0.5em;
+}
+
.chat-message {
margin-bottom: 0.3em;
}
diff --git a/frontend/src/i18n/locales/de/chat.json b/frontend/src/i18n/locales/de/chat.json
index 4bc53b9..013e47e 100644
--- a/frontend/src/i18n/locales/de/chat.json
+++ b/frontend/src/i18n/locales/de/chat.json
@@ -116,6 +116,10 @@
"types": {}
},
"password": {
+ "title": "Passwort erforderlich",
+ "inputLabel": "Passwort eingeben",
+ "submit": "Beitreten",
+ "cancel": "Abbrechen",
"requiredPrompt": "Der Raum \"{room}\" ist passwortgeschützt. Bitte Passwort eingeben:",
"invalidPrompt": "Falsches Passwort für \"{room}\". Bitte erneut eingeben:",
"cancelled": "Beitritt zu \"{room}\" abgebrochen.",
diff --git a/frontend/src/i18n/locales/en/chat.json b/frontend/src/i18n/locales/en/chat.json
index c4a5522..e142d93 100644
--- a/frontend/src/i18n/locales/en/chat.json
+++ b/frontend/src/i18n/locales/en/chat.json
@@ -116,6 +116,10 @@
"types": {}
},
"password": {
+ "title": "Password required",
+ "inputLabel": "Enter password",
+ "submit": "Join room",
+ "cancel": "Cancel",
"requiredPrompt": "Room \"{room}\" is password-protected. Please enter password:",
"invalidPrompt": "Wrong password for \"{room}\". Please try again:",
"cancelled": "Join to \"{room}\" was cancelled.",
diff --git a/frontend/src/i18n/locales/es/chat.json b/frontend/src/i18n/locales/es/chat.json
index b91ada0..dc3af8b 100644
--- a/frontend/src/i18n/locales/es/chat.json
+++ b/frontend/src/i18n/locales/es/chat.json
@@ -115,6 +115,10 @@
"types": {}
},
"password": {
+ "title": "Contraseña requerida",
+ "inputLabel": "Introduce la contraseña",
+ "submit": "Entrar en sala",
+ "cancel": "Cancelar",
"requiredPrompt": "La sala \"{room}\" está protegida por contraseña. Introduce la contraseña:",
"invalidPrompt": "Contraseña incorrecta para \"{room}\". Inténtalo de nuevo:",
"cancelled": "Se canceló el acceso a \"{room}\".",