fix: Fix video using in route pages

This commit is contained in:
2025-07-10 06:17:43 +03:00
parent 2d4a1e169b
commit 717031cd7a
7 changed files with 268 additions and 484 deletions

View File

@ -307,29 +307,55 @@ export const RouteCreatePage = observer(() => {
Видео превью
</label>
<Box className="flex gap-2">
<Typography
variant="body1"
onClick={handleVideoPreviewClick}
component="span"
<Box
className="flex-1"
onClick={handleVideoPreviewClick}
sx={{
color:
videoPreview && videoPreview !== "" ? "inherit" : "#999",
cursor:
videoPreview && videoPreview !== "" ? "pointer" : "default",
border: "1px solid #ccc",
borderRadius: "4px",
padding: "16.5px 14px",
display: "flex",
alignItems: "center",
minHeight: "56px",
backgroundColor: "#fff",
}}
>
{videoPreview && videoPreview !== ""
? "Видео выбрано"
: "Видео не выбрано"}
</Typography>
<Box
className="w-full h-[50px] border border-gray-400 rounded-sm flex items-center justify-between px-4"
sx={{
"& .MuiInputBase-input": {
color:
videoPreview && videoPreview !== ""
? "inherit"
: "#999",
cursor:
videoPreview && videoPreview !== ""
? "pointer"
: "default",
},
}}
>
<Typography variant="body1" className="text-sm">
{videoPreview && videoPreview !== ""
? "Видео выбрано"
: "Видео не выбрано"}
</Typography>
{videoPreview && videoPreview !== "" && (
<Box
onClick={(e) => {
e.stopPropagation();
setVideoPreview("");
}}
sx={{
cursor: "pointer",
color: "#999",
"&:hover": {
color: "#666",
},
}}
>
<Typography variant="body1" className="text-lg font-bold">
×
</Typography>
</Box>
)}
</Box>
</Box>
<Button
variant="outlined"
onClick={() => setIsSelectVideoDialogOpen(true)}

View File

@ -313,17 +313,10 @@ export const RouteEditPage = observer(() => {
Видео превью
</label>
<Box className="flex gap-2">
<Typography
variant="body1"
onClick={handleVideoPreviewClick}
component="span"
<Box
className="flex-1"
onClick={handleVideoPreviewClick}
sx={{
color:
editRouteData.video_preview &&
editRouteData.video_preview !== ""
? "inherit"
: "#999",
cursor:
editRouteData.video_preview &&
editRouteData.video_preview !== ""
@ -331,11 +324,54 @@ export const RouteEditPage = observer(() => {
: "default",
}}
>
{editRouteData.video_preview &&
editRouteData.video_preview !== ""
? "Видео выбрано"
: "Видео не выбрано"}
</Typography>
<Box
className="w-full h-[50px] border border-gray-400 rounded-sm flex items-center justify-between px-4"
sx={{
"& .MuiInputBase-input": {
color:
editRouteData.video_preview &&
editRouteData.video_preview !== ""
? "inherit"
: "#999",
cursor:
editRouteData.video_preview &&
editRouteData.video_preview !== ""
? "pointer"
: "default",
},
}}
>
<Typography variant="body1" className="text-sm">
{editRouteData.video_preview &&
editRouteData.video_preview !== ""
? "Видео выбрано"
: "Видео не выбрано"}
</Typography>
{editRouteData.video_preview &&
editRouteData.video_preview !== "" && (
<Box
onClick={(e) => {
e.stopPropagation();
routeStore.setEditRouteData({ video_preview: "" });
}}
sx={{
cursor: "pointer",
color: "#999",
"&:hover": {
color: "#666",
},
}}
>
<Typography
variant="body1"
className="text-lg font-bold"
>
×
</Typography>
</Box>
)}
</Box>
</Box>
<Button
variant="outlined"
onClick={() => setIsSelectVideoDialogOpen(true)}

View File

@ -54,7 +54,7 @@ export function InfiniteCanvas({
const lastOriginalRotation = useRef<number | undefined>(undefined);
useEffect(() => {
const canvas = applicationRef?.app.canvas;
const canvas = applicationRef?.app?.canvas;
if (!canvas) return;
const canvasRect = canvas.getBoundingClientRect();
@ -63,7 +63,7 @@ export function InfiniteCanvas({
const centerX = window.innerWidth / 2 - canvasLeft;
const centerY = window.innerHeight / 2 - canvasTop;
setScreenCenter({ x: centerX, y: centerY });
}, [applicationRef?.app.canvas, setScreenCenter]);
}, [applicationRef?.app?.canvas, setScreenCenter]);
const handlePointerDown = (e: FederatedMouseEvent) => {
setIsPointerDown(true);

View File

@ -1,5 +1,5 @@
import { FederatedMouseEvent, Graphics } from "pixi.js";
import {useCallback, useState, useEffect, useRef, FC, useMemo} from "react";
import { useCallback, useState, useEffect, useRef, FC, useMemo } from "react";
import { observer } from "mobx-react-lite";
// --- Заглушки для зависимостей (замените на ваши реальные импорты) ---
@ -34,22 +34,6 @@ type LabelAlign = "left" | "center" | "right";
/**
* Преобразует текстовое позиционирование в anchor координаты.
*/
const getAnchorFromTextAlign = (align: TextAlign): { x: number; y: number } => {
const parts = align.split(" ");
const horizontal = parts[0] as HorizontalAlign;
const vertical = (parts[1] as VerticalAlign) || "center";
const horizontalMap: Record<HorizontalAlign, number> = {
left: 0,
center: 0.5,
right: 1,
};
const verticalMap: Record<VerticalAlign, number> = {
top: 0,
center: 0.5,
bottom: 1,
};
return { x: horizontalMap[horizontal], y: verticalMap[vertical] };
};
/**
* Получает координату anchor.x из типа выравнивания.
@ -84,7 +68,10 @@ interface LabelAlignmentControlProps {
interface StationLabelProps
extends Omit<StationProps, "ruLabelAnchor" | "nameLabelAnchor"> {}
const getAnchorFromOffset = (offsetX: number, offsetY: number): { x: number; y: number } => {
const getAnchorFromOffset = (
offsetX: number,
offsetY: number
): { x: number; y: number } => {
if (offsetX === 0 && offsetY === 0) {
return { x: 0.5, y: 0.5 };
}
@ -186,6 +173,7 @@ const LabelAlignmentControl: FC<LabelAlignmentControlProps> = ({
return (
<pixiContainer
position={{ x: 0, y: compensatedRuFontSize * 1.1 + 15 / scale }}
zIndex={999999999999999999}
eventMode="static"
onPointerOver={(e: FederatedMouseEvent) => {
e.stopPropagation();
@ -250,8 +238,7 @@ const StationLabel = observer(
({
station,
ruLabel,
anchorPoint,
labelBlockAnchor: labelBlockAnchorProp,
labelAlign: labelAlignProp = "center",
onLabelAlignChange,
onTextHover,
@ -365,14 +352,6 @@ const StationLabel = observer(
const coordinates = coordinatesToLocal(station.latitude, station.longitude);
const compensatedRuFontSize = (26 * 0.75) / scale;
const compensatedNameFontSize = (16 * 0.75) / scale;
const minDistance = 30;
const compensatedOffset = minDistance / scale;
const textBlockPosition = anchorPoint || position;
const finalLabelBlockAnchor = labelBlockAnchorProp || "right center";
const labelBlockAnchor =
typeof finalLabelBlockAnchor === "string"
? getAnchorFromTextAlign(finalLabelBlockAnchor)
: finalLabelBlockAnchor;
// Измеряем ширину верхнего лейбла
useEffect(() => {
@ -433,8 +412,8 @@ const StationLabel = observer(
};
const dynamicAnchor = useMemo(
() => getAnchorFromOffset(position.x, position.y),
[position.x, position.y]
() => getAnchorFromOffset(position.x, position.y),
[position.x, position.y]
);
// Функция для расчета позиции нижнего лейбла относительно ширины верхнего
@ -475,6 +454,7 @@ const StationLabel = observer(
x={coordinates.x * UP_SCALE}
y={coordinates.y * UP_SCALE}
rotation={-rotation}
zIndex={isHovered || isControlHovered ? 1000 : 0}
eventMode="static"
interactive
cursor={isDragging ? "grabbing" : "grab"}
@ -486,11 +466,16 @@ const StationLabel = observer(
onGlobalPointerMove={handlePointerMove}
>
<pixiContainer
position={{
x: (position.x + Math.cos(Math.atan2(position.y, position.x))) / scale,
y: (position.y + Math.sin(Math.atan2(position.y, position.x))) / scale,
}}
position={{
x:
(position.x + Math.cos(Math.atan2(position.y, position.x))) /
scale,
y:
(position.y + Math.sin(Math.atan2(position.y, position.x))) /
scale,
}}
anchor={dynamicAnchor}
zIndex={isHovered || isControlHovered ? 1000 : 0}
>
{ruLabel && (
<pixiText
@ -544,8 +529,7 @@ const StationLabel = observer(
export const Station = ({
station,
ruLabel,
anchorPoint,
labelBlockAnchor,
labelAlign,
onLabelAlignChange,
}: Readonly<StationProps>) => {
@ -566,8 +550,8 @@ export const Station = ({
// Change fill color when text is hovered
if (isTextHovered) {
g.fill({ color: 0x00AAFF }); // Highlight color when hovered
g.stroke({ color: 0xFFFFFF, width: strokeWidth + 1 }); // Brighter outline when hovered
g.fill({ color: 0x00aaff }); // Highlight color when hovered
g.stroke({ color: 0xffffff, width: strokeWidth + 1 }); // Brighter outline when hovered
} else {
g.fill({ color: PATH_COLOR });
g.stroke({ color: BACKGROUND_COLOR, width: strokeWidth });
@ -577,13 +561,11 @@ export const Station = ({
);
return (
<pixiContainer>
<pixiContainer zIndex={isTextHovered ? 1000 : 0}>
<pixiGraphics draw={draw} />
<StationLabel
station={station}
ruLabel={ruLabel}
anchorPoint={anchorPoint}
labelBlockAnchor={labelBlockAnchor}
labelAlign={labelAlign}
onLabelAlignChange={onLabelAlignChange}
onTextHover={setIsTextHovered}