Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbef06269b | ||
|
|
894815268a | ||
|
|
8ecec0bc7e | ||
|
|
66839e02f6 | ||
|
|
bad8f36bf5 | ||
|
|
f5c50230a9 | ||
|
|
0136fd3cab | ||
|
|
2d18953344 | ||
|
|
d930ab869a | ||
|
|
dbdb82bd74 | ||
|
|
61309bacd9 | ||
|
|
b3e88d33a7 | ||
|
|
73fda641c8 | ||
|
|
be01a4bd81 | ||
|
|
0814e3c905 | ||
|
|
c7dd2e2093 | ||
|
|
cfa525f957 | ||
|
|
43d579744f | ||
|
|
48a008093b | ||
|
|
70c099c4b5 | ||
|
|
363f2340a0 | ||
|
|
3a6346aa63 | ||
|
|
9ef9680e07 | ||
|
|
e3cec93669 | ||
|
|
b6c926d2c8 | ||
|
|
c430ebb3a3 | ||
|
|
ae13814449 | ||
|
|
dc75c1cfb4 | ||
|
|
38f9a79bd3 | ||
|
|
fc1aaf02bf |
35
.eslintrc.js
Normal file
35
.eslintrc.js
Normal file
@@ -0,0 +1,35 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
"matrix-org",
|
||||
],
|
||||
extends: [
|
||||
"plugin:matrix-org/react",
|
||||
"plugin:matrix-org/a11y",
|
||||
"prettier",
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
parserOptions: {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module",
|
||||
},
|
||||
rules: {
|
||||
// We break this rule in a few places: dial it back to a warning
|
||||
// (and run with max warnings) to tolerate the existing code
|
||||
"react-hooks/exhaustive-deps": ["warn"],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
"src/**/*.{ts,tsx}",
|
||||
],
|
||||
},
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect",
|
||||
},
|
||||
},
|
||||
};
|
||||
20
.github/workflows/lint.yaml
vendored
Normal file
20
.github/workflows/lint.yaml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: Lint and format
|
||||
on:
|
||||
pull_request: {}
|
||||
jobs:
|
||||
prettier:
|
||||
name: Lint and format
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
- name: Install dependencies
|
||||
run: "yarn install"
|
||||
- name: Prettier
|
||||
run: "yarn run prettier:check"
|
||||
- name: ESLint
|
||||
run: "yarn run lint"
|
||||
2
.prettierignore
Normal file
2
.prettierignore
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
dist
|
||||
1
.prettierrc.json
Normal file
1
.prettierrc.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
12
package.json
12
package.json
@@ -5,7 +5,10 @@
|
||||
"build": "vite build",
|
||||
"serve": "vite preview",
|
||||
"storybook": "start-storybook -p 6006",
|
||||
"build-storybook": "build-storybook"
|
||||
"build-storybook": "build-storybook",
|
||||
"prettier:check": "prettier -c src",
|
||||
"prettier:format": "prettier -w src",
|
||||
"lint": "eslint --max-warnings 11 src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@juggle/resize-observer": "^3.3.1",
|
||||
@@ -50,6 +53,13 @@
|
||||
"@babel/core": "^7.16.5",
|
||||
"@storybook/react": "^6.5.0-alpha.5",
|
||||
"babel-loader": "^8.2.3",
|
||||
"eslint": "^8.14.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-matrix-org": "^0.4.0",
|
||||
"eslint-plugin-react": "^7.29.4",
|
||||
"eslint-plugin-react-hooks": "^4.5.0",
|
||||
"prettier": "^2.6.2",
|
||||
"sass": "^1.42.1",
|
||||
"storybook-builder-vite": "^0.1.12",
|
||||
"vite": "^2.4.2",
|
||||
|
||||
@@ -4,35 +4,63 @@ import classNames from "classnames";
|
||||
import { Avatar } from "./Avatar";
|
||||
import { getAvatarUrl } from "./matrix-utils";
|
||||
|
||||
export function Facepile({ className, client, participants, ...rest }) {
|
||||
const overlapMap = {
|
||||
xs: 2,
|
||||
sm: 4,
|
||||
md: 8,
|
||||
};
|
||||
|
||||
const sizeMap = {
|
||||
xs: 24,
|
||||
sm: 32,
|
||||
md: 36,
|
||||
};
|
||||
|
||||
export function Facepile({
|
||||
className,
|
||||
client,
|
||||
participants,
|
||||
max,
|
||||
size,
|
||||
...rest
|
||||
}) {
|
||||
const _size = sizeMap[size];
|
||||
const _overlap = overlapMap[size];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(styles.facepile, className)}
|
||||
className={classNames(styles.facepile, styles[size], className)}
|
||||
title={participants.map((member) => member.name).join(", ")}
|
||||
style={{ width: participants.length * (_size - _overlap) + _overlap }}
|
||||
{...rest}
|
||||
>
|
||||
{participants.slice(0, 3).map((member, i) => {
|
||||
{participants.slice(0, max).map((member, i) => {
|
||||
const avatarUrl = member.user?.avatarUrl;
|
||||
return (
|
||||
<Avatar
|
||||
key={member.userId}
|
||||
size="xs"
|
||||
src={avatarUrl && getAvatarUrl(client, avatarUrl, 22)}
|
||||
size={size}
|
||||
src={avatarUrl && getAvatarUrl(client, avatarUrl, _size)}
|
||||
fallback={member.name.slice(0, 1).toUpperCase()}
|
||||
className={styles.avatar}
|
||||
style={{ left: i * 22 }}
|
||||
style={{ left: i * (_size - _overlap) }}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{participants.length > 3 && (
|
||||
{participants.length > max && (
|
||||
<Avatar
|
||||
key="additional"
|
||||
size="xs"
|
||||
fallback={`+${participants.length - 3}`}
|
||||
size={size}
|
||||
fallback={`+${participants.length - max}`}
|
||||
className={styles.avatar}
|
||||
style={{ left: 3 * 22 }}
|
||||
style={{ left: max * (_size - _overlap) }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Facepile.defaultProps = {
|
||||
max: 3,
|
||||
size: "xs",
|
||||
};
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
.facepile {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.facepile.xs {
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.facepile.sm {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.facepile.md {
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.facepile .avatar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
border: 1px solid var(--bgColor2);
|
||||
}
|
||||
|
||||
.facepile.md .avatar {
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ 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 ScreenshareIcon } from "../icons/Screenshare.svg";
|
||||
import { ReactComponent as SettingsIcon } from "../icons/Settings.svg";
|
||||
import { ReactComponent as AddUserIcon } from "../icons/AddUser.svg";
|
||||
import { useButton } from "@react-aria/button";
|
||||
import { mergeProps, useObjectRef } from "@react-aria/utils";
|
||||
import { TooltipTrigger } from "../Tooltip";
|
||||
@@ -20,6 +22,7 @@ export const variantToClassName = {
|
||||
copy: [styles.copyButton],
|
||||
iconCopy: [styles.iconCopyButton],
|
||||
secondaryCopy: [styles.copyButton],
|
||||
secondaryHangup: [styles.secondaryHangup],
|
||||
};
|
||||
|
||||
export const sizeToClassName = {
|
||||
@@ -126,3 +129,25 @@ export function HangupButton({ className, ...rest }) {
|
||||
</TooltipTrigger>
|
||||
);
|
||||
}
|
||||
|
||||
export function SettingsButton({ className, ...rest }) {
|
||||
return (
|
||||
<TooltipTrigger>
|
||||
<Button variant="toolbar" {...rest}>
|
||||
<SettingsIcon />
|
||||
</Button>
|
||||
{() => "Settings"}
|
||||
</TooltipTrigger>
|
||||
);
|
||||
}
|
||||
|
||||
export function InviteButton({ className, ...rest }) {
|
||||
return (
|
||||
<TooltipTrigger>
|
||||
<Button variant="toolbar" {...rest}>
|
||||
<AddUserIcon />
|
||||
</Button>
|
||||
{() => "Invite"}
|
||||
</TooltipTrigger>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ limitations under the License.
|
||||
.iconButton,
|
||||
.iconCopyButton,
|
||||
.secondary,
|
||||
.secondaryHangup,
|
||||
.copyButton {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -34,6 +35,7 @@ limitations under the License.
|
||||
}
|
||||
|
||||
.secondary,
|
||||
.secondaryHangup,
|
||||
.button,
|
||||
.copyButton {
|
||||
padding: 7px 15px;
|
||||
@@ -53,6 +55,7 @@ limitations under the License.
|
||||
.iconButton:focus,
|
||||
.iconCopyButton:focus,
|
||||
.secondary:focus,
|
||||
.secondaryHangup:focus,
|
||||
.copyButton:focus {
|
||||
outline: auto;
|
||||
}
|
||||
@@ -119,6 +122,12 @@ limitations under the License.
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.secondaryHangup {
|
||||
color: #ff5b55;
|
||||
border: 2px solid #ff5b55;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.copyButton.secondaryCopy {
|
||||
color: var(--textColor1);
|
||||
border-color: var(--textColor1);
|
||||
|
||||
@@ -13,22 +13,25 @@ import { JoinExistingCallModal } from "./JoinExistingCallModal";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { Headline, Title } from "../typography/Typography";
|
||||
import { Form } from "../form/Form";
|
||||
import { useShouldShowPtt } from "../useShouldShowPtt";
|
||||
|
||||
export function RegisteredView({ client }) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState();
|
||||
const history = useHistory();
|
||||
const shouldShowPtt = useShouldShowPtt();
|
||||
const onSubmit = useCallback(
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
const data = new FormData(e.target);
|
||||
const roomName = data.get("callName");
|
||||
const ptt = data.get("ptt") !== null;
|
||||
|
||||
async function submit() {
|
||||
setError(undefined);
|
||||
setLoading(true);
|
||||
|
||||
const roomIdOrAlias = await createRoom(client, roomName);
|
||||
const roomIdOrAlias = await createRoom(client, roomName, ptt);
|
||||
|
||||
if (roomIdOrAlias) {
|
||||
history.push(`/room/${roomIdOrAlias}`);
|
||||
@@ -87,6 +90,7 @@ export function RegisteredView({ client }) {
|
||||
required
|
||||
autoComplete="off"
|
||||
/>
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
size="lg"
|
||||
@@ -96,6 +100,16 @@ export function RegisteredView({ client }) {
|
||||
{loading ? "Loading..." : "Go"}
|
||||
</Button>
|
||||
</FieldRow>
|
||||
{shouldShowPtt && (
|
||||
<FieldRow className={styles.fieldRow}>
|
||||
<InputField
|
||||
id="ptt"
|
||||
name="ptt"
|
||||
label="Push to Talk"
|
||||
type="checkbox"
|
||||
/>
|
||||
</FieldRow>
|
||||
)}
|
||||
{error && (
|
||||
<FieldRow className={styles.fieldRow}>
|
||||
<ErrorMessage>{error.message}</ErrorMessage>
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
}
|
||||
|
||||
.fieldRow {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.fieldRow:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,10 @@ import { Form } from "../form/Form";
|
||||
import styles from "./UnauthenticatedView.module.css";
|
||||
import commonStyles from "./common.module.css";
|
||||
import { generateRandomName } from "../auth/generateRandomName";
|
||||
import { useShouldShowPtt } from "../useShouldShowPtt";
|
||||
|
||||
export function UnauthenticatedView() {
|
||||
const shouldShowPtt = useShouldShowPtt();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState();
|
||||
const [{ privacyPolicyUrl, recaptchaKey }, register] =
|
||||
@@ -28,6 +30,7 @@ export function UnauthenticatedView() {
|
||||
const data = new FormData(e.target);
|
||||
const roomName = data.get("callName");
|
||||
const displayName = data.get("displayName");
|
||||
const ptt = data.get("ptt") !== null;
|
||||
|
||||
async function submit() {
|
||||
setError(undefined);
|
||||
@@ -41,7 +44,7 @@ export function UnauthenticatedView() {
|
||||
recaptchaResponse,
|
||||
true
|
||||
);
|
||||
const roomIdOrAlias = await createRoom(client, roomName);
|
||||
const roomIdOrAlias = await createRoom(client, roomName, ptt);
|
||||
|
||||
if (roomIdOrAlias) {
|
||||
history.push(`/room/${roomIdOrAlias}`);
|
||||
@@ -111,6 +114,16 @@ export function UnauthenticatedView() {
|
||||
autoComplete="off"
|
||||
/>
|
||||
</FieldRow>
|
||||
{shouldShowPtt && (
|
||||
<FieldRow>
|
||||
<InputField
|
||||
id="ptt"
|
||||
name="ptt"
|
||||
label="Push to Talk"
|
||||
type="checkbox"
|
||||
/>
|
||||
</FieldRow>
|
||||
)}
|
||||
<Caption>
|
||||
By clicking "Go", you agree to our{" "}
|
||||
<Link href={privacyPolicyUrl}>Terms and conditions</Link>
|
||||
|
||||
41
src/input/Toggle.jsx
Normal file
41
src/input/Toggle.jsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import React, { useCallback, useRef } from "react";
|
||||
import styles from "./Toggle.module.css";
|
||||
import { useToggleButton } from "@react-aria/button";
|
||||
import classNames from "classnames";
|
||||
import { Field } from "./Input";
|
||||
|
||||
export function Toggle({ id, label, className, onChange, isSelected }) {
|
||||
const buttonRef = useRef();
|
||||
const toggle = useCallback(() => {
|
||||
onChange(!isSelected);
|
||||
});
|
||||
const { buttonProps } = useToggleButton(
|
||||
{ isSelected },
|
||||
{ toggle },
|
||||
buttonRef
|
||||
);
|
||||
|
||||
return (
|
||||
<Field
|
||||
className={classNames(
|
||||
styles.toggle,
|
||||
{ [styles.on]: isSelected },
|
||||
className
|
||||
)}
|
||||
>
|
||||
<button
|
||||
{...buttonProps}
|
||||
ref={buttonRef}
|
||||
id={id}
|
||||
className={classNames(styles.button, {
|
||||
[styles.isPressed]: isSelected,
|
||||
})}
|
||||
>
|
||||
<div className={styles.ball} />
|
||||
</button>
|
||||
<label className={styles.label} htmlFor={id}>
|
||||
{label}
|
||||
</label>
|
||||
</Field>
|
||||
);
|
||||
}
|
||||
46
src/input/Toggle.module.css
Normal file
46
src/input/Toggle.module.css
Normal file
@@ -0,0 +1,46 @@
|
||||
.toggle {
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.button {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
transition: background-color 0.2s ease-out 0.1s;
|
||||
width: 44px;
|
||||
height: 24px;
|
||||
border: none;
|
||||
border-radius: 21px;
|
||||
background-color: #6f7882;
|
||||
cursor: pointer;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.ball {
|
||||
transition: left 0.15s ease-out 0.1s;
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 21px;
|
||||
background-color: #15191e;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.label {
|
||||
padding: 10px 8px;
|
||||
line-height: 24px;
|
||||
color: #6f7882;
|
||||
}
|
||||
|
||||
.toggle.on .button {
|
||||
background-color: #0dbd8b;
|
||||
}
|
||||
|
||||
.toggle.on .ball {
|
||||
left: 22px;
|
||||
}
|
||||
|
||||
.toggle.on .label {
|
||||
color: #ffffff;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ export function isLocalRoomId(roomId) {
|
||||
return parts[1] === defaultHomeserverHost;
|
||||
}
|
||||
|
||||
export async function createRoom(client, name) {
|
||||
export async function createRoom(client, name, isPtt = false) {
|
||||
const { room_id, room_alias } = await client.createRoom({
|
||||
visibility: "private",
|
||||
preset: "public_chat",
|
||||
@@ -107,9 +107,12 @@ export async function createRoom(client, name) {
|
||||
},
|
||||
});
|
||||
|
||||
console.log({ isPtt });
|
||||
|
||||
await client.createGroupCall(
|
||||
room_id,
|
||||
GroupCallType.Video,
|
||||
isPtt ? GroupCallType.Voice : GroupCallType.Video,
|
||||
isPtt,
|
||||
GroupCallIntent.Prompt
|
||||
);
|
||||
|
||||
|
||||
61
src/room/AudioPreview.jsx
Normal file
61
src/room/AudioPreview.jsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import React from "react";
|
||||
import styles from "./AudioPreview.module.css";
|
||||
import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import { SelectInput } from "../input/SelectInput";
|
||||
import { Item } from "@react-stately/collections";
|
||||
import { Body } from "../typography/Typography";
|
||||
|
||||
export function AudioPreview({
|
||||
state,
|
||||
roomName,
|
||||
audioInput,
|
||||
audioInputs,
|
||||
setAudioInput,
|
||||
audioOutput,
|
||||
audioOutputs,
|
||||
setAudioOutput,
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<h1>{`${roomName} - Radio Call`}</h1>
|
||||
<div className={styles.preview}>
|
||||
{state === GroupCallState.LocalCallFeedUninitialized && (
|
||||
<Body fontWeight="semiBold" className={styles.microphonePermissions}>
|
||||
Microphone permissions needed to join the call.
|
||||
</Body>
|
||||
)}
|
||||
{state === GroupCallState.InitializingLocalCallFeed && (
|
||||
<Body fontWeight="semiBold" className={styles.microphonePermissions}>
|
||||
Accept microphone permissions to join the call.
|
||||
</Body>
|
||||
)}
|
||||
{state === GroupCallState.LocalCallFeedInitialized && (
|
||||
<>
|
||||
<SelectInput
|
||||
label="Microphone"
|
||||
selectedKey={audioInput}
|
||||
onSelectionChange={setAudioInput}
|
||||
className={styles.inputField}
|
||||
>
|
||||
{audioInputs.map(({ deviceId, label }) => (
|
||||
<Item key={deviceId}>{label}</Item>
|
||||
))}
|
||||
</SelectInput>
|
||||
{audioOutputs.length > 0 && (
|
||||
<SelectInput
|
||||
label="Speaker"
|
||||
selectedKey={audioOutput}
|
||||
onSelectionChange={setAudioOutput}
|
||||
className={styles.inputField}
|
||||
>
|
||||
{audioOutputs.map(({ deviceId, label }) => (
|
||||
<Item key={deviceId}>{label}</Item>
|
||||
))}
|
||||
</SelectInput>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
27
src/room/AudioPreview.module.css
Normal file
27
src/room/AudioPreview.module.css
Normal file
@@ -0,0 +1,27 @@
|
||||
.preview {
|
||||
margin: 20px 0;
|
||||
padding: 24px 20px;
|
||||
border-radius: 8px;
|
||||
width: calc(100% - 40px);
|
||||
max-width: 414px;
|
||||
}
|
||||
|
||||
.inputField {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.inputField:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.microphonePermissions {
|
||||
margin: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
.preview {
|
||||
margin-top: 40px;
|
||||
background-color: #21262c;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { useGroupCall } from "./useGroupCall";
|
||||
import { ErrorView, FullScreenView } from "../FullScreenView";
|
||||
import { LobbyView } from "./LobbyView";
|
||||
import { InCallView } from "./InCallView";
|
||||
import { PTTCallView } from "./PTTCallView";
|
||||
import { CallEndedView } from "./CallEndedView";
|
||||
import { useSentryGroupCallHandler } from "./useSentryGroupCallHandler";
|
||||
import { useLocationNavigation } from "../useLocationNavigation";
|
||||
@@ -47,6 +48,7 @@ export function GroupCallView({
|
||||
localScreenshareFeed,
|
||||
screenshareFeeds,
|
||||
hasLocalParticipant,
|
||||
participants,
|
||||
} = useGroupCall(groupCall);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -72,6 +74,21 @@ export function GroupCallView({
|
||||
if (error) {
|
||||
return <ErrorView error={error} />;
|
||||
} else if (state === GroupCallState.Entered) {
|
||||
if (groupCall.isPtt) {
|
||||
return (
|
||||
<PTTCallView
|
||||
client={client}
|
||||
roomId={roomId}
|
||||
roomName={groupCall.room.name}
|
||||
groupCall={groupCall}
|
||||
participants={participants}
|
||||
userMediaFeeds={userMediaFeeds}
|
||||
onLeave={onLeave}
|
||||
setShowInspector={onChangeShowInspector}
|
||||
showInspector={showInspector}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<InCallView
|
||||
groupCall={groupCall}
|
||||
@@ -93,6 +110,7 @@ export function GroupCallView({
|
||||
roomId={roomId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
} else if (state === GroupCallState.Entering) {
|
||||
return (
|
||||
<FullScreenView>
|
||||
@@ -105,6 +123,7 @@ export function GroupCallView({
|
||||
return (
|
||||
<LobbyView
|
||||
client={client}
|
||||
groupCall={groupCall}
|
||||
hasLocalParticipant={hasLocalParticipant}
|
||||
roomName={groupCall.room.name}
|
||||
state={state}
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import styles from "./LobbyView.module.css";
|
||||
import { Button, CopyButton, MicButton, VideoButton } from "../button";
|
||||
import { Button, CopyButton } from "../button";
|
||||
import { Header, LeftNav, RightNav, RoomHeaderInfo } from "../Header";
|
||||
import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import { useCallFeed } from "../video-grid/useCallFeed";
|
||||
import { useMediaStream } from "../video-grid/useMediaStream";
|
||||
import { getRoomUrl } from "../matrix-utils";
|
||||
import { OverflowMenu } from "./OverflowMenu";
|
||||
import { UserMenuContainer } from "../UserMenuContainer";
|
||||
import { Body, Link } from "../typography/Typography";
|
||||
import { Avatar } from "../Avatar";
|
||||
import { useProfile } from "../profile/useProfile";
|
||||
import useMeasure from "react-use-measure";
|
||||
import { ResizeObserver } from "@juggle/resize-observer";
|
||||
import { useLocationNavigation } from "../useLocationNavigation";
|
||||
import { useMediaHandler } from "../settings/useMediaHandler";
|
||||
import { VideoPreview } from "./VideoPreview";
|
||||
import { AudioPreview } from "./AudioPreview";
|
||||
|
||||
export function LobbyView({
|
||||
client,
|
||||
groupCall,
|
||||
roomName,
|
||||
state,
|
||||
onInitLocalCallFeed,
|
||||
@@ -32,11 +29,14 @@ export function LobbyView({
|
||||
roomId,
|
||||
}) {
|
||||
const { stream } = useCallFeed(localCallFeed);
|
||||
const { audioOutput } = useMediaHandler();
|
||||
const videoRef = useMediaStream(stream, audioOutput, true);
|
||||
const { displayName, avatarUrl } = useProfile(client);
|
||||
const [previewRef, previewBounds] = useMeasure({ polyfill: ResizeObserver });
|
||||
const avatarSize = (previewBounds.height - 66) / 2;
|
||||
const {
|
||||
audioInput,
|
||||
audioInputs,
|
||||
setAudioInput,
|
||||
audioOutput,
|
||||
audioOutputs,
|
||||
setAudioOutput,
|
||||
} = useMediaHandler();
|
||||
|
||||
useEffect(() => {
|
||||
onInitLocalCallFeed();
|
||||
@@ -64,53 +64,31 @@ export function LobbyView({
|
||||
</Header>
|
||||
<div className={styles.joinRoom}>
|
||||
<div className={styles.joinRoomContent}>
|
||||
<div className={styles.preview} ref={previewRef}>
|
||||
<video ref={videoRef} muted playsInline disablePictureInPicture />
|
||||
{state === GroupCallState.LocalCallFeedUninitialized && (
|
||||
<Body fontWeight="semiBold" className={styles.webcamPermissions}>
|
||||
Webcam/microphone permissions needed to join the call.
|
||||
</Body>
|
||||
)}
|
||||
{state === GroupCallState.InitializingLocalCallFeed && (
|
||||
<Body fontWeight="semiBold" className={styles.webcamPermissions}>
|
||||
Accept webcam/microphone permissions to join the call.
|
||||
</Body>
|
||||
)}
|
||||
{state === GroupCallState.LocalCallFeedInitialized && (
|
||||
<>
|
||||
{localVideoMuted && (
|
||||
<div className={styles.avatarContainer}>
|
||||
<Avatar
|
||||
style={{
|
||||
width: avatarSize,
|
||||
height: avatarSize,
|
||||
borderRadius: avatarSize,
|
||||
fontSize: Math.round(avatarSize / 2),
|
||||
}}
|
||||
src={avatarUrl}
|
||||
fallback={displayName.slice(0, 1).toUpperCase()}
|
||||
{groupCall.isPtt ? (
|
||||
<AudioPreview
|
||||
roomName={roomName}
|
||||
state={state}
|
||||
audioInput={audioInput}
|
||||
audioInputs={audioInputs}
|
||||
setAudioInput={setAudioInput}
|
||||
audioOutput={audioOutput}
|
||||
audioOutputs={audioOutputs}
|
||||
setAudioOutput={setAudioOutput}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.previewButtons}>
|
||||
<MicButton
|
||||
muted={microphoneMuted}
|
||||
onPress={toggleMicrophoneMuted}
|
||||
/>
|
||||
<VideoButton
|
||||
muted={localVideoMuted}
|
||||
onPress={toggleLocalVideoMuted}
|
||||
/>
|
||||
<OverflowMenu
|
||||
roomId={roomId}
|
||||
) : (
|
||||
<VideoPreview
|
||||
state={state}
|
||||
client={client}
|
||||
microphoneMuted={microphoneMuted}
|
||||
localVideoMuted={localVideoMuted}
|
||||
toggleLocalVideoMuted={toggleLocalVideoMuted}
|
||||
toggleMicrophoneMuted={toggleMicrophoneMuted}
|
||||
setShowInspector={setShowInspector}
|
||||
showInspector={showInspector}
|
||||
client={client}
|
||||
stream={stream}
|
||||
audioOutput={audioOutput}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<Button
|
||||
ref={joinCallButtonRef}
|
||||
className={styles.copyButton}
|
||||
|
||||
@@ -46,58 +46,6 @@ limitations under the License.
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.preview {
|
||||
position: relative;
|
||||
min-height: 280px;
|
||||
height: 50vh;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
background-color: var(--bgColor3);
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.preview video {
|
||||
width: calc(100% + 1px);
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
background-color: black;
|
||||
/* transform scale doesn't perfectly match width, so make -1.01 border issues */
|
||||
transform: scaleX(-1.01);
|
||||
}
|
||||
|
||||
.avatarContainer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 66px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--bgColor3);
|
||||
}
|
||||
|
||||
.webcamPermissions {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.previewButtons {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 66px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: rgba(23, 25, 28, 0.9);
|
||||
}
|
||||
|
||||
.joinCallButton {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
@@ -118,17 +66,3 @@ limitations under the License.
|
||||
.copyButton:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.previewButtons > * {
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.previewButtons > :last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
.preview {
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
48
src/room/PTTButton.jsx
Normal file
48
src/room/PTTButton.jsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import React from "react";
|
||||
import classNames from "classnames";
|
||||
import styles from "./PTTButton.module.css";
|
||||
import { ReactComponent as MicIcon } from "../icons/Mic.svg";
|
||||
import { Avatar } from "../Avatar";
|
||||
|
||||
export function PTTButton({
|
||||
showTalkOverError,
|
||||
activeSpeakerUserId,
|
||||
activeSpeakerDisplayName,
|
||||
activeSpeakerAvatarUrl,
|
||||
activeSpeakerIsLocalUser,
|
||||
size,
|
||||
startTalking,
|
||||
stopTalking,
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
className={classNames(styles.pttButton, {
|
||||
[styles.talking]: activeSpeakerUserId,
|
||||
[styles.error]: showTalkOverError,
|
||||
})}
|
||||
onMouseDown={startTalking}
|
||||
onMouseUp={stopTalking}
|
||||
>
|
||||
{activeSpeakerIsLocalUser || !activeSpeakerUserId ? (
|
||||
<MicIcon
|
||||
className={styles.micIcon}
|
||||
width={size / 3}
|
||||
height={size / 3}
|
||||
/>
|
||||
) : (
|
||||
<Avatar
|
||||
key={activeSpeakerUserId}
|
||||
style={{
|
||||
width: size - 12,
|
||||
height: size - 12,
|
||||
borderRadius: size - 12,
|
||||
fontSize: Math.round((size - 12) / 2),
|
||||
}}
|
||||
src={activeSpeakerAvatarUrl}
|
||||
fallback={activeSpeakerDisplayName.slice(0, 1).toUpperCase()}
|
||||
className={styles.avatar}
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
25
src/room/PTTButton.module.css
Normal file
25
src/room/PTTButton.module.css
Normal file
@@ -0,0 +1,25 @@
|
||||
.pttButton {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
max-height: 232px;
|
||||
max-width: 232px;
|
||||
border-radius: 116px;
|
||||
color: ##fff;
|
||||
border: 6px solid #0dbd8b;
|
||||
background-color: #21262c;
|
||||
position: relative;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.talking {
|
||||
background-color: #0dbd8b;
|
||||
box-shadow: 0px 0px 0px 17px rgba(13, 189, 139, 0.2),
|
||||
0px 0px 0px 34px rgba(13, 189, 139, 0.2);
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: #ff5b55;
|
||||
border-color: #ff5b55;
|
||||
box-shadow: 0px 0px 0px 17px rgba(255, 91, 85, 0.2),
|
||||
0px 0px 0px 34px rgba(255, 91, 85, 0.2);
|
||||
}
|
||||
164
src/room/PTTCallView.jsx
Normal file
164
src/room/PTTCallView.jsx
Normal file
@@ -0,0 +1,164 @@
|
||||
import React from "react";
|
||||
import { useModalTriggerState } from "../Modal";
|
||||
import { SettingsModal } from "../settings/SettingsModal";
|
||||
import { InviteModal } from "./InviteModal";
|
||||
import { HangupButton, InviteButton, SettingsButton } from "../button";
|
||||
import { Header, LeftNav, RightNav, RoomSetupHeaderInfo } from "../Header";
|
||||
import styles from "./PTTCallView.module.css";
|
||||
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";
|
||||
import { usePTT } from "./usePTT";
|
||||
import { Timer } from "./Timer";
|
||||
import { Toggle } from "../input/Toggle";
|
||||
import { getAvatarUrl } from "../matrix-utils";
|
||||
import { ReactComponent as AudioIcon } from "../icons/Audio.svg";
|
||||
|
||||
export function PTTCallView({
|
||||
client,
|
||||
roomId,
|
||||
roomName,
|
||||
groupCall,
|
||||
participants,
|
||||
userMediaFeeds,
|
||||
onLeave,
|
||||
setShowInspector,
|
||||
showInspector,
|
||||
}) {
|
||||
const { modalState: inviteModalState, modalProps: inviteModalProps } =
|
||||
useModalTriggerState();
|
||||
const { modalState: settingsModalState, modalProps: settingsModalProps } =
|
||||
useModalTriggerState();
|
||||
const [containerRef, bounds] = useMeasure({ polyfill: ResizeObserver });
|
||||
const facepileSize = bounds.width < 800 ? "sm" : "md";
|
||||
const pttButtonSize = 232;
|
||||
const pttBorderWidth = 6;
|
||||
|
||||
const { audioOutput } = useMediaHandler();
|
||||
|
||||
const {
|
||||
pttButtonHeld,
|
||||
isAdmin,
|
||||
talkOverEnabled,
|
||||
setTalkOverEnabled,
|
||||
activeSpeakerUserId,
|
||||
startTalking,
|
||||
stopTalking,
|
||||
} = usePTT(client, groupCall, userMediaFeeds);
|
||||
|
||||
const activeSpeakerIsLocalUser =
|
||||
activeSpeakerUserId && client.getUserId() === activeSpeakerUserId;
|
||||
const showTalkOverError =
|
||||
pttButtonHeld && !activeSpeakerIsLocalUser && !talkOverEnabled;
|
||||
const activeSpeakerUser = activeSpeakerUserId
|
||||
? client.getUser(activeSpeakerUserId)
|
||||
: null;
|
||||
const activeSpeakerAvatarUrl = activeSpeakerUser
|
||||
? getAvatarUrl(
|
||||
client,
|
||||
activeSpeakerUser.avatarUrl,
|
||||
pttButtonSize - pttBorderWidth * 2
|
||||
)
|
||||
: null;
|
||||
const activeSpeakerDisplayName = activeSpeakerUser
|
||||
? activeSpeakerUser.displayName
|
||||
: "";
|
||||
|
||||
return (
|
||||
<div className={styles.pttCallView} ref={containerRef}>
|
||||
<Header className={styles.header}>
|
||||
<LeftNav>
|
||||
<RoomSetupHeaderInfo roomName={roomName} onPress={onLeave} />
|
||||
</LeftNav>
|
||||
<RightNav />
|
||||
</Header>
|
||||
<div className={styles.center}>
|
||||
<div className={styles.participants}>
|
||||
<p>{`${participants.length} ${
|
||||
participants.length > 1 ? "people" : "person"
|
||||
} connected`}</p>
|
||||
<Facepile
|
||||
size={facepileSize}
|
||||
max={8}
|
||||
className={styles.facepile}
|
||||
client={client}
|
||||
participants={participants}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.footer}>
|
||||
<SettingsButton onPress={() => settingsModalState.open()} />
|
||||
<HangupButton onPress={onLeave} />
|
||||
<InviteButton onPress={() => inviteModalState.open()} />
|
||||
</div>
|
||||
|
||||
<div className={styles.pttButtonContainer}>
|
||||
{activeSpeakerUserId ? (
|
||||
<div className={styles.talkingInfo}>
|
||||
<h2>
|
||||
{!activeSpeakerIsLocalUser && (
|
||||
<AudioIcon className={styles.speakerIcon} />
|
||||
)}
|
||||
{activeSpeakerIsLocalUser
|
||||
? "Talking..."
|
||||
: `${activeSpeakerDisplayName} is talking...`}
|
||||
</h2>
|
||||
<Timer value={activeSpeakerUserId} />
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.talkingInfo} />
|
||||
)}
|
||||
<PTTButton
|
||||
showTalkOverError={showTalkOverError}
|
||||
activeSpeakerUserId={activeSpeakerUserId}
|
||||
activeSpeakerDisplayName={activeSpeakerDisplayName}
|
||||
activeSpeakerAvatarUrl={activeSpeakerAvatarUrl}
|
||||
activeSpeakerIsLocalUser={activeSpeakerIsLocalUser}
|
||||
size={pttButtonSize}
|
||||
startTalking={startTalking}
|
||||
stopTalking={stopTalking}
|
||||
/>
|
||||
<p className={styles.actionTip}>
|
||||
{showTalkOverError
|
||||
? "You can't talk at the same time"
|
||||
: pttButtonHeld
|
||||
? "Release spacebar key to stop"
|
||||
: talkOverEnabled &&
|
||||
activeSpeakerUserId &&
|
||||
!activeSpeakerIsLocalUser
|
||||
? `Press and hold spacebar to talk over ${activeSpeakerDisplayName}`
|
||||
: "Press and hold spacebar to talk"}
|
||||
</p>
|
||||
{userMediaFeeds.map((callFeed) => (
|
||||
<PTTFeed
|
||||
key={callFeed.userId}
|
||||
callFeed={callFeed}
|
||||
audioOutputDevice={audioOutput}
|
||||
/>
|
||||
))}
|
||||
{isAdmin && (
|
||||
<Toggle
|
||||
isSelected={talkOverEnabled}
|
||||
onChange={setTalkOverEnabled}
|
||||
label="Talk over speaker"
|
||||
id="talkOverEnabled"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{settingsModalState.isOpen && (
|
||||
<SettingsModal
|
||||
{...settingsModalProps}
|
||||
setShowInspector={setShowInspector}
|
||||
showInspector={showInspector}
|
||||
/>
|
||||
)}
|
||||
{inviteModalState.isOpen && (
|
||||
<InviteModal roomId={roomId} {...inviteModalProps} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
106
src/room/PTTCallView.module.css
Normal file
106
src/room/PTTCallView.module.css
Normal file
@@ -0,0 +1,106 @@
|
||||
.pttCallView {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
min-height: 100%;
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.center {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.participants {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.participants > p {
|
||||
color: #a9b2bc;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.facepile {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.talkingInfo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
height: 88px;
|
||||
}
|
||||
|
||||
.speakerIcon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.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;
|
||||
height: 64px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.footer > * {
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.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: 0;
|
||||
margin-bottom: 0;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.footer {
|
||||
flex: auto;
|
||||
order: 4;
|
||||
}
|
||||
}
|
||||
10
src/room/PTTFeed.jsx
Normal file
10
src/room/PTTFeed.jsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import React from "react";
|
||||
import { useCallFeed } from "../video-grid/useCallFeed";
|
||||
import { useMediaStream } from "../video-grid/useMediaStream";
|
||||
import styles from "./PTTFeed.module.css";
|
||||
|
||||
export function PTTFeed({ callFeed, audioOutputDevice }) {
|
||||
const { isLocal, stream } = useCallFeed(callFeed);
|
||||
const mediaRef = useMediaStream(stream, audioOutputDevice, isLocal);
|
||||
return <audio ref={mediaRef} className={styles.audioFeed} playsInline />;
|
||||
}
|
||||
3
src/room/PTTFeed.module.css
Normal file
3
src/room/PTTFeed.module.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.audioFeed {
|
||||
display: none;
|
||||
}
|
||||
37
src/room/Timer.jsx
Normal file
37
src/room/Timer.jsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
function leftPad(value) {
|
||||
return value < 10 ? "0" + value : value;
|
||||
}
|
||||
|
||||
function formatTime(msElapsed) {
|
||||
const secondsElapsed = msElapsed / 1000;
|
||||
const hours = Math.floor(secondsElapsed / 3600);
|
||||
const minutes = Math.floor(secondsElapsed / 60) - hours * 60;
|
||||
const seconds = Math.floor(secondsElapsed - hours * 3600 - minutes * 60);
|
||||
return `${leftPad(hours)}:${leftPad(minutes)}:${leftPad(seconds)}`;
|
||||
}
|
||||
|
||||
export function Timer({ value }) {
|
||||
const [timestamp, setTimestamp] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
const startTimeMs = performance.now();
|
||||
|
||||
let animationFrame;
|
||||
|
||||
function onUpdate(curTimeMs) {
|
||||
const msElapsed = curTimeMs - startTimeMs;
|
||||
setTimestamp(formatTime(msElapsed));
|
||||
animationFrame = requestAnimationFrame(onUpdate);
|
||||
}
|
||||
|
||||
onUpdate(startTimeMs);
|
||||
|
||||
return () => {
|
||||
cancelAnimationFrame(animationFrame);
|
||||
};
|
||||
}, [value]);
|
||||
|
||||
return <p>{timestamp}</p>;
|
||||
}
|
||||
80
src/room/VideoPreview.jsx
Normal file
80
src/room/VideoPreview.jsx
Normal file
@@ -0,0 +1,80 @@
|
||||
import React from "react";
|
||||
import { MicButton, VideoButton } from "../button";
|
||||
import { useMediaStream } from "../video-grid/useMediaStream";
|
||||
import { OverflowMenu } from "./OverflowMenu";
|
||||
import { Avatar } from "../Avatar";
|
||||
import { useProfile } from "../profile/useProfile";
|
||||
import useMeasure from "react-use-measure";
|
||||
import { ResizeObserver } from "@juggle/resize-observer";
|
||||
import { GroupCallState } from "matrix-js-sdk/src/webrtc/groupCall";
|
||||
import styles from "./VideoPreview.module.css";
|
||||
import { Body } from "../typography/Typography";
|
||||
|
||||
export function VideoPreview({
|
||||
client,
|
||||
state,
|
||||
roomId,
|
||||
microphoneMuted,
|
||||
localVideoMuted,
|
||||
toggleLocalVideoMuted,
|
||||
toggleMicrophoneMuted,
|
||||
setShowInspector,
|
||||
showInspector,
|
||||
audioOutput,
|
||||
stream,
|
||||
}) {
|
||||
const videoRef = useMediaStream(stream, audioOutput, true);
|
||||
const { displayName, avatarUrl } = useProfile(client);
|
||||
const [previewRef, previewBounds] = useMeasure({ polyfill: ResizeObserver });
|
||||
const avatarSize = (previewBounds.height - 66) / 2;
|
||||
|
||||
return (
|
||||
<div className={styles.preview} ref={previewRef}>
|
||||
<video ref={videoRef} muted playsInline disablePictureInPicture />
|
||||
{state === GroupCallState.LocalCallFeedUninitialized && (
|
||||
<Body fontWeight="semiBold" className={styles.webcamPermissions}>
|
||||
Webcam/microphone permissions needed to join the call.
|
||||
</Body>
|
||||
)}
|
||||
{state === GroupCallState.InitializingLocalCallFeed && (
|
||||
<Body fontWeight="semiBold" className={styles.webcamPermissions}>
|
||||
Accept webcam/microphone permissions to join the call.
|
||||
</Body>
|
||||
)}
|
||||
{state === GroupCallState.LocalCallFeedInitialized && (
|
||||
<>
|
||||
{localVideoMuted && (
|
||||
<div className={styles.avatarContainer}>
|
||||
<Avatar
|
||||
style={{
|
||||
width: avatarSize,
|
||||
height: avatarSize,
|
||||
borderRadius: avatarSize,
|
||||
fontSize: Math.round(avatarSize / 2),
|
||||
}}
|
||||
src={avatarUrl}
|
||||
fallback={displayName.slice(0, 1).toUpperCase()}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.previewButtons}>
|
||||
<MicButton
|
||||
muted={microphoneMuted}
|
||||
onPress={toggleMicrophoneMuted}
|
||||
/>
|
||||
<VideoButton
|
||||
muted={localVideoMuted}
|
||||
onPress={toggleLocalVideoMuted}
|
||||
/>
|
||||
<OverflowMenu
|
||||
roomId={roomId}
|
||||
setShowInspector={setShowInspector}
|
||||
showInspector={showInspector}
|
||||
client={client}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
65
src/room/VideoPreview.module.css
Normal file
65
src/room/VideoPreview.module.css
Normal file
@@ -0,0 +1,65 @@
|
||||
.preview {
|
||||
position: relative;
|
||||
min-height: 280px;
|
||||
height: 50vh;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
background-color: var(--bgColor3);
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.preview video {
|
||||
width: calc(100% + 1px);
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
background-color: black;
|
||||
/* transform scale doesn't perfectly match width, so make -1.01 border issues */
|
||||
transform: scaleX(-1.01);
|
||||
}
|
||||
|
||||
.avatarContainer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 66px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: var(--bgColor3);
|
||||
}
|
||||
|
||||
.webcamPermissions {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.previewButtons {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 66px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: rgba(23, 25, 28, 0.9);
|
||||
}
|
||||
|
||||
.previewButtons > * {
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.previewButtons > :last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
.preview {
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
121
src/room/usePTT.js
Normal file
121
src/room/usePTT.js
Normal file
@@ -0,0 +1,121 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
export function usePTT(client, groupCall, userMediaFeeds) {
|
||||
const [
|
||||
{ pttButtonHeld, isAdmin, talkOverEnabled, activeSpeakerUserId },
|
||||
setState,
|
||||
] = useState(() => {
|
||||
const roomMember = groupCall.room.getMember(client.getUserId());
|
||||
|
||||
const activeSpeakerFeed = userMediaFeeds.find((f) => !f.isAudioMuted());
|
||||
|
||||
return {
|
||||
isAdmin: roomMember.powerLevel >= 100,
|
||||
talkOverEnabled: false,
|
||||
pttButtonHeld: false,
|
||||
activeSpeakerUserId: activeSpeakerFeed ? activeSpeakerFeed.userId : null,
|
||||
};
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
function onMuteStateChanged(...args) {
|
||||
const activeSpeakerFeed = userMediaFeeds.find((f) => !f.isAudioMuted());
|
||||
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
activeSpeakerUserId: activeSpeakerFeed
|
||||
? activeSpeakerFeed.userId
|
||||
: null,
|
||||
}));
|
||||
}
|
||||
|
||||
for (const callFeed of userMediaFeeds) {
|
||||
callFeed.addListener("mute_state_changed", onMuteStateChanged);
|
||||
}
|
||||
|
||||
const activeSpeakerFeed = userMediaFeeds.find((f) => !f.isAudioMuted());
|
||||
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
activeSpeakerUserId: activeSpeakerFeed ? activeSpeakerFeed.userId : null,
|
||||
}));
|
||||
|
||||
return () => {
|
||||
for (const callFeed of userMediaFeeds) {
|
||||
callFeed.removeListener("mute_state_changed", onMuteStateChanged);
|
||||
}
|
||||
};
|
||||
}, [userMediaFeeds]);
|
||||
|
||||
const startTalking = useCallback(() => {
|
||||
if (!activeSpeakerUserId || isAdmin || talkOverEnabled) {
|
||||
if (groupCall.isMicrophoneMuted()) {
|
||||
groupCall.setMicrophoneMuted(false);
|
||||
}
|
||||
|
||||
setState((prevState) => ({ ...prevState, pttButtonHeld: true }));
|
||||
}
|
||||
}, []);
|
||||
|
||||
const stopTalking = useCallback(() => {
|
||||
if (!groupCall.isMicrophoneMuted()) {
|
||||
groupCall.setMicrophoneMuted(true);
|
||||
}
|
||||
|
||||
setState((prevState) => ({ ...prevState, pttButtonHeld: false }));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
function onKeyDown(event) {
|
||||
if (event.code === "Space") {
|
||||
event.preventDefault();
|
||||
|
||||
startTalking();
|
||||
}
|
||||
}
|
||||
|
||||
function onKeyUp(event) {
|
||||
if (event.code === "Space") {
|
||||
event.preventDefault();
|
||||
|
||||
stopTalking();
|
||||
}
|
||||
}
|
||||
|
||||
function onBlur() {
|
||||
// TODO: We will need to disable this for a global PTT hotkey to work
|
||||
if (!groupCall.isMicrophoneMuted()) {
|
||||
groupCall.setMicrophoneMuted(true);
|
||||
}
|
||||
|
||||
setState((prevState) => ({ ...prevState, pttButtonHeld: false }));
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", onKeyDown);
|
||||
window.addEventListener("keyup", onKeyUp);
|
||||
window.addEventListener("blur", onBlur);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("keydown", onKeyDown);
|
||||
window.removeEventListener("keyup", onKeyUp);
|
||||
window.removeEventListener("blur", onBlur);
|
||||
};
|
||||
}, [activeSpeakerUserId, isAdmin, talkOverEnabled]);
|
||||
|
||||
const setTalkOverEnabled = useCallback((talkOverEnabled) => {
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
talkOverEnabled,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
return {
|
||||
pttButtonHeld,
|
||||
isAdmin,
|
||||
talkOverEnabled,
|
||||
setTalkOverEnabled,
|
||||
activeSpeakerUserId,
|
||||
startTalking,
|
||||
stopTalking,
|
||||
};
|
||||
}
|
||||
6
src/useShouldShowPtt.js
Normal file
6
src/useShouldShowPtt.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
export function useShouldShowPtt() {
|
||||
const { hash } = useLocation();
|
||||
return hash.startsWith("#ptt");
|
||||
}
|
||||
@@ -4,4 +4,3 @@
|
||||
flex: 1;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
.videoMutedOverlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #21262C;
|
||||
background-color: #21262c;
|
||||
}
|
||||
|
||||
.presenterLabel {
|
||||
@@ -93,7 +93,7 @@
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background-color: #17191C;
|
||||
background-color: #17191c;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
@@ -24,6 +24,9 @@ export default defineConfig(({ mode }) => {
|
||||
const env = loadEnv(mode, process.cwd());
|
||||
|
||||
return {
|
||||
build: {
|
||||
sourcemap: true,
|
||||
},
|
||||
plugins: [
|
||||
svgrPlugin(),
|
||||
htmlTemplate({
|
||||
|
||||
533
yarn.lock
533
yarn.lock
@@ -1067,6 +1067,14 @@
|
||||
pirates "^4.0.0"
|
||||
source-map-support "^0.5.16"
|
||||
|
||||
"@babel/runtime-corejs3@^7.10.2":
|
||||
version "7.17.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.17.9.tgz#3d02d0161f0fbf3ada8e88159375af97690f4055"
|
||||
integrity sha512-WxYHHUWF2uZ7Hp1K+D1xQgbgkGUfA+5UPOegEXGt2Y5SMog/rYCVaifLZDbw8UkNXozEqqrZTy6bglL7xTaCOw==
|
||||
dependencies:
|
||||
core-js-pure "^3.20.2"
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
|
||||
@@ -1081,6 +1089,13 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.16.3":
|
||||
version "7.17.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
|
||||
integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/template@^7.12.7", "@babel/template@^7.16.7":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155"
|
||||
@@ -1244,6 +1259,21 @@
|
||||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
|
||||
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
|
||||
|
||||
"@eslint/eslintrc@^1.2.2":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.2.tgz#4989b9e8c0216747ee7cca314ae73791bb281aae"
|
||||
integrity sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.3.2"
|
||||
espree "^9.3.1"
|
||||
globals "^13.9.0"
|
||||
ignore "^5.2.0"
|
||||
import-fresh "^3.2.1"
|
||||
js-yaml "^4.1.0"
|
||||
minimatch "^3.0.4"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@formatjs/ecma402-abstract@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.0.tgz#7e91e6cc7cfebdc07171e00a3288719705e0108c"
|
||||
@@ -1288,6 +1318,20 @@
|
||||
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210"
|
||||
integrity sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==
|
||||
|
||||
"@humanwhocodes/config-array@^0.9.2":
|
||||
version "0.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7"
|
||||
integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==
|
||||
dependencies:
|
||||
"@humanwhocodes/object-schema" "^1.2.1"
|
||||
debug "^4.1.1"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
"@humanwhocodes/object-schema@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
||||
|
||||
"@internationalized/date@3.0.0-alpha.1":
|
||||
version "3.0.0-alpha.1"
|
||||
resolved "https://registry.yarnpkg.com/@internationalized/date/-/date-3.0.0-alpha.1.tgz#987a86a98b837f275bce084ef502421bc5cdb5f7"
|
||||
@@ -3309,6 +3353,11 @@ acorn-import-assertions@^1.7.6:
|
||||
resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9"
|
||||
integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==
|
||||
|
||||
acorn-jsx@^5.3.1:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
||||
|
||||
acorn@^6.4.1:
|
||||
version "6.4.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
|
||||
@@ -3319,6 +3368,11 @@ acorn@^8.4.1:
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
|
||||
integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
|
||||
|
||||
acorn@^8.7.0:
|
||||
version "8.7.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30"
|
||||
integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==
|
||||
|
||||
address@^1.0.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
|
||||
@@ -3365,7 +3419,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2:
|
||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
|
||||
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
|
||||
|
||||
ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
|
||||
ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
|
||||
@@ -3467,6 +3521,19 @@ are-we-there-yet@^2.0.0:
|
||||
delegates "^1.0.0"
|
||||
readable-stream "^3.6.0"
|
||||
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
aria-query@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b"
|
||||
integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.10.2"
|
||||
"@babel/runtime-corejs3" "^7.10.2"
|
||||
|
||||
arr-diff@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
|
||||
@@ -3492,7 +3559,7 @@ array-flatten@1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
||||
integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
|
||||
|
||||
array-includes@^3.0.3:
|
||||
array-includes@^3.0.3, array-includes@^3.1.4:
|
||||
version "3.1.4"
|
||||
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9"
|
||||
integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==
|
||||
@@ -3543,6 +3610,16 @@ array.prototype.flatmap@^1.2.1:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.0"
|
||||
|
||||
array.prototype.flatmap@^1.2.5:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f"
|
||||
integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.2"
|
||||
es-shim-unscopables "^1.0.0"
|
||||
|
||||
array.prototype.map@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.4.tgz#0d97b640cfdd036c1b41cfe706a5e699aa0711f2"
|
||||
@@ -3599,6 +3676,11 @@ assign-symbols@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
|
||||
integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
|
||||
|
||||
ast-types-flow@^0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
|
||||
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
|
||||
|
||||
ast-types@^0.14.2:
|
||||
version "0.14.2"
|
||||
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd"
|
||||
@@ -3649,6 +3731,16 @@ aws4@^1.8.0:
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
|
||||
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
|
||||
|
||||
axe-core@^4.3.5:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.1.tgz#7dbdc25989298f9ad006645cd396782443757413"
|
||||
integrity sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==
|
||||
|
||||
axobject-query@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
|
||||
integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==
|
||||
|
||||
babel-loader@^8.0.0, babel-loader@^8.2.3:
|
||||
version "8.2.3"
|
||||
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d"
|
||||
@@ -4245,7 +4337,7 @@ chalk@^2.0.0, chalk@^2.4.1:
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
chalk@^4.1.0:
|
||||
chalk@^4.0.0, chalk@^4.1.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||
@@ -4604,6 +4696,11 @@ core-js-compat@^3.20.0, core-js-compat@^3.20.2, core-js-compat@^3.8.1:
|
||||
browserslist "^4.19.1"
|
||||
semver "7.0.0"
|
||||
|
||||
core-js-pure@^3.20.2:
|
||||
version "3.22.4"
|
||||
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.4.tgz#a992210f4cad8b32786b8654563776c56b0e0d0a"
|
||||
integrity sha512-4iF+QZkpzIz0prAFuepmxwJ2h5t4agvE8WPYqs2mjLJMNNwJOnpch76w2Q7bUfCPEv/V7wpvOfog0w273M+ZSw==
|
||||
|
||||
core-js-pure@^3.8.1, core-js-pure@^3.8.2:
|
||||
version "3.20.3"
|
||||
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.20.3.tgz#6cc4f36da06c61d95254efc54024fe4797fd5d02"
|
||||
@@ -4709,7 +4806,7 @@ cross-fetch@^3.0.4:
|
||||
dependencies:
|
||||
node-fetch "2.6.1"
|
||||
|
||||
cross-spawn@^7.0.0:
|
||||
cross-spawn@^7.0.0, cross-spawn@^7.0.2:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||
@@ -5339,6 +5436,11 @@ dagre@^0.8.5:
|
||||
graphlib "^2.1.8"
|
||||
lodash "^4.17.15"
|
||||
|
||||
damerau-levenshtein@^1.0.7:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
|
||||
integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
||||
@@ -5372,6 +5474,13 @@ debug@^4.1.0, debug@^4.1.1:
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debug@^4.3.2:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
decamelize@^1.1.2:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||
@@ -5387,6 +5496,11 @@ dedent@^0.7.0:
|
||||
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
|
||||
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
|
||||
|
||||
deep-is@^0.1.3:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||
|
||||
deep-object-diff@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.0.tgz#d6fabf476c2ed1751fc94d5ca693d2ed8c18bc5a"
|
||||
@@ -5513,6 +5627,13 @@ dir-glob@^3.0.1:
|
||||
dependencies:
|
||||
path-type "^4.0.0"
|
||||
|
||||
doctrine@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
|
||||
integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
doctrine@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
|
||||
@@ -5661,6 +5782,11 @@ emoji-regex@^8.0.0:
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||
|
||||
emoji-regex@^9.2.2:
|
||||
version "9.2.2"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
|
||||
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
|
||||
|
||||
emojis-list@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
|
||||
@@ -5765,6 +5891,32 @@ es-abstract@^1.19.0, es-abstract@^1.19.1:
|
||||
string.prototype.trimstart "^1.0.4"
|
||||
unbox-primitive "^1.0.1"
|
||||
|
||||
es-abstract@^1.19.2:
|
||||
version "1.19.5"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.5.tgz#a2cb01eb87f724e815b278b0dd0d00f36ca9a7f1"
|
||||
integrity sha512-Aa2G2+Rd3b6kxEUKTF4TaW67czBLyAv3z7VOhYRU50YBx+bbsYZ9xQP4lMNazePuFlybXI0V4MruPos7qUo5fA==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
es-to-primitive "^1.2.1"
|
||||
function-bind "^1.1.1"
|
||||
get-intrinsic "^1.1.1"
|
||||
get-symbol-description "^1.0.0"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.3"
|
||||
internal-slot "^1.0.3"
|
||||
is-callable "^1.2.4"
|
||||
is-negative-zero "^2.0.2"
|
||||
is-regex "^1.1.4"
|
||||
is-shared-array-buffer "^1.0.2"
|
||||
is-string "^1.0.7"
|
||||
is-weakref "^1.0.2"
|
||||
object-inspect "^1.12.0"
|
||||
object-keys "^1.1.1"
|
||||
object.assign "^4.1.2"
|
||||
string.prototype.trimend "^1.0.4"
|
||||
string.prototype.trimstart "^1.0.4"
|
||||
unbox-primitive "^1.0.1"
|
||||
|
||||
es-array-method-boxes-properly@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e"
|
||||
@@ -5789,6 +5941,13 @@ es-module-lexer@^0.9.0, es-module-lexer@^0.9.3:
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19"
|
||||
integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==
|
||||
|
||||
es-shim-unscopables@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241"
|
||||
integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
es-to-primitive@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
||||
@@ -6039,6 +6198,64 @@ escape-string-regexp@^1.0.5:
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
escape-string-regexp@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
eslint-config-prettier@^8.5.0:
|
||||
version "8.5.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1"
|
||||
integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==
|
||||
|
||||
eslint-plugin-jsx-a11y@^6.5.1:
|
||||
version "6.5.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz#cdbf2df901040ca140b6ec14715c988889c2a6d8"
|
||||
integrity sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.16.3"
|
||||
aria-query "^4.2.2"
|
||||
array-includes "^3.1.4"
|
||||
ast-types-flow "^0.0.7"
|
||||
axe-core "^4.3.5"
|
||||
axobject-query "^2.2.0"
|
||||
damerau-levenshtein "^1.0.7"
|
||||
emoji-regex "^9.2.2"
|
||||
has "^1.0.3"
|
||||
jsx-ast-utils "^3.2.1"
|
||||
language-tags "^1.0.5"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
eslint-plugin-matrix-org@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-matrix-org/-/eslint-plugin-matrix-org-0.4.0.tgz#de2d2db1cd471d637728133ce9a2b921690e5cd1"
|
||||
integrity sha512-yVkNwtc33qtrQB4PPzpU+PUdFzdkENPan3JF4zhtAQJRUYXyvKEXnYSrXLUWYRXoYFxs9LbyI2CnhJL/RnHJaQ==
|
||||
|
||||
eslint-plugin-react-hooks@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz#5f762dfedf8b2cf431c689f533c9d3fa5dcf25ad"
|
||||
integrity sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==
|
||||
|
||||
eslint-plugin-react@^7.29.4:
|
||||
version "7.29.4"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz#4717de5227f55f3801a5fd51a16a4fa22b5914d2"
|
||||
integrity sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==
|
||||
dependencies:
|
||||
array-includes "^3.1.4"
|
||||
array.prototype.flatmap "^1.2.5"
|
||||
doctrine "^2.1.0"
|
||||
estraverse "^5.3.0"
|
||||
jsx-ast-utils "^2.4.1 || ^3.0.0"
|
||||
minimatch "^3.1.2"
|
||||
object.entries "^1.1.5"
|
||||
object.fromentries "^2.0.5"
|
||||
object.hasown "^1.1.0"
|
||||
object.values "^1.1.5"
|
||||
prop-types "^15.8.1"
|
||||
resolve "^2.0.0-next.3"
|
||||
semver "^6.3.0"
|
||||
string.prototype.matchall "^4.0.6"
|
||||
|
||||
eslint-scope@5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||
@@ -6055,6 +6272,88 @@ eslint-scope@^4.0.3:
|
||||
esrecurse "^4.1.0"
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-scope@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642"
|
||||
integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==
|
||||
dependencies:
|
||||
esrecurse "^4.3.0"
|
||||
estraverse "^5.2.0"
|
||||
|
||||
eslint-utils@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
|
||||
integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
|
||||
eslint-visitor-keys@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
|
||||
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
|
||||
|
||||
eslint-visitor-keys@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
||||
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
||||
|
||||
eslint@^8.14.0:
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.14.0.tgz#62741f159d9eb4a79695b28ec4989fcdec623239"
|
||||
integrity sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw==
|
||||
dependencies:
|
||||
"@eslint/eslintrc" "^1.2.2"
|
||||
"@humanwhocodes/config-array" "^0.9.2"
|
||||
ajv "^6.10.0"
|
||||
chalk "^4.0.0"
|
||||
cross-spawn "^7.0.2"
|
||||
debug "^4.3.2"
|
||||
doctrine "^3.0.0"
|
||||
escape-string-regexp "^4.0.0"
|
||||
eslint-scope "^7.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
espree "^9.3.1"
|
||||
esquery "^1.4.0"
|
||||
esutils "^2.0.2"
|
||||
fast-deep-equal "^3.1.3"
|
||||
file-entry-cache "^6.0.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
glob-parent "^6.0.1"
|
||||
globals "^13.6.0"
|
||||
ignore "^5.2.0"
|
||||
import-fresh "^3.0.0"
|
||||
imurmurhash "^0.1.4"
|
||||
is-glob "^4.0.0"
|
||||
js-yaml "^4.1.0"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.4.1"
|
||||
lodash.merge "^4.6.2"
|
||||
minimatch "^3.0.4"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.9.1"
|
||||
regexpp "^3.2.0"
|
||||
strip-ansi "^6.0.1"
|
||||
strip-json-comments "^3.1.0"
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
espree@^9.3.1:
|
||||
version "9.3.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd"
|
||||
integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==
|
||||
dependencies:
|
||||
acorn "^8.7.0"
|
||||
acorn-jsx "^5.3.1"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
esquery@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5"
|
||||
integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==
|
||||
dependencies:
|
||||
estraverse "^5.1.0"
|
||||
|
||||
esrecurse@^4.1.0, esrecurse@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
|
||||
@@ -6067,7 +6366,7 @@ estraverse@^4.1.1:
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
|
||||
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
|
||||
|
||||
estraverse@^5.2.0:
|
||||
estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
||||
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
|
||||
@@ -6240,6 +6539,11 @@ fast-json-stable-stringify@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||
|
||||
fast-levenshtein@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
|
||||
fast-memoize@^2.5.1:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz"
|
||||
@@ -6289,6 +6593,13 @@ figgy-pudding@^3.5.1:
|
||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
|
||||
integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==
|
||||
|
||||
file-entry-cache@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
|
||||
integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
|
||||
dependencies:
|
||||
flat-cache "^3.0.4"
|
||||
|
||||
file-loader@^6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d"
|
||||
@@ -6603,6 +6914,11 @@ function.prototype.name@^1.1.0:
|
||||
es-abstract "^1.19.0"
|
||||
functions-have-names "^1.2.2"
|
||||
|
||||
functional-red-black-tree@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
||||
|
||||
functions-have-names@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21"
|
||||
@@ -6687,6 +7003,13 @@ glob-parent@^5.1.2, glob-parent@~5.1.2:
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob-parent@^6.0.1:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
|
||||
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
|
||||
dependencies:
|
||||
is-glob "^4.0.3"
|
||||
|
||||
glob-promise@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20"
|
||||
@@ -6736,6 +7059,13 @@ globals@^11.1.0:
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
||||
|
||||
globals@^13.6.0, globals@^13.9.0:
|
||||
version "13.13.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b"
|
||||
integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==
|
||||
dependencies:
|
||||
type-fest "^0.20.2"
|
||||
|
||||
globalthis@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b"
|
||||
@@ -6833,6 +7163,11 @@ has-symbols@^1.0.1, has-symbols@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423"
|
||||
integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==
|
||||
|
||||
has-symbols@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
||||
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
||||
|
||||
has-tostringtag@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25"
|
||||
@@ -7149,7 +7484,7 @@ immutable@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23"
|
||||
integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==
|
||||
|
||||
import-fresh@^3.1.0, import-fresh@^3.2.1:
|
||||
import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
|
||||
@@ -7347,6 +7682,13 @@ is-callable@^1.1.4, is-callable@^1.2.4:
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
|
||||
integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
|
||||
|
||||
is-core-module@^2.2.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69"
|
||||
integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-core-module@^2.8.0, is-core-module@^2.8.1:
|
||||
version "2.8.1"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211"
|
||||
@@ -7442,7 +7784,7 @@ is-glob@^3.0.0, is-glob@^3.1.0:
|
||||
dependencies:
|
||||
is-extglob "^2.1.0"
|
||||
|
||||
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
|
||||
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||
@@ -7459,7 +7801,7 @@ is-map@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127"
|
||||
integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==
|
||||
|
||||
is-negative-zero@^2.0.1:
|
||||
is-negative-zero@^2.0.1, is-negative-zero@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
|
||||
integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
|
||||
@@ -7513,6 +7855,13 @@ is-shared-array-buffer@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
|
||||
integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==
|
||||
|
||||
is-shared-array-buffer@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
|
||||
integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
|
||||
is-string@^1.0.5, is-string@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
|
||||
@@ -7537,7 +7886,7 @@ is-utf8@^0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
|
||||
integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
|
||||
|
||||
is-weakref@^1.0.1:
|
||||
is-weakref@^1.0.1, is-weakref@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
|
||||
integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
|
||||
@@ -7676,6 +8025,13 @@ js-string-escape@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
@@ -7711,6 +8067,11 @@ json-schema@0.2.3:
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
|
||||
json-stable-stringify-without-jsonify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
|
||||
|
||||
json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
@@ -7756,6 +8117,14 @@ jsprim@^1.2.2:
|
||||
json-schema "0.2.3"
|
||||
verror "1.10.0"
|
||||
|
||||
"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.0.tgz#e624f259143b9062c92b6413ff92a164c80d3ccb"
|
||||
integrity sha512-XzO9luP6L0xkxwhIJMTJQpZo/eeN60K08jHdexfD569AGxeNug6UketeHXEhROoM8aR7EcUoOQmIhcJQjcuq8Q==
|
||||
dependencies:
|
||||
array-includes "^3.1.4"
|
||||
object.assign "^4.1.2"
|
||||
|
||||
junk@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1"
|
||||
@@ -7807,6 +8176,18 @@ klona@^2.0.4:
|
||||
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc"
|
||||
integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==
|
||||
|
||||
language-subtag-registry@~0.3.2:
|
||||
version "0.3.21"
|
||||
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a"
|
||||
integrity sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==
|
||||
|
||||
language-tags@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a"
|
||||
integrity sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=
|
||||
dependencies:
|
||||
language-subtag-registry "~0.3.2"
|
||||
|
||||
lazy-universal-dotenv@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38"
|
||||
@@ -7818,6 +8199,14 @@ lazy-universal-dotenv@^3.0.1:
|
||||
dotenv "^8.0.0"
|
||||
dotenv-expand "^5.1.0"
|
||||
|
||||
levn@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
|
||||
integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
|
||||
dependencies:
|
||||
prelude-ls "^1.2.1"
|
||||
type-check "~0.4.0"
|
||||
|
||||
lines-and-columns@^1.1.6:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||
@@ -7906,6 +8295,11 @@ lodash.flow@^3.3.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a"
|
||||
integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=
|
||||
|
||||
lodash.merge@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash.uniq@4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
@@ -8013,8 +8407,8 @@ markdown-to-jsx@^7.1.3:
|
||||
integrity sha512-1wrIGZYwIG2gR3yfRmbr4FlQmhaAKoKTpRo4wur4fp9p0njU1Hi7vR8fj0AUKKIcPduiJmPprzmCB5B/GvlC7g==
|
||||
|
||||
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#robertlong/group-call":
|
||||
version "13.0.0"
|
||||
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/ba57736bf6d6d99342c64cca5eb6156ee7b9e178"
|
||||
version "15.1.0"
|
||||
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/8d9cd0fcb37188f63a938f4dd16e1f4e967cf1b6"
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
another-json "^0.2.0"
|
||||
@@ -8266,6 +8660,13 @@ minimatch@^3.0.2, minimatch@^3.0.4:
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimatch@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz"
|
||||
@@ -8407,6 +8808,11 @@ nanomatch@^1.2.9:
|
||||
snapdragon "^0.8.1"
|
||||
to-regex "^3.0.1"
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||
|
||||
negotiator@0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
||||
@@ -8556,7 +8962,7 @@ object-copy@^0.1.0:
|
||||
define-property "^0.2.5"
|
||||
kind-of "^3.0.3"
|
||||
|
||||
object-inspect@^1.11.0, object-inspect@^1.9.0:
|
||||
object-inspect@^1.11.0, object-inspect@^1.12.0, object-inspect@^1.9.0:
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
|
||||
integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
|
||||
@@ -8583,7 +8989,7 @@ object.assign@^4.1.0, object.assign@^4.1.2:
|
||||
has-symbols "^1.0.1"
|
||||
object-keys "^1.1.1"
|
||||
|
||||
object.entries@^1.1.0:
|
||||
object.entries@^1.1.0, object.entries@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
|
||||
integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==
|
||||
@@ -8592,7 +8998,7 @@ object.entries@^1.1.0:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.1"
|
||||
|
||||
"object.fromentries@^2.0.0 || ^1.0.0":
|
||||
"object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251"
|
||||
integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==
|
||||
@@ -8610,6 +9016,14 @@ object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.2
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.1"
|
||||
|
||||
object.hasown@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5"
|
||||
integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.1"
|
||||
|
||||
object.pick@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
|
||||
@@ -8617,7 +9031,7 @@ object.pick@^1.3.0:
|
||||
dependencies:
|
||||
isobject "^3.0.1"
|
||||
|
||||
object.values@^1.1.0:
|
||||
object.values@^1.1.0, object.values@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
|
||||
integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
|
||||
@@ -8667,6 +9081,18 @@ open@^8.4.0:
|
||||
is-docker "^2.1.1"
|
||||
is-wsl "^2.2.0"
|
||||
|
||||
optionator@^0.9.1:
|
||||
version "0.9.1"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
|
||||
integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==
|
||||
dependencies:
|
||||
deep-is "^0.1.3"
|
||||
fast-levenshtein "^2.0.6"
|
||||
levn "^0.4.1"
|
||||
prelude-ls "^1.2.1"
|
||||
type-check "^0.4.0"
|
||||
word-wrap "^1.2.3"
|
||||
|
||||
os-browserify@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
|
||||
@@ -8916,7 +9342,7 @@ path-key@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||
|
||||
path-parse@^1.0.7:
|
||||
path-parse@^1.0.6, path-parse@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
@@ -9422,11 +9848,21 @@ postcss@^8.4.5:
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.1"
|
||||
|
||||
prelude-ls@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||
|
||||
prettier@<=2.3.0, "prettier@>=2.2.1 <=2.3.0":
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18"
|
||||
integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==
|
||||
|
||||
prettier@^2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032"
|
||||
integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==
|
||||
|
||||
pretty-error@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6"
|
||||
@@ -9501,7 +9937,7 @@ prompts@^2.4.0:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.5"
|
||||
|
||||
prop-types@^15.6.0, prop-types@^15.7.2:
|
||||
prop-types@^15.6.0, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
@@ -10045,6 +10481,20 @@ regexp.prototype.flags@^1.3.1:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
|
||||
regexp.prototype.flags@^1.4.1:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
|
||||
integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
functions-have-names "^1.2.2"
|
||||
|
||||
regexpp@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
|
||||
|
||||
regexpu-core@^4.7.1:
|
||||
version "4.8.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0"
|
||||
@@ -10224,6 +10674,14 @@ resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.2
|
||||
path-parse "^1.0.7"
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
resolve@^2.0.0-next.3:
|
||||
version "2.0.0-next.3"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46"
|
||||
integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==
|
||||
dependencies:
|
||||
is-core-module "^2.2.0"
|
||||
path-parse "^1.0.6"
|
||||
|
||||
ret@~0.1.10:
|
||||
version "0.1.15"
|
||||
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
|
||||
@@ -10798,6 +11256,20 @@ stream-shift@^1.0.0:
|
||||
regexp.prototype.flags "^1.3.1"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
string.prototype.matchall@^4.0.6:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d"
|
||||
integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.19.1"
|
||||
get-intrinsic "^1.1.1"
|
||||
has-symbols "^1.0.3"
|
||||
internal-slot "^1.0.3"
|
||||
regexp.prototype.flags "^1.4.1"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
string.prototype.padend@^3.0.0:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz#997a6de12c92c7cb34dc8a201a6c53d9bd88a5f1"
|
||||
@@ -10881,6 +11353,11 @@ strip-indent@^3.0.0:
|
||||
dependencies:
|
||||
min-indent "^1.0.0"
|
||||
|
||||
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
||||
style-loader@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e"
|
||||
@@ -11051,6 +11528,11 @@ test-exclude@^6.0.0:
|
||||
glob "^7.1.4"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
text-table@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||
|
||||
throttle-debounce@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb"
|
||||
@@ -11203,6 +11685,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
type-check@^0.4.0, type-check@~0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
||||
integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
|
||||
dependencies:
|
||||
prelude-ls "^1.2.1"
|
||||
|
||||
type-fest@^0.20.2:
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
||||
@@ -11531,6 +12020,11 @@ uuid@^3.3.2:
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||
|
||||
v8-compile-cache@^2.0.3:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
||||
|
||||
v8-to-istanbul@^8.0.0:
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed"
|
||||
@@ -11827,6 +12321,11 @@ widest-line@^3.1.0:
|
||||
dependencies:
|
||||
string-width "^4.0.0"
|
||||
|
||||
word-wrap@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
||||
|
||||
wordwrap@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||
|
||||
Reference in New Issue
Block a user