feat(call): add docked call panel and remote cursor overlay

- Implemented DockedCallPanel component to render the docked call interface when an active call is present.
- Created RemoteCursorOverlay component to display remote cursor positions during screen sharing.
- Added hooks for managing docked call state and remote cursor functionality.
- Introduced pending drag state management for seamless transitions between docked and floating states.
- Developed embed filter management components for personal and room-wide settings, allowing users to customize URL embed visibility.
- Implemented auto-joining functionality for rooms within spaces, enhancing user experience during space navigation.
- Added state management for tracking joining progress of rooms in spaces.
This commit is contained in:
2026-02-19 17:49:48 +11:00
parent bfbdf98468
commit 3f6f2134ad
42 changed files with 3801 additions and 219 deletions

View File

@@ -1,5 +1,5 @@
import { style } from '@vanilla-extract/css';
import { config, DefaultReset, color } from 'folds';
import { config, DefaultReset, color, toRem } from 'folds';
export const CallOverlayContainer = style([
DefaultReset,
@@ -25,6 +25,53 @@ export const CallOverlayDragging = style({
opacity: 0.95,
});
export const CallOverlayDocked = style({
position: 'fixed',
top: 0,
right: 0,
bottom: 0,
width: toRem(266),
maxWidth: toRem(266),
minWidth: toRem(266),
borderRadius: 0,
zIndex: 100,
display: 'flex',
flexDirection: 'column',
transform: 'none !important',
borderLeft: `${config.borderWidth.B300} solid ${color.Background.ContainerLine}`,
});
export const DockIndicator = style({
position: 'fixed',
top: 0,
right: 0,
bottom: 0,
width: toRem(266),
backgroundColor: color.Primary.Container,
opacity: 0.5,
zIndex: 9998,
pointerEvents: 'none',
borderLeft: `2px dashed ${color.Primary.Main}`,
});
export const DockedCallPanelLayout = style({
width: toRem(266),
height: '100%',
display: 'flex',
flexDirection: 'column',
backgroundColor: color.Background.Container,
overflow: 'hidden',
});
export const DockedCallPanelContent = style({
display: 'flex',
flexDirection: 'column',
height: '100%',
padding: config.space.S300,
backgroundColor: color.Surface.Container,
color: color.Surface.OnContainer,
});
export const CallOverlayFullscreen = style({
position: 'fixed',
top: 0,
@@ -134,6 +181,20 @@ export const ParticipantsSection = style({
borderRadius: config.radii.R300,
backgroundColor: color.Surface.ContainerActive,
overflow: 'hidden',
selectors: {
[`${CallOverlayDocked} &`]: {
flex: 1,
display: 'flex',
flexDirection: 'column',
overflow: 'auto',
},
[`${CallOverlayFullscreen} &`]: {
flex: 1,
display: 'flex',
flexDirection: 'column',
overflow: 'auto',
},
},
});
export const ParticipantsHeader = style({
@@ -214,3 +275,39 @@ export const ParticipantAvatar = style({
export const ParticipantSpeaking = style({
boxShadow: `0 0 0 2px ${color.Success.Main}`,
});
export const RemoteCursorOverlay = style({
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
pointerEvents: 'none',
overflow: 'hidden',
zIndex: 10,
});
export const RemoteCursorDot = style({
position: 'absolute',
width: '12px',
height: '12px',
borderRadius: '50%',
border: '2px solid white',
boxShadow: '0 0 4px rgba(0,0,0,0.4)',
transform: 'translate(-50%, -50%)',
transition: 'left 0.05s linear, top 0.05s linear, opacity 0.2s ease',
pointerEvents: 'none',
});
export const RemoteCursorLabel = style({
position: 'absolute',
transform: 'translate(-50%, 8px)',
fontSize: '10px',
fontWeight: 600,
color: 'white',
backgroundColor: 'rgba(0,0,0,0.6)',
borderRadius: '4px',
padding: '1px 5px',
whiteSpace: 'nowrap',
pointerEvents: 'none',
});