Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/aaa_syncupstream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: minor
---

Merge in upstream call things and remove the duplicate new voice room button.
10 changes: 10 additions & 0 deletions src/app/cs-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ export type AutoDiscoveryInfo = Record<string, unknown> & {
'm.identity_server'?: {
base_url: string;
};
'org.matrix.msc2965.authentication'?: {
account?: string;
issuer?: string;
};
'org.matrix.msc4143.rtc_foci'?: [
{
livekit_service_url: string;
type: 'livekit';
},
];
};

export const autoDiscovery = async (
Expand Down
101 changes: 81 additions & 20 deletions src/app/features/call-status/CallControl.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { Box, Chip, Icon, IconButton, Icons, Text, Tooltip, TooltipProvider } from 'folds';
import { useState } from 'react';
import { Box, Chip, Icon, IconButton, Icons, Spinner, Text, Tooltip, TooltipProvider } from 'folds';
import { useCallback } from 'react';
import { useSetAtom } from 'jotai';
import { StatusDivider } from './components';
import { CallEmbed, useCallControlState } from '../../plugins/call';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { callEmbedAtom } from '../../state/callEmbed';

type MicrophoneButtonProps = {
enabled: boolean;
onToggle: () => Promise<unknown>;
disabled?: boolean;
};
function MicrophoneButton({ enabled, onToggle }: MicrophoneButtonProps) {
function MicrophoneButton({ enabled, onToggle, disabled }: MicrophoneButtonProps) {
return (
<TooltipProvider
position="Top"
Expand All @@ -26,6 +30,7 @@ function MicrophoneButton({ enabled, onToggle }: MicrophoneButtonProps) {
size="300"
onClick={() => onToggle()}
outlined
disabled={disabled}
>
<Icon size="100" src={enabled ? Icons.Mic : Icons.MicMute} filled={!enabled} />
</IconButton>
Expand All @@ -37,8 +42,9 @@ function MicrophoneButton({ enabled, onToggle }: MicrophoneButtonProps) {
type SoundButtonProps = {
enabled: boolean;
onToggle: () => void;
disabled?: boolean;
};
function SoundButton({ enabled, onToggle }: SoundButtonProps) {
function SoundButton({ enabled, onToggle, disabled }: SoundButtonProps) {
return (
<TooltipProvider
position="Top"
Expand All @@ -57,6 +63,7 @@ function SoundButton({ enabled, onToggle }: SoundButtonProps) {
size="300"
onClick={() => onToggle()}
outlined
disabled={disabled}
>
<Icon
size="100"
Expand All @@ -72,8 +79,9 @@ function SoundButton({ enabled, onToggle }: SoundButtonProps) {
type VideoButtonProps = {
enabled: boolean;
onToggle: () => Promise<unknown>;
disabled?: boolean;
};
function VideoButton({ enabled, onToggle }: VideoButtonProps) {
function VideoButton({ enabled, onToggle, disabled }: VideoButtonProps) {
return (
<TooltipProvider
position="Top"
Expand All @@ -92,6 +100,7 @@ function VideoButton({ enabled, onToggle }: VideoButtonProps) {
size="300"
onClick={() => onToggle()}
outlined
disabled={disabled}
>
<Icon
size="100"
Expand All @@ -104,9 +113,12 @@ function VideoButton({ enabled, onToggle }: VideoButtonProps) {
);
}

function ScreenShareButton() {
const [enabled, setEnabled] = useState(false);

type ScreenShareButtonProps = {
enabled: boolean;
onToggle: () => void;
disabled?: boolean;
};
function ScreenShareButton({ enabled, onToggle, disabled }: ScreenShareButtonProps) {
return (
<TooltipProvider
position="Top"
Expand All @@ -123,8 +135,9 @@ function ScreenShareButton() {
fill="Soft"
radii="300"
size="300"
onClick={() => setEnabled(!enabled)}
onClick={onToggle}
outlined
disabled={disabled}
>
<Icon size="100" src={Icons.ScreenShare} filled={enabled} />
</IconButton>
Expand All @@ -133,32 +146,80 @@ function ScreenShareButton() {
);
}

export function CallControl({ callEmbed }: { callEmbed: CallEmbed }) {
const { microphone, video, sound } = useCallControlState(callEmbed.control);
export function CallControl({
callEmbed,
compact,
callJoined,
}: {
callEmbed: CallEmbed;
compact: boolean;
callJoined: boolean;
}) {
const { microphone, video, sound, screenshare } = useCallControlState(callEmbed.control);
const setCallEmbed = useSetAtom(callEmbedAtom);

const [hangupState, hangup] = useAsyncCallback(
useCallback(() => callEmbed.hangup(), [callEmbed])
);
const exiting =
hangupState.status === AsyncStatus.Loading || hangupState.status === AsyncStatus.Success;

const handleHangup = () => {
if (!callJoined) {
setCallEmbed(undefined);
return;
}
hangup();
};

return (
<Box shrink="No" alignItems="Center" gap="300">
<Box alignItems="Inherit" gap="200">
<MicrophoneButton
enabled={microphone}
onToggle={() => callEmbed.control.toggleMicrophone()}
disabled={!callJoined}
/>
<SoundButton
enabled={sound}
onToggle={() => callEmbed.control.toggleSound()}
disabled={!callJoined}
/>
<SoundButton enabled={sound} onToggle={() => callEmbed.control.toggleSound()} />
<VideoButton enabled={video} onToggle={() => callEmbed.control.toggleVideo()} />
{false && <ScreenShareButton />}
{!compact && <StatusDivider />}
<VideoButton
enabled={video}
onToggle={() => callEmbed.control.toggleVideo()}
disabled={!callJoined}
/>
{!compact && (
<ScreenShareButton
enabled={screenshare}
onToggle={() => callEmbed.control.toggleScreenshare()}
disabled={!callJoined}
/>
)}
</Box>
<StatusDivider />
<Chip
variant="Critical"
radii="300"
radii="Pill"
fill="Soft"
before={<Icon size="50" src={Icons.PhoneDown} filled />}
before={
exiting ? (
<Spinner variant="Critical" fill="Soft" size="50" />
) : (
<Icon size="50" src={Icons.PhoneDown} filled />
)
}
disabled={exiting}
outlined
onClick={() => callEmbed.hangup()}
onClick={handleHangup}
>
<Text as="span" size="L400">
End
</Text>
{!compact && (
<Text as="span" size="L400">
End
</Text>
)}
</Chip>
</Box>
);
Expand Down
30 changes: 17 additions & 13 deletions src/app/features/call-status/CallStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,17 @@ export function CallStatus({ callEmbed }: CallStatusProps) {
) : (
<Spinner variant="Secondary" size="200" />
)}
<Box
grow="Yes"
alignItems="Center"
gap="Inherit"
justifyContent={compact ? 'Center' : undefined}
>
<CallRoomName room={room} />
{speakers.size > 0 && !compact && (
<Box grow="Yes" alignItems="Center" gap="Inherit">
{!compact && (
<>
<StatusDivider />
<span data-spacing-node />
<MemberSpeaking room={room} speakers={speakers} />
<CallRoomName room={room} />
{speakers.size > 0 && (
<>
<StatusDivider />
<span data-spacing-node />
<MemberSpeaking room={room} speakers={speakers} />
</>
)}
</>
)}
</Box>
Expand All @@ -68,8 +67,13 @@ export function CallStatus({ callEmbed }: CallStatusProps) {
)}
</Box>
{memberVisible && !compact && <StatusDivider />}
<Box shrink="No" alignItems="Center" justifyContent="Center" gap="Inherit">
<CallControl callEmbed={callEmbed} />
<Box shrink="No" alignItems="Center" gap="Inherit">
{compact && (
<Box grow="Yes">
<CallRoomName room={room} />
</Box>
)}
<CallControl callJoined={callJoined} compact={compact} callEmbed={callEmbed} />
</Box>
</Box>
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/features/call-status/LiveChip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export function LiveChip({ count, room, members }: LiveChipProps) {
radii="Pill"
onClick={handleOpenMenu}
>
<Text className={css.LiveChipText} as="span" size="L400">
<Text className={css.LiveChipText} as="span" size="L400" truncate>
{count} Live
</Text>
</Chip>
Expand Down
2 changes: 1 addition & 1 deletion src/app/features/call-status/MemberSpeaking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function MemberSpeaking({ room, speakers }: MemberSpeakingProps) {
);
return (
<Box alignItems="Center" gap="100">
<Icon size="100" src={Icons.Phone} filled />
<Icon size="100" src={Icons.Mic} filled />
<Text size="T200" truncate>
{speakingNames.length === 1 && (
<>
Expand Down
Loading
Loading