handleCategoryDragStart(e, category.id)}
- onDragEnd={handleDragEnd}
- onDragOver={(e) => handleChannelDragOver(e, category.id, 'category')}
+ activeDrag?.type === 'category' && activeDrag.dragId === category.id ? 'opacity-50' : ''
+ } ${dropTarget?.targetId === category.id && dropTarget.targetType === 'category' ? 'ring-1 ring-accent-mint/40 rounded' : ''}`}
+ {...categoryHandlers(category.id)}
onClick={() => toggleCollapse(category.id)}
>
@@ -728,20 +722,17 @@ export function ChannelSidebar() {
isActive={currentChannelId === channel.id}
isUnread={unreadChannels.has(channel.id) && currentChannelId !== channel.id}
canManage={canManageChannels}
- isDragging={channelDragState?.dragType === 'channel' && channelDragState.dragId === channel.id}
- dropIndicator={dropIndicator?.targetId === channel.id ? dropIndicator.position : null}
+ isDragging={activeDrag?.type === 'channel' && activeDrag.dragId === channel.id}
+ dropIndicator={dropTarget?.targetId === channel.id ? dropTarget.position : null}
onChannelClick={channel.type === 'voice' ? (() => {
const chPerms = channelPermissions.get(channel.id);
const canConnect = hasPermissionBit(chPerms, PermissionBits.CONNECT);
if (canConnect) handleVoiceJoin(channel.id);
}) : (() => handleChannelClick(channel.id))}
onSettingsClick={() => openModal('channelSettings', { channelId: channel.id })}
- onDragStart={(e) => handleChannelDragStart(e, channel.id)}
- onDragOver={(e) => handleChannelDragOver(e, channel.id, 'channel')}
- onDragEnd={handleDragEnd}
- voiceDragState={voiceDragState}
- onVoiceDragStart={(userId: string) => setVoiceDragState({ userId, fromChannelId: channel.id })}
- onVoiceDragEnd={() => setVoiceDragState(null)}
+ channelDragHandlers={channelHandlers(channel.id)}
+ voiceUserHandlers={voiceUserHandlers}
+ voiceChannelDropZone={voiceChannelDropZone(channel.id)}
channelPermissions={channelPermissions}
handleVoiceJoin={handleVoiceJoin}
/>
@@ -1221,12 +1212,9 @@ function ChannelItem({
dropIndicator,
onChannelClick,
onSettingsClick,
- onDragStart,
- onDragOver,
- onDragEnd,
- voiceDragState,
- onVoiceDragStart,
- onVoiceDragEnd,
+ channelDragHandlers,
+ voiceUserHandlers,
+ voiceChannelDropZone,
channelPermissions,
handleVoiceJoin,
}: {
@@ -1238,12 +1226,26 @@ function ChannelItem({
dropIndicator: 'before' | 'after' | null;
onChannelClick: () => void;
onSettingsClick: () => void;
- onDragStart: (e: React.DragEvent) => void;
- onDragOver: (e: React.DragEvent) => void;
- onDragEnd: () => void;
- voiceDragState: { userId: string; fromChannelId: string } | null;
- onVoiceDragStart: (userId: string) => void;
- onVoiceDragEnd: () => void;
+ channelDragHandlers: {
+ draggable: boolean;
+ onDragStart: (e: React.DragEvent) => void;
+ onDragOver: (e: React.DragEvent) => void;
+ onDragEnd: () => void;
+ };
+ voiceUserHandlers: (userId: string, channelId: string) => {
+ draggable: boolean;
+ isBeingDragged: boolean;
+ onDragStart: (e: React.DragEvent) => void;
+ onDragEnd: (e: React.DragEvent) => void;
+ };
+ voiceChannelDropZone: {
+ onDragOver: (e: React.DragEvent) => void;
+ onDragEnter: (e: React.DragEvent) => void;
+ onDragLeave: (e: React.DragEvent) => void;
+ onDrop: (e: React.DragEvent) => void;
+ isDragOver: boolean;
+ isValidTarget: boolean;
+ };
channelPermissions: Map
;
handleVoiceJoin: (channelId: string) => void;
}) {
@@ -1253,10 +1255,7 @@ function ChannelItem({
return (
{dropIndicator === 'before' &&
}
{dropIndicator === 'after' &&
}
@@ -1278,10 +1276,7 @@ function ChannelItem({
return (
{dropIndicator === 'before' &&
}