upd
This commit is contained in:
+3
-3
@@ -15,8 +15,8 @@
|
||||
"@livekit/components-styles": "^1.0.6",
|
||||
"@uidotdev/usehooks": "^2.0.1",
|
||||
"date-fns": "^2.30.0",
|
||||
"i18next": "^22.5.0",
|
||||
"i18next-browser-languagedetector": "^7.0.2",
|
||||
"i18next": "^23.8.2",
|
||||
"i18next-browser-languagedetector": "^7.2.0",
|
||||
"ky": "^1.1.3",
|
||||
"livekit-client": "^1.13.2",
|
||||
"react": "^18.2.0",
|
||||
@@ -25,7 +25,7 @@
|
||||
"react-device-detect": "^2.2.3",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-full-screen": "^1.1.1",
|
||||
"react-i18next": "^12.3.1",
|
||||
"react-i18next": "^14.0.3",
|
||||
"react-input-mask": "^2.0.4",
|
||||
"react-qr-code": "^2.0.11",
|
||||
"react-router-dom": "^6.11.2",
|
||||
|
||||
+29
-13
@@ -1,6 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import ky from "ky";
|
||||
import { useEffect, useState } from "react";
|
||||
import { parseUserAgent } from "react-device-detect";
|
||||
|
||||
function HistoryPage() {
|
||||
const [history, setHistory] = useState([]);
|
||||
@@ -20,19 +21,34 @@ function HistoryPage() {
|
||||
return (
|
||||
<div className="text-[#F2F2F2] space-y-4 p-4">
|
||||
<p>Всего сессий: {history.length}</p>
|
||||
{history.map((item: any) => (
|
||||
<div key={item.id} className="p-4 rounded-lg bg-[#22222A]">
|
||||
<p>
|
||||
Дата и время: {new Date(item.createdAt).toLocaleString()}
|
||||
</p>
|
||||
<p>Сборка: "{item.build}"</p>
|
||||
<p>Локация: "{item.location}"</p>
|
||||
<p>Сервер: "{item.server}"</p>
|
||||
<p>IP клиента: {item.ownerIp}</p>
|
||||
{/* <p>Город: {item.city}</p> */}
|
||||
{/* <p>Устройство: {item.headers["user-agent"]}</p> */}
|
||||
</div>
|
||||
))}
|
||||
{history.map(
|
||||
(item: any) =>
|
||||
item.city &&
|
||||
item.headers && (
|
||||
<div key={item.id} className="p-4 rounded-lg bg-[#22222A]">
|
||||
<p>
|
||||
Дата и время: <b>{new Date(item.createdAt).toLocaleString()}</b>
|
||||
</p>
|
||||
<p>
|
||||
Сборка: <b>{item.title}</b>
|
||||
</p>
|
||||
<p>
|
||||
Город: <b>{item.city}</b>
|
||||
</p>
|
||||
<p>
|
||||
Устройство:{" "}
|
||||
<b>
|
||||
{parseUserAgent(item.headers["user-agent"]).os.name}{" "}
|
||||
{parseUserAgent(item.headers["user-agent"]).os.version} (
|
||||
{parseUserAgent(item.headers["user-agent"]).browser.name})
|
||||
</b>
|
||||
</p>
|
||||
<p>Локация: {item.location}</p>
|
||||
<p>Сервер: {item.server}</p>
|
||||
<p>IP клиента: {item.headers["x-forwarded-for"]}</p>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ function ScheduledPage() {
|
||||
<p className="text-2xl font-gilroy">Сеанс начнется через:</p>
|
||||
<p className="text-6xl font-gilroy">
|
||||
<Countdown
|
||||
date={Date.now() + countdownSeconds + 10000}
|
||||
date={Date.now() + countdownSeconds + 15000}
|
||||
onComplete={() => window.location.reload()}
|
||||
/>
|
||||
</p>
|
||||
|
||||
+24
-1
@@ -35,6 +35,7 @@ import { differenceInMilliseconds, format, parseISO } from "date-fns";
|
||||
import HandOnIcon from "./components/icons/HandOnIcon";
|
||||
import { useMobileOrientation } from "react-device-detect";
|
||||
import RotateDeviceIcon from "./components/icons/RotateDeviceIcon";
|
||||
import LoaderIcon from "./components/icons/LoaderIcon";
|
||||
|
||||
function StreamPage() {
|
||||
const { t } = useTranslation();
|
||||
@@ -161,6 +162,25 @@ function StreamPage() {
|
||||
});
|
||||
}
|
||||
|
||||
async function checkIsActiveSession() {
|
||||
const activeSession: any = await ky
|
||||
.get(`${import.meta.env.VITE_COORD_URL}/active_sessions/${params.id}`)
|
||||
.json();
|
||||
|
||||
console.log(activeSession);
|
||||
|
||||
if (!activeSession) {
|
||||
setIsStreamEnded(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isStreamEnded) {
|
||||
setTimeout(() => {
|
||||
checkIsActiveSession();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
connect();
|
||||
|
||||
@@ -206,6 +226,8 @@ function StreamPage() {
|
||||
}
|
||||
});
|
||||
|
||||
checkIsActiveSession();
|
||||
|
||||
return () => {
|
||||
socket.off("connect");
|
||||
socket.off("join");
|
||||
@@ -249,7 +271,8 @@ function StreamPage() {
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="absolute top-0 left-0 w-full h-full flex justify-center items-center">
|
||||
<div className="absolute top-0 left-0 w-full h-full flex justify-center items-center gap-4">
|
||||
<LoaderIcon className="animate-spin w-8 h-8" />
|
||||
<Trans i18nKey="streamWaiting">Ожидание потока</Trans>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
PixelStreaming,
|
||||
} from "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3";
|
||||
import { Trans } from "react-i18next";
|
||||
import LoaderIcon from "./icons/LoaderIcon";
|
||||
|
||||
export interface PixelStreamingWrapperProps {
|
||||
initialSettings?: Partial<AllSettings>;
|
||||
@@ -25,6 +26,8 @@ export const PixelStreamingWrapper = ({
|
||||
// A boolean state variable that determines if the Click to play overlay is shown:
|
||||
const [clickToPlayVisible, setClickToPlayVisible] = useState<boolean>(false);
|
||||
const [videoInitialized, setVideoInitialized] = useState<boolean>(false);
|
||||
const videoInitializedRef = useRef<boolean>();
|
||||
videoInitializedRef.current = videoInitialized;
|
||||
|
||||
// Run on component mount:
|
||||
useEffect(() => {
|
||||
@@ -50,6 +53,12 @@ export const PixelStreamingWrapper = ({
|
||||
document.getElementById("hiddenInput")?.remove();
|
||||
document.getElementById("editTextButton")?.remove();
|
||||
|
||||
setTimeout(() => {
|
||||
if (!videoInitializedRef.current) {
|
||||
window.location.reload();
|
||||
}
|
||||
}, 10000);
|
||||
|
||||
// Clean up on component unmount:
|
||||
return () => {
|
||||
try {
|
||||
@@ -65,7 +74,8 @@ export const PixelStreamingWrapper = ({
|
||||
<div className="relative w-screen h-screen">
|
||||
<div className="w-full h-[100svh]" ref={videoParent} />
|
||||
{!videoInitialized && (
|
||||
<div className="absolute top-0 left-0 w-full h-full flex justify-center items-center">
|
||||
<div className="absolute top-0 left-0 w-full h-full flex justify-center items-center gap-4">
|
||||
<LoaderIcon className="animate-spin w-8 h-8" />
|
||||
<Trans i18nKey="streamBuffering">Буферизация потока</Trans>
|
||||
</div>
|
||||
)}
|
||||
|
||||
+8
-6
@@ -1,6 +1,6 @@
|
||||
import i18n from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import detector from "i18next-browser-languagedetector";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
|
||||
// the translations
|
||||
// (tip move them in a JSON file and import them,
|
||||
@@ -237,15 +237,17 @@ const resources = {
|
||||
};
|
||||
|
||||
void i18n
|
||||
.use(detector)
|
||||
.use(initReactI18next) // passes i18n down to react-i18next
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
resources,
|
||||
fallbackLng: ["ru"],
|
||||
fallbackLng: "ru",
|
||||
interpolation: {
|
||||
escapeValue: false, // react already safes from xss
|
||||
escapeValue: false,
|
||||
},
|
||||
// debug: true,
|
||||
// detection: {
|
||||
// caches: [],
|
||||
// },
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
|
||||
Reference in New Issue
Block a user