This commit is contained in:
2024-07-10 14:04:20 +05:00
parent 37bce16c51
commit 652554c6a2
3 changed files with 129 additions and 46 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ function App() {
state.setIsOpen,
]);
const [loading, setLoading] = useState<boolean>(false);
const [countdownTimer, setCountdownTimer] = useState(10);
const [countdownTimer, setCountdownTimer] = useState(15);
const { t, i18n } = useTranslation();
const build = searchParams.get("build") || null;
const type = searchParams.get("type") || "demo";
@@ -41,6 +41,9 @@ export const PixelStreamingWrapper2 = ({
// Save the library instance into component state so that it can be accessed later:
setPixelStreaming(streaming);
document.getElementById("hiddenInput")?.remove();
document.getElementById("editTextButton")?.remove();
// Clean up on component unmount:
return () => {
try {
+125 -45
View File
@@ -4,7 +4,7 @@
import { useEffect, useRef, useState } from "react";
import { PixelStreamingWrapper2 } from "../components/PixelStreamingWrapper2";
import api from "../utils/api";
import { useParams } from "react-router-dom";
import { useParams, useSearchParams } from "react-router-dom";
import useStateRef from "react-usestateref";
import Peer from "peerjs";
import useIsAudioActive from "use-is-audio-active";
@@ -31,6 +31,8 @@ import FullscreenIcon from "../components/icons/FullscreenIcon";
import ShareIcon from "../components/icons/ShareIcon";
import { useFullscreen } from "ahooks";
import InviteModal from "../components/modals/stream/InviteModal";
import Tooltip from "../components/Tooltip";
import { toast, ToastContainer } from "react-toastify";
// import MoreIcon from "../components/icons/MoreIcon";
@@ -38,6 +40,7 @@ const userId = uuidv4();
function StreamPage3() {
const params = useParams();
const [searchParams] = useSearchParams();
const [WSUrl, setWSUrl] = useState<string>("");
const localVideoRef = useRef<HTMLVideoElement>(null);
@@ -53,8 +56,8 @@ function StreamPage3() {
const isSpeaking = useIsAudioActive({
source: localStream.getTracks().length ? localStream : null,
});
const [users, setUsers] = useState<IUser[]>([]);
const [me, setMe] = useState<IUser>();
const [users, setUsers, usersRef] = useStateRef<IUser[]>([]);
const [me, setMe, meRef] = useStateRef<IUser>();
const isCallInit = useRef<boolean>(false);
const [roomId] = useState<string>(params.id!);
const [socket, setSocket] = useState<Socket>();
@@ -141,9 +144,21 @@ function StreamPage3() {
}
function initSocket() {
const superAdmin = searchParams.has("admin", true);
console.log("superAdmin", superAdmin);
const socket = io(import.meta.env.VITE_SOCKET_URL, {
transports: ["websocket"],
auth: { roomId, user: { id: userId, name, peerId } },
auth: {
roomId,
user: {
id: userId,
name,
peerId,
superAdmin,
},
},
});
socket.on("update", async (users: IUser[]) => {
@@ -164,7 +179,17 @@ function StreamPage3() {
});
socket.on("request-control", (userId) => {
console.log("request-control", userId);
const user = usersRef.current.find((user) => user.id === userId);
if (user?.id === meRef.current?.id || !meRef.current?.isAdmin) return;
toast.info(`${user?.name} запрашивает разрешение на управление`);
});
socket.on("transfer-control", (userId) => {
if (meRef.current?.id !== userId) return;
toast.info(`Вы получили разрешение на управление`);
});
socket.on("connect", () => {
@@ -281,7 +306,10 @@ function StreamPage3() {
}, [users.length]);
return (
<div ref={fullscreenRef} className="h-[100dvh] flex flex-col bg-[#111C26]">
<div
ref={fullscreenRef}
className="h-[100dvh] flex flex-col bg-[#111C26] overflow-hidden"
>
{isEnded === false ? (
<>
<div className="flex items-center bg-white h-12 px-6">
@@ -301,28 +329,64 @@ function StreamPage3() {
<p className="text-xs">{name}</p>
</div>
<div className="flex items-center gap-2">
<Button
variant="secondary"
icon={me?.isControlAllowed ? <HandOnIcon /> : <HandOffIcon />}
onlyIcon
onClick={() =>
me!.isAdmin
? transferControl(me!.id)
: requestControl(me!.id)
}
/>
<Button
variant="secondary"
icon={isMicEnabled ? <MicroOnIcon /> : <MicroOffIcon />}
onlyIcon
onClick={toggleMic}
/>
<Button
variant="secondary"
icon={isCameraEnabled ? <CameraOnIcon /> : <CameraOffIcon />}
onlyIcon
onClick={toggleCamera}
/>
<div className="relative group">
<Button
variant="secondary"
icon={
me?.isControlAllowed ? <HandOnIcon /> : <HandOffIcon />
}
onlyIcon
onClick={() =>
me!.isAdmin
? transferControl(me!.id)
: requestControl(me!.id)
}
/>
{me?.isAdmin && !me.isControlAllowed && (
<Tooltip text={"Вернуть управление"} />
)}
{!me?.isAdmin && !me?.isControlAllowed && (
<Tooltip text={"Запросить управление"} />
)}
</div>
{permission && (
<>
<div className="relative group">
<Button
variant="secondary"
icon={isMicEnabled ? <MicroOnIcon /> : <MicroOffIcon />}
onlyIcon
onClick={toggleMic}
/>
<Tooltip
text={
isMicEnabled
? "Выключить микрофон"
: "Включить микрофон"
}
/>
</div>
<div className="relative group">
<Button
variant="secondary"
icon={
isCameraEnabled ? <CameraOnIcon /> : <CameraOffIcon />
}
onlyIcon
onClick={toggleCamera}
/>
<Tooltip
text={
isCameraEnabled
? "Выключить камеру"
: "Включить камеру"
}
/>
</div>
</>
)}
</div>
<div className="h-4 w-px bg-[#DAE0E5]"></div>
{users.map((user) => {
@@ -347,12 +411,15 @@ function StreamPage3() {
onlyIcon
/> */}
{/* <div className="absolute"> */}
<Button
variant="secondary"
icon={<HandOnIcon />}
onlyIcon
onClick={() => transferControl(user.id)}
/>
<div className="relative group">
<Button
variant="secondary"
icon={<HandOnIcon />}
onlyIcon
onClick={() => transferControl(user.id)}
/>
<Tooltip text={"Передать управление"} />
</div>
{/* </div> */}
</div>
)}
@@ -362,19 +429,29 @@ function StreamPage3() {
})}
</div>
<div className="flex gap-2 ml-auto">
<Button
variant="secondary"
icon={<ShareIcon />}
onlyIcon
onClick={() => setModal(<InviteModal />)}
/>
{!isIOS && (
<div className="relative group">
<Button
variant="secondary"
icon={isFullscreen ? <WindowIcon /> : <FullscreenIcon />}
icon={<ShareIcon />}
onlyIcon
onClick={toggleFullscreen}
onClick={() => setModal(<InviteModal />)}
/>
<Tooltip text={"Поделиться"} />
</div>
{!isIOS && (
<div className="relative group">
<Button
variant="secondary"
icon={isFullscreen ? <WindowIcon /> : <FullscreenIcon />}
onlyIcon
onClick={toggleFullscreen}
/>
<Tooltip
text={
isFullscreen ? "Оконный режим" : "Полноэкранный режим"
}
/>
</div>
)}
</div>
</div>
@@ -395,12 +472,14 @@ function StreamPage3() {
{!users.find((user) => user.id === userId)?.isControlAllowed && (
<div
className="absolute top-0 left-0 w-full h-full"
onClick={() => alert("")}
onClick={() =>
toast.warn("Необходимо запросить разрешение на управление")
}
></div>
)}
<div className="absolute top-2 left-2 space-y-2">
<div className="relative">
<div className={`relative ${!permission ? "hidden" : ""}`}>
<video
ref={localVideoRef}
className={`aspect-video w-[216px] h-[162px] rounded-lg object-cover bg-gray-500 -scale-x-100 ring-2 ${
@@ -427,6 +506,7 @@ function StreamPage3() {
</div>
</div>
<ModalContainer2 />
<ToastContainer />
</>
) : (
<div className="flex-1 flex items-center justify-center p-8">