fix: restore route video preview
This commit is contained in:
@@ -64,6 +64,7 @@ export type GetRouteResponse = {
|
|||||||
route_sys_number: string;
|
route_sys_number: string;
|
||||||
scale_max: number;
|
scale_max: number;
|
||||||
scale_min: number;
|
scale_min: number;
|
||||||
|
video_preview: string;
|
||||||
video_timer?: number;
|
video_timer?: number;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
icon_size?: number;
|
icon_size?: number;
|
||||||
|
|||||||
@@ -7,8 +7,12 @@ import {
|
|||||||
InputLabel,
|
InputLabel,
|
||||||
Typography,
|
Typography,
|
||||||
Box,
|
Box,
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { ImageUploadCard } from "@widgets";
|
import { MediaViewer, VideoPreviewCard, ImageUploadCard } from "@widgets";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { ArrowLeft, Loader2, Save, Plus, X } from "lucide-react";
|
import { ArrowLeft, Loader2, Save, Plus, X } from "lucide-react";
|
||||||
import { useEffect, useState, useMemo } from "react";
|
import { useEffect, useState, useMemo } from "react";
|
||||||
@@ -51,10 +55,14 @@ export const RouteCreatePage = observer(() => {
|
|||||||
const [centerLat, setCenterLat] = useState("");
|
const [centerLat, setCenterLat] = useState("");
|
||||||
const [centerLng, setCenterLng] = useState("");
|
const [centerLng, setCenterLng] = useState("");
|
||||||
const [videoTimer, setVideoTimer] = useState(420);
|
const [videoTimer, setVideoTimer] = useState(420);
|
||||||
|
const [videoPreview, setVideoPreview] = useState<string>("");
|
||||||
const [icon, setIcon] = useState<string>("");
|
const [icon, setIcon] = useState<string>("");
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [isSelectArticleDialogOpen, setIsSelectArticleDialogOpen] =
|
const [isSelectArticleDialogOpen, setIsSelectArticleDialogOpen] =
|
||||||
useState(false);
|
useState(false);
|
||||||
|
const [isSelectVideoDialogOpen, setIsSelectVideoDialogOpen] = useState(false);
|
||||||
|
const [isVideoPreviewOpen, setIsVideoPreviewOpen] = useState(false);
|
||||||
|
const [isUploadVideoDialogOpen, setIsUploadVideoDialogOpen] = useState(false);
|
||||||
const [isSelectIconDialogOpen, setIsSelectIconDialogOpen] = useState(false);
|
const [isSelectIconDialogOpen, setIsSelectIconDialogOpen] = useState(false);
|
||||||
const [isUploadIconDialogOpen, setIsUploadIconDialogOpen] = useState(false);
|
const [isUploadIconDialogOpen, setIsUploadIconDialogOpen] = useState(false);
|
||||||
const [isPreviewIconOpen, setIsPreviewIconOpen] = useState(false);
|
const [isPreviewIconOpen, setIsPreviewIconOpen] = useState(false);
|
||||||
@@ -62,6 +70,7 @@ export const RouteCreatePage = observer(() => {
|
|||||||
const [activeIconMenuType, setActiveIconMenuType] = useState<
|
const [activeIconMenuType, setActiveIconMenuType] = useState<
|
||||||
"thumbnail" | "watermark_lu" | "watermark_rd" | "image" | null
|
"thumbnail" | "watermark_lu" | "watermark_rd" | "image" | null
|
||||||
>(null);
|
>(null);
|
||||||
|
const [fileToUpload, setFileToUpload] = useState<File | null>(null);
|
||||||
const { language } = languageStore;
|
const { language } = languageStore;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -137,11 +146,42 @@ export const RouteCreatePage = observer(() => {
|
|||||||
setIsSelectIconDialogOpen(false);
|
setIsSelectIconDialogOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleVideoSelect = (media: {
|
||||||
|
id: string;
|
||||||
|
filename: string;
|
||||||
|
media_name?: string;
|
||||||
|
media_type: number;
|
||||||
|
}) => {
|
||||||
|
setVideoPreview(media.id);
|
||||||
|
setIsSelectVideoDialogOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleVideoFileSelect = (file?: File) => {
|
||||||
|
if (file) {
|
||||||
|
setFileToUpload(file);
|
||||||
|
setIsUploadVideoDialogOpen(true);
|
||||||
|
} else {
|
||||||
|
setIsSelectVideoDialogOpen(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleVideoUpload = (media: {
|
||||||
|
id: string;
|
||||||
|
filename: string;
|
||||||
|
media_name?: string;
|
||||||
|
media_type: number;
|
||||||
|
}) => {
|
||||||
|
setVideoPreview(media.id);
|
||||||
|
setIsUploadVideoDialogOpen(false);
|
||||||
|
setFileToUpload(null);
|
||||||
|
};
|
||||||
|
|
||||||
const selectedIconMedia =
|
const selectedIconMedia =
|
||||||
icon && !isMediaIdEmpty(icon)
|
icon && !isMediaIdEmpty(icon)
|
||||||
? mediaStore.media.find((m) => m.id === icon)
|
? mediaStore.media.find((m) => m.id === icon)
|
||||||
: null;
|
: null;
|
||||||
const effectiveIconUrl = isMediaIdEmpty(icon) ? null : selectedIconMedia?.id ?? icon;
|
const effectiveIconUrl = isMediaIdEmpty(icon) ? null : selectedIconMedia?.id ?? icon;
|
||||||
|
const effectiveVideoId = isMediaIdEmpty(videoPreview) ? null : videoPreview;
|
||||||
|
|
||||||
const handleCreateRoute = async () => {
|
const handleCreateRoute = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -236,6 +276,7 @@ export const RouteCreatePage = observer(() => {
|
|||||||
center_latitude,
|
center_latitude,
|
||||||
center_longitude,
|
center_longitude,
|
||||||
path,
|
path,
|
||||||
|
video_preview: !isMediaIdEmpty(videoPreview) ? videoPreview : undefined,
|
||||||
icon: !isMediaIdEmpty(icon) ? icon : undefined,
|
icon: !isMediaIdEmpty(icon) ? icon : undefined,
|
||||||
video_timer: videoTimer,
|
video_timer: videoTimer,
|
||||||
};
|
};
|
||||||
@@ -436,6 +477,16 @@ export const RouteCreatePage = observer(() => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-col gap-4 max-w-[300px]">
|
||||||
|
<VideoPreviewCard
|
||||||
|
title="Видеозаставка"
|
||||||
|
videoId={effectiveVideoId}
|
||||||
|
onVideoClick={() => setIsVideoPreviewOpen(true)}
|
||||||
|
onDeleteVideoClick={() => setVideoPreview("")}
|
||||||
|
onSelectVideoClick={handleVideoFileSelect}
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<FormControl fullWidth required>
|
<FormControl fullWidth required>
|
||||||
@@ -552,6 +603,50 @@ export const RouteCreatePage = observer(() => {
|
|||||||
onClose={() => setIsSelectArticleDialogOpen(false)}
|
onClose={() => setIsSelectArticleDialogOpen(false)}
|
||||||
onSelectArticle={handleArticleSelect}
|
onSelectArticle={handleArticleSelect}
|
||||||
/>
|
/>
|
||||||
|
<SelectMediaDialog
|
||||||
|
open={isSelectVideoDialogOpen}
|
||||||
|
onClose={() => setIsSelectVideoDialogOpen(false)}
|
||||||
|
onSelectMedia={handleVideoSelect}
|
||||||
|
mediaType={2}
|
||||||
|
/>
|
||||||
|
{effectiveVideoId && (
|
||||||
|
<Dialog
|
||||||
|
open={isVideoPreviewOpen}
|
||||||
|
onClose={() => setIsVideoPreviewOpen(false)}
|
||||||
|
maxWidth="md"
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
<DialogTitle>Предпросмотр видео</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<Box className="flex justify-center items-center p-4">
|
||||||
|
<MediaViewer
|
||||||
|
media={{
|
||||||
|
id: effectiveVideoId,
|
||||||
|
media_type: 2,
|
||||||
|
filename: "video_preview",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => setIsVideoPreviewOpen(false)}>
|
||||||
|
Закрыть
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
)}
|
||||||
|
<UploadMediaDialog
|
||||||
|
open={isUploadVideoDialogOpen}
|
||||||
|
onClose={() => {
|
||||||
|
setIsUploadVideoDialogOpen(false);
|
||||||
|
setFileToUpload(null);
|
||||||
|
}}
|
||||||
|
hardcodeType="video_preview"
|
||||||
|
contextObjectName={routeName || "Маршрут"}
|
||||||
|
contextType="route"
|
||||||
|
initialFile={fileToUpload || undefined}
|
||||||
|
afterUpload={handleVideoUpload}
|
||||||
|
/>
|
||||||
<SelectMediaDialog
|
<SelectMediaDialog
|
||||||
open={isSelectIconDialogOpen}
|
open={isSelectIconDialogOpen}
|
||||||
onClose={() => setIsSelectIconDialogOpen(false)}
|
onClose={() => setIsSelectIconDialogOpen(false)}
|
||||||
|
|||||||
@@ -7,8 +7,14 @@ import {
|
|||||||
InputLabel,
|
InputLabel,
|
||||||
Typography,
|
Typography,
|
||||||
Box,
|
Box,
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import {
|
import {
|
||||||
|
MediaViewer,
|
||||||
|
VideoPreviewCard,
|
||||||
ImageUploadCard,
|
ImageUploadCard,
|
||||||
DeleteModal,
|
DeleteModal,
|
||||||
} from "@widgets";
|
} from "@widgets";
|
||||||
@@ -48,6 +54,9 @@ export const RouteEditPage = observer(() => {
|
|||||||
const [isLoadingData, setIsLoadingData] = useState(true);
|
const [isLoadingData, setIsLoadingData] = useState(true);
|
||||||
const [isSelectArticleDialogOpen, setIsSelectArticleDialogOpen] =
|
const [isSelectArticleDialogOpen, setIsSelectArticleDialogOpen] =
|
||||||
useState(false);
|
useState(false);
|
||||||
|
const [isSelectVideoDialogOpen, setIsSelectVideoDialogOpen] = useState(false);
|
||||||
|
const [isVideoPreviewOpen, setIsVideoPreviewOpen] = useState(false);
|
||||||
|
const [isUploadVideoDialogOpen, setIsUploadVideoDialogOpen] = useState(false);
|
||||||
const [isSelectIconDialogOpen, setIsSelectIconDialogOpen] = useState(false);
|
const [isSelectIconDialogOpen, setIsSelectIconDialogOpen] = useState(false);
|
||||||
const [isUploadIconDialogOpen, setIsUploadIconDialogOpen] = useState(false);
|
const [isUploadIconDialogOpen, setIsUploadIconDialogOpen] = useState(false);
|
||||||
const [isPreviewIconOpen, setIsPreviewIconOpen] = useState(false);
|
const [isPreviewIconOpen, setIsPreviewIconOpen] = useState(false);
|
||||||
@@ -56,6 +65,7 @@ export const RouteEditPage = observer(() => {
|
|||||||
const [activeIconMenuType, setActiveIconMenuType] = useState<
|
const [activeIconMenuType, setActiveIconMenuType] = useState<
|
||||||
"thumbnail" | "watermark_lu" | "watermark_rd" | "image" | null
|
"thumbnail" | "watermark_lu" | "watermark_rd" | "image" | null
|
||||||
>(null);
|
>(null);
|
||||||
|
const [fileToUpload, setFileToUpload] = useState<File | null>(null);
|
||||||
const { language } = languageStore;
|
const { language } = languageStore;
|
||||||
const [coordinates, setCoordinates] = useState<string>("");
|
const [coordinates, setCoordinates] = useState<string>("");
|
||||||
|
|
||||||
@@ -104,6 +114,9 @@ export const RouteEditPage = observer(() => {
|
|||||||
const effectiveIconUrl = isMediaIdEmpty(editRouteData.icon)
|
const effectiveIconUrl = isMediaIdEmpty(editRouteData.icon)
|
||||||
? null
|
? null
|
||||||
: (selectedIconMedia?.id ?? editRouteData.icon);
|
: (selectedIconMedia?.id ?? editRouteData.icon);
|
||||||
|
const effectiveVideoId = isMediaIdEmpty(editRouteData.video_preview)
|
||||||
|
? null
|
||||||
|
: editRouteData.video_preview;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editRouteData.path && editRouteData.path.length > 0) {
|
if (editRouteData.path && editRouteData.path.length > 0) {
|
||||||
@@ -225,6 +238,36 @@ export const RouteEditPage = observer(() => {
|
|||||||
articlesStore.getArticleList();
|
articlesStore.getArticleList();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleVideoSelect = (media: {
|
||||||
|
id: string;
|
||||||
|
filename: string;
|
||||||
|
media_name?: string;
|
||||||
|
media_type: number;
|
||||||
|
}) => {
|
||||||
|
routeStore.setEditRouteData({ video_preview: media.id });
|
||||||
|
setIsSelectVideoDialogOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleVideoFileSelect = (file?: File) => {
|
||||||
|
if (file) {
|
||||||
|
setFileToUpload(file);
|
||||||
|
setIsUploadVideoDialogOpen(true);
|
||||||
|
} else {
|
||||||
|
setIsSelectVideoDialogOpen(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleVideoUpload = (media: {
|
||||||
|
id: string;
|
||||||
|
filename: string;
|
||||||
|
media_name?: string;
|
||||||
|
media_type: number;
|
||||||
|
}) => {
|
||||||
|
routeStore.setEditRouteData({ video_preview: media.id });
|
||||||
|
setIsUploadVideoDialogOpen(false);
|
||||||
|
setFileToUpload(null);
|
||||||
|
};
|
||||||
|
|
||||||
// Получаем название выбранной статьи для отображения
|
// Получаем название выбранной статьи для отображения
|
||||||
const selectedArticle = articlesStore.articleList.ru.data.find(
|
const selectedArticle = articlesStore.articleList.ru.data.find(
|
||||||
(article) => article.id === editRouteData.governor_appeal
|
(article) => article.id === editRouteData.governor_appeal
|
||||||
@@ -593,6 +636,18 @@ export const RouteEditPage = observer(() => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-col gap-4 max-w-[300px]">
|
||||||
|
<VideoPreviewCard
|
||||||
|
title="Видеозаставка"
|
||||||
|
videoId={effectiveVideoId}
|
||||||
|
onVideoClick={() => setIsVideoPreviewOpen(true)}
|
||||||
|
onDeleteVideoClick={() =>
|
||||||
|
routeStore.setEditRouteData({ video_preview: "" })
|
||||||
|
}
|
||||||
|
onSelectVideoClick={handleVideoFileSelect}
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@@ -638,6 +693,48 @@ export const RouteEditPage = observer(() => {
|
|||||||
onClose={() => setIsSelectArticleDialogOpen(false)}
|
onClose={() => setIsSelectArticleDialogOpen(false)}
|
||||||
onSelectArticle={handleArticleSelect}
|
onSelectArticle={handleArticleSelect}
|
||||||
/>
|
/>
|
||||||
|
<SelectMediaDialog
|
||||||
|
open={isSelectVideoDialogOpen}
|
||||||
|
onClose={() => setIsSelectVideoDialogOpen(false)}
|
||||||
|
onSelectMedia={handleVideoSelect}
|
||||||
|
mediaType={2}
|
||||||
|
/>
|
||||||
|
<Dialog
|
||||||
|
open={isVideoPreviewOpen}
|
||||||
|
onClose={() => setIsVideoPreviewOpen(false)}
|
||||||
|
maxWidth="md"
|
||||||
|
fullWidth
|
||||||
|
>
|
||||||
|
<DialogTitle>Предпросмотр видео</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<Box className="flex justify-center items-center p-4">
|
||||||
|
{effectiveVideoId && (
|
||||||
|
<MediaViewer
|
||||||
|
media={{
|
||||||
|
id: effectiveVideoId,
|
||||||
|
media_type: 2,
|
||||||
|
filename: "video_preview",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => setIsVideoPreviewOpen(false)}>Закрыть</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
<UploadMediaDialog
|
||||||
|
open={isUploadVideoDialogOpen}
|
||||||
|
onClose={() => {
|
||||||
|
setIsUploadVideoDialogOpen(false);
|
||||||
|
setFileToUpload(null);
|
||||||
|
}}
|
||||||
|
hardcodeType="video_preview"
|
||||||
|
contextObjectName={editRouteData.route_name || "Маршрут"}
|
||||||
|
contextType="route"
|
||||||
|
initialFile={fileToUpload || undefined}
|
||||||
|
afterUpload={handleVideoUpload}
|
||||||
|
/>
|
||||||
<SelectMediaDialog
|
<SelectMediaDialog
|
||||||
open={isSelectIconDialogOpen}
|
open={isSelectIconDialogOpen}
|
||||||
onClose={() => setIsSelectIconDialogOpen(false)}
|
onClose={() => setIsSelectIconDialogOpen(false)}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export type Route = {
|
|||||||
route_sys_number: string;
|
route_sys_number: string;
|
||||||
scale_max: number;
|
scale_max: number;
|
||||||
scale_min: number;
|
scale_min: number;
|
||||||
|
video_preview: string;
|
||||||
video_timer: number;
|
video_timer: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -153,16 +154,21 @@ class RouteStore {
|
|||||||
route_sys_number: "",
|
route_sys_number: "",
|
||||||
scale_max: 0,
|
scale_max: 0,
|
||||||
scale_min: 0,
|
scale_min: 0,
|
||||||
|
video_preview: "" as string | undefined,
|
||||||
video_timer: 420,
|
video_timer: 420,
|
||||||
};
|
};
|
||||||
|
|
||||||
setEditRouteData = (data: any) => {
|
setEditRouteData = (data: any) => {
|
||||||
const routeData = { ...data };
|
this.editRouteData = { ...this.editRouteData, ...data };
|
||||||
delete routeData.video_preview;
|
|
||||||
this.editRouteData = { ...this.editRouteData, ...routeData };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
editRoute = async (id: number) => {
|
editRoute = async (id: number) => {
|
||||||
|
if (
|
||||||
|
!this.editRouteData.video_preview ||
|
||||||
|
isMediaIdEmpty(this.editRouteData.video_preview)
|
||||||
|
) {
|
||||||
|
delete this.editRouteData.video_preview;
|
||||||
|
}
|
||||||
if (!this.editRouteData.icon || isMediaIdEmpty(this.editRouteData.icon)) {
|
if (!this.editRouteData.icon || isMediaIdEmpty(this.editRouteData.icon)) {
|
||||||
delete (this.editRouteData as any).icon;
|
delete (this.editRouteData as any).icon;
|
||||||
}
|
}
|
||||||
@@ -174,7 +180,6 @@ class RouteStore {
|
|||||||
center_latitude: parseFloat(this.editRouteData.center_latitude),
|
center_latitude: parseFloat(this.editRouteData.center_latitude),
|
||||||
center_longitude: parseFloat(this.editRouteData.center_longitude),
|
center_longitude: parseFloat(this.editRouteData.center_longitude),
|
||||||
};
|
};
|
||||||
delete dataToSend.video_preview;
|
|
||||||
if (
|
if (
|
||||||
this.editRouteData.governor_appeal === 0 ||
|
this.editRouteData.governor_appeal === 0 ||
|
||||||
!this.editRouteData.governor_appeal
|
!this.editRouteData.governor_appeal
|
||||||
|
|||||||
Reference in New Issue
Block a user