fix: update preview-page bug fix sights
This commit is contained in:
@@ -1,17 +1,12 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { flushSync } from "react-dom";
|
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 { observer } from "mobx-react-lite";
|
||||||
|
|
||||||
import { useMapData } from "../MapDataContext";
|
import { useMapData } from "../MapDataContext";
|
||||||
import { useTransform } from "../TransformContext";
|
import { useTransform } from "../TransformContext";
|
||||||
import { coordinatesToLocal, localToCoordinates } from "../utils";
|
import { coordinatesToLocal, localToCoordinates } from "../utils";
|
||||||
import {
|
import { BACKGROUND_COLOR, SCALE_FACTOR, UP_SCALE } from "../Constants";
|
||||||
BACKGROUND_COLOR,
|
|
||||||
PATH_COLOR,
|
|
||||||
SCALE_FACTOR,
|
|
||||||
UP_SCALE,
|
|
||||||
} from "../Constants";
|
|
||||||
import { languageStore } from "@shared";
|
import { languageStore } from "@shared";
|
||||||
import { SightData } from "../types";
|
import { SightData } from "../types";
|
||||||
|
|
||||||
@@ -360,7 +355,8 @@ const computeViewTransform = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const backgroundColor = toColor(BACKGROUND_COLOR);
|
const backgroundColor = toColor(BACKGROUND_COLOR);
|
||||||
const pathColor = toColor(PATH_COLOR);
|
// Override route & station color to ED1C24
|
||||||
|
const pathColor = toColor(0xed1c24);
|
||||||
|
|
||||||
export const WebGLRouteMapPrototype = observer(() => {
|
export const WebGLRouteMapPrototype = observer(() => {
|
||||||
const {
|
const {
|
||||||
@@ -370,6 +366,7 @@ export const WebGLRouteMapPrototype = observer(() => {
|
|||||||
sightData,
|
sightData,
|
||||||
setSelectedSight,
|
setSelectedSight,
|
||||||
setStationOffset,
|
setStationOffset,
|
||||||
|
setStationAlign,
|
||||||
setSightCoordinates,
|
setSightCoordinates,
|
||||||
setMapCenter,
|
setMapCenter,
|
||||||
} = useMapData();
|
} = useMapData();
|
||||||
@@ -440,6 +437,11 @@ export const WebGLRouteMapPrototype = observer(() => {
|
|||||||
const [liveSightPositions, setLiveSightPositions] = useState<
|
const [liveSightPositions, setLiveSightPositions] = useState<
|
||||||
Map<number, SightLivePosition>
|
Map<number, SightLivePosition>
|
||||||
>(new Map());
|
>(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<{
|
const lastCenterRef = useRef<{
|
||||||
latitude: number | null;
|
latitude: number | null;
|
||||||
longitude: number | null;
|
longitude: number | null;
|
||||||
@@ -586,6 +588,45 @@ export const WebGLRouteMapPrototype = observer(() => {
|
|||||||
}, 120);
|
}, 120);
|
||||||
}, [cancelScheduledCenterCommit, commitCenter]);
|
}, [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(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
cancelScheduledCenterCommit();
|
cancelScheduledCenterCommit();
|
||||||
@@ -1138,8 +1179,8 @@ export const WebGLRouteMapPrototype = observer(() => {
|
|||||||
|
|
||||||
const { scale, translation } = transform;
|
const { scale, translation } = transform;
|
||||||
|
|
||||||
const desiredRouteWidthCss = 13;
|
const desiredRouteWidthCss = 7;
|
||||||
const desiredStationDiameterCss = 30;
|
const desiredStationDiameterCss = 12;
|
||||||
const pointOuterSizePx = desiredStationDiameterCss * dpr;
|
const pointOuterSizePx = desiredStationDiameterCss * dpr;
|
||||||
const pointInnerSizePx = pointOuterSizePx * 0.8;
|
const pointInnerSizePx = pointOuterSizePx * 0.8;
|
||||||
|
|
||||||
@@ -1763,9 +1804,32 @@ export const WebGLRouteMapPrototype = observer(() => {
|
|||||||
const secondaryFontSize = 13 * fontScale;
|
const secondaryFontSize = 13 * fontScale;
|
||||||
const secondaryMarginTop = 5 * 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 (
|
return (
|
||||||
<div
|
<div
|
||||||
key={station.id}
|
key={station.id}
|
||||||
|
onMouseEnter={() => setHoveredStationId(station.id)}
|
||||||
|
onMouseLeave={() =>
|
||||||
|
setHoveredStationId((prev) =>
|
||||||
|
prev === station.id ? null : prev
|
||||||
|
)
|
||||||
|
}
|
||||||
onPointerDown={(event) =>
|
onPointerDown={(event) =>
|
||||||
handleStationPointerDown(
|
handleStationPointerDown(
|
||||||
event,
|
event,
|
||||||
@@ -1807,28 +1871,40 @@ export const WebGLRouteMapPrototype = observer(() => {
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
fontWeight: 700,
|
position: "relative",
|
||||||
fontSize: primaryFontSize,
|
display: "inline-block",
|
||||||
textShadow: "0 0 4px rgba(0,0,0,0.6)",
|
|
||||||
pointerEvents: "none",
|
pointerEvents: "none",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{station.name}
|
|
||||||
</div>
|
|
||||||
{showSecondary ? (
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
fontWeight: 400,
|
fontWeight: 700,
|
||||||
marginTop: -1 * secondaryMarginTop,
|
fontSize: primaryFontSize,
|
||||||
fontSize: secondaryFontSize,
|
textShadow: "0 0 4px rgba(0,0,0,0.6)",
|
||||||
color: "#CBCBCB",
|
|
||||||
textShadow: "0 0 3px rgba(0,0,0,0.4)",
|
|
||||||
pointerEvents: "none",
|
pointerEvents: "none",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{translatedStation?.name}
|
{station.name}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
{showSecondary ? (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
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",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{translatedStation?.name}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -505,7 +505,12 @@ const LinkedStationsContentsInner = <
|
|||||||
}}
|
}}
|
||||||
renderOption={(props, option) => (
|
renderOption={(props, option) => (
|
||||||
<li {...props} key={option.id}>
|
<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>
|
</li>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ export const StationListPage = observer(() => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: "system_name",
|
field: "description",
|
||||||
headerName: "Системное название",
|
headerName: "Описание",
|
||||||
flex: 1,
|
flex: 1,
|
||||||
renderCell: (params: GridRenderCellParams) => {
|
renderCell: (params: GridRenderCellParams) => {
|
||||||
return (
|
return (
|
||||||
@@ -130,7 +130,7 @@ export const StationListPage = observer(() => {
|
|||||||
const rows = filteredStations().map((station: any) => ({
|
const rows = filteredStations().map((station: any) => ({
|
||||||
id: station.id,
|
id: station.id,
|
||||||
name: station.name,
|
name: station.name,
|
||||||
system_name: station.system_name,
|
description: station.description,
|
||||||
direction: station.direction,
|
direction: station.direction,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
BackButton,
|
BackButton,
|
||||||
createSightStore,
|
createSightStore,
|
||||||
|
editSightStore,
|
||||||
languageStore,
|
languageStore,
|
||||||
SelectArticleModal,
|
SelectArticleModal,
|
||||||
TabPanel,
|
TabPanel,
|
||||||
@@ -51,9 +52,6 @@ export const CreateRightTab = observer(
|
|||||||
unlinkPreviewMedia,
|
unlinkPreviewMedia,
|
||||||
createLinkWithRightArticle,
|
createLinkWithRightArticle,
|
||||||
deleteRightArticleMedia,
|
deleteRightArticleMedia,
|
||||||
setFileToUpload,
|
|
||||||
setUploadMediaOpen,
|
|
||||||
uploadMediaOpen,
|
|
||||||
unlinkRightAritcle,
|
unlinkRightAritcle,
|
||||||
deleteRightArticle,
|
deleteRightArticle,
|
||||||
linkExistingRightArticle,
|
linkExistingRightArticle,
|
||||||
@@ -62,6 +60,8 @@ export const CreateRightTab = observer(
|
|||||||
updateRightArticles,
|
updateRightArticles,
|
||||||
} = createSightStore;
|
} = createSightStore;
|
||||||
const { language } = languageStore;
|
const { language } = languageStore;
|
||||||
|
const { setFileToUpload, setUploadMediaOpen, uploadMediaOpen } =
|
||||||
|
editSightStore;
|
||||||
|
|
||||||
const [selectArticleDialogOpen, setSelectArticleDialogOpen] =
|
const [selectArticleDialogOpen, setSelectArticleDialogOpen] =
|
||||||
useState(false);
|
useState(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user