Fix mobile styles

This commit is contained in:
Robert Long 2021-12-10 10:54:18 -08:00
parent fc3960ce63
commit 9174369fb5
13 changed files with 277 additions and 260 deletions

View file

@ -1,12 +1,13 @@
.callTile {
display: flex;
width: 329px;
min-width: 240px;
height: 94px;
padding: 12px;
text-decoration: none;
background-color: var(--bgColor2);
border-radius: 8px;
overflow: hidden;
box-sizing: border-box;
}
.avatar,
@ -54,9 +55,7 @@
}
.callList {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 24px;
flex: 1;
}

View file

@ -297,7 +297,6 @@ export function ClientProvider({ homeserverUrl, children }) {
loading: false,
isGuest: false,
isAuthenticated: true,
isGuest: false,
userName: client.getUserIdLocalpart(),
});
@ -407,40 +406,21 @@ export async function createRoom(client, name) {
return room_alias || room_id;
}
export function useCreateRoom(client) {
const [creatingRoom, setCreatingRoom] = useState(false);
const [createRoomError, setCreateRoomError] = useState();
const onCreateRoom = useCallback(
(roomName) => {
setCreateRoomError(undefined);
setCreatingRoom(true);
return createRoom(client, roomName).catch((error) => {
setCreateRoomError(error);
setCreatingRoom(false);
});
},
[client]
);
return {
creatingRoom,
createRoomError,
createRoom: onCreateRoom,
};
}
export function useCreateRoomAsPasswordlessUser() {
const { register } = useClient();
export function useCreateRoom() {
const { register, client } = useClient();
const [creatingRoom, setCreatingRoom] = useState(false);
const [createRoomError, setCreateRoomError] = useState();
const onCreateRoom = useCallback(
(roomName, userName) => {
async function onCreateRoom(roomName, userName) {
const client = await register(userName, randomString(16));
return await createRoom(client, roomName);
let _client = client;
if (!_client) {
_client = await register(userName, randomString(16));
}
return await createRoom(_client, roomName);
}
setCreateRoomError(undefined);
@ -451,7 +431,7 @@ export function useCreateRoomAsPasswordlessUser() {
setCreatingRoom(false);
});
},
[register]
[register, client]
);
return {

View file

@ -3,16 +3,17 @@
display: flex;
justify-content: space-between;
align-items: center;
height: 64px;
user-select: none;
flex-shrink: 0;
}
.nav {
display: flex;
flex: 1;
align-items: center;
white-space: nowrap;
margin: 0 20px;
padding: 0 20px;
height: 64px;
}
.logo {
@ -25,6 +26,10 @@
margin-right: 12px;
}
.rightNav {
justify-content: flex-end;
}
.rightNav > * {
margin-right: 24px;
}
@ -88,7 +93,7 @@
}
@media (min-width: 800px) {
.header {
.nav {
height: 98px;
}
}

View file

@ -21,7 +21,6 @@ import {
useGroupCallRooms,
usePublicRooms,
useCreateRoom,
useCreateRoomAsPasswordlessUser,
} from "./ConferenceCallManagerHooks";
import { Header, HeaderLogo, LeftNav, RightNav } from "./Header";
import styles from "./Home.module.css";
@ -35,21 +34,8 @@ import { ErrorModal } from "./ErrorModal";
export function Home() {
const { isAuthenticated, isGuest, loading, error, client } = useClient();
if (loading) {
return <div>Loading...</div>;
} else if (error) {
return <ErrorModal error={error} />;
} else if (!isAuthenticated || isGuest) {
return <UnregisteredView />;
} else {
return <RegisteredView client={client} />;
}
}
function UnregisteredView() {
const history = useHistory();
const { createRoomError, creatingRoom, createRoom } =
useCreateRoomAsPasswordlessUser();
const { createRoomError, creatingRoom, createRoom } = useCreateRoom();
const onCreateRoom = useCallback(
(e) => {
@ -59,7 +45,9 @@ function UnregisteredView() {
const userName = data.get("userName");
createRoom(roomName, userName).then((roomIdOrAlias) => {
history.push(`/room/${roomIdOrAlias}`);
if (roomIdOrAlias) {
history.push(`/room/${roomIdOrAlias}`);
}
});
},
[history]
@ -75,78 +63,112 @@ function UnregisteredView() {
[history]
);
if (loading) {
return <div>Loading...</div>;
} else if (error) {
return <ErrorModal error={error} />;
} else if (!isAuthenticated || isGuest) {
return (
<UnregisteredView
onCreateRoom={onCreateRoom}
createRoomError={createRoomError}
creatingRoom={creatingRoom}
onJoinRoom={onJoinRoom}
/>
);
} else {
return (
<RegisteredView
client={client}
onCreateRoom={onCreateRoom}
createRoomError={createRoomError}
creatingRoom={creatingRoom}
onJoinRoom={onJoinRoom}
/>
);
}
}
function UnregisteredView({
onCreateRoom,
createRoomError,
creatingRoom,
onJoinRoom,
}) {
return (
<div className={styles.home}>
<div className={classNames(styles.left, styles.fullWidth)}>
<Header>
<LeftNav>
<HeaderLogo />
</LeftNav>
<RightNav>
<UserMenu />
</RightNav>
</Header>
<div className={styles.content}>
<div className={styles.centered}>
<form onSubmit={onJoinRoom}>
<h1>Join a call</h1>
<FieldRow className={styles.fieldRow}>
<InputField
id="roomId"
name="roomId"
label="Call ID"
type="text"
required
autoComplete="off"
placeholder="Call ID"
/>
</FieldRow>
<FieldRow className={styles.fieldRow}>
<Button className={styles.button} type="submit">
Join call
</Button>
</FieldRow>
</form>
<hr />
<form onSubmit={onCreateRoom}>
<h1>Create a call</h1>
<FieldRow className={styles.fieldRow}>
<InputField
id="userName"
name="userName"
label="Username"
type="text"
required
autoComplete="off"
placeholder="Username"
/>
</FieldRow>
<FieldRow className={styles.fieldRow}>
<InputField
id="roomName"
name="roomName"
label="Room Name"
type="text"
required
autoComplete="off"
placeholder="Room Name"
/>
</FieldRow>
{createRoomError && (
<div className={classNames(styles.home, styles.fullWidth)}>
<Header>
<LeftNav>
<HeaderLogo />
</LeftNav>
<RightNav>
<UserMenu />
</RightNav>
</Header>
<div className={styles.splitContainer}>
<div className={styles.left}>
<div className={styles.content}>
<div className={styles.centered}>
<form onSubmit={onJoinRoom}>
<h1>Join a call</h1>
<FieldRow className={styles.fieldRow}>
<ErrorMessage>{createRoomError.message}</ErrorMessage>
<InputField
id="roomId"
name="roomId"
label="Call ID"
type="text"
required
autoComplete="off"
placeholder="Call ID"
/>
</FieldRow>
)}
<FieldRow className={styles.fieldRow}>
<Button
className={styles.button}
type="submit"
disabled={creatingRoom}
>
{creatingRoom ? "Creating call..." : "Create call"}
</Button>
</FieldRow>
</form>
<FieldRow className={styles.fieldRow}>
<Button className={styles.button} type="submit">
Join call
</Button>
</FieldRow>
</form>
<hr />
<form onSubmit={onCreateRoom}>
<h1>Create a call</h1>
<FieldRow className={styles.fieldRow}>
<InputField
id="userName"
name="userName"
label="Username"
type="text"
required
autoComplete="off"
placeholder="Username"
/>
</FieldRow>
<FieldRow className={styles.fieldRow}>
<InputField
id="roomName"
name="roomName"
label="Room Name"
type="text"
required
autoComplete="off"
placeholder="Room Name"
/>
</FieldRow>
{createRoomError && (
<FieldRow className={styles.fieldRow}>
<ErrorMessage>{createRoomError.message}</ErrorMessage>
</FieldRow>
)}
<FieldRow className={styles.fieldRow}>
<Button
className={styles.button}
type="submit"
disabled={creatingRoom}
>
{creatingRoom ? "Creating call..." : "Create call"}
</Button>
</FieldRow>
</form>
</div>
</div>
</div>
</div>
@ -154,32 +176,13 @@ function UnregisteredView() {
);
}
function RegisteredView({ client }) {
const history = useHistory();
const { createRoomError, creatingRoom, createRoom } = useCreateRoom(client);
const onCreateRoom = useCallback(
(e) => {
e.preventDefault();
const data = new FormData(e.target);
const roomName = data.get("roomName");
createRoom(roomName).then((roomIdOrAlias) => {
history.push(`/room/${roomIdOrAlias}`);
});
},
[history]
);
const onJoinRoom = useCallback(
(e) => {
e.preventDefault();
const data = new FormData(e.target);
const roomId = data.get("roomId");
history.push(`/room/${roomId}`);
},
[history]
);
function RegisteredView({
client,
onCreateRoom,
createRoomError,
creatingRoom,
onJoinRoom,
}) {
const publicRooms = usePublicRooms(
client,
import.meta.env.VITE_PUBLIC_SPACE_ROOM_ID
@ -189,93 +192,87 @@ function RegisteredView({ client }) {
const hideCallList = publicRooms.length === 0 && recentRooms.length === 0;
return (
<div className={styles.home}>
<div
className={classNames(styles.left, {
[styles.fullWidth]: hideCallList,
})}
>
<Header>
<LeftNav>
<HeaderLogo />
</LeftNav>
{hideCallList && (
<RightNav>
<UserMenu />
</RightNav>
)}
</Header>
<div className={styles.content}>
<div className={styles.centered}>
<form onSubmit={onJoinRoom}>
<h1>Join a call</h1>
<FieldRow className={styles.fieldRow}>
<InputField
id="roomId"
name="roomId"
label="Call ID"
type="text"
required
autoComplete="off"
placeholder="Call ID"
/>
</FieldRow>
<FieldRow className={styles.fieldRow}>
<Button className={styles.button} type="submit">
Join call
</Button>
</FieldRow>
</form>
<hr />
<form onSubmit={onCreateRoom}>
<h1>Create a call</h1>
<FieldRow className={styles.fieldRow}>
<InputField
id="roomName"
name="roomName"
label="Room Name"
type="text"
required
autoComplete="off"
placeholder="Room Name"
/>
</FieldRow>
{createRoomError && (
<FieldRow className={styles.fieldRow}>
<ErrorMessage>{createRoomError.message}</ErrorMessage>
</FieldRow>
)}
<FieldRow className={styles.fieldRow}>
<Button
className={styles.button}
type="submit"
disabled={creatingRoom}
>
{creatingRoom ? "Creating call..." : "Create call"}
</Button>
</FieldRow>
</form>
</div>
</div>
</div>
{!hideCallList && (
<div className={styles.right}>
<Header>
<LeftNav />
<RightNav>
<UserMenu />
</RightNav>
</Header>
<div
className={classNames(styles.home, {
[styles.fullWidth]: hideCallList,
})}
>
<Header>
<LeftNav>
<HeaderLogo />
</LeftNav>
<RightNav>
<UserMenu />
</RightNav>
</Header>
<div className={styles.splitContainer}>
<div className={styles.left}>
<div className={styles.content}>
{publicRooms.length > 0 && (
<CallList title="Public Calls" rooms={publicRooms} />
)}
{recentRooms.length > 0 && (
<CallList title="Recent Calls" rooms={recentRooms} />
)}
<div className={styles.centered}>
<form onSubmit={onJoinRoom}>
<h1>Join a call</h1>
<FieldRow className={styles.fieldRow}>
<InputField
id="roomId"
name="roomId"
label="Call ID"
type="text"
required
autoComplete="off"
placeholder="Call ID"
/>
</FieldRow>
<FieldRow className={styles.fieldRow}>
<Button className={styles.button} type="submit">
Join call
</Button>
</FieldRow>
</form>
<hr />
<form onSubmit={onCreateRoom}>
<h1>Create a call</h1>
<FieldRow className={styles.fieldRow}>
<InputField
id="roomName"
name="roomName"
label="Room Name"
type="text"
required
autoComplete="off"
placeholder="Room Name"
/>
</FieldRow>
{createRoomError && (
<FieldRow className={styles.fieldRow}>
<ErrorMessage>{createRoomError.message}</ErrorMessage>
</FieldRow>
)}
<FieldRow className={styles.fieldRow}>
<Button
className={styles.button}
type="submit"
disabled={creatingRoom}
>
{creatingRoom ? "Creating call..." : "Create call"}
</Button>
</FieldRow>
</form>
</div>
</div>
</div>
)}
{!hideCallList && (
<div className={styles.right}>
<div className={styles.content}>
{publicRooms.length > 0 && (
<CallList title="Public Calls" rooms={publicRooms} />
)}
{recentRooms.length > 0 && (
<CallList title="Recent Calls" rooms={recentRooms} />
)}
</div>
</div>
)}
</div>
</div>
);
}

View file

@ -1,7 +1,14 @@
.home {
display: flex;
flex: 1;
height: 100%;
flex-direction: column;
min-height: 100vh;
}
.splitContainer {
display: flex;
flex: 1;
flex-direction: column;
}
.left,
@ -11,13 +18,8 @@
flex: 1;
}
.left {
background-color: var(--bgColor2);
}
.fullWidth {
background-color: var(--bgColor1);
overflow-y: auto;
}
.centered {
@ -50,7 +52,7 @@
}
.left .content hr {
width: 100%;
width: calc(100% - 24px);
border: none;
border-top: 1px solid var(--bgColor4);
color: var(--textColor2);
@ -60,20 +62,17 @@
font-weight: 600;
font-size: 15px;
line-height: 24px;
margin: 0 12px;
}
.left .content hr:after {
background-color: var(--bgColor2);
background-color: var(--bgColor1);
content: "OR";
padding: 0 12px;
position: relative;
top: -12px;
}
.fullWidth .content hr:after {
background-color: var(--bgColor1);
}
.left .content form {
display: flex;
flex-direction: column;
@ -97,14 +96,32 @@
}
.left .content form:last-child {
padding-bottom: 0;
padding-bottom: 40px;
}
.right .content {
padding: 113px 40px 40px 40px;
overflow-y: auto;
}
.right .content h3:first-child {
margin-top: 0;
}
@media (min-width: 800px) {
.left {
background-color: var(--bgColor2);
}
.leftNav:not(.fullWidth) {
background-color: var(--bgColor2);
}
.splitContainer {
flex-direction: row;
}
.fullWidth .content hr:after,
.left .content hr:after {
background-color: var(--bgColor2);
}
}

View file

@ -14,7 +14,7 @@ import styles from "./Modal.module.css";
import classNames from "classnames";
export function Modal(props) {
const { title, children, className } = props;
const { title, children, className, mobileFullScreen } = props;
const modalRef = useRef();
const { overlayProps, underlayProps } = useOverlay(props, modalRef);
usePreventScroll();
@ -34,7 +34,11 @@ export function Modal(props) {
{...dialogProps}
{...modalProps}
ref={modalRef}
className={classNames(styles.modal, className)}
className={classNames(
styles.modal,
{ [styles.mobileFullScreen]: mobileFullScreen },
className
)}
>
<div className={styles.modalHeader}>
<h3 {...titleProps}>{title}</h3>

View file

@ -15,7 +15,8 @@
background: #21262c;
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.15);
border-radius: 8px;
width: 420px;
max-width: 90vw;
min-width: 288px;
}
.modalHeader {
@ -47,3 +48,18 @@
.content p {
margin-top: 0;
}
@media (max-width: 799px) {
.modal.mobileFullScreen {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
max-width: none;
max-height: none;
border-radius: 0;
}
}

View file

@ -40,7 +40,6 @@ limitations under the License.
.preview {
position: relative;
width: 100%;
max-width: 816px;
border-radius: 24px;
overflow: hidden;

View file

@ -22,7 +22,7 @@
font-size: 15px;
color: var(--textColor1);
height: 40px;
width: 320px;
max-width: 100%;
}
.selectedItem {
@ -33,7 +33,6 @@
}
.popover {
width: 320px;
}
.option:first-child {

View file

@ -29,6 +29,7 @@ export function SettingsModal({
<Modal
title="Settings"
isDismissable
mobileFullScreen
className={styles.settingsModal}
{...rest}
>

View file

@ -6,13 +6,14 @@
.tabList {
display: flex;
flex-direction: column;
width: 190px;
list-style: none;
padding: 0;
margin: 0;
}
.tab {
max-width: 190px;
min-width: fit-content;
height: 32px;
border-radius: 8px;
background-color: transparent;
@ -56,4 +57,5 @@
flex-direction: column;
flex: 1;
padding: 0 40px;
overflow-y: auto;
}

View file

@ -124,6 +124,7 @@ limitations under the License.
height: 40px;
transition: border-color 250ms, background-color 250ms;
padding: 0 20px;
flex-shrink: 0;
}
.copyButton span {

View file

@ -159,10 +159,7 @@ details[open] > summary {
margin-bottom: 16px;
}
*[data-overlay-container] {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
#root > [data-overlay-container] {
position: relative;
height: 100%;
}