diff --git a/src/button/Button.jsx b/src/button/Button.jsx index b6c3df9..ab6ed77 100644 --- a/src/button/Button.jsx +++ b/src/button/Button.jsx @@ -20,6 +20,7 @@ export const variantToClassName = { copy: [styles.copyButton], iconCopy: [styles.iconCopyButton], secondaryCopy: [styles.copyButton], + secondaryHangup: [styles.secondaryHangup], }; export const sizeToClassName = { diff --git a/src/button/Button.module.css b/src/button/Button.module.css index 72450d5..5c3ec30 100644 --- a/src/button/Button.module.css +++ b/src/button/Button.module.css @@ -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); diff --git a/src/home/RegisteredView.jsx b/src/home/RegisteredView.jsx index 6e43f20..6849d9f 100644 --- a/src/home/RegisteredView.jsx +++ b/src/home/RegisteredView.jsx @@ -23,12 +23,13 @@ export function RegisteredView({ client }) { 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 +88,7 @@ export function RegisteredView({ client }) { required autoComplete="off" /> + + ); +} diff --git a/src/room/PTTButton.module.css b/src/room/PTTButton.module.css new file mode 100644 index 0000000..6bfc1a1 --- /dev/null +++ b/src/room/PTTButton.module.css @@ -0,0 +1,11 @@ +.pttButton { + width: 100vw; + height: 100vh; + max-height: 232px; + max-width: 232px; + border-radius: 116px; + + color: ##fff; + border: 6px solid #0dbd8b; + background-color: #21262C; +} \ No newline at end of file diff --git a/src/room/PTTCallView.jsx b/src/room/PTTCallView.jsx new file mode 100644 index 0000000..29d90da --- /dev/null +++ b/src/room/PTTCallView.jsx @@ -0,0 +1,88 @@ +import React from "react"; +import { useModalTriggerState } from "../Modal"; +import { SettingsModal } from "../settings/SettingsModal"; +import { InviteModal } from "./InviteModal"; +import { Button } from "../button"; +import { Header, LeftNav, RightNav, RoomSetupHeaderInfo } from "../Header"; +import { ReactComponent as AddUserIcon } from "../icons/AddUser.svg"; +import { ReactComponent as SettingsIcon } from "../icons/Settings.svg"; +import styles from "./PTTCallView.module.css"; +import { Facepile } from "../Facepile"; +import { PTTButton } from "./PTTButton"; +import { PTTFeed } from "./PTTFeed"; +import { useMediaHandler } from "../settings/useMediaHandler"; + +export function PTTCallView({ + groupCall, + participants, + client, + roomName, + microphoneMuted, + toggleMicrophoneMuted, + userMediaFeeds, + activeSpeaker, + onLeave, + setShowInspector, + showInspector, + roomId, +}) { + const { modalState: inviteModalState, modalProps: inviteModalProps } = + useModalTriggerState(); + const { modalState: settingsModalState, modalProps: settingsModalProps } = + useModalTriggerState(); + const { audioOutput } = useMediaHandler(); + + return ( +
+
+ + + + + + + + +
+
+
+

{`${participants.length} user${ + participants.length > 1 ? "s" : "" + } connected`}

+ +
+
+ +

Press and hold spacebar to talk

+ {userMediaFeeds.map((callFeed) => ( + + ))} +
+ + {settingsModalState.isOpen && ( + + )} + {inviteModalState.isOpen && ( + + )} +
+ ); +} diff --git a/src/room/PTTCallView.module.css b/src/room/PTTCallView.module.css new file mode 100644 index 0000000..f513b79 --- /dev/null +++ b/src/room/PTTCallView.module.css @@ -0,0 +1,40 @@ +.pttCallView { + position: relative; + display: flex; + flex-direction: column; + overflow: hidden; + min-height: 100%; + position: fixed; + height: 100%; + width: 100%; +} + +.headerSeparator { + width: calc(100% - 40px); + height: 1px; + margin: 0 20px; + background-color: #21262C; +} + +.center { + width: 100%; + display: flex; + flex: 1; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.actionTip { + margin-top: 42px; + font-size: 17px; +} + +.participants { + margin: 24px 20px 0 20px; +} + +.participants > p { + color: #A9B2BC; + margin-bottom: 8px; +} \ No newline at end of file diff --git a/src/room/PTTFeed.jsx b/src/room/PTTFeed.jsx new file mode 100644 index 0000000..cc655c7 --- /dev/null +++ b/src/room/PTTFeed.jsx @@ -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