feat(ui): tabulate voice and chat panels to prevent overlapping

This commit is contained in:
2026-07-06 12:47:23 +00:00
parent 83c05731ed
commit 549bf842d0
+34 -2
View File
@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Link, Outlet, useLocation, useNavigate } from 'react-router-dom'; import { Link, Outlet, useLocation, useNavigate } from 'react-router-dom';
import { useVoiceStore } from '../stores/voice.ts';
import { useAuthStore, type UserStatus } from '../stores/auth.ts'; import { useAuthStore, type UserStatus } from '../stores/auth.ts';
import { useWebSocketStore } from '../stores/ws.ts'; import { useWebSocketStore } from '../stores/ws.ts';
import { useServerStore } from '../stores/server.ts'; import { useServerStore } from '../stores/server.ts';
@@ -44,6 +45,17 @@ export function Layout() {
const setMobileView = useLayoutStore((s) => s.setMobileView); const setMobileView = useLayoutStore((s) => s.setMobileView);
const [showServerSettings, setShowServerSettings] = useState(false); const [showServerSettings, setShowServerSettings] = useState(false);
const activeServerId = useServerStore((s) => s.activeServerId); const activeServerId = useServerStore((s) => s.activeServerId);
const currentVoiceRoom = useVoiceStore((s) => s.currentRoom);
const [activeTab, setActiveTab] = useState<'chat' | 'voice'>('chat');
useEffect(() => {
if (currentVoiceRoom) {
setActiveTab('voice');
} else {
setActiveTab('chat');
}
}, [currentVoiceRoom]);
useEffect(() => { useEffect(() => {
wsConnect(); wsConnect();
return () => { wsDisconnect(); }; return () => { wsDisconnect(); };
@@ -187,10 +199,30 @@ export function Layout() {
`} `}
> >
<div className="flex-1 min-h-0 flex flex-col overflow-hidden"> <div className="flex-1 min-h-0 flex flex-col overflow-hidden">
<VoicePanel /> {currentVoiceRoom && (
<div className="flex-1 min-h-0"> <div className="flex bg-gb-bg-s border-b border-gb-bg-t">
<button
className={`flex-1 py-2 text-xs text-center border-b-2 ${activeTab === 'chat' ? 'border-gb-fg-f text-gb-fg-f' : 'border-transparent text-gb-fg-s hover:text-gb-fg-f'}`}
onClick={() => setActiveTab('chat')}
>
[CHAT]
</button>
<button
className={`flex-1 py-2 text-xs text-center border-b-2 ${activeTab === 'voice' ? 'border-gb-fg-f text-gb-fg-f' : 'border-transparent text-gb-fg-s hover:text-gb-fg-f'}`}
onClick={() => setActiveTab('voice')}
>
[VOICE/VIDEO]
</button>
</div>
)}
<div className={`flex-1 min-h-0 flex-col ${activeTab === 'chat' || !currentVoiceRoom ? 'flex' : 'hidden'}`}>
<Outlet /> <Outlet />
</div> </div>
{currentVoiceRoom && (
<div className={`flex-1 min-h-0 flex-col overflow-y-auto bg-gb-bg ${activeTab === 'voice' ? 'flex' : 'hidden'}`}>
<VoicePanel />
</div>
)}
</div> </div>
</div> </div>