Merge pull request #1641 from robintown/invite-modal
Implement the new invite modal designs
This commit is contained in:
@@ -87,6 +87,7 @@
|
|||||||
"@storybook/react": "^6.5.0-alpha.5",
|
"@storybook/react": "^6.5.0-alpha.5",
|
||||||
"@testing-library/jest-dom": "^6.0.0",
|
"@testing-library/jest-dom": "^6.0.0",
|
||||||
"@testing-library/react": "^14.0.0",
|
"@testing-library/react": "^14.0.0",
|
||||||
|
"@testing-library/user-event": "^14.5.1",
|
||||||
"@types/content-type": "^1.1.5",
|
"@types/content-type": "^1.1.5",
|
||||||
"@types/d3": "^7.4.0",
|
"@types/d3": "^7.4.0",
|
||||||
"@types/dom-screen-wake-lock": "^1.0.1",
|
"@types/dom-screen-wake-lock": "^1.0.1",
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
"Continue in browser": "Continue in browser",
|
"Continue in browser": "Continue in browser",
|
||||||
"Copied!": "Copied!",
|
"Copied!": "Copied!",
|
||||||
"Copy": "Copy",
|
"Copy": "Copy",
|
||||||
"Copy and share this call link": "Copy and share this call link",
|
"Copy link": "Copy link",
|
||||||
"Create account": "Create account",
|
"Create account": "Create account",
|
||||||
"Debug log": "Debug log",
|
"Debug log": "Debug log",
|
||||||
"Debug log request": "Debug log request",
|
"Debug log request": "Debug log request",
|
||||||
@@ -54,9 +54,12 @@
|
|||||||
"If you are experiencing issues or simply would like to provide some feedback, please send us a short description below.": "If you are experiencing issues or simply would like to provide some feedback, please send us a short description below.",
|
"If you are experiencing issues or simply would like to provide some feedback, please send us a short description below.": "If you are experiencing issues or simply would like to provide some feedback, please send us a short description below.",
|
||||||
"Include debug logs": "Include debug logs",
|
"Include debug logs": "Include debug logs",
|
||||||
"Inspector": "Inspector",
|
"Inspector": "Inspector",
|
||||||
|
"Invite": "Invite",
|
||||||
|
"Invite to this call": "Invite to this call",
|
||||||
"Join call": "Join call",
|
"Join call": "Join call",
|
||||||
"Join call now": "Join call now",
|
"Join call now": "Join call now",
|
||||||
"Join existing call?": "Join existing call?",
|
"Join existing call?": "Join existing call?",
|
||||||
|
"Link copied to clipboard": "Link copied to clipboard",
|
||||||
"Loading…": "Loading…",
|
"Loading…": "Loading…",
|
||||||
"Local volume": "Local volume",
|
"Local volume": "Local volume",
|
||||||
"Logging in…": "Logging in…",
|
"Logging in…": "Logging in…",
|
||||||
@@ -92,9 +95,7 @@
|
|||||||
"Sending debug logs…": "Sending debug logs…",
|
"Sending debug logs…": "Sending debug logs…",
|
||||||
"Sending…": "Sending…",
|
"Sending…": "Sending…",
|
||||||
"Settings": "Settings",
|
"Settings": "Settings",
|
||||||
"Share": "Share",
|
|
||||||
"Share screen": "Share screen",
|
"Share screen": "Share screen",
|
||||||
"Share this call": "Share this call",
|
|
||||||
"Sharing screen": "Sharing screen",
|
"Sharing screen": "Sharing screen",
|
||||||
"Show call inspector": "Show call inspector",
|
"Show call inspector": "Show call inspector",
|
||||||
"Show connection stats": "Show connection stats",
|
"Show connection stats": "Show connection stats",
|
||||||
|
|||||||
@@ -14,96 +14,18 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.overlay {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 100;
|
|
||||||
inset: 0;
|
|
||||||
background: rgba(3, 12, 27, 0.528);
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-in {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialogOverlay[data-state="open"] {
|
|
||||||
animation: fade-in 200ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-out {
|
|
||||||
from {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialogOverlay[data-state="closed"] {
|
|
||||||
animation: fade-out 130ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
position: fixed;
|
|
||||||
z-index: 101;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog {
|
.dialog {
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
inline-size: 520px;
|
inline-size: 520px;
|
||||||
max-inline-size: 90%;
|
max-inline-size: 90%;
|
||||||
max-block-size: 600px;
|
max-block-size: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes zoom-in {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translate(-50%, -50%) scale(80%);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translate(-50%, -50%) scale(100%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes zoom-out {
|
|
||||||
from {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translate(-50%, -50%) scale(100%);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translate(-50%, -50%) scale(80%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog[data-state="open"] {
|
|
||||||
animation: zoom-in 200ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog[data-state="closed"] {
|
|
||||||
animation: zoom-out 130ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion) {
|
|
||||||
.dialog[data-state="open"] {
|
|
||||||
animation-name: fade-in;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog[data-state="closed"] {
|
|
||||||
animation-name: fade-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import classNames from "classnames";
|
|||||||
import { Heading } from "@vector-im/compound-web";
|
import { Heading } from "@vector-im/compound-web";
|
||||||
|
|
||||||
import styles from "./Modal.module.css";
|
import styles from "./Modal.module.css";
|
||||||
|
import overlayStyles from "./Overlay.module.css";
|
||||||
import { useMediaQuery } from "./useMediaQuery";
|
import { useMediaQuery } from "./useMediaQuery";
|
||||||
import { Glass } from "./Glass";
|
import { Glass } from "./Glass";
|
||||||
|
|
||||||
@@ -85,9 +86,14 @@ export function Modal({
|
|||||||
dismissible={onDismiss !== undefined}
|
dismissible={onDismiss !== undefined}
|
||||||
>
|
>
|
||||||
<Drawer.Portal>
|
<Drawer.Portal>
|
||||||
<Drawer.Overlay className={styles.overlay} />
|
<Drawer.Overlay className={classNames(overlayStyles.bg)} />
|
||||||
<Drawer.Content
|
<Drawer.Content
|
||||||
className={classNames(className, styles.modal, styles.drawer)}
|
className={classNames(
|
||||||
|
className,
|
||||||
|
overlayStyles.overlay,
|
||||||
|
styles.modal,
|
||||||
|
styles.drawer
|
||||||
|
)}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
@@ -108,12 +114,18 @@ export function Modal({
|
|||||||
<DialogRoot open={open} onOpenChange={onOpenChange}>
|
<DialogRoot open={open} onOpenChange={onOpenChange}>
|
||||||
<DialogPortal>
|
<DialogPortal>
|
||||||
<DialogOverlay
|
<DialogOverlay
|
||||||
className={classNames(styles.overlay, styles.dialogOverlay)}
|
className={classNames(overlayStyles.bg, overlayStyles.animate)}
|
||||||
/>
|
/>
|
||||||
<DialogContent asChild {...rest}>
|
<DialogContent asChild {...rest}>
|
||||||
<Glass
|
<Glass
|
||||||
frosted
|
frosted
|
||||||
className={classNames(className, styles.modal, styles.dialog)}
|
className={classNames(
|
||||||
|
className,
|
||||||
|
overlayStyles.overlay,
|
||||||
|
overlayStyles.animate,
|
||||||
|
styles.modal,
|
||||||
|
styles.dialog
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
|
|||||||
99
src/Overlay.module.css
Normal file
99
src/Overlay.module.css
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2023 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.bg {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 100;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(3, 12, 27, 0.528);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg.animate[data-state="open"] {
|
||||||
|
animation: fade-in 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-out {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg.animate[data-state="closed"] {
|
||||||
|
animation: fade-out 130ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 101;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay.animate {
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zoom-in {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(-50%, -50%) scale(80%);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate(-50%, -50%) scale(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes zoom-out {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate(-50%, -50%) scale(100%);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(-50%, -50%) scale(80%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay.animate[data-state="open"] {
|
||||||
|
animation: zoom-in 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay.animate[data-state="closed"] {
|
||||||
|
animation: zoom-out 130ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion) {
|
||||||
|
.overlay.animate[data-state="open"] {
|
||||||
|
animation-name: fade-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay.animate[data-state="closed"] {
|
||||||
|
animation-name: fade-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/Toast.module.css
Normal file
38
src/Toast.module.css
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2023 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.toast {
|
||||||
|
color: var(--cpd-color-text-on-solid-primary);
|
||||||
|
background: var(--cpd-color-alpha-gray-1200);
|
||||||
|
padding-inline: var(--cpd-space-3x);
|
||||||
|
padding-block: var(--cpd-space-1x);
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--cpd-radius-pill-effect);
|
||||||
|
box-shadow: var(--small-drop-shadow);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--cpd-space-1x);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast > h3 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast > svg {
|
||||||
|
color: var(--cpd-color-icon-on-solid-primary);
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-inline-end: calc(-1 * var(--cpd-space-1x));
|
||||||
|
}
|
||||||
108
src/Toast.tsx
Normal file
108
src/Toast.tsx
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2023 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
ComponentType,
|
||||||
|
FC,
|
||||||
|
SVGAttributes,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
} from "react";
|
||||||
|
import {
|
||||||
|
Root as DialogRoot,
|
||||||
|
Portal as DialogPortal,
|
||||||
|
Overlay as DialogOverlay,
|
||||||
|
Content as DialogContent,
|
||||||
|
Close as DialogClose,
|
||||||
|
Title as DialogTitle,
|
||||||
|
} from "@radix-ui/react-dialog";
|
||||||
|
import classNames from "classnames";
|
||||||
|
import { Text } from "@vector-im/compound-web";
|
||||||
|
|
||||||
|
import styles from "./Toast.module.css";
|
||||||
|
import overlayStyles from "./Overlay.module.css";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/**
|
||||||
|
* The controlled open state of the toast.
|
||||||
|
*/
|
||||||
|
open: boolean;
|
||||||
|
/**
|
||||||
|
* Callback for when the user dismisses the toast.
|
||||||
|
*/
|
||||||
|
onDismiss: () => void;
|
||||||
|
/**
|
||||||
|
* A number of milliseconds after which the toast should be automatically
|
||||||
|
* dismissed.
|
||||||
|
*/
|
||||||
|
autoDismiss?: number;
|
||||||
|
children: string;
|
||||||
|
/**
|
||||||
|
* A supporting icon to display within the toast.
|
||||||
|
*/
|
||||||
|
Icon?: ComponentType<SVGAttributes<SVGElement>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A temporary message shown in an overlay in the center of the screen.
|
||||||
|
*/
|
||||||
|
export const Toast: FC<Props> = ({
|
||||||
|
open,
|
||||||
|
onDismiss,
|
||||||
|
autoDismiss,
|
||||||
|
children,
|
||||||
|
Icon,
|
||||||
|
}) => {
|
||||||
|
const onOpenChange = useCallback(
|
||||||
|
(open: boolean) => {
|
||||||
|
if (!open) onDismiss();
|
||||||
|
},
|
||||||
|
[onDismiss]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (open && autoDismiss !== undefined) {
|
||||||
|
const timeout = setTimeout(onDismiss, autoDismiss);
|
||||||
|
return () => clearTimeout(timeout);
|
||||||
|
}
|
||||||
|
}, [open, autoDismiss, onDismiss]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogRoot open={open} onOpenChange={onOpenChange}>
|
||||||
|
<DialogPortal>
|
||||||
|
<DialogOverlay
|
||||||
|
className={classNames(overlayStyles.bg, overlayStyles.animate)}
|
||||||
|
/>
|
||||||
|
<DialogContent asChild>
|
||||||
|
<DialogClose
|
||||||
|
className={classNames(
|
||||||
|
overlayStyles.overlay,
|
||||||
|
overlayStyles.animate,
|
||||||
|
styles.toast
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<DialogTitle asChild>
|
||||||
|
<Text as="h3" size="sm" weight="semibold">
|
||||||
|
{children}
|
||||||
|
</Text>
|
||||||
|
</DialogTitle>
|
||||||
|
{Icon && <Icon width={20} height={20} aria-hidden />}
|
||||||
|
</DialogClose>
|
||||||
|
</DialogContent>
|
||||||
|
</DialogPortal>
|
||||||
|
</DialogRoot>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -19,13 +19,13 @@ import { Button } from "@vector-im/compound-web";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import UserAddSolidIcon from "@vector-im/compound-design-tokens/icons/user-add-solid.svg?react";
|
import UserAddSolidIcon from "@vector-im/compound-design-tokens/icons/user-add-solid.svg?react";
|
||||||
|
|
||||||
export const ShareButton: FC<
|
export const InviteButton: FC<
|
||||||
Omit<ComponentPropsWithoutRef<"button">, "children">
|
Omit<ComponentPropsWithoutRef<"button">, "children">
|
||||||
> = (props) => {
|
> = (props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Button kind="secondary" size="sm" Icon={UserAddSolidIcon} {...props}>
|
<Button kind="secondary" size="sm" Icon={UserAddSolidIcon} {...props}>
|
||||||
{t("Share")}
|
{t("Invite")}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -47,7 +47,7 @@ import { useEnableE2EE } from "../settings/useSetting";
|
|||||||
import { useRoomAvatar } from "./useRoomAvatar";
|
import { useRoomAvatar } from "./useRoomAvatar";
|
||||||
import { useRoomName } from "./useRoomName";
|
import { useRoomName } from "./useRoomName";
|
||||||
import { useJoinRule } from "./useJoinRule";
|
import { useJoinRule } from "./useJoinRule";
|
||||||
import { ShareModal } from "./ShareModal";
|
import { InviteModal } from "./InviteModal";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
@@ -267,15 +267,15 @@ export function GroupCallView({
|
|||||||
|
|
||||||
const joinRule = useJoinRule(rtcSession.room);
|
const joinRule = useJoinRule(rtcSession.room);
|
||||||
|
|
||||||
const [shareModalOpen, setShareModalOpen] = useState(false);
|
const [shareModalOpen, setInviteModalOpen] = useState(false);
|
||||||
const onDismissShareModal = useCallback(
|
const onDismissInviteModal = useCallback(
|
||||||
() => setShareModalOpen(false),
|
() => setInviteModalOpen(false),
|
||||||
[setShareModalOpen]
|
[setInviteModalOpen]
|
||||||
);
|
);
|
||||||
|
|
||||||
const onShareClickFn = useCallback(
|
const onShareClickFn = useCallback(
|
||||||
() => setShareModalOpen(true),
|
() => setInviteModalOpen(true),
|
||||||
[setShareModalOpen]
|
[setInviteModalOpen]
|
||||||
);
|
);
|
||||||
const onShareClick = joinRule === JoinRule.Public ? onShareClickFn : null;
|
const onShareClick = joinRule === JoinRule.Public ? onShareClickFn : null;
|
||||||
|
|
||||||
@@ -318,10 +318,10 @@ export function GroupCallView({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const shareModal = (
|
const shareModal = (
|
||||||
<ShareModal
|
<InviteModal
|
||||||
room={rtcSession.room}
|
room={rtcSession.room}
|
||||||
open={shareModalOpen}
|
open={shareModalOpen}
|
||||||
onDismiss={onDismissShareModal}
|
onDismiss={onDismissInviteModal}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ import { useWakeLock } from "../useWakeLock";
|
|||||||
import { useMergedRefs } from "../useMergedRefs";
|
import { useMergedRefs } from "../useMergedRefs";
|
||||||
import { MuteStates } from "./MuteStates";
|
import { MuteStates } from "./MuteStates";
|
||||||
import { MatrixInfo } from "./VideoPreview";
|
import { MatrixInfo } from "./VideoPreview";
|
||||||
import { ShareButton } from "../button/ShareButton";
|
import { InviteButton } from "../button/InviteButton";
|
||||||
import { LayoutToggle } from "./LayoutToggle";
|
import { LayoutToggle } from "./LayoutToggle";
|
||||||
import {
|
import {
|
||||||
ECAddonConnectionState,
|
ECAddonConnectionState,
|
||||||
@@ -416,7 +416,7 @@ export function InCallView({
|
|||||||
</LeftNav>
|
</LeftNav>
|
||||||
<RightNav>
|
<RightNav>
|
||||||
{!reducedControls && onShareClick !== null && (
|
{!reducedControls && onShareClick !== null && (
|
||||||
<ShareButton onClick={onShareClick} />
|
<InviteButton onClick={onShareClick} />
|
||||||
)}
|
)}
|
||||||
</RightNav>
|
</RightNav>
|
||||||
</Header>
|
</Header>
|
||||||
|
|||||||
@@ -14,6 +14,12 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.copyButton {
|
.url {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--cpd-color-text-secondary);
|
||||||
|
margin-block-end: var(--cpd-space-8x);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
84
src/room/InviteModal.tsx
Normal file
84
src/room/InviteModal.tsx
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 - 2023 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { FC, MouseEvent, useCallback, useMemo, useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Room } from "matrix-js-sdk";
|
||||||
|
import { Button, Text } from "@vector-im/compound-web";
|
||||||
|
import LinkIcon from "@vector-im/compound-design-tokens/icons/link.svg?react";
|
||||||
|
import CheckIcon from "@vector-im/compound-design-tokens/icons/check.svg?react";
|
||||||
|
import useClipboard from "react-use-clipboard";
|
||||||
|
|
||||||
|
import { Modal } from "../Modal";
|
||||||
|
import { getAbsoluteRoomUrl } from "../matrix-utils";
|
||||||
|
import styles from "./InviteModal.module.css";
|
||||||
|
import { useRoomSharedKey } from "../e2ee/sharedKeyManagement";
|
||||||
|
import { Toast } from "../Toast";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
room: Room;
|
||||||
|
open: boolean;
|
||||||
|
onDismiss: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const InviteModal: FC<Props> = ({ room, open, onDismiss }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const roomSharedKey = useRoomSharedKey(room.roomId);
|
||||||
|
const url = useMemo(
|
||||||
|
() =>
|
||||||
|
getAbsoluteRoomUrl(room.roomId, room.name, roomSharedKey ?? undefined),
|
||||||
|
[room, roomSharedKey]
|
||||||
|
);
|
||||||
|
const [, setCopied] = useClipboard(url);
|
||||||
|
const [toastOpen, setToastOpen] = useState(false);
|
||||||
|
const onToastDismiss = useCallback(() => setToastOpen(false), [setToastOpen]);
|
||||||
|
|
||||||
|
const onButtonClick = useCallback(
|
||||||
|
(e: MouseEvent) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setCopied();
|
||||||
|
onDismiss();
|
||||||
|
setToastOpen(true);
|
||||||
|
},
|
||||||
|
[setCopied, onDismiss]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Modal title={t("Invite to this call")} open={open} onDismiss={onDismiss}>
|
||||||
|
<Text className={styles.url} size="sm" weight="semibold">
|
||||||
|
{url}
|
||||||
|
</Text>
|
||||||
|
<Button
|
||||||
|
className={styles.button}
|
||||||
|
Icon={LinkIcon}
|
||||||
|
onClick={onButtonClick}
|
||||||
|
data-testid="modal_inviteLink"
|
||||||
|
>
|
||||||
|
{t("Copy link")}
|
||||||
|
</Button>
|
||||||
|
</Modal>
|
||||||
|
<Toast
|
||||||
|
open={toastOpen}
|
||||||
|
onDismiss={onToastDismiss}
|
||||||
|
autoDismiss={2000}
|
||||||
|
Icon={CheckIcon}
|
||||||
|
>
|
||||||
|
{t("Link copied to clipboard")}
|
||||||
|
</Toast>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -27,7 +27,7 @@ import { Header, LeftNav, RightNav, RoomHeaderInfo } from "../Header";
|
|||||||
import { useLocationNavigation } from "../useLocationNavigation";
|
import { useLocationNavigation } from "../useLocationNavigation";
|
||||||
import { MatrixInfo, VideoPreview } from "./VideoPreview";
|
import { MatrixInfo, VideoPreview } from "./VideoPreview";
|
||||||
import { MuteStates } from "./MuteStates";
|
import { MuteStates } from "./MuteStates";
|
||||||
import { ShareButton } from "../button/ShareButton";
|
import { InviteButton } from "../button/InviteButton";
|
||||||
import {
|
import {
|
||||||
HangupButton,
|
HangupButton,
|
||||||
MicButton,
|
MicButton,
|
||||||
@@ -108,7 +108,7 @@ export const LobbyView: FC<Props> = ({
|
|||||||
/>
|
/>
|
||||||
</LeftNav>
|
</LeftNav>
|
||||||
<RightNav>
|
<RightNav>
|
||||||
{onShareClick !== null && <ShareButton onClick={onShareClick} />}
|
{onShareClick !== null && <InviteButton onClick={onShareClick} />}
|
||||||
</RightNav>
|
</RightNav>
|
||||||
</Header>
|
</Header>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2022 - 2023 New Vector Ltd
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { FC } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { Room } from "matrix-js-sdk";
|
|
||||||
|
|
||||||
import { Modal } from "../Modal";
|
|
||||||
import { CopyButton } from "../button";
|
|
||||||
import { getAbsoluteRoomUrl } from "../matrix-utils";
|
|
||||||
import styles from "./ShareModal.module.css";
|
|
||||||
import { useRoomSharedKey } from "../e2ee/sharedKeyManagement";
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
room: Room;
|
|
||||||
open: boolean;
|
|
||||||
onDismiss: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ShareModal: FC<Props> = ({ room, open, onDismiss }) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const roomSharedKey = useRoomSharedKey(room.roomId);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal title={t("Share this call")} open={open} onDismiss={onDismiss}>
|
|
||||||
<p>{t("Copy and share this call link")}</p>
|
|
||||||
<CopyButton
|
|
||||||
className={styles.copyButton}
|
|
||||||
value={getAbsoluteRoomUrl(
|
|
||||||
room.roomId,
|
|
||||||
room.name,
|
|
||||||
roomSharedKey ?? undefined
|
|
||||||
)}
|
|
||||||
data-testid="modal_inviteLink"
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
59
test/Toast-test.tsx
Normal file
59
test/Toast-test.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2023 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { screen, render } from "@testing-library/react";
|
||||||
|
import { Toast } from "../src/Toast";
|
||||||
|
import userEvent from "@testing-library/user-event";
|
||||||
|
import { withFakeTimers } from "./utils";
|
||||||
|
|
||||||
|
test("Toast renders", () => {
|
||||||
|
render(
|
||||||
|
<Toast open={false} onDismiss={() => {}}>
|
||||||
|
Hello world!
|
||||||
|
</Toast>
|
||||||
|
);
|
||||||
|
expect(screen.queryByRole("dialog")).toBe(null);
|
||||||
|
render(
|
||||||
|
<Toast open={true} onDismiss={() => {}}>
|
||||||
|
Hello world!
|
||||||
|
</Toast>
|
||||||
|
);
|
||||||
|
expect(screen.getByRole("dialog")).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Toast dismisses when clicked", async () => {
|
||||||
|
const onDismiss = jest.fn();
|
||||||
|
render(
|
||||||
|
<Toast open={true} onDismiss={onDismiss}>
|
||||||
|
Hello world!
|
||||||
|
</Toast>
|
||||||
|
);
|
||||||
|
await userEvent.click(screen.getByRole("dialog"));
|
||||||
|
expect(onDismiss).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Toast dismisses itself after the specified timeout", async () => {
|
||||||
|
withFakeTimers(() => {
|
||||||
|
const onDismiss = jest.fn();
|
||||||
|
render(
|
||||||
|
<Toast open={true} onDismiss={onDismiss} autoDismiss={2000}>
|
||||||
|
Hello world!
|
||||||
|
</Toast>
|
||||||
|
);
|
||||||
|
jest.advanceTimersByTime(2000);
|
||||||
|
expect(onDismiss).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
22
test/__snapshots__/Toast-test.tsx.snap
Normal file
22
test/__snapshots__/Toast-test.tsx.snap
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Toast renders 1`] = `
|
||||||
|
<button
|
||||||
|
aria-describedby="radix-:r5:"
|
||||||
|
aria-labelledby="radix-:r4:"
|
||||||
|
class="overlay animate toast"
|
||||||
|
data-state="open"
|
||||||
|
id="radix-:r3:"
|
||||||
|
role="dialog"
|
||||||
|
style="pointer-events: auto;"
|
||||||
|
tabindex="-1"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<h3
|
||||||
|
class="_font-body-sm-semibold_1jx6b_45"
|
||||||
|
id="radix-:r4:"
|
||||||
|
>
|
||||||
|
Hello world!
|
||||||
|
</h3>
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
@@ -18,15 +18,7 @@ import { Mocked, mocked } from "jest-mock";
|
|||||||
import { RoomState } from "matrix-js-sdk/src/models/room-state";
|
import { RoomState } from "matrix-js-sdk/src/models/room-state";
|
||||||
import { PosthogAnalytics } from "../../src/analytics/PosthogAnalytics";
|
import { PosthogAnalytics } from "../../src/analytics/PosthogAnalytics";
|
||||||
import { checkForParallelCalls } from "../../src/room/checkForParallelCalls";
|
import { checkForParallelCalls } from "../../src/room/checkForParallelCalls";
|
||||||
|
import { withFakeTimers } from "../utils";
|
||||||
const withFakeTimers = (continuation: () => void) => {
|
|
||||||
jest.useFakeTimers();
|
|
||||||
try {
|
|
||||||
continuation();
|
|
||||||
} finally {
|
|
||||||
jest.useRealTimers();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const withMockedPosthog = (
|
const withMockedPosthog = (
|
||||||
continuation: (posthog: Mocked<PosthogAnalytics>) => void
|
continuation: (posthog: Mocked<PosthogAnalytics>) => void
|
||||||
|
|||||||
24
test/utils.ts
Normal file
24
test/utils.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2023 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function withFakeTimers(continuation: () => void): void {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
try {
|
||||||
|
continuation();
|
||||||
|
} finally {
|
||||||
|
jest.useRealTimers();
|
||||||
|
}
|
||||||
|
}
|
||||||
88
yarn.lock
88
yarn.lock
@@ -65,7 +65,28 @@
|
|||||||
semver "^5.4.1"
|
semver "^5.4.1"
|
||||||
source-map "^0.5.0"
|
source-map "^0.5.0"
|
||||||
|
|
||||||
"@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.16.5", "@babel/core@^7.17.10", "@babel/core@^7.21.3", "@babel/core@^7.22.20", "@babel/core@^7.7.5":
|
"@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.16.5", "@babel/core@^7.17.10", "@babel/core@^7.7.5":
|
||||||
|
version "7.22.20"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.20.tgz#e3d0eed84c049e2a2ae0a64d27b6a37edec385b7"
|
||||||
|
integrity sha512-Y6jd1ahLubuYweD/zJH+vvOY141v4f9igNQAQ+MBgq9JlHS2iTsZKn1aMsb3vGccZsXI16VzTBw52Xx0DWmtnA==
|
||||||
|
dependencies:
|
||||||
|
"@ampproject/remapping" "^2.2.0"
|
||||||
|
"@babel/code-frame" "^7.22.13"
|
||||||
|
"@babel/generator" "^7.22.15"
|
||||||
|
"@babel/helper-compilation-targets" "^7.22.15"
|
||||||
|
"@babel/helper-module-transforms" "^7.22.20"
|
||||||
|
"@babel/helpers" "^7.22.15"
|
||||||
|
"@babel/parser" "^7.22.16"
|
||||||
|
"@babel/template" "^7.22.15"
|
||||||
|
"@babel/traverse" "^7.22.20"
|
||||||
|
"@babel/types" "^7.22.19"
|
||||||
|
convert-source-map "^1.7.0"
|
||||||
|
debug "^4.1.0"
|
||||||
|
gensync "^1.0.0-beta.2"
|
||||||
|
json5 "^2.2.3"
|
||||||
|
semver "^6.3.1"
|
||||||
|
|
||||||
|
"@babel/core@^7.21.3", "@babel/core@^7.22.20":
|
||||||
version "7.23.0"
|
version "7.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.0.tgz#f8259ae0e52a123eb40f552551e647b506a94d83"
|
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.0.tgz#f8259ae0e52a123eb40f552551e647b506a94d83"
|
||||||
integrity sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==
|
integrity sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==
|
||||||
@@ -96,6 +117,16 @@
|
|||||||
"@jridgewell/trace-mapping" "^0.3.17"
|
"@jridgewell/trace-mapping" "^0.3.17"
|
||||||
jsesc "^2.5.1"
|
jsesc "^2.5.1"
|
||||||
|
|
||||||
|
"@babel/generator@^7.22.15", "@babel/generator@^7.7.2":
|
||||||
|
version "7.22.15"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.15.tgz#1564189c7ec94cb8f77b5e8a90c4d200d21b2339"
|
||||||
|
integrity sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.22.15"
|
||||||
|
"@jridgewell/gen-mapping" "^0.3.2"
|
||||||
|
"@jridgewell/trace-mapping" "^0.3.17"
|
||||||
|
jsesc "^2.5.1"
|
||||||
|
|
||||||
"@babel/generator@^7.23.0":
|
"@babel/generator@^7.23.0":
|
||||||
version "7.23.0"
|
version "7.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420"
|
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420"
|
||||||
@@ -106,16 +137,6 @@
|
|||||||
"@jridgewell/trace-mapping" "^0.3.17"
|
"@jridgewell/trace-mapping" "^0.3.17"
|
||||||
jsesc "^2.5.1"
|
jsesc "^2.5.1"
|
||||||
|
|
||||||
"@babel/generator@^7.7.2":
|
|
||||||
version "7.22.15"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.15.tgz#1564189c7ec94cb8f77b5e8a90c4d200d21b2339"
|
|
||||||
integrity sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==
|
|
||||||
dependencies:
|
|
||||||
"@babel/types" "^7.22.15"
|
|
||||||
"@jridgewell/gen-mapping" "^0.3.2"
|
|
||||||
"@jridgewell/trace-mapping" "^0.3.17"
|
|
||||||
jsesc "^2.5.1"
|
|
||||||
|
|
||||||
"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.22.5":
|
"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.22.5":
|
||||||
version "7.22.5"
|
version "7.22.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882"
|
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882"
|
||||||
@@ -253,6 +274,17 @@
|
|||||||
"@babel/helper-split-export-declaration" "^7.22.6"
|
"@babel/helper-split-export-declaration" "^7.22.6"
|
||||||
"@babel/helper-validator-identifier" "^7.22.5"
|
"@babel/helper-validator-identifier" "^7.22.5"
|
||||||
|
|
||||||
|
"@babel/helper-module-transforms@^7.22.20":
|
||||||
|
version "7.22.20"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.20.tgz#da9edc14794babbe7386df438f3768067132f59e"
|
||||||
|
integrity sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-environment-visitor" "^7.22.20"
|
||||||
|
"@babel/helper-module-imports" "^7.22.15"
|
||||||
|
"@babel/helper-simple-access" "^7.22.5"
|
||||||
|
"@babel/helper-split-export-declaration" "^7.22.6"
|
||||||
|
"@babel/helper-validator-identifier" "^7.22.20"
|
||||||
|
|
||||||
"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.23.0":
|
"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.23.0":
|
||||||
version "7.23.0"
|
version "7.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e"
|
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e"
|
||||||
@@ -353,6 +385,15 @@
|
|||||||
"@babel/traverse" "^7.22.11"
|
"@babel/traverse" "^7.22.11"
|
||||||
"@babel/types" "^7.22.11"
|
"@babel/types" "^7.22.11"
|
||||||
|
|
||||||
|
"@babel/helpers@^7.22.15":
|
||||||
|
version "7.22.15"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.15.tgz#f09c3df31e86e3ea0b7ff7556d85cdebd47ea6f1"
|
||||||
|
integrity sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/template" "^7.22.15"
|
||||||
|
"@babel/traverse" "^7.22.15"
|
||||||
|
"@babel/types" "^7.22.15"
|
||||||
|
|
||||||
"@babel/helpers@^7.23.0":
|
"@babel/helpers@^7.23.0":
|
||||||
version "7.23.1"
|
version "7.23.1"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.1.tgz#44e981e8ce2b9e99f8f0b703f3326a4636c16d15"
|
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.1.tgz#44e981e8ce2b9e99f8f0b703f3326a4636c16d15"
|
||||||
@@ -381,7 +422,7 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.14.tgz#c7de58e8de106e88efca42ce17f0033209dfd245"
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.14.tgz#c7de58e8de106e88efca42ce17f0033209dfd245"
|
||||||
integrity sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==
|
integrity sha512-1KucTHgOvaw/LzCVrEOAyXkr9rQlp0A1HiHRYnSUE9dmb8PvPW7o5sscg+5169r54n3vGlbx6GevTE/Iw/P3AQ==
|
||||||
|
|
||||||
"@babel/parser@^7.14.7":
|
"@babel/parser@^7.14.7", "@babel/parser@^7.22.16":
|
||||||
version "7.22.16"
|
version "7.22.16"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.16.tgz#180aead7f247305cce6551bea2720934e2fa2c95"
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.16.tgz#180aead7f247305cce6551bea2720934e2fa2c95"
|
||||||
integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==
|
integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==
|
||||||
@@ -1362,6 +1403,22 @@
|
|||||||
debug "^4.1.0"
|
debug "^4.1.0"
|
||||||
globals "^11.1.0"
|
globals "^11.1.0"
|
||||||
|
|
||||||
|
"@babel/traverse@^7.22.15", "@babel/traverse@^7.22.20":
|
||||||
|
version "7.22.20"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.20.tgz#db572d9cb5c79e02d83e5618b82f6991c07584c9"
|
||||||
|
integrity sha512-eU260mPZbU7mZ0N+X10pxXhQFMGTeLb9eFS0mxehS8HZp9o1uSnFeWQuG1UPrlxgA7QoUzFhOnilHDp0AXCyHw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.22.13"
|
||||||
|
"@babel/generator" "^7.22.15"
|
||||||
|
"@babel/helper-environment-visitor" "^7.22.20"
|
||||||
|
"@babel/helper-function-name" "^7.22.5"
|
||||||
|
"@babel/helper-hoist-variables" "^7.22.5"
|
||||||
|
"@babel/helper-split-export-declaration" "^7.22.6"
|
||||||
|
"@babel/parser" "^7.22.16"
|
||||||
|
"@babel/types" "^7.22.19"
|
||||||
|
debug "^4.1.0"
|
||||||
|
globals "^11.1.0"
|
||||||
|
|
||||||
"@babel/traverse@^7.23.0":
|
"@babel/traverse@^7.23.0":
|
||||||
version "7.23.0"
|
version "7.23.0"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.0.tgz#18196ddfbcf4ccea324b7f6d3ada00d8c5a99c53"
|
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.0.tgz#18196ddfbcf4ccea324b7f6d3ada00d8c5a99c53"
|
||||||
@@ -1396,7 +1453,7 @@
|
|||||||
"@babel/helper-validator-identifier" "^7.22.5"
|
"@babel/helper-validator-identifier" "^7.22.5"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@babel/types@^7.3.3":
|
"@babel/types@^7.22.19", "@babel/types@^7.3.3":
|
||||||
version "7.22.19"
|
version "7.22.19"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.19.tgz#7425343253556916e440e662bb221a93ddb75684"
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.19.tgz#7425343253556916e440e662bb221a93ddb75684"
|
||||||
integrity sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==
|
integrity sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==
|
||||||
@@ -4333,6 +4390,11 @@
|
|||||||
"@testing-library/dom" "^9.0.0"
|
"@testing-library/dom" "^9.0.0"
|
||||||
"@types/react-dom" "^18.0.0"
|
"@types/react-dom" "^18.0.0"
|
||||||
|
|
||||||
|
"@testing-library/user-event@^14.5.1":
|
||||||
|
version "14.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.5.1.tgz#27337d72046d5236b32fd977edee3f74c71d332f"
|
||||||
|
integrity sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg==
|
||||||
|
|
||||||
"@tootallnate/once@2":
|
"@tootallnate/once@2":
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
|
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
|
||||||
|
|||||||
Reference in New Issue
Block a user