add option to start voice/video call in dms
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
|||||||
RectCords,
|
RectCords,
|
||||||
Badge,
|
Badge,
|
||||||
Spinner,
|
Spinner,
|
||||||
|
Button,
|
||||||
} from 'folds';
|
} from 'folds';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Room } from 'matrix-js-sdk';
|
import { Room } from 'matrix-js-sdk';
|
||||||
@@ -254,6 +255,125 @@ const RoomMenu = forwardRef<HTMLDivElement, RoomMenuProps>(({ room, requestClose
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type CallMenuProps = {
|
||||||
|
onVoiceCall: () => void;
|
||||||
|
onVideoCall: () => void;
|
||||||
|
requestClose: () => void;
|
||||||
|
};
|
||||||
|
const CallMenu = forwardRef<HTMLDivElement, CallMenuProps>(
|
||||||
|
({ requestClose, onVoiceCall, onVideoCall }, ref) => {
|
||||||
|
const handleVoice = () => {
|
||||||
|
onVoiceCall();
|
||||||
|
requestClose();
|
||||||
|
};
|
||||||
|
const handleVideo = () => {
|
||||||
|
onVideoCall();
|
||||||
|
requestClose();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Menu ref={ref} style={{ padding: config.space.S200 }}>
|
||||||
|
<Box direction="Column" gap="200">
|
||||||
|
<Box direction="Column">
|
||||||
|
<Text size="L400">Start Call</Text>
|
||||||
|
</Box>
|
||||||
|
<Box alignItems="Center" gap="200">
|
||||||
|
<Button
|
||||||
|
size="300"
|
||||||
|
variant="Success"
|
||||||
|
radii="300"
|
||||||
|
before={<Icon size="100" src={Icons.Phone} filled />}
|
||||||
|
onClick={handleVoice}
|
||||||
|
>
|
||||||
|
<Text size="B300">Voice</Text>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
size="300"
|
||||||
|
variant="Success"
|
||||||
|
radii="300"
|
||||||
|
before={<Icon size="100" src={Icons.VideoCamera} filled />}
|
||||||
|
onClick={handleVideo}
|
||||||
|
>
|
||||||
|
<Text size="B300">Video</Text>
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
function CallButton() {
|
||||||
|
const room = useRoom();
|
||||||
|
const direct = useIsDirectRoom();
|
||||||
|
|
||||||
|
const callEmbed = useCallEmbed();
|
||||||
|
const startCall = useCallStart(direct);
|
||||||
|
const callStarted = callEmbed && callEmbed.roomId === room.roomId;
|
||||||
|
const inAnotherCall = callEmbed && !callStarted;
|
||||||
|
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
||||||
|
|
||||||
|
const handleOpenMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
|
||||||
|
setMenuAnchor(evt.currentTarget.getBoundingClientRect());
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TooltipProvider
|
||||||
|
position="Bottom"
|
||||||
|
offset={4}
|
||||||
|
tooltip={
|
||||||
|
<Tooltip>
|
||||||
|
{inAnotherCall ? (
|
||||||
|
<Text size="L400">Already in another call — End the current call to join!</Text>
|
||||||
|
) : (
|
||||||
|
<Text>Call</Text>
|
||||||
|
)}
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{(triggerRef) => (
|
||||||
|
<IconButton
|
||||||
|
variant="Surface"
|
||||||
|
fill="None"
|
||||||
|
ref={triggerRef}
|
||||||
|
onClick={handleOpenMenu}
|
||||||
|
disabled={inAnotherCall}
|
||||||
|
aria-pressed={!!menuAnchor}
|
||||||
|
>
|
||||||
|
<Icon size="400" src={Icons.VideoCamera} filled={callStarted} />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
</TooltipProvider>
|
||||||
|
<PopOut
|
||||||
|
anchor={menuAnchor}
|
||||||
|
position="Bottom"
|
||||||
|
align="Center"
|
||||||
|
content={
|
||||||
|
<FocusTrap
|
||||||
|
focusTrapOptions={{
|
||||||
|
initialFocus: false,
|
||||||
|
returnFocusOnDeactivate: false,
|
||||||
|
onDeactivate: () => setMenuAnchor(undefined),
|
||||||
|
clickOutsideDeactivates: true,
|
||||||
|
isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown',
|
||||||
|
isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp',
|
||||||
|
escapeDeactivates: stopPropagation,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CallMenu
|
||||||
|
onVideoCall={() => startCall(room, { microphone: true, video: true, sound: true })}
|
||||||
|
onVoiceCall={() => startCall(room, { microphone: true, video: false, sound: true })}
|
||||||
|
requestClose={() => setMenuAnchor(undefined)}
|
||||||
|
/>
|
||||||
|
</FocusTrap>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function RoomViewHeader({ callView }: { callView?: boolean }) {
|
export function RoomViewHeader({ callView }: { callView?: boolean }) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
@@ -261,6 +381,7 @@ export function RoomViewHeader({ callView }: { callView?: boolean }) {
|
|||||||
const screenSize = useScreenSizeContext();
|
const screenSize = useScreenSizeContext();
|
||||||
const room = useRoom();
|
const room = useRoom();
|
||||||
const space = useSpaceOptionally();
|
const space = useSpaceOptionally();
|
||||||
|
|
||||||
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
||||||
const [pinMenuAnchor, setPinMenuAnchor] = useState<RectCords>();
|
const [pinMenuAnchor, setPinMenuAnchor] = useState<RectCords>();
|
||||||
const direct = useIsDirectRoom();
|
const direct = useIsDirectRoom();
|
||||||
@@ -305,11 +426,6 @@ export function RoomViewHeader({ callView }: { callView?: boolean }) {
|
|||||||
setPeopleDrawer(!peopleDrawer);
|
setPeopleDrawer(!peopleDrawer);
|
||||||
};
|
};
|
||||||
|
|
||||||
const callEmbed = useCallEmbed();
|
|
||||||
const startCall = useCallStart(direct);
|
|
||||||
const callStarted = callEmbed && callEmbed.roomId === room.roomId;
|
|
||||||
const inAnotherCall = callEmbed && !callStarted;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageHeader
|
<PageHeader
|
||||||
className={ContainerColor({ variant: 'Surface' })}
|
className={ContainerColor({ variant: 'Surface' })}
|
||||||
@@ -459,33 +575,7 @@ export function RoomViewHeader({ callView }: { callView?: boolean }) {
|
|||||||
</FocusTrap>
|
</FocusTrap>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{direct && !callStarted && (
|
{direct && <CallButton />}
|
||||||
<TooltipProvider
|
|
||||||
position="Bottom"
|
|
||||||
offset={4}
|
|
||||||
tooltip={
|
|
||||||
<Tooltip>
|
|
||||||
{inAnotherCall ? (
|
|
||||||
<Text size="L400">Already in another call — End the current call to join!</Text>
|
|
||||||
) : (
|
|
||||||
<Text>Start Call</Text>
|
|
||||||
)}
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{(triggerRef) => (
|
|
||||||
<IconButton
|
|
||||||
variant="Surface"
|
|
||||||
fill="None"
|
|
||||||
ref={triggerRef}
|
|
||||||
onClick={() => startCall(room, { microphone: true, video: true, sound: true })}
|
|
||||||
disabled={inAnotherCall}
|
|
||||||
>
|
|
||||||
<Icon size="400" src={Icons.VideoCamera} filled={callStarted} />
|
|
||||||
</IconButton>
|
|
||||||
)}
|
|
||||||
</TooltipProvider>
|
|
||||||
)}
|
|
||||||
{screenSize === ScreenSize.Desktop && (
|
{screenSize === ScreenSize.Desktop && (
|
||||||
<TooltipProvider
|
<TooltipProvider
|
||||||
position="Bottom"
|
position="Bottom"
|
||||||
|
|||||||
Reference in New Issue
Block a user