Add seperation of voice channels, creation of new ones, and move around users
This commit is contained in:
@@ -172,6 +172,8 @@ export class RoomsSidePanelComponent {
|
||||
volumeMenuY = signal(0);
|
||||
volumeMenuPeerId = signal('');
|
||||
volumeMenuDisplayName = signal('');
|
||||
draggedVoiceUserId = signal<string | null>(null);
|
||||
dragTargetVoiceChannelId = signal<string | null>(null);
|
||||
|
||||
private roomMemberKey(member: RoomMember): string {
|
||||
return member.oderId || member.id;
|
||||
@@ -371,9 +373,16 @@ export class RoomsSidePanelComponent {
|
||||
}
|
||||
|
||||
const channels = this.currentRoom()?.channels ?? [];
|
||||
const channelType = excludeChannelId
|
||||
? channels.find((channel) => channel.id === excludeChannelId)?.type
|
||||
: this.createChannelType();
|
||||
|
||||
if (isChannelNameTaken(channels, name, excludeChannelId)) {
|
||||
return 'Channel names must be unique in a server.';
|
||||
if (!channelType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isChannelNameTaken(channels, name, channelType, excludeChannelId)) {
|
||||
return 'Channel names must be unique within text or voice channels.';
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -618,6 +627,113 @@ export class RoomsSidePanelComponent {
|
||||
this.voiceWorkspace.focusStream(userId, { connectRemoteShares: true });
|
||||
}
|
||||
|
||||
canMoveVoiceUsers(): boolean {
|
||||
return this.canManageChannels();
|
||||
}
|
||||
|
||||
canDragVoiceUser(user: User): boolean {
|
||||
return this.canMoveVoiceUsers() && !this.isCurrentUserIdentity(user) && !!user.voiceState?.isConnected;
|
||||
}
|
||||
|
||||
onVoiceUserDragStart(event: DragEvent, user: User): void {
|
||||
if (!this.canDragVoiceUser(user)) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
const dragId = user.id || user.oderId;
|
||||
|
||||
if (!dragId) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
this.draggedVoiceUserId.set(dragId);
|
||||
event.dataTransfer?.setData('text/plain', dragId);
|
||||
|
||||
if (event.dataTransfer) {
|
||||
event.dataTransfer.effectAllowed = 'move';
|
||||
}
|
||||
}
|
||||
|
||||
onVoiceUserDragEnd(): void {
|
||||
this.draggedVoiceUserId.set(null);
|
||||
this.dragTargetVoiceChannelId.set(null);
|
||||
}
|
||||
|
||||
onVoiceChannelDragOver(event: DragEvent, channelId: string): void {
|
||||
if (!this.draggedVoiceUserId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
this.dragTargetVoiceChannelId.set(channelId);
|
||||
|
||||
if (event.dataTransfer) {
|
||||
event.dataTransfer.dropEffect = 'move';
|
||||
}
|
||||
}
|
||||
|
||||
onVoiceChannelDragLeave(channelId: string): void {
|
||||
if (this.dragTargetVoiceChannelId() === channelId) {
|
||||
this.dragTargetVoiceChannelId.set(null);
|
||||
}
|
||||
}
|
||||
|
||||
onVoiceChannelDrop(event: DragEvent, channelId: string): void {
|
||||
event.preventDefault();
|
||||
|
||||
const draggedUserId = this.draggedVoiceUserId() || event.dataTransfer?.getData('text/plain') || null;
|
||||
|
||||
this.draggedVoiceUserId.set(null);
|
||||
this.dragTargetVoiceChannelId.set(null);
|
||||
|
||||
if (!draggedUserId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.moveVoiceUserToChannel(draggedUserId, channelId);
|
||||
}
|
||||
|
||||
private moveVoiceUserToChannel(draggedUserId: string, channelId: string): void {
|
||||
const room = this.currentRoom();
|
||||
const actor = this.currentUser();
|
||||
|
||||
if (!room || !actor || !this.canMoveVoiceUsers()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const targetUser = this.onlineUsers().find((user) => user.id === draggedUserId || user.oderId === draggedUserId);
|
||||
|
||||
if (!targetUser?.voiceState?.isConnected || targetUser.voiceState.serverId !== room.id || targetUser.voiceState.roomId === channelId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const movedVoiceState: Partial<User['voiceState']> = {
|
||||
isConnected: true,
|
||||
isMuted: targetUser.voiceState.isMuted,
|
||||
isDeafened: targetUser.voiceState.isDeafened,
|
||||
isSpeaking: targetUser.voiceState.isSpeaking,
|
||||
isMutedByAdmin: targetUser.voiceState.isMutedByAdmin,
|
||||
volume: targetUser.voiceState.volume,
|
||||
roomId: channelId,
|
||||
serverId: room.id
|
||||
};
|
||||
|
||||
this.store.dispatch(UsersActions.updateVoiceState({
|
||||
userId: targetUser.id,
|
||||
voiceState: movedVoiceState
|
||||
}));
|
||||
|
||||
this.realtime.broadcastMessage({
|
||||
type: 'voice-channel-move',
|
||||
roomId: room.id,
|
||||
targetUserId: targetUser.oderId || targetUser.id,
|
||||
voiceState: movedVoiceState,
|
||||
displayName: targetUser.displayName
|
||||
});
|
||||
}
|
||||
|
||||
isUserLocallyMuted(user: User): boolean {
|
||||
const peerId = user.oderId || user.id;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user