upd
This commit is contained in:
+118
-74
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user