Add basic mobile styling
This commit is contained in:
parent
b6c926d2c8
commit
e3cec93669
4 changed files with 80 additions and 30 deletions
|
@ -4,6 +4,18 @@ import classNames from "classnames";
|
|||
import { Avatar } from "./Avatar";
|
||||
import { getAvatarUrl } from "./matrix-utils";
|
||||
|
||||
const overlapMap = {
|
||||
xs: 2,
|
||||
sm: 4,
|
||||
md: 8,
|
||||
};
|
||||
|
||||
const sizeMap = {
|
||||
xs: 24,
|
||||
sm: 32,
|
||||
md: 36,
|
||||
};
|
||||
|
||||
export function Facepile({
|
||||
className,
|
||||
client,
|
||||
|
@ -12,18 +24,14 @@ export function Facepile({
|
|||
size,
|
||||
...rest
|
||||
}) {
|
||||
const _size = size === "md" ? 36 : 24;
|
||||
const _overlap = size === "md" ? 8 : 2;
|
||||
const _size = sizeMap[size];
|
||||
const _overlap = overlapMap[size];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
styles.facepile,
|
||||
{ [styles.md]: size === "md" },
|
||||
className
|
||||
)}
|
||||
className={classNames(styles.facepile, styles[size], className)}
|
||||
title={participants.map((member) => member.name).join(", ")}
|
||||
style={{ width: participants.length * _size + _overlap }}
|
||||
style={{ width: participants.length * (_size - _overlap) + _overlap }}
|
||||
{...rest}
|
||||
>
|
||||
{participants.slice(0, max).map((member, i) => {
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
.facepile {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.facepile.xs {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.facepile.sm {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.facepile.md {
|
||||
height: 36px;
|
||||
}
|
||||
|
@ -15,5 +22,5 @@
|
|||
}
|
||||
|
||||
.facepile.md .avatar {
|
||||
border: 2px solid var(--bgColor2);
|
||||
border-width: 2px;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ import { Facepile } from "../Facepile";
|
|||
import { PTTButton } from "./PTTButton";
|
||||
import { PTTFeed } from "./PTTFeed";
|
||||
import { useMediaHandler } from "../settings/useMediaHandler";
|
||||
import useMeasure from "react-use-measure";
|
||||
import { ResizeObserver } from "@juggle/resize-observer";
|
||||
|
||||
export function PTTCallView({
|
||||
groupCall,
|
||||
|
@ -31,9 +33,11 @@ export function PTTCallView({
|
|||
const { modalState: settingsModalState, modalProps: settingsModalProps } =
|
||||
useModalTriggerState();
|
||||
const { audioOutput } = useMediaHandler();
|
||||
const [containerRef, bounds] = useMeasure({ polyfill: ResizeObserver });
|
||||
const facepileSize = bounds.width < 800 ? "sm" : "md";
|
||||
|
||||
return (
|
||||
<div className={styles.pttCallView}>
|
||||
<div className={styles.pttCallView} ref={containerRef}>
|
||||
<Header className={styles.header}>
|
||||
<LeftNav>
|
||||
<RoomSetupHeaderInfo roomName={roomName} onPress={onLeave} />
|
||||
|
@ -46,18 +50,24 @@ export function PTTCallView({
|
|||
participants.length > 1 ? "people" : "person"
|
||||
} connected`}</p>
|
||||
<Facepile
|
||||
size="md"
|
||||
size={facepileSize}
|
||||
max={8}
|
||||
className={styles.facepile}
|
||||
client={client}
|
||||
participants={participants}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.talkingInfo}>
|
||||
<h2>Talking...</h2>
|
||||
<p>00:01:24</p>
|
||||
<div className={styles.footer}>
|
||||
<SettingsButton onPress={() => settingsModalState.open()} />
|
||||
<HangupButton onPress={onLeave} />
|
||||
<InviteButton onPress={() => inviteModalState.open()} />
|
||||
</div>
|
||||
|
||||
<div className={styles.pttButtonContainer}>
|
||||
<div className={styles.talkingInfo}>
|
||||
<h2>Talking...</h2>
|
||||
<p>00:01:24</p>
|
||||
</div>
|
||||
<PTTButton
|
||||
client={client}
|
||||
activeSpeaker={activeSpeaker}
|
||||
|
@ -72,11 +82,6 @@ export function PTTCallView({
|
|||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className={styles.footer}>
|
||||
<SettingsButton onPress={() => settingsModalState.open()} />
|
||||
<HangupButton onPress={onLeave} />
|
||||
<InviteButton onPress={() => inviteModalState.open()} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{settingsModalState.isOpen && (
|
||||
|
|
|
@ -16,20 +16,12 @@
|
|||
flex: 1;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 48px;
|
||||
}
|
||||
|
||||
.actionTip {
|
||||
margin-top: 42px;
|
||||
margin-bottom: 45px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.participants {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 20px;
|
||||
margin-bottom: 67px;
|
||||
}
|
||||
|
||||
.participants > p {
|
||||
|
@ -45,21 +37,29 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 38px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pttButtonContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.actionTip {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 64px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.footer > * {
|
||||
|
@ -68,4 +68,34 @@
|
|||
|
||||
.footer > :last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
.participants {
|
||||
margin-bottom: 67px;
|
||||
}
|
||||
|
||||
.talkingInfo {
|
||||
margin-bottom: 38px;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin-top: 48px;
|
||||
}
|
||||
|
||||
.actionTip {
|
||||
margin-top: 42px;
|
||||
margin-bottom: 45px;
|
||||
}
|
||||
|
||||
.pttButtonContainer {
|
||||
flex: auto;
|
||||
margin-bottom: 0;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.footer {
|
||||
flex: auto;
|
||||
order: 4;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue