This commit is contained in:
2025-12-12 23:21:05 -08:00
parent dd5010d4df
commit 84cdc6fe82
2 changed files with 64 additions and 4 deletions

3
.gitignore vendored
View File

@@ -3,6 +3,7 @@ node_modules/
*.log *.log
.DS_Store .DS_Store
music/ music/
music/*
data/ data/
dist/ dist/
build/ build/
@@ -11,6 +12,8 @@ build/
*.swp *.swp
*.swo *.swo
*~ *~
*.mp3
*.mp4
coverage/ coverage/
.nyc_output/ .nyc_output/
tmp/ tmp/

View File

@@ -6,6 +6,8 @@ export default function ConnectionStatus() {
const [channels, setChannels] = useState([]); const [channels, setChannels] = useState([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [disconnecting, setDisconnecting] = useState(false); const [disconnecting, setDisconnecting] = useState(false);
const [joining, setJoining] = useState(false);
const [showChannels, setShowChannels] = useState(false);
useEffect(() => { useEffect(() => {
loadChannels(); loadChannels();
@@ -43,9 +45,29 @@ export default function ConnectionStatus() {
} }
}; };
const handleJoin = async (channelId) => {
try {
setJoining(true);
const response = await fetch(`${API_URL}/channels/join`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ channelId })
});
if (response.ok) {
loadChannels();
setShowChannels(false);
}
} catch (error) {
console.error('Failed to join channel:', error);
} finally {
setJoining(false);
}
};
const currentChannel = channels.find(c => c.current); const currentChannel = channels.find(c => c.current);
if (loading && !currentChannel) { if (loading && channels.length === 0) {
return ( return (
<div className="flex items-center gap-2 px-4 py-2 bg-slate-700/50 rounded-lg"> <div className="flex items-center gap-2 px-4 py-2 bg-slate-700/50 rounded-lg">
<div className="text-slate-400 text-sm">Loading...</div> <div className="text-slate-400 text-sm">Loading...</div>
@@ -55,9 +77,44 @@ export default function ConnectionStatus() {
if (!currentChannel) { if (!currentChannel) {
return ( return (
<div className="flex items-center gap-2 px-4 py-2 bg-slate-700/50 rounded-lg"> <div className="relative">
<div className="w-2 h-2 bg-slate-500 rounded-full"></div> <div className="flex items-center gap-3 px-4 py-2 bg-slate-700/50 rounded-lg">
<div className="text-slate-400 text-sm">Disconnected</div> <div className="flex items-center gap-2 flex-1">
<div className="w-2 h-2 bg-slate-500 rounded-full"></div>
<div className="text-slate-400 text-sm">Disconnected</div>
</div>
<button
onClick={() => setShowChannels(!showChannels)}
className="px-3 py-1 bg-green-600 hover:bg-green-700 text-white text-sm rounded transition-colors"
>
Connect
</button>
</div>
{showChannels && (
<div className="absolute top-full right-0 mt-2 w-64 bg-slate-800 border border-slate-700 rounded-lg shadow-xl z-50">
<div className="p-3">
<div className="text-white font-medium mb-2">Select Channel</div>
<div className="space-y-1">
{channels.map(channel => (
<button
key={channel.id}
onClick={() => handleJoin(channel.id)}
disabled={joining}
className="w-full text-left p-2 rounded hover:bg-slate-700 text-white text-sm transition-colors disabled:opacity-50"
>
<div className="font-medium">{channel.name}</div>
{channel.userCount > 0 && (
<div className="text-xs text-slate-400">
{channel.userCount} {channel.userCount === 1 ? 'user' : 'users'}
</div>
)}
</button>
))}
</div>
</div>
</div>
)}
</div> </div>
); );
} }