Fine-tune appearance of buttons in calling interface UI
GitLab: #97
Change-Id: Iecf16921171196547e2a392ba6826971ca23ac47
diff --git a/client/src/pages/CallInterface.tsx b/client/src/pages/CallInterface.tsx
index 43d6211..b22821c 100644
--- a/client/src/pages/CallInterface.tsx
+++ b/client/src/pages/CallInterface.tsx
@@ -16,7 +16,17 @@
* <https://www.gnu.org/licenses/>.
*/
import { Box, Button, Card, Grid, Stack, Typography } from '@mui/material';
-import { ComponentType, Fragment, ReactNode, useContext, useLayoutEffect, useMemo, useRef, useState } from 'react';
+import {
+ ComponentType,
+ Fragment,
+ ReactNode,
+ useCallback,
+ useContext,
+ useLayoutEffect,
+ useMemo,
+ useRef,
+ useState,
+} from 'react';
import Draggable from 'react-draggable';
import { ExpandableButtonProps } from '../components/Button';
@@ -49,16 +59,6 @@
);
};
-export enum SecondaryButtons {
- Volume = 1,
- Group,
- Chat,
- ScreenShare,
- Record,
- Extension,
- FullScreen,
-}
-
interface Props {
children?: ReactNode;
}
@@ -69,6 +69,7 @@
return (
<>
+ {/* Guest video, takes the whole screen */}
<video
ref={remoteVideoRef}
autoPlay
@@ -85,10 +86,10 @@
<Box>
<CallInterfaceInformation />
</Box>
- {/* Guest video, with empty space to be moved around and stickied to walls */}
+ {/* Local video, with empty space to be moved around and stickied to walls */}
<Box height="100%">
{isVideoOn && (
- <Draggable bounds="parent">
+ <Draggable bounds="parent" nodeRef={localVideoRef ?? undefined}>
<video
ref={localVideoRef}
autoPlay
@@ -140,10 +141,11 @@
const { sendWebRTCOffer } = useContext(WebRTCContext);
return (
- <Card sx={{ backgroundColor: '#00000088', overflow: 'visible', textAlign: 'center' }}>
- <Stack direction="row" justifyContent="flex-end" alignItems="flex-end">
+ <Card sx={{ backgroundColor: '#00000088', overflow: 'visible' }}>
+ <Stack direction="row" justifyContent="center" alignItems="center">
<Button
variant="contained"
+ size="small"
onClick={() => {
sendWebRTCOffer();
}}
@@ -152,7 +154,7 @@
Call
</Button>
<CallingMicButton />
- <CallingEndButton />
+ <CallingEndButton hidden={false} />
<CallingVideoCameraButton />
</Stack>
</Card>
@@ -172,26 +174,37 @@
const CallInterfaceSecondaryButtons = (props: Props & { gridItemRef: React.RefObject<HTMLElement> }) => {
const stackRef = useRef<HTMLElement>(null);
+ const [initialMeasurementDone, setInitialMeasurementDone] = useState(false);
const [hiddenStackCount, setHiddenStackCount] = useState(0);
const [hiddenMenuVisible, setHiddenMenuVisible] = useState(false);
- useLayoutEffect(() => {
- const onResize = () => {
- if (stackRef?.current && props.gridItemRef?.current) {
- const buttonWidth = stackRef.current.children[0].clientWidth;
- const availableSpace = props.gridItemRef.current.clientWidth;
- let availableButtons = Math.floor((availableSpace - 1) / buttonWidth);
- if (availableButtons < SECONDARY_BUTTONS.length) {
- availableButtons -= 1; // Leave room for CallingMoreVerticalButton
- }
- setHiddenStackCount(SECONDARY_BUTTONS.length - availableButtons);
+ const calculateStackCount = useCallback(() => {
+ if (stackRef?.current && props.gridItemRef?.current) {
+ const buttonWidth = stackRef.current.children[0].clientWidth;
+ const availableSpace = props.gridItemRef.current.clientWidth;
+ let availableButtons = Math.floor((availableSpace - 1) / buttonWidth);
+ if (availableButtons < SECONDARY_BUTTONS.length) {
+ availableButtons -= 1; // Leave room for CallingMoreVerticalButton
}
+ setHiddenStackCount(SECONDARY_BUTTONS.length - availableButtons);
+ }
+ }, [props.gridItemRef]);
+
+ useLayoutEffect(() => {
+ // Run once, at the beginning, for initial measurements
+ if (!initialMeasurementDone) {
+ calculateStackCount();
+ setInitialMeasurementDone(true);
+ }
+
+ const onResize = () => {
+ calculateStackCount();
};
window.addEventListener('resize', onResize);
return () => {
window.removeEventListener('resize', onResize);
};
- }, [props.gridItemRef]);
+ }, [calculateStackCount, initialMeasurementDone]);
const { displayedButtons, hiddenButtons } = useMemo(() => {
const displayedButtons: ComponentType<ExpandableButtonProps>[] = [];
@@ -211,29 +224,37 @@
}, [hiddenStackCount]);
return (
- <Card sx={{ backgroundColor: '#00000088', overflow: 'visible' }}>
- <Stack direction="row" justifyContent="flex-end" alignItems="flex-end" ref={stackRef}>
- {displayedButtons.map((SecondaryButton, i) => (
- <Fragment key={i}>
- <SecondaryButton />
- </Fragment>
- ))}
- {!!hiddenButtons.length && (
- <Card sx={{ position: 'relative', backgroundColor: '#00000088', overflow: 'visible' }}>
- <CallingMoreVerticalButton onClick={() => setHiddenMenuVisible(!hiddenMenuVisible)} />
+ <Card sx={{ backgroundColor: '#00000088', overflow: 'visible', height: '100%' }}>
+ <Stack direction="row" justifyContent="center" alignItems="center" height="100%" ref={stackRef}>
+ {initialMeasurementDone &&
+ displayedButtons.map((SecondaryButton, i) => (
+ <Fragment key={i}>
+ <SecondaryButton hidden={false} />
+ </Fragment>
+ ))}
+ {(!!hiddenButtons.length || !initialMeasurementDone) && (
+ <CallingMoreVerticalButton hidden={true} onClick={() => setHiddenMenuVisible(!hiddenMenuVisible)} />
+ )}
+ </Stack>
+
+ {!!hiddenButtons.length && hiddenMenuVisible && (
+ <Box sx={{ position: 'absolute', right: 0, bottom: '50px' }}>
+ <Card sx={{ backgroundColor: '#00000088', overflow: 'visible', justifyContent: 'flex-end' }}>
<Stack
- direction="column-reverse"
- sx={{ bottom: 0, right: 0, height: '100%', position: 'absolute', top: '-40px' }}
+ direction="column"
+ justifyContent="flex-end"
+ alignItems="flex-end"
+ sx={{ bottom: 0, right: 0, height: '100%' }}
>
{hiddenButtons.map((SecondaryButton, i) => (
<Fragment key={i}>
- <SecondaryButton key={i} />
+ <SecondaryButton hidden={true} />
</Fragment>
))}
</Stack>
</Card>
- )}
- </Stack>
+ </Box>
+ )}
</Card>
);
};