feat: Allow admin to create new text channels
This commit is contained in:
@@ -108,8 +108,18 @@ export class ChatMessagesComponent {
|
||||
}
|
||||
|
||||
handleTypingStarted(): void {
|
||||
const roomId = this.currentRoom()?.id;
|
||||
|
||||
if (!roomId) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.webrtc.sendRawMessage({ type: 'typing', serverId: this.webrtc.currentServerId });
|
||||
this.webrtc.sendRawMessage({
|
||||
type: 'typing',
|
||||
serverId: roomId,
|
||||
channelId: this.activeChannelId() ?? 'general'
|
||||
});
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
|
||||
@@ -9,7 +9,10 @@ import {
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { RealtimeSessionFacade } from '../../../../core/realtime';
|
||||
import { selectCurrentRoom } from '../../../../store/rooms/rooms.selectors';
|
||||
import {
|
||||
selectActiveChannelId,
|
||||
selectCurrentRoom
|
||||
} from '../../../../store/rooms/rooms.selectors';
|
||||
import {
|
||||
merge,
|
||||
interval,
|
||||
@@ -27,6 +30,7 @@ interface TypingSignalingMessage {
|
||||
displayName: string;
|
||||
oderId: string;
|
||||
serverId: string;
|
||||
channelId?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
@@ -39,10 +43,12 @@ interface TypingSignalingMessage {
|
||||
}
|
||||
})
|
||||
export class TypingIndicatorComponent {
|
||||
private readonly typingMap = new Map<string, { name: string; expiresAt: number }>();
|
||||
private readonly typingMap = new Map<string, { name: string; channelId: string; expiresAt: number }>();
|
||||
private readonly store = inject(Store);
|
||||
private readonly currentRoom = this.store.selectSignal(selectCurrentRoom);
|
||||
private readonly activeChannelId = this.store.selectSignal(selectActiveChannelId);
|
||||
private lastRoomId: string | null = null;
|
||||
private lastConversationKey: string | null = null;
|
||||
|
||||
typingDisplay = signal<string[]>([]);
|
||||
typingOthersCount = signal<number>(0);
|
||||
@@ -60,9 +66,13 @@ export class TypingIndicatorComponent {
|
||||
filter((msg) => msg.serverId === this.currentRoom()?.id),
|
||||
tap((msg) => {
|
||||
const now = Date.now();
|
||||
const channelId = typeof msg.channelId === 'string' && msg.channelId.trim()
|
||||
? msg.channelId.trim()
|
||||
: 'general';
|
||||
|
||||
this.typingMap.set(msg.oderId, {
|
||||
this.typingMap.set(`${channelId}:${msg.oderId}`, {
|
||||
name: msg.displayName,
|
||||
channelId,
|
||||
expiresAt: now + TYPING_TTL
|
||||
});
|
||||
})
|
||||
@@ -89,20 +99,27 @@ export class TypingIndicatorComponent {
|
||||
|
||||
effect(() => {
|
||||
const roomId = this.currentRoom()?.id ?? null;
|
||||
const activeChannelId = this.activeChannelId() ?? 'general';
|
||||
const conversationKey = roomId ? `${roomId}:${activeChannelId}` : null;
|
||||
|
||||
if (roomId === this.lastRoomId)
|
||||
if (roomId !== this.lastRoomId) {
|
||||
this.lastRoomId = roomId;
|
||||
this.typingMap.clear();
|
||||
}
|
||||
|
||||
if (conversationKey === this.lastConversationKey)
|
||||
return;
|
||||
|
||||
this.lastRoomId = roomId;
|
||||
this.typingMap.clear();
|
||||
this.lastConversationKey = conversationKey;
|
||||
this.recomputeDisplay();
|
||||
});
|
||||
}
|
||||
|
||||
private recomputeDisplay(): void {
|
||||
const now = Date.now();
|
||||
const activeChannelId = this.activeChannelId() ?? 'general';
|
||||
const names = Array.from(this.typingMap.values())
|
||||
.filter((e) => e.expiresAt > now)
|
||||
.filter((entry) => entry.expiresAt > now && entry.channelId === activeChannelId)
|
||||
.map((e) => e.name);
|
||||
|
||||
this.typingDisplay.set(names.slice(0, MAX_SHOWN));
|
||||
|
||||
Reference in New Issue
Block a user