Добавлено новое поле route_name: Текстовые поля на двух страницах Поле в списке маршрутов Добавлено выбор видео на двух страниц вместе с редактором статей в виде модального окна Модальное окно позволяет создать статью, выбрать готовую, отредактировать выбранную сразу на трех языках Микаэл: Пожалуйста, перепроверь код, вдруг чего найдешь как улучшить + захости локально и потыкай пж: создай с 0 маршрут и прикрепи к нему созданную / какую-нибудь статью с видео, можешь попробовать загрузить либо взять готовое после того как создашь, попробуй потыкать и поменять чего-нибудь (проще обьясню: представь, что ты Руслан) Reviewed-on: #16 Reviewed-by: Микаэл Оганесян <15lu.akari@unprism.ru> Co-authored-by: fisenko <kkzemeow@gmail.com> Co-committed-by: fisenko <kkzemeow@gmail.com>
153 lines
3.9 KiB
TypeScript
153 lines
3.9 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) {
|
|
// Используем новый cache manager для очистки кеша
|
|
clearMediaTransitionCache(
|
|
previousMediaId,
|
|
|
|
media?.media_type
|
|
);
|
|
|
|
setResetKey(0);
|
|
setPreviousMediaId(media?.id || null);
|
|
}
|
|
}, [media?.id, media?.media_type, previousMediaId]);
|
|
|
|
const handleReset = () => {
|
|
setResetKey((prev) => {
|
|
const newKey = prev + 1;
|
|
|
|
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>
|
|
);
|
|
}
|