From 37bce16c512d6053fb061193992b66d18ad26c75 Mon Sep 17 00:00:00 2001 From: inmake Date: Mon, 8 Jul 2024 17:34:40 +0500 Subject: [PATCH] upd --- package.json | 2 +- src/components/ChatNew.tsx | 84 ----- src/components/Video.tsx | 14 + src/components/modals/stream/InviteModal.tsx | 96 ++++++ src/pages/StreamPage3.tsx | 316 ++++++++++++------- yarn.lock | 8 +- 6 files changed, 311 insertions(+), 209 deletions(-) create mode 100644 src/components/modals/stream/InviteModal.tsx diff --git a/package.json b/package.json index 8651344..80e47e2 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3": "^1.0.1", + "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3": "^1.0.4", "@epicgames-ps/lib-pixelstreamingfrontend-ue5.5": "^0.0.12", "@livekit/components-react": "^2.0.3", "@livekit/components-styles": "^1.0.10", diff --git a/src/components/ChatNew.tsx b/src/components/ChatNew.tsx index 2f33857..f801f7e 100644 --- a/src/components/ChatNew.tsx +++ b/src/components/ChatNew.tsx @@ -80,90 +80,6 @@ function ChatNew({ isShow, socket, userId, name, onClose }: ChatNewProps) { }, [isShow]); return ( - //
- //
- //
- //

Чат

- //
- //
- //
- //
- // {messages.map((message) => ( - //
- // {message.user.id !== userId && ( - //
- //
- // {message.user.name[0].toUpperCase()} - //
- //
- // )} - //
- //
- // {message.user.id !== userId && ( - //

- // {message.user.name} - //

- // )} - //

- // {message.text} - //

- //

- // {message.time} - //

- //
- // {message.user.id !== userId && ( - //
- // - //
- // )} - //
- //
- // ))} - //
- //
- //
- // setMessage(e.target.value)} - // /> - // - //
- //
- //
- //
-
(null); const isSpeaking = useIsAudioActive({ source: mediaStream }); const [_muted, setMuted] = useState(muted); + const [isLoading, setIsLoading] = useState(true); function toggleSound() { if (!remoteVideoRef.current) return; @@ -30,6 +31,10 @@ function Video({ mediaStream, muted, user }: Props) { remoteVideoRef.current.onloadedmetadata = () => { remoteVideoRef.current?.play(); }; + + remoteVideoRef.current.onplay = () => { + setIsLoading(false); + }; }, [mediaStream]); useEffect(() => { @@ -55,6 +60,15 @@ function Video({ mediaStream, muted, user }: Props) { {_muted ? : }
+ {isLoading && ( +
+ +
+ )} ); } diff --git a/src/components/modals/stream/InviteModal.tsx b/src/components/modals/stream/InviteModal.tsx new file mode 100644 index 0000000..31940eb --- /dev/null +++ b/src/components/modals/stream/InviteModal.tsx @@ -0,0 +1,96 @@ +import { Trans } from "react-i18next"; +import QRCode from "react-qr-code"; +import CloseIcon from "../../icons/CloseIcon"; +import LinkIcon from "../../icons/LinkIcon"; +import Button from "../../ui/Button"; +import useModalStore from "../../../stores/useModalStore"; +import { useClipboard } from "use-clipboard-copy"; +import { toast, Bounce, ToastContainer } from "react-toastify"; +import InfoIcon from "../../icons/InfoBlueIcon"; + +function InviteModal() { + const { setModal } = useModalStore(); + const clipboard = useClipboard(); + const link = window.location.origin + window.location.pathname; + + function handleClickClipboard() { + clipboard.copy(); + + toast.info("Ссылка скопирована в буфер обмена", { + icon: , + position: "top-center", + autoClose: 3000, + hideProgressBar: true, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + theme: "light", + transition: Bounce, + }); + } + + return ( +
+
+
+

+ Пригласить +

+
+
+
+ +

+ + Отсканируйте QR-код, +
+ чтобы присоедениться +
к демонстрации +
+

+
+
+ + +
+ {/*
+
e.preventDefault()} className="flex gap-2"> + + +
+
*/} +
+
+ + +
+ ); +} + +export default InviteModal; diff --git a/src/pages/StreamPage3.tsx b/src/pages/StreamPage3.tsx index 1191c50..d95d539 100644 --- a/src/pages/StreamPage3.tsx +++ b/src/pages/StreamPage3.tsx @@ -24,6 +24,13 @@ import MicroOnIcon from "../components/icons/MicroOnIcon"; import MicroOffIcon from "../components/icons/MicroOffIcon"; import CameraOnIcon from "../components/icons/CameraOnIcon"; import CameraOffIcon from "../components/icons/CameraOffIcon"; +import { Trans } from "react-i18next"; +import { isIOS } from "react-device-detect"; +import WindowIcon from "../components/icons/WindowIcon"; +import FullscreenIcon from "../components/icons/FullscreenIcon"; +import ShareIcon from "../components/icons/ShareIcon"; +import { useFullscreen } from "ahooks"; +import InviteModal from "../components/modals/stream/InviteModal"; // import MoreIcon from "../components/icons/MoreIcon"; @@ -55,6 +62,10 @@ function StreamPage3() { const { name } = useStreamStore(); const [isMicEnabled, setIsMicEnabled] = useState(true); const [isCameraEnabled, setIsCameraEnabled] = useState(true); + const [isEnded, setIsEnded] = useState(); + const [, setEndAt] = useState(); + const fullscreenRef = useRef(null); + const [isFullscreen, { toggleFullscreen }] = useFullscreen(fullscreenRef); async function startCall(remotePeerId: string) { if (!peerInstance) return; @@ -152,6 +163,10 @@ function StreamPage3() { setMe(users.find((user) => user.id === userId)); }); + socket.on("request-control", (userId) => { + console.log("request-control", userId); + }); + socket.on("connect", () => { setSocket(socket); }); @@ -192,37 +207,59 @@ function StreamPage3() { }, 500); } - async function getActiveSession() { - const activeSession: any = await api - .get(`activeSessions/${params.id}`) - .json(); - - // if (activeSession?.endAt) { - // setEndAt(activeSession.endAt); - // } - - return activeSession; - } - async function getWSUrl() { const activeSession = await getActiveSession(); if (!activeSession || activeSession.status === "error") { + setIsEnded(true); return; } + setIsEnded(false); setWSUrl( `wss://${activeSession.location}.sess.stream.graff.tech/${activeSession.name}/${activeSession.cirrusPort}/` ); + setModal(); + + checkSessionStatus(); } function transferControl(userId: string) { socket?.emit("transfer-control", userId); } + function requestControl(userId: string) { + console.log("requestControl func", userId); + socket?.emit("request-control", userId); + } + + async function getActiveSession() { + const activeSession: any = await api + .get(`activeSessions/${params.id}`) + .json(); + + if (activeSession?.endAt) { + setEndAt(activeSession.endAt); + } + + return activeSession; + } + + async function checkSessionStatus() { + const activeSession = await getActiveSession(); + + if (!activeSession || activeSession.status === "error") { + setIsEnded(true); + return; + } + + setTimeout(async () => { + await checkSessionStatus(); + }, 1000); + } + useEffect(() => { getWSUrl(); - setModal(); }, []); useEffect(() => { @@ -244,123 +281,162 @@ function StreamPage3() { }, [users.length]); return ( -
-
-
- -
-
-
-
-

{name[0]?.toUpperCase()}

- {me?.isControlAllowed && ( -
- )} +
+ {isEnded === false ? ( + <> +
+
+
-

{name}

-
-
-
+
+ {users.map((user) => { + if (user.id !== userId) { + return ( +
+
+

+ {name[0]?.toUpperCase()} +

+ {user?.isControlAllowed && ( +
+ )} +
+

{user.name}

-
-
- {users.map((user) => { - if (user.id !== userId) { - return ( -
-
-

- {name[0]?.toUpperCase()} -

- {user?.isControlAllowed && ( -
- )} -
-

{user.name}

- - {me?.isAdmin && me?.isControlAllowed && ( -
- {/*
*/} + {/*
*/} +
*/} +
+ )}
- )} -
- ); - } - })} -
-
-
- {WSUrl && ( - - )} - -
-
- -
-

{name}

+ ); + } + })} +
+
+
- {remoteStreams.map(({ peerId, mediaStream }) => ( -
-
+
+ {WSUrl && ( + + )} - + {!users.find((user) => user.id === userId)?.isControlAllowed && ( +
alert("")} + >
+ )} + +
+
+ +
+

{name}

+
+
+ {remoteStreams.map(({ peerId, mediaStream }) => ( +
+
+ + + ) : ( +
+

+ + Данная демонстрация была завершена + +

+
+ )}
); } diff --git a/yarn.lock b/yarn.lock index fbd73ee..09f7bf4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -36,10 +36,10 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f" integrity sha512-Qv4LTqO11jepd5Qmlp3M1YEjBumoTHcHFdgPTQ+sFlIL5myi/7xu/POwP7IRu6odBdmLXdtIs1D6TuW6kbwbbg== -"@epicgames-ps/lib-pixelstreamingfrontend-ue5.3@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@epicgames-ps/lib-pixelstreamingfrontend-ue5.3/-/lib-pixelstreamingfrontend-ue5.3-1.0.1.tgz#ba7d0fb42ede74109fcbb2510d7f6a4442bed7a0" - integrity sha512-DLeMbwi/szf4/rQAPXFl1YH5lT5kHJ2GcnxYNPvYVWZ9xgX5hjieREXyi8DaxCAPF81e+ev57TjZKJy7R3tvpw== +"@epicgames-ps/lib-pixelstreamingfrontend-ue5.3@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@epicgames-ps/lib-pixelstreamingfrontend-ue5.3/-/lib-pixelstreamingfrontend-ue5.3-1.0.4.tgz#71533a4f940627702d26896eb3380d08c6d05523" + integrity sha512-gqt2lFGLys3YOvloK9X/gpk+ZPgRlLi+uB9kWWWMJd+Gih0jgRwc6GJ0b+LuIVmZau4qNUbTmfOklKpti0G07g== dependencies: sdp "^3.1.0"