Add chat input functionality in ChatBoxComponent and backend support for sending server messages

This commit is contained in:
2026-08-02 18:30:33 +02:00
parent 8533cfa365
commit 065db06e16
7 changed files with 207 additions and 4 deletions
@@ -12,3 +12,15 @@
</p>
}
</div>
@if (canChat()) {
<div class="chat-input-container">
<input
type="text"
[(ngModel)]="chatText"
(keyup.enter)="sendMessage()"
placeholder="Type a message..."
/>
<button (click)="sendMessage()">Send</button>
</div>
}
@@ -1,12 +1,14 @@
:host {
display: block;
display: flex;
flex-direction: column;
height: 100%;
}
.message-container {
flex: 1 1 auto;
display: flex;
flex-direction: column-reverse;
height: 100%;
min-height: 0;
overflow-y: auto;
box-sizing: border-box;
scrollbar-width: thin;
@@ -41,3 +43,51 @@
.date-time {
color: gray;
}
.chat-input-container {
flex: 0 0 auto;
padding: 10px;
display: flex;
gap: 10px;
background: rgba(0, 0, 0, 0.2);
border-top: 1px solid rgba(255, 255, 255, 0.1);
input {
flex: 1 1 auto;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 4px;
padding: 8px 12px;
color: white;
outline: none;
font-size: 14px;
&:focus {
border-color: #4f8cff;
background: rgba(255, 255, 255, 0.1);
}
&::placeholder {
color: rgba(255, 255, 255, 0.3);
}
}
button {
cursor: pointer;
border: 0;
border-radius: 4px;
padding: 8px 16px;
background: #4f8cff;
color: #ffffff;
font-weight: 700;
transition: background 0.2s;
&:hover {
background: #3b7dff;
}
&:active {
background: #2a6ae0;
}
}
}
@@ -1,17 +1,63 @@
import {Component, input} from '@angular/core';
import {Component, computed, inject, input} from '@angular/core';
import {DatePipe} from '@angular/common';
import {ChatMessage} from '@pages/altitude/chat/objects/chat-message.object';
import {MiniMessageComponent} from '@pages/altitude/chat/components/mini-message/mini-message.component';
import {AuthService} from '@services/auth.service';
import {ChatService} from '@pages/altitude/chat/service/chat.service';
import {ServerMessageService} from '@api';
import {FormsModule} from '@angular/forms';
import {MatSnackBar} from '@angular/material/snack-bar';
@Component({
selector: 'app-chat-box',
standalone: true,
imports: [
MiniMessageComponent,
DatePipe
DatePipe,
FormsModule
],
templateUrl: './chat-box.component.html',
styleUrl: './chat-box.component.scss'
})
export class ChatBoxComponent {
private readonly authService = inject(AuthService);
private readonly chatService = inject(ChatService);
private readonly serverMessageService = inject(ServerMessageService);
private readonly matSnackBar = inject(MatSnackBar);
readonly messages = input.required<ChatMessage[]>();
chatText = '';
readonly canChat = computed(() => {
const hasPrivilege = this.authService.hasAccess(['SCOPE_head_mod']);
const isServerChannel = this.chatService.selectedChannel()?.type === 'SERVER';
if (!hasPrivilege || !isServerChannel) {
console.log(`User has privilege ${hasPrivilege}, user in server channel ${isServerChannel}`);
}
return hasPrivilege && isServerChannel;
});
sendMessage() {
const message = this.chatText.trim();
if (!message) return;
const selectedChannel = this.chatService.selectedChannel();
const uuid = this.authService.getUuid();
if (selectedChannel?.type === 'SERVER' && uuid) {
this.serverMessageService.sendServerMessage(selectedChannel.name, {
uuid,
message
}).subscribe({
next: () => {
this.chatText = '';
},
error: (err) => {
this.matSnackBar.open('Failed to send message', 'Dismiss', {
duration: 3000
});
}
});
}
}
}