Skip to content

Commit 1df2e0c

Browse files
authored
Merge pull request element-hq#2738 from robintown/narrow-footer
Make the footer display more nicely on narrow screens
2 parents 5d88c52 + f1233ca commit 1df2e0c

File tree

3 files changed

+146
-106
lines changed

3 files changed

+146
-106
lines changed

src/button/ReactionToggleButton.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,15 @@ export function ReactionPopupMenu({
211211
);
212212
}
213213

214-
interface ReactionToggleButtonProps {
214+
interface ReactionToggleButtonProps extends ComponentPropsWithoutRef<"button"> {
215215
rtcSession: MatrixRTCSession;
216216
client: MatrixClient;
217217
}
218218

219219
export function ReactionToggleButton({
220220
client,
221221
rtcSession,
222+
...props
222223
}: ReactionToggleButtonProps): ReactNode {
223224
const { t } = useTranslation();
224225
const { raisedHands, lowerHand, reactions } = useReactions();
@@ -327,6 +328,7 @@ export function ReactionToggleButton({
327328
onClick={() => setShowReactionsMenu((show) => !show)}
328329
raised={isHandRaised}
329330
open={showReactionsMenu}
331+
{...props}
330332
/>
331333
<Modal
332334
open={showReactionsMenu}

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;
98109
}
99110
}
100111

101-
@media (min-height: 800px) {
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+
}
129+
}
130+
}
131+
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
@@ -213,7 +213,6 @@ export const InCallView: FC<InCallViewProps> = ({
213213

214214
const containerRef1 = useRef<HTMLDivElement | null>(null);
215215
const [containerRef2, bounds] = useMeasure();
216-
const boundsValid = bounds.height > 0;
217216
// Merge the refs so they can attach to the same element
218217
const containerRef = useMergedRefs(containerRef1, containerRef2);
219218

@@ -241,10 +240,6 @@ export const InCallView: FC<InCallViewProps> = ({
241240
(muted) => muteStates.audio.setEnabled?.(!muted),
242241
);
243242

244-
const mobile = boundsValid && bounds.width <= 660;
245-
const reducedControls = boundsValid && bounds.width <= 340;
246-
const noControls = reducedControls && bounds.height <= 400;
247-
248243
const windowMode = useObservableEagerState(vm.windowMode);
249244
const layout = useObservableEagerState(vm.layout);
250245
const gridMode = useObservableEagerState(vm.gridMode);
@@ -526,95 +521,94 @@ export const InCallView: FC<InCallViewProps> = ({
526521
.catch(logger.error);
527522
}, [localParticipant, isScreenShareEnabled]);
528523

529-
let footer: JSX.Element | null;
530-
531-
if (noControls) {
532-
footer = null;
533-
} else {
534-
const buttons: JSX.Element[] = [];
535-
524+
const buttons: JSX.Element[] = [];
525+
526+
buttons.push(
527+
<MicButton
528+
key="audio"
529+
muted={!muteStates.audio.enabled}
530+
onClick={toggleMicrophone}
531+
disabled={muteStates.audio.setEnabled === null}
532+
data-testid="incall_mute"
533+
/>,
534+
<VideoButton
535+
key="video"
536+
muted={!muteStates.video.enabled}
537+
onClick={toggleCamera}
538+
disabled={muteStates.video.setEnabled === null}
539+
data-testid="incall_videomute"
540+
/>,
541+
);
542+
if (switchCamera !== null)
536543
buttons.push(
537-
<MicButton
538-
key="audio"
539-
muted={!muteStates.audio.enabled}
540-
onClick={toggleMicrophone}
541-
disabled={muteStates.audio.setEnabled === null}
542-
data-testid="incall_mute"
543-
/>,
544-
<VideoButton
545-
key="video"
546-
muted={!muteStates.video.enabled}
547-
onClick={toggleCamera}
548-
disabled={muteStates.video.setEnabled === null}
549-
data-testid="incall_videomute"
544+
<SwitchCameraButton
545+
key="switch_camera"
546+
className={styles.switchCamera}
547+
onClick={switchCamera}
550548
/>,
551549
);
552-
if (!reducedControls) {
553-
if (switchCamera !== null)
554-
buttons.push(
555-
<SwitchCameraButton key="switch_camera" onClick={switchCamera} />,
556-
);
557-
if (canScreenshare && !hideScreensharing) {
558-
buttons.push(
559-
<ShareScreenButton
560-
key="share_screen"
561-
enabled={isScreenShareEnabled}
562-
onClick={toggleScreensharing}
563-
data-testid="incall_screenshare"
564-
/>,
565-
);
566-
}
567-
if (supportsReactions) {
568-
buttons.push(
569-
<ReactionToggleButton
570-
client={client}
571-
rtcSession={rtcSession}
572-
key="4"
573-
/>,
574-
);
575-
}
576-
buttons.push(<SettingsButton key="settings" onClick={openSettings} />);
577-
}
578-
550+
if (canScreenshare && !hideScreensharing) {
579551
buttons.push(
580-
<EndCallButton
581-
key="end_call"
582-
onClick={function (): void {
583-
onLeave();
584-
}}
585-
data-testid="incall_leave"
552+
<ShareScreenButton
553+
key="share_screen"
554+
className={styles.shareScreen}
555+
enabled={isScreenShareEnabled}
556+
onClick={toggleScreensharing}
557+
data-testid="incall_screenshare"
586558
/>,
587559
);
588-
footer = (
589-
<div
590-
ref={footerRef}
591-
className={classNames(styles.footer, {
592-
[styles.overlay]: windowMode === "flat",
593-
[styles.hidden]: !showFooter || (!showControls && hideHeader),
594-
})}
595-
>
596-
{!mobile && !hideHeader && (
597-
<div className={styles.logo}>
598-
<LogoMark width={24} height={24} aria-hidden />
599-
<LogoType
600-
width={80}
601-
height={11}
602-
aria-label={import.meta.env.VITE_PRODUCT_NAME || "Element Call"}
603-
/>
604-
</div>
605-
)}
606-
{showControls && <div className={styles.buttons}>{buttons}</div>}
607-
{!mobile && showControls && (
608-
<LayoutToggle
609-
className={styles.layout}
610-
layout={gridMode}
611-
setLayout={setGridMode}
612-
onTouchEnd={onLayoutToggleTouchEnd}
613-
/>
614-
)}
615-
</div>
560+
}
561+
if (supportsReactions) {
562+
buttons.push(
563+
<ReactionToggleButton
564+
key="raise_hand"
565+
className={styles.raiseHand}
566+
client={client}
567+
rtcSession={rtcSession}
568+
/>,
616569
);
617570
}
571+
if (layout.type !== "pip")
572+
buttons.push(<SettingsButton key="settings" onClick={openSettings} />);
573+
574+
buttons.push(
575+
<EndCallButton
576+
key="end_call"
577+
onClick={function (): void {
578+
onLeave();
579+
}}
580+
data-testid="incall_leave"
581+
/>,
582+
);
583+
const footer = (
584+
<div
585+
ref={footerRef}
586+
className={classNames(styles.footer, {
587+
[styles.overlay]: windowMode === "flat",
588+
[styles.hidden]: !showFooter || (!showControls && hideHeader),
589+
})}
590+
>
591+
{!hideHeader && (
592+
<div className={styles.logo}>
593+
<LogoMark width={24} height={24} aria-hidden />
594+
<LogoType
595+
width={80}
596+
height={11}
597+
aria-label={import.meta.env.VITE_PRODUCT_NAME || "Element Call"}
598+
/>
599+
</div>
600+
)}
601+
{showControls && <div className={styles.buttons}>{buttons}</div>}
602+
{showControls && (
603+
<LayoutToggle
604+
className={styles.layout}
605+
layout={gridMode}
606+
setLayout={setGridMode}
607+
onTouchEnd={onLayoutToggleTouchEnd}
608+
/>
609+
)}
610+
</div>
611+
);
618612

619613
return (
620614
<div
@@ -646,8 +640,11 @@ export const InCallView: FC<InCallViewProps> = ({
646640
/>
647641
</LeftNav>
648642
<RightNav>
649-
{!reducedControls && showControls && onShareClick !== null && (
650-
<InviteButton onClick={onShareClick} />
643+
{showControls && onShareClick !== null && (
644+
<InviteButton
645+
className={styles.invite}
646+
onClick={onShareClick}
647+
/>
651648
)}
652649
</RightNav>
653650
</Header>
@@ -669,15 +666,19 @@ export const InCallView: FC<InCallViewProps> = ({
669666
</span>
670667
))}
671668
{footer}
672-
{!noControls && <RageshakeRequestModal {...rageshakeRequestModalProps} />}
673-
<SettingsModal
674-
client={client}
675-
roomId={rtcSession.room.roomId}
676-
open={settingsModalOpen}
677-
onDismiss={closeSettings}
678-
tab={settingsTab}
679-
onTabChange={setSettingsTab}
680-
/>
669+
{layout.type !== "pip" && (
670+
<>
671+
<RageshakeRequestModal {...rageshakeRequestModalProps} />
672+
<SettingsModal
673+
client={client}
674+
roomId={rtcSession.room.roomId}
675+
open={settingsModalOpen}
676+
onDismiss={closeSettings}
677+
tab={settingsTab}
678+
onTabChange={setSettingsTab}
679+
/>
680+
</>
681+
)}
681682
</div>
682683
);
683684
};

0 commit comments

Comments
 (0)