fix: update preview-page bug fix sights

This commit is contained in:
2025-11-26 19:37:26 +03:00
parent aaeaed3fa5
commit 11133b6839
4 changed files with 111 additions and 30 deletions

View File

@@ -1,17 +1,12 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { flushSync } from "react-dom";
import type { PointerEvent as ReactPointerEvent } from "react";
import type { PointerEvent as ReactPointerEvent, CSSProperties } from "react";
import { observer } from "mobx-react-lite";
import { useMapData } from "../MapDataContext";
import { useTransform } from "../TransformContext";
import { coordinatesToLocal, localToCoordinates } from "../utils";
import {
BACKGROUND_COLOR,
PATH_COLOR,
SCALE_FACTOR,
UP_SCALE,
} from "../Constants";
import { BACKGROUND_COLOR, SCALE_FACTOR, UP_SCALE } from "../Constants";
import { languageStore } from "@shared";
import { SightData } from "../types";
@@ -360,7 +355,8 @@ const computeViewTransform = (
};
const backgroundColor = toColor(BACKGROUND_COLOR);
const pathColor = toColor(PATH_COLOR);
// Override route & station color to ED1C24
const pathColor = toColor(0xed1c24);
export const WebGLRouteMapPrototype = observer(() => {
const {
@@ -370,6 +366,7 @@ export const WebGLRouteMapPrototype = observer(() => {
sightData,
setSelectedSight,
setStationOffset,
setStationAlign,
setSightCoordinates,
setMapCenter,
} = useMapData();
@@ -440,6 +437,11 @@ export const WebGLRouteMapPrototype = observer(() => {
const [liveSightPositions, setLiveSightPositions] = useState<
Map<number, SightLivePosition>
>(new Map());
type StationAlignment = "left" | "center" | "right";
const [stationAlignments, setStationAlignments] = useState<
Map<number, StationAlignment>
>(new Map());
const [hoveredStationId, setHoveredStationId] = useState<number | null>(null);
const lastCenterRef = useRef<{
latitude: number | null;
longitude: number | null;
@@ -586,6 +588,45 @@ export const WebGLRouteMapPrototype = observer(() => {
}, 120);
}, [cancelScheduledCenterCommit, commitCenter]);
useEffect(() => {
if (hoveredStationId == null) {
return;
}
const handleKeyDown = (event: KeyboardEvent) => {
const key = event.key;
let nextAlignment: StationAlignment | null = null;
let alignNumber: number | null = null;
if (key === "1") {
nextAlignment = "left";
alignNumber = 1;
} else if (key === "2") {
nextAlignment = "center";
alignNumber = 2;
} else if (key === "3") {
nextAlignment = "right";
alignNumber = 3;
}
if (!nextAlignment || alignNumber === null) {
return;
}
setStationAlignments((prev) => {
const next = new Map(prev);
next.set(hoveredStationId, nextAlignment as StationAlignment);
return next;
});
setStationAlign(hoveredStationId, alignNumber);
};
window.addEventListener("keydown", handleKeyDown);
return () => {
window.removeEventListener("keydown", handleKeyDown);
};
}, [hoveredStationId, setStationAlignments, setStationAlign]);
useEffect(() => {
return () => {
cancelScheduledCenterCommit();
@@ -1138,8 +1179,8 @@ export const WebGLRouteMapPrototype = observer(() => {
const { scale, translation } = transform;
const desiredRouteWidthCss = 13;
const desiredStationDiameterCss = 30;
const desiredRouteWidthCss = 7;
const desiredStationDiameterCss = 12;
const pointOuterSizePx = desiredStationDiameterCss * dpr;
const pointInnerSizePx = pointOuterSizePx * 0.8;
@@ -1763,9 +1804,32 @@ export const WebGLRouteMapPrototype = observer(() => {
const secondaryFontSize = 13 * fontScale;
const secondaryMarginTop = 5 * fontScale;
const backendAlign = station.align;
const alignmentFromData: StationAlignment =
backendAlign === 1
? "left"
: backendAlign === 3
? "right"
: "center";
const alignment: StationAlignment =
stationAlignments.get(station.id) ?? alignmentFromData;
const secondaryPositionStyle: CSSProperties =
alignment === "left"
? { left: 0, transform: "none" }
: alignment === "right"
? { right: 0, transform: "none" }
: { left: "50%", transform: "translateX(-50%)" };
return (
<div
key={station.id}
onMouseEnter={() => setHoveredStationId(station.id)}
onMouseLeave={() =>
setHoveredStationId((prev) =>
prev === station.id ? null : prev
)
}
onPointerDown={(event) =>
handleStationPointerDown(
event,
@@ -1804,6 +1868,13 @@ export const WebGLRouteMapPrototype = observer(() => {
transformOrigin: "left center",
transform: `rotate(${counterRotationCss})`,
}}
>
<div
style={{
position: "relative",
display: "inline-block",
pointerEvents: "none",
}}
>
<div
style={{
@@ -1818,11 +1889,15 @@ export const WebGLRouteMapPrototype = observer(() => {
{showSecondary ? (
<div
style={{
fontWeight: 400,
position: "absolute",
top: "100%",
marginTop: -1 * secondaryMarginTop,
fontWeight: 400,
fontSize: secondaryFontSize,
color: "#CBCBCB",
textShadow: "0 0 3px rgba(0,0,0,0.4)",
whiteSpace: "nowrap",
...secondaryPositionStyle,
pointerEvents: "none",
}}
>
@@ -1832,6 +1907,7 @@ export const WebGLRouteMapPrototype = observer(() => {
</div>
</div>
</div>
</div>
);
})}
</div>

View File

@@ -505,7 +505,12 @@ const LinkedStationsContentsInner = <
}}
renderOption={(props, option) => (
<li {...props} key={option.id}>
{String(option.name)}
<div className="flex justify-between items-center w-full">
<p>{String(option.name)}</p>
<p className="text-xs text-gray-500 max-w-[300px] mr-4 truncate">
{String(option.description)}
</p>
</div>
</li>
)}
/>

View File

@@ -51,8 +51,8 @@ export const StationListPage = observer(() => {
},
},
{
field: "system_name",
headerName: "Системное название",
field: "description",
headerName: "Описание",
flex: 1,
renderCell: (params: GridRenderCellParams) => {
return (
@@ -130,7 +130,7 @@ export const StationListPage = observer(() => {
const rows = filteredStations().map((station: any) => ({
id: station.id,
name: station.name,
system_name: station.system_name,
description: station.description,
direction: station.direction,
}));

View File

@@ -10,6 +10,7 @@ import {
import {
BackButton,
createSightStore,
editSightStore,
languageStore,
SelectArticleModal,
TabPanel,
@@ -51,9 +52,6 @@ export const CreateRightTab = observer(
unlinkPreviewMedia,
createLinkWithRightArticle,
deleteRightArticleMedia,
setFileToUpload,
setUploadMediaOpen,
uploadMediaOpen,
unlinkRightAritcle,
deleteRightArticle,
linkExistingRightArticle,
@@ -62,6 +60,8 @@ export const CreateRightTab = observer(
updateRightArticles,
} = createSightStore;
const { language } = languageStore;
const { setFileToUpload, setUploadMediaOpen, uploadMediaOpen } =
editSightStore;
const [selectArticleDialogOpen, setSelectArticleDialogOpen] =
useState(false);