167 lines
4.4 KiB
TypeScript
167 lines
4.4 KiB
TypeScript
import { Box } from "@mui/material";
|
||
import { useState, useEffect } from "react";
|
||
|
||
import { ReactPhotoSphereViewer } from "react-photo-sphere-viewer";
|
||
import { ThreeView } from "./ThreeView";
|
||
import { ThreeViewErrorBoundary } from "./ThreeViewErrorBoundary";
|
||
import { clearMediaTransitionCache } from "../../shared/lib/gltfCacheManager";
|
||
|
||
export interface MediaData {
|
||
id: string | number;
|
||
media_type: number;
|
||
filename?: string;
|
||
}
|
||
|
||
export function MediaViewer({
|
||
media,
|
||
className,
|
||
height,
|
||
width,
|
||
fullWidth,
|
||
fullHeight,
|
||
}: Readonly<{
|
||
media?: MediaData;
|
||
className?: string;
|
||
height?: string;
|
||
width?: string;
|
||
fullWidth?: boolean;
|
||
fullHeight?: boolean;
|
||
}>) {
|
||
const token = localStorage.getItem("token");
|
||
const [resetKey, setResetKey] = useState(0);
|
||
const [previousMediaId, setPreviousMediaId] = useState<
|
||
string | number | null
|
||
>(null);
|
||
|
||
// Сбрасываем ключ при смене медиа
|
||
useEffect(() => {
|
||
if (media?.id !== previousMediaId) {
|
||
console.log("🔄 MediaViewer: Смена медиа, сброс ключа", {
|
||
previousMediaId,
|
||
newMediaId: media?.id,
|
||
mediaType: media?.media_type,
|
||
});
|
||
|
||
// Используем новый cache manager для очистки кеша
|
||
clearMediaTransitionCache(
|
||
previousMediaId,
|
||
media?.id || null,
|
||
media?.media_type
|
||
);
|
||
|
||
setResetKey(0);
|
||
setPreviousMediaId(media?.id || null);
|
||
}
|
||
}, [media?.id, media?.media_type, previousMediaId]);
|
||
|
||
const handleReset = () => {
|
||
console.log("🔄 MediaViewer: handleReset вызван", {
|
||
currentResetKey: resetKey,
|
||
mediaId: media?.id,
|
||
});
|
||
setResetKey((prev) => {
|
||
const newKey = prev + 1;
|
||
console.log("🔄 MediaViewer: resetKey обновлен", {
|
||
oldKey: prev,
|
||
newKey,
|
||
});
|
||
return newKey;
|
||
});
|
||
};
|
||
|
||
return (
|
||
<Box
|
||
className={className}
|
||
sx={{
|
||
width: fullWidth ? "100%" : "auto",
|
||
height: fullHeight ? "100%" : "auto",
|
||
display: "flex",
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
overflow: "hidden",
|
||
}}
|
||
width={fullWidth ? "100%" : "auto"}
|
||
height={fullHeight ? "100%" : "auto"}
|
||
>
|
||
{media?.media_type === 1 && (
|
||
<img
|
||
src={`${import.meta.env.VITE_KRBL_MEDIA}${
|
||
media?.id
|
||
}/download?token=${token}`}
|
||
alt={media?.filename}
|
||
style={{
|
||
height: fullHeight ? "100%" : height ? height : "auto",
|
||
width: fullWidth ? "100%" : width ? width : "auto",
|
||
}}
|
||
/>
|
||
)}
|
||
|
||
{media?.media_type === 2 && (
|
||
<video
|
||
src={`${import.meta.env.VITE_KRBL_MEDIA}${
|
||
media?.id
|
||
}/download?token=${token}`}
|
||
style={{
|
||
width: width ? width : "100%",
|
||
height: height ? height : "100%",
|
||
objectFit: "cover",
|
||
borderRadius: 8,
|
||
}}
|
||
controls
|
||
autoPlay
|
||
muted
|
||
/>
|
||
)}
|
||
{media?.media_type === 3 && (
|
||
<img
|
||
src={`${import.meta.env.VITE_KRBL_MEDIA}${
|
||
media?.id
|
||
}/download?token=${token}`}
|
||
alt={media?.filename}
|
||
style={{
|
||
height: fullHeight ? "100%" : height ? height : "auto",
|
||
width: fullWidth ? "100%" : width ? width : "auto",
|
||
}}
|
||
/>
|
||
)}
|
||
{media?.media_type === 4 && (
|
||
<img
|
||
src={`${import.meta.env.VITE_KRBL_MEDIA}${
|
||
media?.id
|
||
}/download?token=${token}`}
|
||
alt={media?.filename}
|
||
style={{
|
||
objectFit: "cover",
|
||
}}
|
||
/>
|
||
)}
|
||
|
||
{media?.media_type === 5 && (
|
||
<ReactPhotoSphereViewer
|
||
src={`${import.meta.env.VITE_KRBL_MEDIA}${
|
||
media?.id
|
||
}/download?token=${token}`}
|
||
width={width ? width : "500px"}
|
||
height={height ? height : "300px"}
|
||
/>
|
||
)}
|
||
|
||
{media?.media_type === 6 && (
|
||
<ThreeViewErrorBoundary
|
||
onReset={handleReset}
|
||
resetKey={`${media?.id}-${resetKey}`}
|
||
>
|
||
<ThreeView
|
||
key={`3d-model-${media?.id}-${resetKey}`}
|
||
fileUrl={`${import.meta.env.VITE_KRBL_MEDIA}${
|
||
media?.id
|
||
}/download?token=${token}`}
|
||
height={height ? height : "500px"}
|
||
width={width ? width : "500px"}
|
||
/>
|
||
</ThreeViewErrorBoundary>
|
||
)}
|
||
</Box>
|
||
);
|
||
}
|