Add call button to header

Signed-off-by: Timo K <toger5@hotmail.de>
This commit is contained in:
Timo K 2025-10-12 19:33:45 +02:00
parent c9effa0860
commit 94ff2d1d7d
3 changed files with 67 additions and 3 deletions

View file

@ -96,7 +96,7 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string }) {
return ( return (
<Page ref={roomViewRef}> <Page ref={roomViewRef}>
<RoomViewHeader /> <RoomViewHeader onCallClick={() => setShowCall(true)} callJoined={callJoined} />
<Box grow="Yes" direction="Row"> <Box grow="Yes" direction="Row">
{showCall && ( {showCall && (
<CallView <CallView

View file

@ -69,6 +69,7 @@ import { useRoomNavigate } from '../../hooks/useRoomNavigate';
import { useRoomCreators } from '../../hooks/useRoomCreators'; import { useRoomCreators } from '../../hooks/useRoomCreators';
import { useRoomPermissions } from '../../hooks/useRoomPermissions'; import { useRoomPermissions } from '../../hooks/useRoomPermissions';
import { InviteUserPrompt } from '../../components/invite-user-prompt'; import { InviteUserPrompt } from '../../components/invite-user-prompt';
import { useCallOngoing } from '../../hooks/useCallOngoing';
type RoomMenuProps = { type RoomMenuProps = {
room: Room; room: Room;
@ -253,8 +254,11 @@ const RoomMenu = forwardRef<HTMLDivElement, RoomMenuProps>(({ room, requestClose
</Menu> </Menu>
); );
}); });
interface RoomViewHeaderProps {
export function RoomViewHeader() { onCallClick?: () => void;
callJoined?: boolean;
}
export function RoomViewHeader({ onCallClick, callJoined }: RoomViewHeaderProps) {
const navigate = useNavigate(); const navigate = useNavigate();
const mx = useMatrixClient(); const mx = useMatrixClient();
const useAuthentication = useMediaAuthentication(); const useAuthentication = useMediaAuthentication();
@ -274,6 +278,7 @@ export function RoomViewHeader() {
const avatarUrl = avatarMxc const avatarUrl = avatarMxc
? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined ? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined
: undefined; : undefined;
const callOngoing = useCallOngoing(room);
const [peopleDrawer, setPeopleDrawer] = useSetting(settingsAtom, 'isPeopleDrawer'); const [peopleDrawer, setPeopleDrawer] = useSetting(settingsAtom, 'isPeopleDrawer');
@ -295,6 +300,9 @@ export function RoomViewHeader() {
setPinMenuAnchor(evt.currentTarget.getBoundingClientRect()); setPinMenuAnchor(evt.currentTarget.getBoundingClientRect());
}; };
const notParticipatingState = callOngoing ? 'join' : 'start';
const buttonState = callJoined ? 'participating' : notParticipatingState;
return ( return (
<PageHeader balance={screenSize === ScreenSize.Mobile}> <PageHeader balance={screenSize === ScreenSize.Mobile}>
<Box grow="Yes" gap="300"> <Box grow="Yes" gap="300">
@ -387,6 +395,33 @@ export function RoomViewHeader() {
)} )}
</TooltipProvider> </TooltipProvider>
)} )}
<TooltipProvider
position="Bottom"
offset={4}
tooltip={
<Tooltip>
{buttonState === 'start' && <Text>Start Call</Text>}
{buttonState === 'join' && <Text>Join Call</Text>}
{buttonState === 'participating' && <Text>Call Ongoing</Text>}
</Tooltip>
}
>
{(triggerRef) => (
<IconButton
variant={buttonState === 'join' ? 'Primary' : undefined}
style={{ position: 'relative' }}
onClick={onCallClick}
ref={triggerRef}
disabled={buttonState === 'participating'}
aria-pressed={!!pinMenuAnchor}
>
{buttonState === 'join' && <Text size="B400">Join</Text>}
<Icon size="400" src={Icons.Phone} filled={buttonState === 'participating'} />
</IconButton>
)}
</TooltipProvider>
<TooltipProvider <TooltipProvider
position="Bottom" position="Bottom"
offset={4} offset={4}

View file

@ -0,0 +1,29 @@
import { Room } from 'matrix-js-sdk';
import { useEffect, useState } from 'react';
import { MatrixRTCSessionManagerEvents } from 'matrix-js-sdk/lib/matrixrtc/MatrixRTCSessionManager';
export const useCallOngoing = (room: Room) => {
const [callOngoing, setCallOngoing] = useState(
room.client.matrixRTC.getRoomSession(room).memberships.length > 0
);
useEffect(() => {
const start = (roomId: string) => {
if (roomId !== room.roomId) return;
setCallOngoing(true);
};
const end = (roomId: string) => {
if (roomId !== room.roomId) return;
setCallOngoing(false);
};
room.client.matrixRTC.on(MatrixRTCSessionManagerEvents.SessionStarted, start);
room.client.matrixRTC.on(MatrixRTCSessionManagerEvents.SessionEnded, end);
return () => {
room.client.matrixRTC.off(MatrixRTCSessionManagerEvents.SessionStarted, start);
room.client.matrixRTC.off(MatrixRTCSessionManagerEvents.SessionEnded, end);
};
}, [room]);
return callOngoing;
};