feat: Add preview_video for sights

This commit is contained in:
2025-07-13 20:26:45 +03:00
parent ced3067915
commit bf117ef048
11 changed files with 437 additions and 38 deletions

View File

@@ -5,6 +5,10 @@ import {
Autocomplete,
MenuItem,
Menu as MuiMenu,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
} from "@mui/material";
import {
BackButton,
@@ -20,7 +24,12 @@ import {
UploadMediaDialog,
MEDIA_TYPE_VALUES,
} from "@shared";
import { ImageUploadCard, LanguageSwitcher } from "@widgets";
import {
ImageUploadCard,
LanguageSwitcher,
VideoPreviewCard,
MediaViewer,
} from "@widgets";
import { Save } from "lucide-react";
import { observer } from "mobx-react-lite";
@@ -45,13 +54,17 @@ export const InformationTab = observer(
// Menu state for each media button
const [menuAnchorEl, setMenuAnchorEl] = useState<null | HTMLElement>(null);
const [activeMenuType, setActiveMenuType] = useState<
"thumbnail" | "watermark_lu" | "watermark_rd" | null
"thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview" | null
>(null);
const [isAddMediaOpen, setIsAddMediaOpen] = useState(false);
const [isVideoPreviewOpen, setIsVideoPreviewOpen] = useState(false);
const [hardcodeType, setHardcodeType] = useState<
"thumbnail" | "watermark_lu" | "watermark_rd" | null
"thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview" | null
>(null);
const { cities } = cityStore;
useEffect(() => {}, [hardcodeType]);
useEffect(() => {
// Показывать только при инициализации (не менять при ошибках пользователя)
if (sight.common.latitude !== 0 || sight.common.longitude !== 0) {
@@ -74,22 +87,28 @@ export const InformationTab = observer(
handleMenuClose();
};
const handleMediaSelect = (media: {
id: string;
filename: string;
media_name?: string;
media_type: number;
}) => {
if (!activeMenuType) return;
const handleMediaSelect = (
media: {
id: string;
filename: string;
media_name?: string;
media_type: number;
},
type: "thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview"
) => {
handleChange(
language as Language,
{
[activeMenuType ?? "thumbnail"]: media.id,
[type]: media.id,
},
true
);
};
setIsUploadMediaOpen(false);
const handleVideoPreviewClick = () => {
if (sight.common.video_preview && sight.common.video_preview !== "") {
setIsVideoPreviewOpen(true);
}
};
const handleChange = (
@@ -337,6 +356,33 @@ export const InformationTab = observer(
setHardcodeType("watermark_rd");
}}
/>
<VideoPreviewCard
title="Видео превью"
videoId={sight.common.video_preview}
onVideoClick={handleVideoPreviewClick}
onDeleteVideoClick={() => {
handleChange(
language as Language,
{
video_preview: null,
},
true
);
}}
onSelectVideoClick={(file) => {
if (file) {
// Если передан файл, открываем диалог загрузки медиа
editSightStore.setFileToUpload(file);
setActiveMenuType("video_preview");
setIsUploadMediaOpen(true);
} else {
// Если файл не передан, открываем диалог выбора существующих медиа
setActiveMenuType("video_preview");
setIsAddMediaOpen(true);
}
}}
/>
</Box>
</Box>
</Box>
@@ -395,8 +441,13 @@ export const InformationTab = observer(
open={isAddMediaOpen}
onClose={() => {
setIsAddMediaOpen(false);
setActiveMenuType(null);
}}
onSelectMedia={(media) => {
if (activeMenuType) {
handleMediaSelect(media, activeMenuType);
}
}}
onSelectMedia={handleMediaSelect}
mediaType={
activeMenuType
? MEDIA_TYPE_VALUES[
@@ -412,23 +463,62 @@ export const InformationTab = observer(
contextObjectName={sight[language].name}
contextType="sight"
afterUpload={(media) => {
handleChange(
language as Language,
{
[activeMenuType ?? "thumbnail"]: media.id,
},
true
);
if (activeMenuType === "video_preview") {
handleChange(
language as Language,
{
video_preview: media.id,
},
true
);
} else {
handleChange(
language as Language,
{
[activeMenuType ?? "thumbnail"]: media.id,
},
true
);
}
setActiveMenuType(null);
setIsUploadMediaOpen(false);
}}
hardcodeType={hardcodeType}
hardcodeType={activeMenuType}
initialFile={editSightStore.fileToUpload || undefined}
/>
<PreviewMediaDialog
open={isPreviewMediaOpen}
onClose={() => setIsPreviewMediaOpen(false)}
mediaId={mediaId}
/>
{/* Модальное окно предпросмотра видео */}
{sight.common.video_preview && sight.common.video_preview !== "" && (
<Dialog
open={isVideoPreviewOpen}
onClose={() => setIsVideoPreviewOpen(false)}
maxWidth="md"
fullWidth
>
<DialogTitle>Предпросмотр видео</DialogTitle>
<DialogContent>
<Box className="flex justify-center items-center p-4">
<MediaViewer
media={{
id: sight.common.video_preview,
media_type: 2,
filename: "video_preview",
}}
/>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={() => setIsVideoPreviewOpen(false)}>
Закрыть
</Button>
</DialogActions>
</Dialog>
)}
</>
);
}