Create an account
diff --git a/packages/web/src/components/chat/MessageInput.js b/packages/web/src/components/chat/MessageInput.js
index aeb4cee6..38cd3483 100644
--- a/packages/web/src/components/chat/MessageInput.js
+++ b/packages/web/src/components/chat/MessageInput.js
@@ -98,7 +98,7 @@ export function MessageInput({ channelId, channelName }) {
textarea.style.height = 'auto';
textarea.style.height = Math.min(textarea.scrollHeight, 300) + 'px';
};
- return (_jsxs("div", { className: "px-4 pb-6 flex-shrink-0", children: [replyTo && (_jsxs("div", { className: "bg-discord-bg-hover rounded-t-lg px-4 py-2 flex items-center justify-between border-b border-discord-bg-tertiary/50", children: [_jsxs("div", { className: "flex items-center gap-1 text-[14px] text-discord-text-normal truncate", children: [_jsx("span", { className: "opacity-60", children: "Replying to" }), _jsx("span", { className: "font-bold", children: replyTo.user.displayName ?? replyTo.user.username })] }), _jsx("button", { onClick: () => setReplyTo(null), className: "text-discord-text-muted hover:text-discord-text-primary transition-colors", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M18.4 4L12 10.4L5.6 4L4 5.6L10.4 12L4 18.4L5.6 20L12 13.6L18.4 20L20 18.4L13.6 12L20 5.6L18.4 4Z" }) }) })] })), _jsxs("div", { className: `bg-discord-bg-input ${replyTo ? 'rounded-b-lg' : 'rounded-lg'} overflow-hidden`, onDrop: handleDrop, onDragOver: handleDragOver, children: [files.length > 0 && (_jsx("div", { className: "p-4 flex flex-wrap gap-4 bg-discord-bg-secondary/30", children: files.map((file, i) => (_jsxs("div", { className: "relative group bg-discord-bg-secondary rounded-lg p-2 max-w-[200px] shadow-elevation-low border border-discord-bg-tertiary", children: [file.type.startsWith('image/') ? (_jsx("img", { src: URL.createObjectURL(file), alt: file.name, className: "max-h-[150px] rounded object-cover" })) : (_jsxs("div", { className: "flex items-center gap-2 text-sm text-discord-text-secondary py-4 px-2", children: [_jsx("svg", { className: "w-8 h-8 opacity-60", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }), _jsx("span", { className: "truncate max-w-[120px] font-medium", children: file.name })] })), _jsx("button", { onClick: () => removeFile(i), className: "absolute -top-2 -right-2 w-7 h-7 bg-discord-red hover:bg-discord-red-hover shadow-elevation-high rounded-lg flex items-center justify-center text-white transition-colors z-10", children: _jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "currentColor", children: _jsx("path", { d: "M5 2a1 1 0 011-1h4a1 1 0 011 1v1h3a1 1 0 110 2h-.08L13 14a2 2 0 01-2 2H5a2 2 0 01-2-2L2.08 5H2a1 1 0 110-2h3V2zm2 0v1h2V2H7z" }) }) })] }, i))) })), _jsxs("div", { className: "flex items-start px-1", children: [_jsx("button", { onClick: () => fileInputRef.current?.click(), className: "p-3 text-discord-text-muted hover:text-discord-text-secondary transition-colors sticky top-0", title: "Attach file", children: _jsx("div", { className: "bg-discord-text-muted/20 hover:bg-discord-text-muted/40 rounded-full p-0.5 transition-colors", children: _jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z" }) }) }) }), _jsx("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: (e) => {
+ return (_jsxs("div", { className: "px-4 pb-6 flex-shrink-0", children: [replyTo && (_jsxs("div", { className: "bg-discord-bg-hover rounded-t-lg px-4 py-2 flex items-center justify-between border-b border-discord-bg-tertiary/50", children: [_jsxs("div", { className: "flex items-center gap-1 text-[14px] text-discord-text-normal truncate", children: [_jsx("span", { className: "opacity-60", children: "Replying to" }), _jsx("span", { className: "font-bold", children: replyTo.user.displayName ?? replyTo.user.username })] }), _jsx("button", { onClick: () => setReplyTo(null), className: "text-discord-text-muted hover:text-discord-text-primary transition-colors", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M18.4 4L12 10.4L5.6 4L4 5.6L10.4 12L4 18.4L5.6 20L12 13.6L18.4 20L20 18.4L13.6 12L20 5.6L18.4 4Z" }) }) })] })), _jsxs("div", { className: `bg-discord-bg-input ${replyTo ? 'rounded-b-lg' : 'rounded-lg'} overflow-hidden`, onDrop: handleDrop, onDragOver: handleDragOver, children: [files.length > 0 && (_jsx("div", { className: "p-4 flex flex-wrap gap-4 bg-discord-bg-secondary/30", children: files.map((file, i) => (_jsxs("div", { className: "relative group bg-discord-bg-secondary rounded-lg p-2 max-w-[200px] shadow-elevation-low border border-discord-bg-tertiary", children: [file.type.startsWith('image/') ? (_jsx("img", { src: URL.createObjectURL(file), alt: file.name, className: "max-h-[150px] rounded object-cover" })) : (_jsxs("div", { className: "flex items-center gap-2 text-sm text-discord-text-secondary py-4 px-2", children: [_jsx("svg", { className: "w-8 h-8 opacity-60", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }), _jsx("span", { className: "truncate max-w-[120px] font-medium", children: file.name })] })), _jsx("button", { onClick: () => removeFile(i), className: "absolute -top-2 -right-2 w-7 h-7 bg-discord-red hover:bg-discord-red-hover shadow-elevation-high rounded-lg flex items-center justify-center text-white transition-colors z-10", children: _jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "currentColor", children: _jsx("path", { d: "M5 2a1 1 0 011-1h4a1 1 0 011 1v1h3a1 1 0 110 2h-.08L13 14a2 2 0 01-2 2H5a2 2 0 01-2-2L2.08 5H2a1 1 0 110-2h3V2zm2 0v1h2V2H7z" }) }) })] }, i))) })), _jsxs("div", { className: "flex items-start px-1", children: [_jsx("button", { onClick: () => fileInputRef.current?.click(), className: "p-3 text-discord-text-muted hover:text-discord-text-secondary transition-colors sticky top-0", title: "Attach file", children: _jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z" }) }) }), _jsx("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: (e) => {
const selected = Array.from(e.target.files ?? []);
if (selected.length > 0) {
setFiles((prev) => [...prev, ...selected]);
diff --git a/packages/web/src/components/chat/MessageInput.tsx b/packages/web/src/components/chat/MessageInput.tsx
index 8e62f352..63cf7a9a 100644
--- a/packages/web/src/components/chat/MessageInput.tsx
+++ b/packages/web/src/components/chat/MessageInput.tsx
@@ -172,11 +172,9 @@ export function MessageInput({ channelId, channelName }: MessageInputProps) {
className="p-3 text-discord-text-muted hover:text-discord-text-secondary transition-colors sticky top-0"
title="Attach file"
>
-
+
{ e.stopPropagation(); }, className: "opacity-0 group-hover:opacity-100 text-discord-text-muted hover:text-discord-text-primary transition-opacity flex-shrink-0 ml-1", title: "Close DM", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M18.4 4L12 10.4L5.6 4L4 5.6L10.4 12L4 18.4L5.6 20L12 13.6L18.4 20L20 18.4L13.6 12L20 5.6L18.4 4Z" }) }) })] }, dm.id));
}), dmChannels.length === 0 && (_jsx("p", { className: "px-2 py-4 text-[13px] text-discord-text-muted italic opacity-60", children: "No DM conversations yet." }))] })] }), currentVoiceChannelId && _jsx(VoiceControls, {}), user && (_jsx(UserAreaPanel, { user: user, isMuted: isMuted, isDeafened: isDeafened, onMicToggle: handleMicToggle, onDeafenToggle: handleDeafenToggle, onSettingsClick: () => openModal('userSettings') }))] }));
}
- return (_jsxs("div", { className: "w-60 bg-discord-bg-secondary flex flex-col flex-shrink-0 select-none", children: [_jsxs("button", { onClick: () => openModal('serverSettings'), className: "h-12 px-4 flex items-center justify-between shadow-header z-10 hover:bg-discord-modifier-hover transition-colors group", children: [_jsx("span", { className: "font-bold text-[16px] text-discord-text-primary truncate leading-tight", children: server.name }), _jsx("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "currentColor", className: "text-discord-text-muted flex-shrink-0 group-hover:text-discord-text-secondary", children: _jsx("path", { d: "M5.293 7.293a1 1 0 011.414 0L9 9.586l2.293-2.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto pt-3 px-2 space-y-[21px] no-scrollbar", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between px-1 mb-1 group cursor-pointer", children: [_jsxs("div", { className: "flex items-center gap-0.5 text-discord-text-muted hover:text-discord-text-secondary transition-colors", children: [_jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "currentColor", className: "opacity-70", children: _jsx("path", { d: "M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" }) }), _jsx("span", { className: "text-[12px] font-bold uppercase tracking-wider", children: "Text Channels" })] }), isAdminUser && (_jsx("button", { onClick: (e) => {
+ return (_jsxs("div", { className: "w-60 bg-discord-bg-secondary flex flex-col flex-shrink-0 select-none", children: [_jsxs("div", { className: "h-12 flex items-center shadow-header z-10 group/header", children: [_jsxs("button", { onClick: () => openModal('serverSettings'), className: "flex-1 h-full px-4 flex items-center justify-between hover:bg-discord-modifier-hover transition-colors min-w-0", children: [_jsx("span", { className: "font-bold text-[16px] text-discord-text-primary truncate leading-tight", children: server.name }), _jsx("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "currentColor", className: "text-discord-text-muted flex-shrink-0", children: _jsx("path", { d: "M5.293 7.293a1 1 0 011.414 0L9 9.586l2.293-2.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" }) })] }), _jsx("button", { onClick: () => openModal('invite'), className: "w-10 h-full flex items-center justify-center text-discord-text-muted hover:text-discord-text-primary hover:bg-discord-modifier-hover transition-all opacity-0 group-hover/header:opacity-100 flex-shrink-0", title: "Invite People", children: _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M21 3H24V5H21V8H19V5H16V3H19V0H21V3ZM10 12C12.21 12 14 10.21 14 8C14 5.79 12.21 4 10 4C7.79 4 6 5.79 6 8C6 10.21 7.79 12 10 12ZM10 13C6.69 13 1 14.66 1 18V20H19V18C19 14.66 13.31 13 10 13Z" }) }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto pt-3 px-2 space-y-[21px] no-scrollbar", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between px-1 mb-1 group cursor-pointer", children: [_jsxs("div", { className: "flex items-center gap-0.5 text-discord-text-muted hover:text-discord-text-secondary transition-colors", children: [_jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "currentColor", className: "opacity-70", children: _jsx("path", { d: "M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" }) }), _jsx("span", { className: "text-[12px] font-bold uppercase tracking-wider", children: "Text Channels" })] }), isAdminUser && (_jsx("button", { onClick: (e) => {
e.stopPropagation();
openModal('createChannel');
}, className: "text-discord-text-muted hover:text-discord-text-primary transition-colors", title: "Create Channel", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: _jsx("path", { d: "M8 2a.5.5 0 01.5.5v5h5a.5.5 0 010 1h-5v5a.5.5 0 01-1 0v-5h-5a.5.5 0 010-1h5v-5A.5.5 0 018 2z" }) }) }))] }), _jsx("div", { className: "space-y-[2px]", children: textChannels.map((channel) => {
@@ -97,7 +97,7 @@ export function ChannelSidebar() {
}) })] }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between px-1 mb-1 group cursor-pointer", children: [_jsxs("div", { className: "flex items-center gap-0.5 text-discord-text-muted hover:text-discord-text-secondary transition-colors", children: [_jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "currentColor", className: "opacity-70", children: _jsx("path", { d: "M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" }) }), _jsx("span", { className: "text-[12px] font-bold uppercase tracking-wider", children: "Voice Channels" })] }), isAdminUser && (_jsx("button", { onClick: (e) => {
e.stopPropagation();
openModal('createChannel');
- }, className: "text-discord-text-muted hover:text-discord-text-primary transition-colors", title: "Create Channel", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: _jsx("path", { d: "M8 2a.5.5 0 01.5.5v5h5a.5.5 0 010 1h-5v5a.5.5 0 01-1 0v-5h-5a.5.5 0 010-1h5v-5A.5.5 0 018 2z" }) }) }))] }), _jsx("div", { className: "space-y-[2px]", children: voiceChannels.map((channel) => (_jsx(VoiceChannel, { channelId: channel.id, channelName: channel.name, onClick: () => handleVoiceJoin(channel.id) }, channel.id))) })] }), _jsx("div", { className: "pt-2", children: _jsxs("button", { onClick: () => openModal('invite'), className: "w-full flex items-center gap-2 px-2 h-8 rounded-[4px] text-[15px] font-medium text-discord-text-muted hover:text-discord-text-secondary hover:bg-discord-modifier-hover transition-colors", children: [_jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", className: "opacity-60", children: _jsx("path", { d: "M13 13v5h-2v-5H6v-2h5V6h2v5h5v2h-5z" }) }), "Invite People"] }) })] }), currentVoiceChannelId && _jsx(VoiceControls, {}), user && (_jsx(UserAreaPanel, { user: user, isMuted: isMuted, isDeafened: isDeafened, onMicToggle: handleMicToggle, onDeafenToggle: handleDeafenToggle, onSettingsClick: () => openModal('userSettings') }))] }));
+ }, className: "text-discord-text-muted hover:text-discord-text-primary transition-colors", title: "Create Channel", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: _jsx("path", { d: "M8 2a.5.5 0 01.5.5v5h5a.5.5 0 010 1h-5v5a.5.5 0 01-1 0v-5h-5a.5.5 0 010-1h5v-5A.5.5 0 018 2z" }) }) }))] }), _jsx("div", { className: "space-y-[2px]", children: voiceChannels.map((channel) => (_jsx(VoiceChannel, { channelId: channel.id, channelName: channel.name, onClick: () => handleVoiceJoin(channel.id) }, channel.id))) })] })] }), currentVoiceChannelId && _jsx(VoiceControls, {}), user && (_jsx(UserAreaPanel, { user: user, isMuted: isMuted, isDeafened: isDeafened, onMicToggle: handleMicToggle, onDeafenToggle: handleDeafenToggle, onSettingsClick: () => openModal('userSettings') }))] }));
}
/* ─── User Area Panel ──────────────────────────────────────────────────────── */
function UserAreaPanel({ user, isMuted, isDeafened, onMicToggle, onDeafenToggle, onSettingsClick, }) {
@@ -213,7 +213,7 @@ function UserAreaPanel({ user, isMuted, isDeafened, onMicToggle, onDeafenToggle,
// Generate mic level bars (20 bars like Discord)
const micBars = 20;
const activeBars = Math.round(micLevel * micBars * (inputVolume / 100));
- return (_jsxs("div", { className: "relative", ref: panelRef, children: [openPanel === 'input' && (_jsxs("div", { className: "absolute bottom-full left-0 right-0 mb-0 bg-[#2b2d31] rounded-t-lg shadow-lg z-50 border-t border-x border-discord-bg-tertiary", children: [_jsxs("div", { className: "relative", children: [_jsxs("button", { onClick: () => setShowInputDeviceList(!showInputDeviceList), className: "w-full px-4 py-3 flex items-center justify-between hover:bg-discord-modifier-hover transition-colors", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-[15px] font-semibold text-discord-text-primary text-left", children: "Input Device" }), _jsx("div", { className: "text-[13px] text-discord-text-muted truncate text-left", children: selectedInputLabel })] }), _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-text-muted flex-shrink-0 ml-2", children: _jsx("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) })] }), showInputDeviceList && (_jsx("div", { className: "bg-discord-bg-floating rounded-lg shadow-lg mx-2 mb-2 py-1 border border-discord-bg-tertiary", children: inputDevices.map(d => (_jsxs("button", { onClick: () => selectInput(d), className: `w-full px-3 py-2 text-left text-[13px] hover:bg-discord-modifier-hover transition-colors flex items-center gap-2 ${selectedInput === d.deviceId ? 'text-discord-text-primary' : 'text-discord-text-secondary'}`, children: [selectedInput === d.deviceId && (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-blurple flex-shrink-0", children: _jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" }) })), _jsx("span", { className: selectedInput === d.deviceId ? '' : 'pl-6', children: d.label || 'Default' })] }, d.deviceId))) }))] }), _jsx("div", { className: "mx-4 border-t border-[#3f4147]" }), _jsxs("div", { className: "px-4 py-3", children: [_jsx("div", { className: "text-[15px] font-semibold text-discord-text-primary mb-2", children: "Input Volume" }), _jsx("input", { type: "range", min: 0, max: 200, value: inputVolume, onChange: (e) => {
+ return (_jsxs("div", { className: "relative", ref: panelRef, children: [openPanel === 'input' && (_jsxs("div", { className: "absolute bottom-full left-0 right-0 mb-0 bg-[#1e1f22] rounded-t-lg shadow-lg z-50 border-t border-x border-discord-bg-tertiary", children: [_jsxs("div", { className: "relative", children: [_jsxs("button", { onClick: () => setShowInputDeviceList(!showInputDeviceList), className: "w-full px-4 py-3 flex items-center justify-between hover:bg-discord-modifier-hover transition-colors", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-[15px] font-semibold text-discord-text-primary text-left", children: "Input Device" }), _jsx("div", { className: "text-[13px] text-discord-text-muted truncate text-left", children: selectedInputLabel })] }), _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-text-muted flex-shrink-0 ml-2", children: _jsx("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) })] }), showInputDeviceList && (_jsx("div", { className: "bg-discord-bg-floating rounded-lg shadow-lg mx-2 mb-2 py-1 border border-discord-bg-tertiary", children: inputDevices.map(d => (_jsxs("button", { onClick: () => selectInput(d), className: `w-full px-3 py-2 text-left text-[13px] hover:bg-discord-modifier-hover transition-colors flex items-center gap-2 ${selectedInput === d.deviceId ? 'text-discord-text-primary' : 'text-discord-text-secondary'}`, children: [selectedInput === d.deviceId && (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-blurple flex-shrink-0", children: _jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" }) })), _jsx("span", { className: selectedInput === d.deviceId ? '' : 'pl-6', children: d.label || 'Default' })] }, d.deviceId))) }))] }), _jsx("div", { className: "mx-4 border-t border-[#2b2d31]" }), _jsxs("div", { className: "px-4 py-3", children: [_jsx("div", { className: "text-[15px] font-semibold text-discord-text-primary mb-2", children: "Input Volume" }), _jsx("input", { type: "range", min: 0, max: 200, value: inputVolume, onChange: (e) => {
const vol = Number(e.target.value);
storeSetInputVolume(vol);
// Apply gain to mic: at 0 = mute, 100 = normal, 200 = 2x boost
@@ -229,7 +229,7 @@ function UserAreaPanel({ user, isMuted, isDeafened, onMicToggle, onDeafenToggle,
}
}, className: "w-full h-1.5 rounded-full appearance-none cursor-pointer accent-discord-blurple bg-discord-bg-tertiary [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white [&::-webkit-slider-thumb]:shadow-md", style: {
background: `linear-gradient(to right, #5865f2 0%, #5865f2 ${inputVolume / 2}%, #4e5058 ${inputVolume / 2}%, #4e5058 100%)`,
- } }), _jsx("div", { className: "flex items-center gap-[3px] mt-2.5", children: Array.from({ length: micBars }).map((_, i) => (_jsx("div", { className: `flex-1 h-[6px] rounded-[1px] transition-colors duration-75 ${i < activeBars ? 'bg-discord-text-muted' : 'bg-[#3f4147]'}` }, i))) })] }), _jsx("div", { className: "mx-4 border-t border-[#3f4147]" }), _jsxs("button", { onClick: onSettingsClick, className: "w-full px-4 py-3 flex items-center justify-between hover:bg-discord-modifier-hover transition-colors", children: [_jsx("span", { className: "text-[15px] font-semibold text-discord-text-primary", children: "Voice Settings" }), _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-text-muted", children: _jsx("path", { d: "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z" }) })] })] })), openPanel === 'output' && (_jsxs("div", { className: "absolute bottom-full left-0 right-0 mb-0 bg-[#2b2d31] rounded-t-lg shadow-lg z-50 border-t border-x border-discord-bg-tertiary", children: [_jsxs("div", { className: "relative", children: [_jsxs("button", { onClick: () => setShowOutputDeviceList(!showOutputDeviceList), className: "w-full px-4 py-3 flex items-center justify-between hover:bg-discord-modifier-hover transition-colors", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-[15px] font-semibold text-discord-text-primary text-left", children: "Output Device" }), _jsx("div", { className: "text-[13px] text-discord-text-muted truncate text-left", children: selectedOutputLabel })] }), _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-text-muted flex-shrink-0 ml-2", children: _jsx("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) })] }), showOutputDeviceList && (_jsx("div", { className: "bg-discord-bg-floating rounded-lg shadow-lg mx-2 mb-2 py-1 border border-discord-bg-tertiary", children: outputDevices.map(d => (_jsxs("button", { onClick: () => selectOutput(d), className: `w-full px-3 py-2 text-left text-[13px] hover:bg-discord-modifier-hover transition-colors flex items-center gap-2 ${selectedOutput === d.deviceId ? 'text-discord-text-primary' : 'text-discord-text-secondary'}`, children: [selectedOutput === d.deviceId && (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-blurple flex-shrink-0", children: _jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" }) })), _jsx("span", { className: selectedOutput === d.deviceId ? '' : 'pl-6', children: d.label || 'Default' })] }, d.deviceId))) }))] }), _jsx("div", { className: "mx-4 border-t border-[#3f4147]" }), _jsxs("div", { className: "px-4 py-3", children: [_jsx("div", { className: "text-[15px] font-semibold text-discord-text-primary mb-2", children: "Output Volume" }), _jsx("input", { type: "range", min: 0, max: 200, value: outputVolume, onChange: (e) => {
+ } }), _jsx("div", { className: "flex items-center gap-[3px] mt-2.5", children: Array.from({ length: micBars }).map((_, i) => (_jsx("div", { className: `flex-1 h-[6px] rounded-[1px] transition-colors duration-75 ${i < activeBars ? 'bg-discord-text-muted' : 'bg-[#313338]'}` }, i))) })] }), _jsx("div", { className: "mx-4 border-t border-[#2b2d31]" }), _jsxs("button", { onClick: onSettingsClick, className: "w-full px-4 py-3 flex items-center justify-between hover:bg-discord-modifier-hover transition-colors", children: [_jsx("span", { className: "text-[15px] font-semibold text-discord-text-primary", children: "Voice Settings" }), _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-text-muted", children: _jsx("path", { d: "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z" }) })] })] })), openPanel === 'output' && (_jsxs("div", { className: "absolute bottom-full left-0 right-0 mb-0 bg-[#1e1f22] rounded-t-lg shadow-lg z-50 border-t border-x border-discord-bg-tertiary", children: [_jsxs("div", { className: "relative", children: [_jsxs("button", { onClick: () => setShowOutputDeviceList(!showOutputDeviceList), className: "w-full px-4 py-3 flex items-center justify-between hover:bg-discord-modifier-hover transition-colors", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-[15px] font-semibold text-discord-text-primary text-left", children: "Output Device" }), _jsx("div", { className: "text-[13px] text-discord-text-muted truncate text-left", children: selectedOutputLabel })] }), _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-text-muted flex-shrink-0 ml-2", children: _jsx("path", { d: "M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" }) })] }), showOutputDeviceList && (_jsx("div", { className: "bg-discord-bg-floating rounded-lg shadow-lg mx-2 mb-2 py-1 border border-discord-bg-tertiary", children: outputDevices.map(d => (_jsxs("button", { onClick: () => selectOutput(d), className: `w-full px-3 py-2 text-left text-[13px] hover:bg-discord-modifier-hover transition-colors flex items-center gap-2 ${selectedOutput === d.deviceId ? 'text-discord-text-primary' : 'text-discord-text-secondary'}`, children: [selectedOutput === d.deviceId && (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-blurple flex-shrink-0", children: _jsx("path", { d: "M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" }) })), _jsx("span", { className: selectedOutput === d.deviceId ? '' : 'pl-6', children: d.label || 'Default' })] }, d.deviceId))) }))] }), _jsx("div", { className: "mx-4 border-t border-[#2b2d31]" }), _jsxs("div", { className: "px-4 py-3", children: [_jsx("div", { className: "text-[15px] font-semibold text-discord-text-primary mb-2", children: "Output Volume" }), _jsx("input", { type: "range", min: 0, max: 200, value: outputVolume, onChange: (e) => {
const vol = Number(e.target.value);
storeSetOutputVolume(vol);
// Apply volume to all remote participants
@@ -242,5 +242,5 @@ function UserAreaPanel({ user, isMuted, isDeafened, onMicToggle, onDeafenToggle,
}
}, className: "w-full h-1.5 rounded-full appearance-none cursor-pointer bg-discord-bg-tertiary [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white [&::-webkit-slider-thumb]:shadow-md", style: {
background: `linear-gradient(to right, #5865f2 0%, #5865f2 ${outputVolume / 2}%, #4e5058 ${outputVolume / 2}%, #4e5058 100%)`,
- } })] }), _jsx("div", { className: "mx-4 border-t border-[#3f4147]" }), _jsxs("button", { onClick: onSettingsClick, className: "w-full px-4 py-3 flex items-center justify-between hover:bg-discord-modifier-hover transition-colors", children: [_jsx("span", { className: "text-[15px] font-semibold text-discord-text-primary", children: "Voice Settings" }), _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-text-muted", children: _jsx("path", { d: "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z" }) })] })] })), _jsxs("div", { className: "h-[52px] px-2 bg-discord-bg-user-area flex items-center select-none", children: [_jsxs("div", { className: "p-1 hover:bg-discord-modifier-hover rounded-[4px] flex items-center gap-2 flex-1 min-w-0 cursor-pointer transition-colors group", children: [_jsx(Avatar, { src: user.avatar, name: user.displayName ?? user.username, size: 32, status: user.status, user: user }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "text-[13px] font-semibold text-discord-text-primary truncate leading-tight", children: user.displayName ?? user.username }), _jsxs("div", { className: "text-[11px] text-discord-text-muted truncate leading-tight group-hover:text-discord-text-secondary", children: ["@", user.username] })] })] }), _jsxs("div", { className: "flex items-center", children: [_jsx("button", { onClick: onMicToggle, className: `w-8 h-8 flex items-center justify-center hover:bg-discord-modifier-hover rounded-l-[4px] transition-colors ${isMuted ? 'text-discord-red' : 'text-discord-text-muted hover:text-discord-text-primary'}`, title: isMuted ? 'Unmute' : 'Mute', children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: [_jsx("path", { d: "M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z" }), _jsx("path", { d: "M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z" }), isMuted && _jsx("line", { x1: "3", y1: "3", x2: "21", y2: "21", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" })] }) }), _jsx("button", { onClick: () => togglePanel('input'), className: `w-[18px] h-8 flex items-center justify-center hover:bg-discord-modifier-hover rounded-r-[4px] transition-colors ${openPanel === 'input' ? 'text-discord-text-primary bg-discord-modifier-hover' : 'text-discord-text-muted hover:text-discord-text-primary'}`, title: "Input Devices", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "currentColor", className: `transition-transform ${openPanel === 'input' ? 'rotate-180' : ''}`, children: _jsx("path", { d: "M7 10l5 5 5-5z" }) }) }), _jsx("button", { onClick: onDeafenToggle, className: `w-8 h-8 flex items-center justify-center hover:bg-discord-modifier-hover rounded-l-[4px] transition-colors ${isDeafened ? 'text-discord-red' : 'text-discord-text-muted hover:text-discord-text-primary'}`, title: isDeafened ? 'Undeafen' : 'Deafen', children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: [_jsx("path", { d: "M12 3c-4.97 0-9 4.03-9 9v7c0 1.1.9 2 2 2h2v-7H5v-2c0-3.87 3.13-7 7-7s7 3.13 7 7v2h-2v7h2c1.1 0 2-.9 2-2v-7c0-4.97-4.03-9-9-9z" }), isDeafened && _jsx("line", { x1: "3", y1: "3", x2: "21", y2: "21", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" })] }) }), _jsx("button", { onClick: () => togglePanel('output'), className: `w-[18px] h-8 flex items-center justify-center hover:bg-discord-modifier-hover rounded-r-[4px] transition-colors ${openPanel === 'output' ? 'text-discord-text-primary bg-discord-modifier-hover' : 'text-discord-text-muted hover:text-discord-text-primary'}`, title: "Output Devices", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "currentColor", className: `transition-transform ${openPanel === 'output' ? 'rotate-180' : ''}`, children: _jsx("path", { d: "M7 10l5 5 5-5z" }) }) }), _jsx("button", { onClick: onSettingsClick, className: "w-8 h-8 flex items-center justify-center text-discord-text-muted hover:text-discord-text-primary hover:bg-discord-modifier-hover rounded-[4px] transition-colors", title: "User Settings", children: _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z" }) }) })] })] })] }));
+ } })] }), _jsx("div", { className: "mx-4 border-t border-[#2b2d31]" }), _jsxs("button", { onClick: onSettingsClick, className: "w-full px-4 py-3 flex items-center justify-between hover:bg-discord-modifier-hover transition-colors", children: [_jsx("span", { className: "text-[15px] font-semibold text-discord-text-primary", children: "Voice Settings" }), _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", className: "text-discord-text-muted", children: _jsx("path", { d: "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z" }) })] })] })), _jsxs("div", { className: "h-[52px] px-2 bg-discord-bg-user-area flex items-center select-none", children: [_jsxs("div", { className: "p-1 hover:bg-discord-modifier-hover rounded-[4px] flex items-center gap-2 flex-1 min-w-0 cursor-pointer transition-colors group", children: [_jsx(Avatar, { src: user.avatar, name: user.displayName ?? user.username, size: 32, status: user.status, user: user }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("div", { className: "text-[13px] font-semibold text-discord-text-primary truncate leading-tight", children: user.displayName ?? user.username }), _jsxs("div", { className: "text-[11px] text-discord-text-muted truncate leading-tight group-hover:text-discord-text-secondary", children: ["@", user.username] })] })] }), _jsxs("div", { className: "flex items-center", children: [_jsx("button", { onClick: onMicToggle, className: `w-8 h-8 flex items-center justify-center hover:bg-discord-modifier-hover rounded-l-[4px] transition-colors ${isMuted ? 'text-discord-red' : 'text-discord-text-muted hover:text-discord-text-primary'}`, title: isMuted ? 'Unmute' : 'Mute', children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: [_jsx("path", { d: "M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z" }), _jsx("path", { d: "M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.61 6.43 6 6.92V21h2v-3.08c3.39-.49 6-3.39 6-6.92h-2z" }), isMuted && _jsx("line", { x1: "3", y1: "3", x2: "21", y2: "21", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" })] }) }), _jsx("button", { onClick: () => togglePanel('input'), className: `w-[18px] h-8 flex items-center justify-center hover:bg-discord-modifier-hover rounded-r-[4px] transition-colors ${openPanel === 'input' ? 'text-discord-text-primary bg-discord-modifier-hover' : 'text-discord-text-muted hover:text-discord-text-primary'}`, title: "Input Devices", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "currentColor", className: `transition-transform ${openPanel === 'input' ? 'rotate-180' : ''}`, children: _jsx("path", { d: "M7 10l5 5 5-5z" }) }) }), _jsx("button", { onClick: onDeafenToggle, className: `w-8 h-8 flex items-center justify-center hover:bg-discord-modifier-hover rounded-l-[4px] transition-colors ${isDeafened ? 'text-discord-red' : 'text-discord-text-muted hover:text-discord-text-primary'}`, title: isDeafened ? 'Undeafen' : 'Deafen', children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: [_jsx("path", { d: "M12 3c-4.97 0-9 4.03-9 9v7c0 1.1.9 2 2 2h2v-7H5v-2c0-3.87 3.13-7 7-7s7 3.13 7 7v2h-2v7h2c1.1 0 2-.9 2-2v-7c0-4.97-4.03-9-9-9z" }), isDeafened && _jsx("line", { x1: "3", y1: "3", x2: "21", y2: "21", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" })] }) }), _jsx("button", { onClick: () => togglePanel('output'), className: `w-[18px] h-8 flex items-center justify-center hover:bg-discord-modifier-hover rounded-r-[4px] transition-colors ${openPanel === 'output' ? 'text-discord-text-primary bg-discord-modifier-hover' : 'text-discord-text-muted hover:text-discord-text-primary'}`, title: "Output Devices", children: _jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "currentColor", className: `transition-transform ${openPanel === 'output' ? 'rotate-180' : ''}`, children: _jsx("path", { d: "M7 10l5 5 5-5z" }) }) }), _jsx("button", { onClick: onSettingsClick, className: "w-8 h-8 flex items-center justify-center text-discord-text-muted hover:text-discord-text-primary hover:bg-discord-modifier-hover rounded-[4px] transition-colors", title: "User Settings", children: _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z" }) }) })] })] })] }));
}
diff --git a/packages/web/src/components/layout/ChannelSidebar.tsx b/packages/web/src/components/layout/ChannelSidebar.tsx
index 3fc90a34..1d8ba612 100644
--- a/packages/web/src/components/layout/ChannelSidebar.tsx
+++ b/packages/web/src/components/layout/ChannelSidebar.tsx
@@ -208,15 +208,26 @@ export function ChannelSidebar() {
return (
{/* Server header */}
-
+
+
+
+
{/* Channels */}
@@ -308,18 +319,6 @@ export function ChannelSidebar() {
- {/* Restore Invite Button */}
-
-
-
{/* Voice controls — VoiceControls reads state and calls LiveKit SDK directly */}
@@ -473,7 +472,7 @@ function UserAreaPanel({