fix: Delete ai comments
This commit is contained in:
@@ -3,11 +3,9 @@ import { OrbitControls, Stage, useGLTF } from "@react-three/drei";
|
||||
import { useEffect, Suspense } from "react";
|
||||
import { Box, CircularProgress, Typography } from "@mui/material";
|
||||
|
||||
// Утилита для очистки кеша GLTF
|
||||
const clearGLTFCache = (url?: string) => {
|
||||
try {
|
||||
if (url) {
|
||||
// Если это blob URL, очищаем его из кеша
|
||||
if (url.startsWith("blob:")) {
|
||||
useGLTF.clear(url);
|
||||
} else {
|
||||
@@ -19,29 +17,23 @@ const clearGLTFCache = (url?: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
// Утилита для проверки типа файла
|
||||
const isValid3DFile = (url: string): boolean => {
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
const pathname = urlObj.pathname.toLowerCase();
|
||||
const searchParams = urlObj.searchParams;
|
||||
|
||||
// Проверяем расширение файла в пути
|
||||
const validExtensions = [".glb", ".gltf"];
|
||||
const hasValidExtension = validExtensions.some((ext) =>
|
||||
pathname.endsWith(ext)
|
||||
);
|
||||
|
||||
// Проверяем параметры запроса на наличие типа файла
|
||||
const fileType = searchParams.get("type") || searchParams.get("format");
|
||||
const hasValidType =
|
||||
fileType && ["glb", "gltf"].includes(fileType.toLowerCase());
|
||||
|
||||
// Если это blob URL, считаем его валидным (пользователь выбрал файл)
|
||||
const isBlobUrl = url.startsWith("blob:");
|
||||
|
||||
// Если это URL с токеном и нет явного расширения, считаем валидным
|
||||
// (предполагаем что сервер вернет правильный файл)
|
||||
const hasToken = searchParams.has("token");
|
||||
const isServerUrl = hasToken && !hasValidExtension;
|
||||
|
||||
@@ -51,7 +43,7 @@ const isValid3DFile = (url: string): boolean => {
|
||||
return isValid;
|
||||
} catch (error) {
|
||||
console.warn("⚠️ isValid3DFile: Ошибка при проверке URL", error);
|
||||
// В случае ошибки парсинга URL, считаем валидным (пусть useGLTF сам разберется)
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -63,13 +55,10 @@ type ModelViewerProps = {
|
||||
};
|
||||
|
||||
const Model = ({ fileUrl }: { fileUrl: string }) => {
|
||||
// Очищаем кеш перед загрузкой новой модели
|
||||
useEffect(() => {
|
||||
// Очищаем кеш для текущего URL
|
||||
clearGLTFCache(fileUrl);
|
||||
}, [fileUrl]);
|
||||
|
||||
// Проверяем валидность файла перед загрузкой (только для blob URL)
|
||||
if (fileUrl.startsWith("blob:") && !isValid3DFile(fileUrl)) {
|
||||
console.warn("⚠️ Model: Попытка загрузить невалидный 3D файл", { fileUrl });
|
||||
throw new Error(`Файл не является корректной 3D моделью: ${fileUrl}`);
|
||||
@@ -114,16 +103,13 @@ export const ThreeView = ({
|
||||
height = "100%",
|
||||
width = "100%",
|
||||
}: ModelViewerProps) => {
|
||||
// Проверяем валидность файла (только для blob URL)
|
||||
useEffect(() => {
|
||||
if (fileUrl.startsWith("blob:") && !isValid3DFile(fileUrl)) {
|
||||
console.warn("⚠️ ThreeView: Невалидный 3D файл", { fileUrl });
|
||||
}
|
||||
}, [fileUrl]);
|
||||
|
||||
// Очищаем кеш при размонтировании и при смене URL
|
||||
useEffect(() => {
|
||||
// Очищаем кеш сразу при монтировании компонента
|
||||
clearGLTFCache(fileUrl);
|
||||
|
||||
return () => {
|
||||
|
||||
@@ -35,7 +35,6 @@ export class ThreeViewErrorBoundary extends Component<Props, State> {
|
||||
props: Props,
|
||||
state: State
|
||||
): Partial<State> | null {
|
||||
// Сбрасываем ошибку ТОЛЬКО при смене медиа (когда меняется ID в resetKey)
|
||||
if (
|
||||
props.resetKey !== state.lastResetKey &&
|
||||
state.lastResetKey !== undefined
|
||||
@@ -43,7 +42,6 @@ export class ThreeViewErrorBoundary extends Component<Props, State> {
|
||||
const oldMediaId = String(state.lastResetKey).split("-")[0];
|
||||
const newMediaId = String(props.resetKey).split("-")[0];
|
||||
|
||||
// Сбрасываем ошибку только если изменился ID медиа (пользователь выбрал другую модель)
|
||||
if (oldMediaId !== newMediaId) {
|
||||
return {
|
||||
hasError: false,
|
||||
@@ -52,9 +50,6 @@ export class ThreeViewErrorBoundary extends Component<Props, State> {
|
||||
};
|
||||
}
|
||||
|
||||
// Если изменился только счетчик (нажата кнопка "Попробовать снова"), обновляем lastResetKey
|
||||
// но не сбрасываем ошибку автоматически - ждем результата загрузки
|
||||
|
||||
return {
|
||||
lastResetKey: props.resetKey,
|
||||
};
|
||||
@@ -127,15 +122,12 @@ export class ThreeViewErrorBoundary extends Component<Props, State> {
|
||||
};
|
||||
|
||||
handleReset = () => {
|
||||
// Сначала сбрасываем состояние ошибки
|
||||
this.setState(
|
||||
{
|
||||
hasError: false,
|
||||
error: null,
|
||||
},
|
||||
() => {
|
||||
// После того как состояние обновилось, вызываем callback для изменения resetKey
|
||||
// Это приведет к пересозданию компонента и новой попытке загрузки
|
||||
this.props.onReset?.();
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user