Skip to content

Commit c7e220e

Browse files
committed
Make the footer display more nicely on narrow screens
It needed a bit of tweaking now that we have up to 6 buttons in the footer. I tried to do everything in CSS this time.
1 parent 5b94dd6 commit c7e220e

File tree

3 files changed

+147
-106
lines changed

3 files changed

+147
-106
lines changed

src/button/RaisedHandToggleButton.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,16 @@ const InnerButton: FC<InnerButtonProps> = ({ raised, ...props }) => {
5353
);
5454
};
5555

56-
interface RaisedHandToggleButtonProps {
56+
interface RaisedHandToggleButtonProps
57+
extends ComponentPropsWithoutRef<"button"> {
5758
rtcSession: MatrixRTCSession;
5859
client: MatrixClient;
5960
}
6061

6162
export function RaiseHandToggleButton({
6263
client,
6364
rtcSession,
65+
...props
6466
}: RaisedHandToggleButtonProps): ReactNode {
6567
const { raisedHands, lowerHand } = useReactions();
6668
const [busy, setBusy] = useState(false);
@@ -121,6 +123,7 @@ export function RaiseHandToggleButton({
121123
disabled={busy}
122124
onClick={toggleRaisedHand}
123125
raised={isHandRaised}
126+
{...props}
124127
/>
125128
);
126129
}

src/room/InCallView.module.css

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,14 @@ Please see LICENSE in the repository root for full details.
3636
inset-block-end: 0;
3737
z-index: 1;
3838
display: grid;
39-
grid-template-columns: 1fr auto 1fr;
40-
grid-template-areas: "logo buttons layout";
39+
grid-template-columns: minmax(0, var(--inline-content-inset)) 1fr auto 1fr minmax(
40+
0,
41+
var(--inline-content-inset)
42+
);
43+
grid-template-areas: ". logo buttons layout .";
4144
align-items: center;
4245
gap: var(--cpd-space-3x);
43-
padding-block: var(--cpd-space-4x);
44-
padding-inline: var(--inline-content-inset);
46+
padding-block: var(--cpd-space-10x);
4547
background: linear-gradient(
4648
180deg,
4749
rgba(0, 0, 0, 0) 0%,
@@ -83,6 +85,7 @@ Please see LICENSE in the repository root for full details.
8385

8486
.buttons {
8587
grid-area: buttons;
88+
justify-self: center;
8689
display: flex;
8790
gap: var(--cpd-space-3x);
8891
}
@@ -92,15 +95,49 @@ Please see LICENSE in the repository root for full details.
9295
justify-self: end;
9396
}
9497

95-
@media (min-height: 400px) {
98+
@media (max-width: 660px) {
9699
.footer {
97-
padding-block: var(--cpd-space-8x);
100+
grid-template-areas: ". buttons buttons buttons .";
101+
}
102+
103+
.logo {
104+
display: none;
105+
}
106+
107+
.layout {
108+
display: none !important;
109+
}
110+
}
111+
112+
@media (max-width: 370px) {
113+
.raiseHand {
114+
display: none;
115+
}
116+
}
117+
118+
@media (max-width: 340px) {
119+
.invite,
120+
.switchCamera,
121+
.shareScreen {
122+
display: none;
123+
}
124+
125+
@media (max-height: 400px) {
126+
.footer {
127+
display: none;
128+
}
98129
}
99130
}
100131

101-
@media (min-height: 800px) {
132+
@media (max-height: 400px) {
102133
.footer {
103-
padding-block: var(--cpd-space-10x);
134+
padding-block: var(--cpd-space-4x);
135+
}
136+
}
137+
138+
@media (max-height: 800px) {
139+
.footer {
140+
padding-block: var(--cpd-space-8x);
104141
}
105142
}
106143

src/room/InCallView.tsx

Lines changed: 98 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ export const InCallView: FC<InCallViewProps> = ({
198198

199199
const containerRef1 = useRef<HTMLDivElement | null>(null);
200200
const [containerRef2, bounds] = useMeasure();
201-
const boundsValid = bounds.height > 0;
202201
// Merge the refs so they can attach to the same element
203202
const containerRef = useMergedRefs(containerRef1, containerRef2);
204203

@@ -226,10 +225,6 @@ export const InCallView: FC<InCallViewProps> = ({
226225
(muted) => muteStates.audio.setEnabled?.(!muted),
227226
);
228227

229-
const mobile = boundsValid && bounds.width <= 660;
230-
const reducedControls = boundsValid && bounds.width <= 340;
231-
const noControls = reducedControls && bounds.height <= 400;
232-
233228
const windowMode = useObservableEagerState(vm.windowMode);
234229
const layout = useObservableEagerState(vm.layout);
235230
const gridMode = useObservableEagerState(vm.gridMode);
@@ -511,95 +506,94 @@ export const InCallView: FC<InCallViewProps> = ({
511506
.catch(logger.error);
512507
}, [localParticipant, isScreenShareEnabled]);
513508

514-
let footer: JSX.Element | null;
515-
516-
if (noControls) {
517-
footer = null;
518-
} else {
519-
const buttons: JSX.Element[] = [];
520-
509+
const buttons: JSX.Element[] = [];
510+
511+
buttons.push(
512+
<MicButton
513+
key="audio"
514+
muted={!muteStates.audio.enabled}
515+
onClick={toggleMicrophone}
516+
disabled={muteStates.audio.setEnabled === null}
517+
data-testid="incall_mute"
518+
/>,
519+
<VideoButton
520+
key="video"
521+
muted={!muteStates.video.enabled}
522+
onClick={toggleCamera}
523+
disabled={muteStates.video.setEnabled === null}
524+
data-testid="incall_videomute"
525+
/>,
526+
);
527+
if (switchCamera !== null)
521528
buttons.push(
522-
<MicButton
523-
key="audio"
524-
muted={!muteStates.audio.enabled}
525-
onClick={toggleMicrophone}
526-
disabled={muteStates.audio.setEnabled === null}
527-
data-testid="incall_mute"
528-
/>,
529-
<VideoButton
530-
key="video"
531-
muted={!muteStates.video.enabled}
532-
onClick={toggleCamera}
533-
disabled={muteStates.video.setEnabled === null}
534-
data-testid="incall_videomute"
529+
<SwitchCameraButton
530+
key="switch_camera"
531+
className={styles.switchCamera}
532+
onClick={switchCamera}
535533
/>,
536534
);
537-
if (!reducedControls) {
538-
if (switchCamera !== null)
539-
buttons.push(
540-
<SwitchCameraButton key="switch_camera" onClick={switchCamera} />,
541-
);
542-
if (canScreenshare && !hideScreensharing) {
543-
buttons.push(
544-
<ShareScreenButton
545-
key="share_screen"
546-
enabled={isScreenShareEnabled}
547-
onClick={toggleScreensharing}
548-
data-testid="incall_screenshare"
549-
/>,
550-
);
551-
}
552-
if (supportsReactions) {
553-
buttons.push(
554-
<RaiseHandToggleButton
555-
client={client}
556-
rtcSession={rtcSession}
557-
key="4"
558-
/>,
559-
);
560-
}
561-
buttons.push(<SettingsButton key="settings" onClick={openSettings} />);
562-
}
563-
535+
if (canScreenshare && !hideScreensharing) {
564536
buttons.push(
565-
<EndCallButton
566-
key="end_call"
567-
onClick={function (): void {
568-
onLeave();
569-
}}
570-
data-testid="incall_leave"
537+
<ShareScreenButton
538+
key="share_screen"
539+
className={styles.shareScreen}
540+
enabled={isScreenShareEnabled}
541+
onClick={toggleScreensharing}
542+
data-testid="incall_screenshare"
571543
/>,
572544
);
573-
footer = (
574-
<div
575-
ref={footerRef}
576-
className={classNames(styles.footer, {
577-
[styles.overlay]: windowMode === "flat",
578-
[styles.hidden]: !showFooter || (!showControls && hideHeader),
579-
})}
580-
>
581-
{!mobile && !hideHeader && (
582-
<div className={styles.logo}>
583-
<LogoMark width={24} height={24} aria-hidden />
584-
<LogoType
585-
width={80}
586-
height={11}
587-
aria-label={import.meta.env.VITE_PRODUCT_NAME || "Element Call"}
588-
/>
589-
</div>
590-
)}
591-
{showControls && <div className={styles.buttons}>{buttons}</div>}
592-
{!mobile && showControls && (
593-
<LayoutToggle
594-
className={styles.layout}
595-
layout={gridMode}
596-
setLayout={setGridMode}
597-
onTouchEnd={onLayoutToggleTouchEnd}
598-
/>
599-
)}
600-
</div>
545+
}
546+
if (supportsReactions) {
547+
buttons.push(
548+
<RaiseHandToggleButton
549+
key="raise_hand"
550+
className={styles.raiseHand}
551+
client={client}
552+
rtcSession={rtcSession}
553+
/>,
601554
);
602555
}
556+
if (layout.type !== "pip")
557+
buttons.push(<SettingsButton key="settings" onClick={openSettings} />);
558+
559+
buttons.push(
560+
<EndCallButton
561+
key="end_call"
562+
onClick={function (): void {
563+
onLeave();
564+
}}
565+
data-testid="incall_leave"
566+
/>,
567+
);
568+
const footer = (
569+
<div
570+
ref={footerRef}
571+
className={classNames(styles.footer, {
572+
[styles.overlay]: windowMode === "flat",
573+
[styles.hidden]: !showFooter || (!showControls && hideHeader),
574+
})}
575+
>
576+
{!hideHeader && (
577+
<div className={styles.logo}>
578+
<LogoMark width={24} height={24} aria-hidden />
579+
<LogoType
580+
width={80}
581+
height={11}
582+
aria-label={import.meta.env.VITE_PRODUCT_NAME || "Element Call"}
583+
/>
584+
</div>
585+
)}
586+
{showControls && <div className={styles.buttons}>{buttons}</div>}
587+
{showControls && (
588+
<LayoutToggle
589+
className={styles.layout}
590+
layout={gridMode}
591+
setLayout={setGridMode}
592+
onTouchEnd={onLayoutToggleTouchEnd}
593+
/>
594+
)}
595+
</div>
596+
);
603597

604598
return (
605599
<div
@@ -631,8 +625,11 @@ export const InCallView: FC<InCallViewProps> = ({
631625
/>
632626
</LeftNav>
633627
<RightNav>
634-
{!reducedControls && showControls && onShareClick !== null && (
635-
<InviteButton onClick={onShareClick} />
628+
{showControls && onShareClick !== null && (
629+
<InviteButton
630+
className={styles.invite}
631+
onClick={onShareClick}
632+
/>
636633
)}
637634
</RightNav>
638635
</Header>
@@ -644,15 +641,19 @@ export const InCallView: FC<InCallViewProps> = ({
644641
<source src={handSoundMp3} type="audio/mpeg" />
645642
</audio>
646643
{footer}
647-
{!noControls && <RageshakeRequestModal {...rageshakeRequestModalProps} />}
648-
<SettingsModal
649-
client={client}
650-
roomId={rtcSession.room.roomId}
651-
open={settingsModalOpen}
652-
onDismiss={closeSettings}
653-
tab={settingsTab}
654-
onTabChange={setSettingsTab}
655-
/>
644+
{layout.type !== "pip" && (
645+
<>
646+
<RageshakeRequestModal {...rageshakeRequestModalProps} />
647+
<SettingsModal
648+
client={client}
649+
roomId={rtcSession.room.roomId}
650+
open={settingsModalOpen}
651+
onDismiss={closeSettings}
652+
tab={settingsTab}
653+
onTabChange={setSettingsTab}
654+
/>
655+
</>
656+
)}
656657
</div>
657658
);
658659
};

0 commit comments

Comments
 (0)