feat(call): add sound effects and incoming call notification UI
- Implemented sound management for call events including mute, unmute, deafen, undeafen, call joined, call depart, and dialing sounds. - Created a new CallSounds class to handle sound playback and state management. - Added IncomingCallNotification component to display incoming call alerts with caller information and action buttons. - Styled the incoming call notification using vanilla-extract CSS for animations and layout. - Integrated sound playback for incoming calls with a 15-second threshold for dialing sound.
This commit is contained in:
@@ -5,7 +5,7 @@ export const CallOverlayContainer = style([
|
||||
DefaultReset,
|
||||
{
|
||||
position: 'fixed',
|
||||
bottom: config.space.S400,
|
||||
top: '60px',
|
||||
right: config.space.S400,
|
||||
zIndex: 9999,
|
||||
backgroundColor: color.Surface.Container,
|
||||
@@ -16,6 +16,7 @@ export const CallOverlayContainer = style([
|
||||
maxWidth: '400px',
|
||||
transition: 'box-shadow 0.2s ease',
|
||||
userSelect: 'none',
|
||||
color: color.Surface.OnContainer,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -44,6 +45,7 @@ export const CallOverlayHeader = style({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: config.space.S200,
|
||||
color: color.Surface.OnContainer,
|
||||
});
|
||||
|
||||
export const CallOverlayControls = style({
|
||||
@@ -55,6 +57,7 @@ export const CallOverlayControls = style({
|
||||
|
||||
export const CallDuration = style({
|
||||
fontVariantNumeric: 'tabular-nums',
|
||||
color: color.Surface.OnContainer,
|
||||
});
|
||||
|
||||
export const VideoContainer = style({
|
||||
@@ -111,21 +114,6 @@ export const ScreenShareContainer = style({
|
||||
},
|
||||
});
|
||||
|
||||
export const ScreenShareLabel = style({
|
||||
position: 'absolute',
|
||||
top: config.space.S100,
|
||||
left: config.space.S100,
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
||||
color: 'white',
|
||||
padding: `${config.space.S100} ${config.space.S200}`,
|
||||
borderRadius: config.radii.R300,
|
||||
fontSize: '0.75rem',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: config.space.S100,
|
||||
zIndex: 1,
|
||||
});
|
||||
|
||||
export const ScreenShareVideoContainer = style({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
@@ -140,3 +128,89 @@ export const ScreenShareVideo = style({
|
||||
height: '100%',
|
||||
objectFit: 'contain',
|
||||
});
|
||||
|
||||
export const ParticipantsSection = style({
|
||||
marginBottom: config.space.S200,
|
||||
borderRadius: config.radii.R300,
|
||||
backgroundColor: color.Surface.ContainerActive,
|
||||
overflow: 'hidden',
|
||||
});
|
||||
|
||||
export const ParticipantsHeader = style({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
width: '100%',
|
||||
padding: `${config.space.S200} ${config.space.S300}`,
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
color: color.Surface.OnContainer,
|
||||
transition: 'background-color 0.15s ease',
|
||||
':hover': {
|
||||
backgroundColor: color.Surface.ContainerHover,
|
||||
},
|
||||
});
|
||||
|
||||
export const ParticipantsHeaderText = style({
|
||||
color: color.Surface.OnContainer,
|
||||
});
|
||||
|
||||
export const ParticipantsList = style({
|
||||
padding: `0 ${config.space.S200} ${config.space.S200}`,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: config.space.S100,
|
||||
});
|
||||
|
||||
export const ParticipantItem = style({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: config.space.S200,
|
||||
padding: config.space.S200,
|
||||
borderRadius: config.radii.R300,
|
||||
backgroundColor: color.Surface.Container,
|
||||
transition: 'background-color 0.15s ease',
|
||||
':hover': {
|
||||
backgroundColor: color.Surface.ContainerHover,
|
||||
},
|
||||
});
|
||||
|
||||
export const ParticipantName = style({
|
||||
color: color.Surface.OnContainer,
|
||||
fontWeight: 500,
|
||||
});
|
||||
|
||||
export const ParticipantId = style({
|
||||
color: color.Secondary.Main,
|
||||
opacity: 0.7,
|
||||
});
|
||||
|
||||
export const YouBadge = style({
|
||||
color: color.Primary.Main,
|
||||
fontWeight: 600,
|
||||
});
|
||||
|
||||
export const ParticipantMutedIcon = style({
|
||||
color: color.Critical.Main,
|
||||
flexShrink: 0,
|
||||
});
|
||||
|
||||
export const ParticipantAvatarWrapper = style({
|
||||
position: 'relative',
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
flexShrink: 0,
|
||||
borderRadius: '50%',
|
||||
transition: 'box-shadow 0.15s ease',
|
||||
});
|
||||
|
||||
export const ParticipantAvatar = style({
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
borderRadius: '50%',
|
||||
});
|
||||
|
||||
export const ParticipantSpeaking = style({
|
||||
boxShadow: `0 0 0 2px ${color.Success.Main}`,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user