This commit is contained in:
2023-09-15 18:07:20 +05:00
parent 9a0dbe390e
commit 16768bfe7d
12 changed files with 607 additions and 241 deletions
+118 -74
View File
@@ -1,16 +1,14 @@
/* eslint-disable no-irregular-whitespace */
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useParams } from "react-router-dom";
import { FullScreen, useFullScreenHandle } from "react-full-screen";
import { useEffect, useState } from "react";
import ky from "ky";
import { io } from "socket.io-client";
import { Socket, io } from "socket.io-client";
import userAgentParser from "ua-parser-js";
import { Player } from "./components/Player";
import { Trans, useTranslation } from "react-i18next";
// import { useScreen } from "usehooks-ts";
import ShareIcon from "./components/icons/ShareIcon";
import ModalContainer from "./components/ModalContainer";
import useModalStore from "./stores/useModalStore";
@@ -25,76 +23,47 @@ import UsersManagementModal from "./components/modals/UsersManagementModal";
import useStreamUserStore from "./stores/useStreamUserStore";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import UserIcon from "./components/icons/UserIcon";
import HandOnIcon from "./components/icons/HandOnIcon";
// import UserIcon from "./components/icons/UserIcon";
// import HandOnIcon from "./components/icons/HandOnIcon";
import AlertIcon from "./components/icons/AlertIcon";
import useSocketStore from "./stores/useSocketStore";
import { LiveKitRoom, RoomAudioRenderer } from "@livekit/components-react";
import ToggleMic from "./components/ToggleMic";
function StreamPage() {
const { t } = useTranslation();
const params = useParams();
const handleFullScreen = useFullScreenHandle();
const [streamUrl, setStreamUrl] = useState<string>("");
const [isStreamEnded, setIsStreamEnded] = useState<boolean>(false);
const [isStreamLoaded, setStreamLoaded] = useState<boolean>(false);
const [socket, setSocket] = useState<any>(null);
const [users, setUsers] = useStreamUserStore((state) => [
state.users,
state.setUsers,
]);
const [me, setMe] = useState<any>({});
// const screen = useScreen();
const [modal, setModal] = useModalStore((state) => [
state.modal,
state.setModal,
]);
const params = useParams();
const roomId = params.id;
const serverUrl = "wss://livekit.stream.graff.tech";
const [token, setToken] = useState<string>();
const [socket, setSocket] = useSocketStore((state) => [
state.socket,
state.setSocket,
]);
const [users, setUsers] = useStreamUserStore((state) => [
state.users,
state.setUsers,
]);
// useEffect(() => {
// if (screen?.orientation.type.includes("portrait")) {
// alert("portrait");
// }
// }, [screen]);
async function getToken() {
if (!socket) return;
function toastWarn(text: string) {
toast.warn(text, {
position: "top-center",
autoClose: 2000,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
theme: "dark",
icon: <AlertIcon />,
closeButton: false,
});
}
const { token }: any = await ky
.get(
`https://coord.graff.tech/getToken?roomName=${roomId}&participantName=${socket.id}`
)
.json();
function toastUser(text: string) {
toast.info(text, {
position: "top-center",
autoClose: 2000,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
theme: "dark",
icon: <UserIcon />,
closeButton: false,
});
}
function toastHandOn(text: string) {
toast.info(text, {
position: "top-center",
autoClose: 2000,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
theme: "dark",
icon: <HandOnIcon />,
closeButton: false,
});
setToken(token);
}
async function connect() {
@@ -113,35 +82,89 @@ function StreamPage() {
}
}
function update(socketId: string, params: object) {
socket.emit("update", socketId, params);
function update(socketId: string, data: { [key: string]: any }) {
if (!socket) return;
socket.emit("update", socketId, data);
console.log("Users: ", users);
}
function kick(socketId: string) {
if (!socket) return;
socket.emit("kick", socketId);
console.log("User kick: ", socketId);
}
function toastWarn(text: string) {
toast.warn(text, {
position: "top-center",
autoClose: 2000,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
theme: "dark",
icon: <AlertIcon />,
closeButton: false,
});
}
// function toastUser(text: string) {
// toast.info(text, {
// position: "top-center",
// autoClose: 2000,
// hideProgressBar: true,
// closeOnClick: true,
// pauseOnHover: true,
// draggable: true,
// theme: "dark",
// icon: <UserIcon />,
// closeButton: false,
// });
// }
// function toastHandOn(text: string) {
// toast.info(text, {
// position: "top-center",
// autoClose: 2000,
// hideProgressBar: true,
// closeOnClick: true,
// pauseOnHover: true,
// draggable: true,
// theme: "dark",
// icon: <HandOnIcon />,
// closeButton: false,
// });
// }
useEffect(() => {
connect();
const socket = io(import.meta.env.VITE_COORD_URL, {
query: { roomId: params.id },
const socket: Socket = io(import.meta.env.VITE_COORD_URL, {
query: {
roomId,
},
});
socket.on("connect", () => {
console.log("Socket: ", socket.id);
setSocket(socket);
// console.log("connect: ", socket.id);
});
socket.on("join", (_socketId, room) => {
setUsers(room.users);
// console.log("join: ", _socketId, room.users);
toastUser(t("notification.newMember"));
socket.on("join", (socketId, sockets) => {
console.log("User connected: ", socketId, sockets);
setUsers(sockets);
});
socket.on("update", (_socketId, room) => {
setUsers(room.users);
// console.log("update: ", _socketId, room.users);
socket.on("update", (socketId, data, sockets) => {
console.log("Update users: ", socketId, data, sockets);
setUsers(sockets);
});
socket.on("leave", (socketId, sockets) => {
console.log("User disconnected: ", socketId);
setUsers(sockets);
});
socket.on("kick", () => {
@@ -162,12 +185,20 @@ function StreamPage() {
}, []);
useEffect(() => {
setMe(users.find((user: any) => user.id === socket.id));
if (!socket) return;
getToken();
}, [socket]);
useEffect(() => {
if (socket) {
setMe(users.find((user: any) => user.id === socket.id));
}
}, [users]);
useEffect(() => {
if (me && me.allowControl && !me.admin) {
toastHandOn(t("notification.controlReceived"));
// toastHandOn(t("notification.controlReceived"));
}
}, [me]);
@@ -206,7 +237,7 @@ function StreamPage() {
)}
<div className="absolute top-0 left-0 min-h-screen flex flex-col justify-center transition-all">
<div className="flex flex-col gap-2 lg:p-4 p-2">
<div className="flex flex-col gap-4 lg:p-4 p-2">
{new userAgentParser().getDevice().model !== "iPhone" && (
<>
{!handleFullScreen.active ? (
@@ -260,8 +291,8 @@ function StreamPage() {
setModal(
<UsersManagementModal
me={me}
handleUpdate={(socketId, params) => update(socketId, params)}
handleKick={(socketId) => kick(socketId)}
handleUpdate={update}
handleKick={kick}
/>
)
}
@@ -271,7 +302,20 @@ function StreamPage() {
<span className="absolute left-12 top-[50%] -translate-y-[50%] invisible group-hover:visible opacity-0 group-hover:opacity-100 text-xs transition-all px-2 py-1 bg-[#131313] rounded">
<Trans i18nKey={"members"}>Участники</Trans>
</span>
<div className="absolute px-2 py-1 text-xs flex flex-col justify-center items-center rounded-full -top-2 -right-2 bg-[#131313] -z-10">
{users.length}
</div>
</button>
<LiveKitRoom
video={false}
audio={true}
token={token}
serverUrl={serverUrl}
>
<RoomAudioRenderer />
<ToggleMic socket={socket} handleUpdate={update} />
</LiveKitRoom>
</div>
</div>