feat: Add Picture-in-Picture floating video + fix local track visibility
- New PictureInPicture component: draggable floating window that shows active stream when navigating away from voice channel, with LIVE badge, snap-to-edge, click-to-navigate-back - Fix VoiceUser to check actual track presence instead of boolean flags for video rendering - Add LocalTrackPublished/LocalTrackUnpublished events to useLiveKit so local screen share and camera show immediately in VoiceGrid - Add pipCollapsed state to uiStore
This commit is contained in:
@@ -14,6 +14,7 @@ import { UserSettingsModal } from '../modals/UserSettings';
|
||||
import { ServerSettingsModal } from '../modals/ServerSettings';
|
||||
import { NewDmModal } from '../modals/NewDmModal';
|
||||
import { IncomingCallModal } from '../voice/IncomingCallModal';
|
||||
import { PictureInPicture } from '../voice/PictureInPicture';
|
||||
import { UserProfilePopout } from '../ui/UserProfilePopout';
|
||||
import { useAuth } from '../../hooks/useAuth';
|
||||
import { useWebSocket } from '../../hooks/useWebSocket';
|
||||
@@ -100,5 +101,5 @@ export function AppLayout() {
|
||||
if (isLoading || !user) {
|
||||
return (_jsx("div", { className: "h-screen flex items-center justify-center bg-discord-bg-primary", children: _jsxs("div", { className: "text-center", children: [_jsxs("svg", { className: "animate-spin w-10 h-10 text-discord-blurple mx-auto mb-4", viewBox: "0 0 24 24", fill: "none", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })] }), _jsx("p", { className: "text-discord-text-muted", children: "Loading Opencord..." })] }) }));
|
||||
}
|
||||
return (_jsxs("div", { className: "h-screen flex bg-discord-bg-tertiary overflow-hidden", children: [_jsxs("div", { className: `${isMobile ? `fixed z-40 h-full transition-transform ${sidebarOpen ? 'translate-x-0' : '-translate-x-full'}` : 'flex h-full'}`, children: [_jsx(ServerSidebar, {}), _jsx(ChannelSidebar, {})] }), _jsxs("div", { className: "flex-1 flex min-w-0 bg-discord-bg-primary relative", children: [_jsx(MainContent, {}), serverId === '@me' ? (_jsx("div", { className: "w-[358px] bg-discord-bg-secondary flex-shrink-0 hidden xl:flex flex-col", children: _jsxs("div", { className: "p-4", children: [_jsx("h3", { className: "text-[20px] font-bold text-discord-text-header mb-4", children: "Active Now" }), _jsxs("div", { className: "text-center py-8", children: [_jsx("div", { className: "text-[16px] font-bold text-discord-text-header mb-1 text-center", children: "It's quiet for now..." }), _jsx("div", { className: "text-[14px] text-discord-text-muted text-center max-w-[200px] mx-auto", children: "When a friend starts an activity\u2014like playing a game or hanging out on voice\u2014we\u2019ll show it here!" })] })] }) })) : (_jsx(MemberSidebar, {}))] }), _jsx(CreateServerModal, {}), _jsx(JoinServerModal, {}), _jsx(CreateChannelModal, {}), _jsx(InviteModal, {}), _jsx(UserSettingsModal, {}), _jsx(ServerSettingsModal, {}), _jsx(NewDmModal, {}), _jsx(IncomingCallModal, {}), _jsx(ImagePreview, {}), userProfilePopout.user && userProfilePopout.position && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-[45]", onClick: closeUserProfile }), _jsx(UserProfilePopout, { user: userProfilePopout.user, onClose: closeUserProfile, position: userProfilePopout.position })] }))] }));
|
||||
return (_jsxs("div", { className: "h-screen flex bg-discord-bg-tertiary overflow-hidden", children: [_jsxs("div", { className: `${isMobile ? `fixed z-40 h-full transition-transform ${sidebarOpen ? 'translate-x-0' : '-translate-x-full'}` : 'flex h-full'}`, children: [_jsx(ServerSidebar, {}), _jsx(ChannelSidebar, {})] }), _jsxs("div", { className: "flex-1 flex min-w-0 bg-discord-bg-primary relative", children: [_jsx(MainContent, {}), serverId === '@me' ? (_jsx("div", { className: "w-[358px] bg-discord-bg-secondary flex-shrink-0 hidden xl:flex flex-col", children: _jsxs("div", { className: "p-4", children: [_jsx("h3", { className: "text-[20px] font-bold text-discord-text-header mb-4", children: "Active Now" }), _jsxs("div", { className: "text-center py-8", children: [_jsx("div", { className: "text-[16px] font-bold text-discord-text-header mb-1 text-center", children: "It's quiet for now..." }), _jsx("div", { className: "text-[14px] text-discord-text-muted text-center max-w-[200px] mx-auto", children: "When a friend starts an activity\u2014like playing a game or hanging out on voice\u2014we\u2019ll show it here!" })] })] }) })) : (_jsx(MemberSidebar, {}))] }), _jsx(CreateServerModal, {}), _jsx(JoinServerModal, {}), _jsx(CreateChannelModal, {}), _jsx(InviteModal, {}), _jsx(UserSettingsModal, {}), _jsx(ServerSettingsModal, {}), _jsx(NewDmModal, {}), _jsx(IncomingCallModal, {}), _jsx(ImagePreview, {}), _jsx(PictureInPicture, {}), userProfilePopout.user && userProfilePopout.position && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-[45]", onClick: closeUserProfile }), _jsx(UserProfilePopout, { user: userProfilePopout.user, onClose: closeUserProfile, position: userProfilePopout.position })] }))] }));
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import { UserSettingsModal } from '../modals/UserSettings';
|
||||
import { ServerSettingsModal } from '../modals/ServerSettings';
|
||||
import { NewDmModal } from '../modals/NewDmModal';
|
||||
import { IncomingCallModal } from '../voice/IncomingCallModal';
|
||||
import { PictureInPicture } from '../voice/PictureInPicture';
|
||||
import { UserProfilePopout } from '../ui/UserProfilePopout';
|
||||
import { useAuth } from '../../hooks/useAuth';
|
||||
import { useWebSocket } from '../../hooks/useWebSocket';
|
||||
@@ -161,6 +162,7 @@ export function AppLayout() {
|
||||
<NewDmModal />
|
||||
<IncomingCallModal />
|
||||
<ImagePreview />
|
||||
<PictureInPicture />
|
||||
|
||||
{/* User Profile Popout */}
|
||||
{userProfilePopout.user && userProfilePopout.position && (
|
||||
|
||||
Reference in New Issue
Block a user