Styling for video room

This commit is contained in:
Robert Long 2021-08-19 12:11:12 -07:00
parent 91e244772f
commit cc59e42bba
40 changed files with 937 additions and 270 deletions

View file

@ -2,9 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<title>Matrix Video Chat</title>
<script>
window.global = window;
</script>

682
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -16,7 +16,8 @@
"react-dom": "^17.0.0",
"react-router-dom": "^5.2.0",
"react-use-gesture": "^9.1.3",
"react-use-measure": "^2.0.4"
"react-use-measure": "^2.0.4",
"vite-plugin-svgr": "^0.4.0"
},
"devDependencies": {
"@vitejs/plugin-react-refresh": "^1.3.1",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -8,31 +8,3 @@
display: flex;
flex-direction: column;
}
.grid {
position: relative;
overflow: hidden;
flex: 1;
}
.participantTile {
position: absolute;
will-change: transform, width, height, opacity, box-shadow;
border-radius: 24px;
overflow: hidden;
background-color: #444;
}
.participantTile video {
width: 100%;
height: 100%;
object-fit: cover;
}
.participantName {
position: absolute;
bottom: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.2);
padding: 8px 24px;
}

7
src/Logo.svg Normal file
View file

@ -0,0 +1,7 @@
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M30 60C46.5686 60 60 46.5686 60 30C60 13.4315 46.5686 0 30 0C13.4315 0 0 13.4315 0 30C0 46.5686 13.4315 60 30 60Z" fill="#0DBD8B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.5148 13.9784C24.5148 12.7674 25.4985 11.7858 26.712 11.7858C34.9366 11.7858 41.6039 18.4393 41.6039 26.6468C41.6039 27.8577 40.6202 28.8394 39.4067 28.8394C38.1932 28.8394 37.2095 27.8577 37.2095 26.6468C37.2095 20.8612 32.5096 16.171 26.712 16.171C25.4985 16.171 24.5148 15.1893 24.5148 13.9784Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.017 24.4541C47.2304 24.4541 48.2142 25.4358 48.2142 26.6467C48.2142 34.8542 41.5468 41.5077 33.3223 41.5077C32.1088 41.5077 31.1251 40.5261 31.1251 39.3151C31.1251 38.1042 32.1088 37.1225 33.3223 37.1225C39.1199 37.1225 43.8198 32.4323 43.8198 26.6467C43.8198 25.4358 44.8035 24.4541 46.017 24.4541Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M35.5193 46.0216C35.5193 47.2326 34.5355 48.2142 33.3221 48.2142C25.0975 48.2142 18.4302 41.5607 18.4302 33.3532C18.4302 32.1423 19.4139 31.1606 20.6274 31.1606C21.8408 31.1606 22.8245 32.1423 22.8245 33.3532C22.8245 39.1388 27.5244 43.829 33.3221 43.829C34.5355 43.829 35.5193 44.8107 35.5193 46.0216Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.9825 35.5459C12.7691 35.5459 11.7854 34.5642 11.7854 33.3533C11.7854 25.1458 18.4527 18.4923 26.6773 18.4923C27.8907 18.4923 28.8744 19.4739 28.8744 20.6849C28.8744 21.8958 27.8907 22.8775 26.6773 22.8775C20.8796 22.8775 16.1797 27.5677 16.1797 33.3533C16.1797 34.5642 15.196 35.5459 13.9825 35.5459Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -20,6 +20,13 @@ import { useParams, useLocation, Link } from "react-router-dom";
import { useVideoRoom } from "./ConferenceCallManagerHooks";
import { DevTools } from "./DevTools";
import { VideoGrid } from "./VideoGrid";
import {
HangupButton,
SettingsButton,
MicButton,
VideoButton,
} from "./RoomButton";
import { ReactComponent as Logo } from "./Logo.svg";
function useQuery() {
const location = useLocation();
@ -64,11 +71,17 @@ export function Room({ manager }) {
{!loading && room && (
<div className={styles.header}>
<div className={styles.backNav}>
<Link to="/">Back</Link>
<Link className={styles.logo} to="/">
<Logo width={32} height={32} />
</Link>
</div>
<h3>{room.name}</h3>
<div className={styles.userNav}>
<h5>{manager.client.getUserId()}</h5>
<SettingsButton
title={debug ? "Disable DevTools" : "Enable DevTools"}
on={debug}
onClick={() => setDebug((debug) => !debug)}
/>
</div>
</div>
)}
@ -101,46 +114,12 @@ export function Room({ manager }) {
)}
{!loading && room && joined && (
<div className={styles.footer}>
<button className={styles.leaveButton} onClick={leaveCall}>
Leave Call
</button>
<button
className={styles.leaveButton}
onClick={() => setDebug((debug) => !debug)}
>
Toggle Debugger
</button>
<MicButton />
<VideoButton />
<HangupButton onClick={leaveCall} />
</div>
)}
{debug && <DevTools manager={manager} />}
</div>
);
}
function Participant({ userId, stream, local }) {
const videoRef = useRef();
useEffect(() => {
if (stream) {
if (local) {
videoRef.current.muted = true;
}
videoRef.current.srcObject = stream;
videoRef.current.play();
} else {
videoRef.current.srcObject = null;
}
}, [stream]);
return (
<div className={styles.participant}>
<video ref={videoRef} playsInline></video>
<div className={styles.participantLabel}>
<p>
{userId} {local && "(You)"}
</p>
</div>
</div>
);
}

View file

@ -28,7 +28,7 @@ limitations under the License.
display: flex;
justify-content: center;
align-items: center;
height: 64px;
height: 98px;
}
.header h5 {
@ -38,14 +38,18 @@ limitations under the License.
.backNav {
position: absolute;
left: 0;
padding: 0 8px;
left: 20px;
}
.logo {
display: flex;
align-items: center;
text-decoration: none;
}
.userNav {
position: absolute;
right: 0;
padding: 0 8px;
right: 20px;
max-width: 30%;
}
@ -96,37 +100,20 @@ limitations under the License.
min-height: 0;
}
.participant {
display: flex;
position: relative;
flex: 1;
flex-shrink: 1;
min-height: 0;
background-color: black;
}
.participant video {
max-height: 100%;
z-index: 0;
display: block;
margin: auto;
max-width: 100%;
}
.participantLabel {
position: absolute;
bottom: 0;
right: 0;
padding: 8px 16px;
background: rgba(0, 0, 0, 0.2);
}
.footer {
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 64px;
height: 118px;
}
.footer > * {
margin-right: 30px;
}
.footer > :last-child {
margin-right: 0px;
}
@media(min-width: 800px) {

68
src/RoomButton.jsx Normal file
View file

@ -0,0 +1,68 @@
import React from "react";
import classNames from "classnames";
import styles from "./RoomButton.module.css";
import { ReactComponent as MicIcon } from "./icons/Mic.svg";
import { ReactComponent as MuteMicIcon } from "./icons/MuteMic.svg";
import { ReactComponent as VideoIcon } from "./icons/Video.svg";
import { ReactComponent as DisableVideoIcon } from "./icons/DisableVideo.svg";
import { ReactComponent as HangupIcon } from "./icons/Hangup.svg";
import { ReactComponent as SettingsIcon } from "./icons/Settings.svg";
export function RoomButton({ on, className, children, ...rest }) {
return (
<button
className={classNames(styles.roomButton, className, { [styles.on]: on })}
{...rest}
>
{children}
</button>
);
}
export function MicButton({ muted, ...rest }) {
return (
<RoomButton {...rest} on={muted}>
{muted ? <MuteMicIcon /> : <MicIcon />}
</RoomButton>
);
}
export function VideoButton({ enabled, ...rest }) {
return (
<RoomButton {...rest} on={enabled}>
{enabled ? <DisableVideoIcon /> : <VideoIcon />}
</RoomButton>
);
}
export function HangupButton({ className, ...rest }) {
return (
<RoomButton
className={classNames(styles.hangupButton, className)}
{...rest}
>
<HangupIcon />
</RoomButton>
);
}
export function HeaderButton({ on, className, children, ...rest }) {
return (
<button
className={classNames(styles.headerButton, className, {
[styles.on]: on,
})}
{...rest}
>
{children}
</button>
);
}
export function SettingsButton(props) {
return (
<HeaderButton {...props}>
<SettingsIcon />
</HeaderButton>
);
}

65
src/RoomButton.module.css Normal file
View file

@ -0,0 +1,65 @@
/*
Copyright 2021 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.roomButton {
width: 50px;
height: 50px;
border-radius: 50px;
background-color: rgba(111, 120, 130, 0.3);
display: flex;
justify-content: center;
align-items: center;
padding: 0;
}
.roomButton:hover {
background-color: #8D97A5;
}
.roomButton:active {
}
.roomButton.on {
background-color: #ffffff;
}
.headerButton {
width: 32px;
height: 32px;
display: flex;
justify-content: center;
align-items: center;
background-color: transparent;
border-radius: 32px;
padding: 0;
}
.headerButton:hover {
background-color: #8D97A5;
}
.headerButton:hover svg * {
fill: #394049;
}
.headerButton.on svg * {
fill: #0DBD8B
}
.hangupButton, .hangupButton:hover {
background-color: #FF5B55;
}

View file

@ -1,9 +1,11 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import { useDrag } from "react-use-gesture";
import { useSprings, animated } from "@react-spring/web";
import styles from "./GridDemo.module.css";
import classNames from "classnames";
import styles from "./VideoGrid.module.css";
import useMeasure from "react-use-measure";
import moveArrItem from "lodash-move";
import { ReactComponent as MicIcon } from "./icons/Mic.svg";
function useIsMounted() {
const isMountedRef = useRef(false);
@ -344,10 +346,20 @@ function ParticipantTile({ style, participant, remove, ...rest }) {
}
}, [participant.stream]);
// Firefox doesn't respect the disablePictureInPicture attribute
// https://bugzilla.mozilla.org/show_bug.cgi?id=1611831
return (
<animated.div className={styles.participantTile} style={style} {...rest}>
<div className={styles.participantName}>{participant.userId}</div>
<video ref={videoRef} playsInline />
<div
className={classNames(styles.participantName, {
[styles.speaking]: participant.speaking,
})}
>
{participant.speaking && <MicIcon />}
<span>{participant.userId}</span>
</div>
<video ref={videoRef} playsInline disablePictureInPicture />
</animated.div>
);
}

67
src/VideoGrid.module.css Normal file
View file

@ -0,0 +1,67 @@
/*
Copyright 2021 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.grid {
position: relative;
overflow: hidden;
flex: 1;
}
.participantTile {
position: absolute;
will-change: transform, width, height, opacity, box-shadow;
border-radius: 24px;
overflow: hidden;
background-color: #444;
}
.participantTile video {
width: 100%;
height: 100%;
object-fit: cover;
}
.participantName {
position: absolute;
bottom: 16px;
left: 16px;
height: 32px;
padding: 0 8px;
background-color: rgba(23, 25, 28, 0.96);
display: none;
align-items: center;
justify-content: center;
border-radius: 8px;
}
.participantName > * {
margin-right: 8px;
}
.participantName > :last-child {
margin-right: 0px;
}
.participantName span {
font-size: 15px;
font-weight: 600;
line-height: 32px;
}
.participantTile:hover .participantName, .participantName.speaking {
display: flex;
}

BIN
src/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -1,15 +0,0 @@
<svg width="410" height="404" viewBox="0 0 410 404" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M399.641 59.5246L215.643 388.545C211.844 395.338 202.084 395.378 198.228 388.618L10.5817 59.5563C6.38087 52.1896 12.6802 43.2665 21.0281 44.7586L205.223 77.6824C206.398 77.8924 207.601 77.8904 208.776 77.6763L389.119 44.8058C397.439 43.2894 403.768 52.1434 399.641 59.5246Z" fill="url(#paint0_linear)"/>
<path d="M292.965 1.5744L156.801 28.2552C154.563 28.6937 152.906 30.5903 152.771 32.8664L144.395 174.33C144.198 177.662 147.258 180.248 150.51 179.498L188.42 170.749C191.967 169.931 195.172 173.055 194.443 176.622L183.18 231.775C182.422 235.487 185.907 238.661 189.532 237.56L212.947 230.446C216.577 229.344 220.065 232.527 219.297 236.242L201.398 322.875C200.278 328.294 207.486 331.249 210.492 326.603L212.5 323.5L323.454 102.072C325.312 98.3645 322.108 94.137 318.036 94.9228L279.014 102.454C275.347 103.161 272.227 99.746 273.262 96.1583L298.731 7.86689C299.767 4.27314 296.636 0.855181 292.965 1.5744Z" fill="url(#paint1_linear)"/>
<defs>
<linearGradient id="paint0_linear" x1="6.00017" y1="32.9999" x2="235" y2="344" gradientUnits="userSpaceOnUse">
<stop stop-color="#41D1FF"/>
<stop offset="1" stop-color="#BD34FE"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="194.651" y1="8.81818" x2="236.076" y2="292.989" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFEA83"/>
<stop offset="0.0833333" stop-color="#FFDD35"/>
<stop offset="1" stop-color="#FFA800"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

3
src/icons/Chevron.svg Normal file
View file

@ -0,0 +1,3 @@
<svg width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.25 1.25L5 5L8.75 1.25" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 220 B

View file

@ -0,0 +1,6 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.290472 1.37627C0.677768 0.985743 1.3057 0.985743 1.69299 1.37627L16.569 16.3762C16.9563 16.7668 16.9563 17.3999 16.569 17.7904C16.1817 18.181 15.5538 18.181 15.1665 17.7904L0.290472 2.79048C-0.096824 2.39995 -0.096824 1.76679 0.290472 1.37627Z" fill="#394049"/>
<path d="M0.597515 5.19186C0.323238 5.646 0.165249 6.17941 0.165249 6.75001V14.0833C0.165249 15.7402 1.49729 17.0833 3.14045 17.0833H12.363L0.639137 5.2371C0.624608 5.22242 0.610733 5.20733 0.597515 5.19186Z" fill="#394049"/>
<path d="M14.2148 6.75002V11.9031L6.14598 3.75002H11.2396C12.8828 3.75002 14.2148 5.09317 14.2148 6.75002Z" fill="#394049"/>
<path d="M18.3887 5.88312L15.8677 7.91669V12.9167L18.3887 14.9503C19.038 15.4741 19.9999 15.0079 19.9999 14.1694V6.66399C19.9999 5.82548 19.038 5.35931 18.3887 5.88312Z" fill="#394049"/>
</svg>

After

Width:  |  Height:  |  Size: 915 B

11
src/icons/Grid.svg Normal file
View file

@ -0,0 +1,11 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="1" y="9" width="6" height="6" rx="1" fill="#8E99A4"/>
<rect x="9" y="9" width="6" height="6" rx="1" fill="#8E99A4"/>
<rect x="17" y="9" width="6" height="6" rx="1" fill="#8E99A4"/>
<rect x="1" y="17" width="6" height="6" rx="1" fill="#8E99A4"/>
<rect x="9" y="17" width="6" height="6" rx="1" fill="#8E99A4"/>
<rect x="17" y="17" width="6" height="6" rx="1" fill="#8E99A4"/>
<rect x="1" y="1" width="6" height="6" rx="1" fill="#8E99A4"/>
<rect x="9" y="1" width="6" height="6" rx="1" fill="#8E99A4"/>
<rect x="17" y="1" width="6" height="6" rx="1" fill="#8E99A4"/>
</svg>

After

Width:  |  Height:  |  Size: 676 B

3
src/icons/Hangup.svg Normal file
View file

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.007 6.46375C8.60094 6.4097 5.70947 6.77458 5.00651 6.95945C4.96493 6.97038 4.91704 6.98261 4.86347 6.99628C3.78418 7.27174 0.402266 8.13487 0.0368686 10.8697C-0.246222 12.9885 1.17146 13.6298 1.88015 13.5322C2.37066 13.4707 3.77508 13.2486 5.0727 13.0158C6.34691 12.7872 6.34626 11.9466 6.34582 11.3782C6.34581 11.3677 6.34581 11.3574 6.34581 11.3471L6.34581 10.2044C6.34581 9.91339 6.61929 9.74516 6.9965 9.69969C8.33185 9.51831 9.44662 9.5178 10.0046 9.51779L10.0093 9.51779C10.5672 9.51779 11.6682 9.51832 13.0035 9.6997C13.3807 9.74517 13.6542 9.9134 13.6542 10.2044L13.6542 11.3471C13.6542 11.3574 13.6542 11.3677 13.6542 11.3782C13.6537 11.9466 13.6531 12.7872 14.9273 13.0158C16.2249 13.2486 17.6293 13.4707 18.1198 13.5322C18.8285 13.6298 20.2462 12.9885 19.9631 10.8697C19.5977 8.13487 16.2158 7.27174 15.1365 6.99629C15.083 6.98262 15.0351 6.97039 14.9935 6.95946C14.2905 6.77459 11.413 6.4097 10.007 6.46375Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

4
src/icons/Mic.svg Normal file
View file

@ -0,0 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.37785 4.70549C6.37785 2.79707 7.99961 1.25 10.0001 1.25C12.0007 1.25 13.6224 2.79707 13.6224 4.70548V9.87324C13.6224 11.7817 12.0007 13.3287 10.0001 13.3287C7.99961 13.3287 6.37785 11.7817 6.37785 9.87324V4.70549Z" fill="white"/>
<path d="M3.66099 8.77015C4.30219 8.77015 4.82198 9.266 4.82198 9.87768C4.82198 12.5957 7.1314 14.8024 9.98617 14.8095C9.99084 14.8094 9.99552 14.8094 10.0002 14.8094C10.0049 14.8094 10.0095 14.8094 10.0141 14.8095C12.8688 14.8022 15.178 12.5956 15.178 9.87768C15.178 9.266 15.6978 8.77015 16.339 8.77015C16.9802 8.77015 17.5 9.266 17.5 9.87768C17.5 13.4496 14.7509 16.4077 11.1612 16.9394V17.6425C11.1612 18.2541 10.6414 18.75 10.0002 18.75C9.359 18.75 8.83921 18.2541 8.83921 17.6425V16.9395C5.24925 16.4079 2.5 13.4497 2.5 9.87768C2.5 9.266 3.01979 8.77015 3.66099 8.77015Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 938 B

5
src/icons/MuteMic.svg Normal file
View file

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.74372 1.50628C2.40201 1.16457 1.84799 1.16457 1.50628 1.50628C1.16457 1.84799 1.16457 2.40201 1.50628 2.74372L6.5 7.73744V10C6.5 11.933 8.067 13.5 10 13.5C10.6491 13.5 11.2569 13.3233 11.778 13.0154L13.042 14.2794C12.1838 14.8906 11.1339 15.25 10 15.25C7.10051 15.25 4.75 12.8995 4.75 10C4.75 9.51675 4.35825 9.125 3.875 9.125C3.39175 9.125 3 9.51675 3 10C3 13.5697 5.67198 16.5153 9.125 16.9458V17.875C9.125 18.3582 9.51675 18.75 10 18.75C10.4832 18.75 10.875 18.3582 10.875 17.875V16.9458C12.1531 16.7865 13.3242 16.2825 14.2924 15.5299L17.2563 18.4937C17.598 18.8354 18.152 18.8354 18.4937 18.4937C18.8354 18.152 18.8354 17.598 18.4937 17.2563L2.74372 1.50628Z" fill="#394049"/>
<path d="M15.0678 11.3763L16.439 12.7504C16.8001 11.9061 17 10.9764 17 10C17 9.51675 16.6082 9.125 16.125 9.125C15.6418 9.125 15.25 9.51675 15.25 10C15.25 10.4762 15.1866 10.9376 15.0678 11.3763Z" fill="#394049"/>
<path d="M6.87692 3.16834L13.5 9.80523V4.75C13.5 2.817 11.933 1.25 10 1.25C8.63618 1.25 7.45455 2.03005 6.87692 3.16834Z" fill="#394049"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

3
src/icons/Settings.svg Normal file
View file

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.0988 9.01625C20.3188 9.59375 20.8825 9.97875 21.5013 9.97875C22.3263 9.97875 23 10.6525 23 11.4775V12.5225C23 13.3475 22.3263 14.0213 21.5013 14.0213C20.8825 14.0213 20.3188 14.4062 20.0988 14.9838C20.0806 15.0292 20.0624 15.0753 20.0441 15.1218C19.9792 15.2863 19.9125 15.4555 19.8375 15.6163C19.5763 16.18 19.7 16.84 20.14 17.28C20.7313 17.8575 20.7313 18.8062 20.14 19.3975L19.3975 20.14C18.82 20.7313 17.8713 20.7313 17.28 20.14C16.8538 19.7 16.18 19.5763 15.6163 19.8375C15.41 19.9338 15.2037 20.0163 14.9838 20.0988C14.4062 20.3188 14.0213 20.8825 14.0213 21.5013C14.0213 22.3263 13.3475 23 12.5225 23H11.4775C10.6525 23 9.97875 22.3263 9.97875 21.5013C9.97875 20.8825 9.59375 20.3188 9.01625 20.0988C8.97079 20.0806 8.92466 20.0624 8.87815 20.044C8.71368 19.9792 8.54454 19.9125 8.38375 19.8375C7.82 19.5763 7.16 19.7 6.72 20.14C6.1425 20.7313 5.19375 20.7313 4.6025 20.14L3.86 19.3975C3.26875 18.82 3.26875 17.8713 3.86 17.28C4.3 16.8538 4.42375 16.18 4.1625 15.6163C4.06625 15.41 3.98375 15.2037 3.90125 14.9838C3.68125 14.4062 3.1175 14.0213 2.49875 14.0213C1.67375 14.0213 1 13.3475 1 12.5225V11.4775C1 10.6525 1.67375 9.97875 2.49875 9.97875C3.1175 9.97875 3.68125 9.59375 3.90125 9.01625C3.94464 8.87742 3.99897 8.74406 4.0539 8.60926C4.086 8.53046 4.11831 8.45117 4.14875 8.37C4.41 7.80625 4.28625 7.14625 3.84625 6.70625C3.255 6.12875 3.255 5.18 3.84625 4.58875L4.6025 3.86C5.18 3.26875 6.12875 3.26875 6.72 3.86C7.14625 4.3 7.82 4.42375 8.38375 4.1625C8.59 4.06625 8.79625 3.97 9.01625 3.90125C9.59375 3.68125 9.97875 3.1175 9.97875 2.49875C9.97875 1.67375 10.6525 1 11.4775 1H12.5225C13.3475 1 14.0213 1.67375 14.0213 2.49875C14.0213 3.13125 14.4062 3.68125 14.9838 3.90125C15.0292 3.91943 15.0753 3.93762 15.1218 3.95595C15.2863 4.02079 15.4555 4.08746 15.6163 4.1625C16.18 4.42375 16.84 4.3 17.28 3.86C17.8575 3.26875 18.8062 3.26875 19.3975 3.86L20.14 4.6025C20.7313 5.18 20.7313 6.12875 20.14 6.72C19.7 7.14625 19.5763 7.82 19.8375 8.38375C19.9338 8.59 20.0163 8.79625 20.0988 9.01625ZM12 17.5C8.96125 17.5 6.5 15.0387 6.5 12C6.5 8.96125 8.96125 6.5 12 6.5C15.0387 6.5 17.5 8.96125 17.5 12C17.5 15.0387 15.0387 17.5 12 17.5Z" fill="#8E99A4"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

4
src/icons/User.svg Normal file
View file

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.8914 9.0784C18.5132 9.0784 18.2066 8.777 18.2066 8.4052V5.71251H15.4678C15.0896 5.71251 14.783 5.41111 14.783 5.03931C14.783 4.66751 15.0896 4.36611 15.4678 4.36611H18.2066V1.6732C18.2066 1.3014 18.5132 1 18.8914 1C19.2696 1 19.5761 1.3014 19.5761 1.6732V4.36611H22.3153C22.6934 4.36611 23 4.66751 23 5.03931C23 5.41111 22.6934 5.71251 22.3153 5.71251H19.5761V8.4052C19.5761 8.777 19.2696 9.0784 18.8914 9.0784Z" fill="#8E99A4"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.5002 11.5094C19.8949 11.5094 20.281 11.4736 20.6555 11.4051C20.7505 11.9558 20.8 12.5221 20.8 13.1C20.8 18.5676 16.3676 23 10.9 23C5.43238 23 1 18.5676 1 13.1C1 7.63238 5.43238 3.2 10.9 3.2C11.7973 3.2 12.6666 3.31937 13.4931 3.54308C13.3177 4.11118 13.2234 4.71396 13.2234 5.33841C13.2234 8.74655 16.0336 11.5094 19.5002 11.5094ZM11.1308 21.4653C13.2927 21.4653 15.2551 20.6258 16.6993 19.2603C15.7939 17.0769 13.6417 15.5412 11.1308 15.5412C8.61988 15.5412 6.46768 17.0769 5.56225 19.2603C7.00643 20.6258 8.96888 21.4653 11.1308 21.4653ZM11.2799 7.81768C9.78854 7.9515 8.62035 9.18434 8.62035 10.6854C8.62035 12.2759 9.93179 13.5652 11.5495 13.5652C12.6276 13.5652 13.5696 12.9927 14.0781 12.1401C12.6655 11.1035 11.6462 9.57751 11.2799 7.81768Z" fill="#8E99A4"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

4
src/icons/Video.svg Normal file
View file

@ -0,0 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.50001 3.33334C1.11929 3.33334 0 4.45264 0 5.83336V14.1667C0 15.5474 1.11929 16.6667 2.50001 16.6667H11.6667C13.0474 16.6667 14.1667 15.5474 14.1667 14.1667V5.83336C14.1667 4.45264 13.0474 3.33334 11.6667 3.33334H2.50001Z" fill="white"/>
<path d="M18.6462 5.24983L15.8334 7.50004V12.5001L18.6462 14.7503C19.1918 15.1868 20.0001 14.7983 20.0001 14.0996V5.90056C20.0001 5.2018 19.1918 4.81332 18.6462 5.24983Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 538 B

View file

@ -14,11 +14,101 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
/* Inter unexpectedly contains various codepoints which collide with emoji, even
when variation-16 is applied to request the emoji variant. From eyeballing
the emoji picker, these are: 20e3, 23cf, 24c2, 25a0-25c1, 2665, 2764, 2b06, 2b1c.
Therefore we define a unicode-range to load which excludes the glyphs
(to avoid having to maintain a fork of Inter). */
:root {
--inter-unicode-range: U+0000-20e2,U+20e4-23ce,U+23d0-24c1,U+24c3-259f,U+25c2-2664,U+2666-2763,U+2765-2b05,U+2b07-2b1b,U+2b1d-10FFFF;
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
unicode-range: var(--inter-unicode-range);
src: url("/fonts/Inter/Inter-Regular.woff2") format("woff2"),
url("/fonts/Inter/Inter-Regular.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 400;
font-display: swap;
unicode-range: var(--inter-unicode-range);
src: url("/fonts/Inter/Inter-Italic.woff2") format("woff2"),
url("/fonts/Inter/Inter-Italic.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 500;
font-display: swap;
unicode-range: var(--inter-unicode-range);
src: url("/fonts/Inter/Inter-Medium.woff2") format("woff2"),
url("/fonts/Inter/Inter-Medium.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 500;
font-display: swap;
unicode-range: var(--inter-unicode-range);
src: url("/fonts/Inter/Inter-MediumItalic.woff2") format("woff2"),
url("/fonts/Inter/Inter-MediumItalic.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
unicode-range: var(--inter-unicode-range);
src: url("/fonts/Inter/Inter-SemiBold.woff2") format("woff2"),
url("/fonts/Inter/Inter-SemiBold.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 600;
font-display: swap;
unicode-range: var(--inter-unicode-range);
src: url("/fonts/Inter/Inter-SemiBoldItalic.woff2") format("woff2"),
url("/fonts/Inter/Inter-SemiBoldItalic.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
unicode-range: var(--inter-unicode-range);
src: url("/fonts/Inter/Inter-Bold.woff2") format("woff2"),
url("/fonts/Inter/Inter-Bold.woff") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 700;
font-display: swap;
unicode-range: var(--inter-unicode-range);
src: url("/fonts/Inter/Inter-BoldItalic.woff2") format("woff2"),
url("/fonts/Inter/Inter-BoldItalic.woff") format("woff");
}
body {
background-color: #333;
background-color: #21262C;
color: #fff;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
font-family: "Inter", -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
@ -27,7 +117,7 @@ body {
button {
border: none;
background: #ccc;
background-color: #ccc;
color: black;
font-size: 16px;
font-weight: bold;
@ -37,7 +127,7 @@ button {
}
button:hover, button:active {
background: #888;
background-color: #888;
}
a {

View file

@ -16,10 +16,11 @@ limitations under the License.
import { defineConfig } from "vite";
import reactRefresh from "@vitejs/plugin-react-refresh";
import svgrPlugin from "vite-plugin-svgr";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [reactRefresh()],
plugins: [reactRefresh(), svgrPlugin()],
server: {
proxy: {
"/_matrix": "http://localhost:8008",