This commit is contained in:
2023-08-08 19:42:14 +05:00
parent b8816f1935
commit 12ca24ad6a
10 changed files with 263 additions and 217 deletions
+83 -201
View File
@@ -1,3 +1,4 @@
/* eslint-disable no-irregular-whitespace */
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-explicit-any */
@@ -9,7 +10,7 @@ import { io } from "socket.io-client";
import userAgentParser from "ua-parser-js";
import { Player } from "./components/Player";
import { Trans } from "react-i18next";
import { useScreen } from "usehooks-ts";
// import { useScreen } from "usehooks-ts";
import ShareIcon from "./components/icons/ShareIcon";
import ModalContainer from "./components/ModalContainer";
import useModalStore from "./stores/useModalStore";
@@ -20,14 +21,9 @@ import "react-toastify/dist/ReactToastify.css";
import FullscreenIcon from "./components/icons/FullscreenIcon";
import WindowedModeIcon from "./components/icons/WindowedModeIcon";
import QRIcon from "./components/icons/QRIcon";
import AdminUserIcon from "./components/icons/AdminUserIcon";
import UserIcon from "./components/icons/UserIcon";
import MobilePhoneIcon from "./components/icons/MobilePhoneIcon";
import DesktopIcon from "./components/icons/DesktopIcon";
import HandOffIcon from "./components/icons/HandOffIcon";
import HandOnIcon from "./components/icons/HandOnIcon";
import ExitIcon from "./components/icons/ExitIcon";
import QRCodeModal from "./components/modals/QRCodeModal";
import PersonsIcon from "./components/icons/PersonsIcon";
import UsersManagementModal from "./components/modals/UsersManagementModal";
function StreamPage() {
const params = useParams();
@@ -38,18 +34,18 @@ function StreamPage() {
const [socket, setSocket] = useState<any>(null);
const [users, setUsers] = useState<any>([]);
const [me, setMe] = useState<any>({});
const [isOpenSidebar, setIsOpenSidebar] = useState<boolean>(false);
const screen = useScreen();
// const screen = useScreen();
const [modal, setModal] = useModalStore((state) => [
state.modal,
state.setModal,
]);
useEffect(() => {
if (screen?.orientation.type.includes("portrait")) {
// alert("portrait");
}
}, [screen]);
// useEffect(() => {
// if (screen?.orientation.type.includes("portrait")) {
// alert("portrait");
// }
// }, [screen]);
function toastWarn(text: string) {
toast.warn(text, {
@@ -116,6 +112,8 @@ function StreamPage() {
socket.on("join", (_socketId, room) => {
setUsers(room.users);
// console.log("join: ", _socketId, room.users);
toastInfo("Присоеденился новый участник");
});
socket.on("update", (_socketId, room) => {
@@ -147,192 +145,7 @@ function StreamPage() {
}, [me]);
return (
<FullScreen handle={handleFullScreen} className="h-screen text-[#F2F2F2] ">
<div
className={[
"absolute z-30 top-0 left-0 h-screen bg-[#1C1D21] space-y-2 flex flex-col justify-between text-xs whitespace-nowrap text-clip transition-all",
isOpenSidebar ? "w-[280px]" : "w-0",
].join(" ")}
>
<div
className={[
"p-2 transition-opacity",
isOpenSidebar ? "opacity-100" : "opacity-0",
].join(" ")}
>
<div className="flex flex-col overflow-hidden">
{!handleFullScreen.active ? (
<button
onClick={handleFullScreen.enter}
className="p-2 flex space-x-2 items-center outline-none"
>
<FullscreenIcon />
<span>
<Trans i18nKey={"fullscreenMode"}>Полноэкранный режим</Trans>
</span>
</button>
) : (
<button
onClick={handleFullScreen.exit}
className="p-2 flex space-x-2 items-center outline-none"
>
<WindowedModeIcon />
<span>
<Trans i18nKey={"windowedMode"}>Оконный режим</Trans>
</span>
</button>
)}
<button
onClick={() => setModal(<QRCodeModal />)}
className="p-2 flex space-x-2 items-center outline-none"
>
<QRIcon />
<span>
<Trans i18nKey={"inviteByQR"}>Пригласить по QR</Trans>
</span>
</button>
<button
onClick={() => setModal(<ShareModal />)}
className="p-2 flex space-x-2 items-center outline-none"
>
<ShareIcon />
<span>Поделиться</span>
</button>
</div>
<div className="m-1 h-0.5 bg-[#2E3038]"></div>
<div className="">
{users.map((user: any) => (
<div
key={user.id}
className="p-2 border-gray-700 flex items-center space-x-2"
>
<div className="flex flex-col justify-center items-center">
{user.admin ? <AdminUserIcon /> : <UserIcon />}
{me && me.id === user.id && (
<p className="text-[#73788C]">Вы</p>
)}
</div>
<div>
<p className="font-bold">
{user.admin ? "Администратор" : "Пользователь"}
</p>
<p>({user.city})</p>
</div>
{new userAgentParser(user.ua).getDevice().type === "mobile" ? (
<MobilePhoneIcon />
) : (
<DesktopIcon />
)}
{!user.admin && (
<>
{user.allowControl ? (
<button
onClick={() => update(user.id, { allowControl: false })}
className="outline-none mt-1"
>
<HandOnIcon />
</button>
) : (
<button
onClick={() => update(user.id, { allowControl: true })}
className="outline-none mt-1"
>
<HandOffIcon />
</button>
)}
</>
)}
{me && me.admin && !user.admin && (
<button
onClick={() => kick(user.id)}
className="outline-none"
>
<ExitIcon />
</button>
)}
</div>
))}
</div>
</div>
<div className="absolute top-[50%] -right-[29px] -translate-y-[50%] transition-all">
{!isOpenSidebar ? (
<button
onClick={() => setIsOpenSidebar(true)}
className="p-2 relative outline-none"
>
<svg
width="24"
height="130"
viewBox="0 0 24 130"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 1H3.69231L22.4433 30.547C23.4601 32.1492 24 34.0076 24 35.9053V94.0947C24 95.9924 23.4601 97.8508 22.4433 99.453L3.69231 129H0V1Z"
fill="#1C1D21"
/>
<path
d="M13 70L18 65L13 60"
stroke="#C5C7CE"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M8 75L8 65L8 55"
stroke="#C5C7CE"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</button>
) : (
<button
onClick={() => setIsOpenSidebar(false)}
className="p-2 outline-none"
>
<svg
width="24"
height="130"
viewBox="0 0 24 130"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 1H3.69231L22.4433 30.547C23.4601 32.1492 24 34.0076 24 35.9053V94.0947C24 95.9924 23.4601 97.8508 22.4433 99.453L3.69231 129H0V1Z"
fill="#1C1D21"
/>
<path
d="M11 70L6 65L11 60"
stroke="#C5C7CE"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M16 75L16 65L16 55"
stroke="#C5C7CE"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</button>
)}
</div>
</div>
<FullScreen handle={handleFullScreen} className="h-screen text-[#F2F2F2]">
{!isStreamEnded ? (
isStreamLoaded ? (
<>{streamUrl && <Player ss={streamUrl} />}</>
@@ -369,6 +182,75 @@ 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">
{new userAgentParser().getDevice().model !== "iPhone" && (
<>
{!handleFullScreen.active ? (
<button
onClick={() => handleFullScreen.enter()}
className="relative group outline-none bg-[#131313] rounded-full shadow-lg shadow-[#131313] p-2 opacity-90"
>
<FullscreenIcon />
<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">
Полноэкранный режим
</span>
</button>
) : (
<button
onClick={() => handleFullScreen.exit()}
className="relative group outline-none bg-[#131313] rounded-full shadow-lg shadow-[#131313] p-2 opacity-90"
>
<WindowedModeIcon />
<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">
Оконный режим
</span>
</button>
)}
</>
)}
<button
onClick={() => setModal(<QRCodeModal />)}
className="relative group outline-none bg-[#131313] rounded-full shadow-lg shadow-[#131313] p-2 opacity-90"
>
<QRIcon />
<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">
Пригласить по QR
</span>
</button>
<button
onClick={() => setModal(<ShareModal />)}
className="relative group outline-none bg-[#131313] rounded-full shadow-lg shadow-[#131313] p-2 opacity-90"
>
<ShareIcon />
<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">
Пригласить по ссылке
</span>
</button>
<button
onClick={() =>
setModal(
<UsersManagementModal
users={users}
me={me}
handleUpdate={(socketId, params) => update(socketId, params)}
handleKick={(socketId) => kick(socketId)}
/>
)
}
className="relative group outline-none bg-[#131313] rounded-full shadow-lg shadow-[#131313] p-2 opacity-90"
>
<PersonsIcon />
<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">
Участники
</span>
</button>
</div>
</div>
<Transition
in={modal ? true : false}
timeout={200}