feat: Allow admin to create new text channels
This commit is contained in:
@@ -40,6 +40,10 @@ import { VoiceActivityService, VoiceConnectionFacade } from '../../../domains/vo
|
||||
import { VoiceSessionFacade, VoiceWorkspaceService } from '../../../domains/voice-session';
|
||||
import { VoicePlaybackService } from '../../../domains/voice-connection/application/voice-playback.service';
|
||||
import { VoiceControlsComponent } from '../../../domains/voice-session/feature/voice-controls/voice-controls.component';
|
||||
import {
|
||||
isChannelNameTaken,
|
||||
normalizeChannelName
|
||||
} from '../../../store/rooms/room-channels.rules';
|
||||
import {
|
||||
ContextMenuComponent,
|
||||
UserAvatarComponent,
|
||||
@@ -152,6 +156,7 @@ export class RoomsSidePanelComponent {
|
||||
contextChannel = signal<Channel | null>(null);
|
||||
|
||||
renamingChannelId = signal<string | null>(null);
|
||||
channelNameError = signal<string | null>(null);
|
||||
|
||||
showCreateChannelDialog = signal(false);
|
||||
createChannelType = signal<'text' | 'voice'>('text');
|
||||
@@ -243,6 +248,7 @@ export class RoomsSidePanelComponent {
|
||||
const ch = this.contextChannel();
|
||||
|
||||
this.closeChannelMenu();
|
||||
this.channelNameError.set(null);
|
||||
|
||||
if (ch) {
|
||||
this.renamingChannelId.set(ch.id);
|
||||
@@ -251,10 +257,29 @@ export class RoomsSidePanelComponent {
|
||||
|
||||
confirmRename(event: Event) {
|
||||
const input = event.target as HTMLInputElement;
|
||||
const name = input.value.trim();
|
||||
const name = normalizeChannelName(input.value);
|
||||
const channelId = this.renamingChannelId();
|
||||
|
||||
if (channelId && name) {
|
||||
if (!channelId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const validationError = this.getChannelNameError(name, channelId);
|
||||
|
||||
if (validationError) {
|
||||
this.channelNameError.set(validationError);
|
||||
requestAnimationFrame(() => {
|
||||
input.focus();
|
||||
input.select();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.channelNameError.set(null);
|
||||
|
||||
const currentName = this.currentRoom()?.channels?.find((channel) => channel.id === channelId)?.name;
|
||||
|
||||
if (currentName !== name) {
|
||||
this.store.dispatch(RoomsActions.renameChannel({ channelId, name }));
|
||||
}
|
||||
|
||||
@@ -262,6 +287,7 @@ export class RoomsSidePanelComponent {
|
||||
}
|
||||
|
||||
cancelRename() {
|
||||
this.channelNameError.set(null);
|
||||
this.renamingChannelId.set(null);
|
||||
}
|
||||
|
||||
@@ -300,14 +326,19 @@ export class RoomsSidePanelComponent {
|
||||
createChannel(type: 'text' | 'voice') {
|
||||
this.createChannelType.set(type);
|
||||
this.newChannelName = '';
|
||||
this.channelNameError.set(null);
|
||||
this.showCreateChannelDialog.set(true);
|
||||
}
|
||||
|
||||
confirmCreateChannel() {
|
||||
const name = this.newChannelName.trim();
|
||||
const name = normalizeChannelName(this.newChannelName);
|
||||
|
||||
if (!name)
|
||||
const validationError = this.getChannelNameError(name);
|
||||
|
||||
if (validationError) {
|
||||
this.channelNameError.set(validationError);
|
||||
return;
|
||||
}
|
||||
|
||||
const type = this.createChannelType();
|
||||
const existing = type === 'text' ? this.textChannels() : this.voiceChannels();
|
||||
@@ -319,13 +350,35 @@ export class RoomsSidePanelComponent {
|
||||
};
|
||||
|
||||
this.store.dispatch(RoomsActions.addChannel({ channel }));
|
||||
this.channelNameError.set(null);
|
||||
this.showCreateChannelDialog.set(false);
|
||||
}
|
||||
|
||||
cancelCreateChannel() {
|
||||
this.channelNameError.set(null);
|
||||
this.showCreateChannelDialog.set(false);
|
||||
}
|
||||
|
||||
clearChannelNameError(): void {
|
||||
if (this.channelNameError()) {
|
||||
this.channelNameError.set(null);
|
||||
}
|
||||
}
|
||||
|
||||
private getChannelNameError(name: string, excludeChannelId?: string): string | null {
|
||||
if (!name) {
|
||||
return 'Channel name is required.';
|
||||
}
|
||||
|
||||
const channels = this.currentRoom()?.channels ?? [];
|
||||
|
||||
if (isChannelNameTaken(channels, name, excludeChannelId)) {
|
||||
return 'Channel names must be unique in a server.';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
openUserContextMenu(evt: MouseEvent, user: User) {
|
||||
evt.preventDefault();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user