feat: Add checkbox for sightbar entity + fix build errors

This commit is contained in:
2025-06-09 18:48:25 +03:00
parent 2ca1f2cba4
commit e2e750877a
25 changed files with 302 additions and 269 deletions

View File

@ -171,20 +171,14 @@ export const MapDataProvider = observer(
async function saveStationChanges() {
for (const station of stationChanges) {
const response = await authInstance.patch(
`/route/${routeId}/station`,
station
);
await authInstance.patch(`/route/${routeId}/station`, station);
}
}
async function saveSightChanges() {
console.log("sightChanges", sightChanges);
for (const sight of sightChanges) {
const response = await authInstance.patch(
`/route/${routeId}/sight`,
sight
);
await authInstance.patch(`/route/${routeId}/sight`, sight);
}
}

View File

@ -2,118 +2,106 @@ import { useEffect, useState } from "react";
import { useTransform } from "./TransformContext";
import { SightData } from "./types";
import { Assets, FederatedMouseEvent, Graphics, Texture } from "pixi.js";
import { COLORS } from "../../contexts/color-mode/theme";
import { SIGHT_SIZE, UP_SCALE } from "./Constants";
import { coordinatesToLocal, localToCoordinates } from "./utils";
import { useMapData } from "./MapDataContext";
interface SightProps {
sight: SightData;
id: number;
sight: SightData;
id: number;
}
export function Sight({
sight, id
}: Readonly<SightProps>) {
const { rotation, scale } = useTransform();
const { setSightCoordinates } = useMapData();
export function Sight({ sight, id }: Readonly<SightProps>) {
const { rotation, scale } = useTransform();
const { setSightCoordinates } = useMapData();
const [position, setPosition] = useState(coordinatesToLocal(sight.latitude, sight.longitude));
const [isDragging, setIsDragging] = useState(false);
const [startPosition, setStartPosition] = useState({ x: 0, y: 0 });
const [startMousePosition, setStartMousePosition] = useState({ x: 0, y: 0 });
const [position, setPosition] = useState(
coordinatesToLocal(sight.latitude, sight.longitude)
);
const [isDragging, setIsDragging] = useState(false);
const [startPosition, setStartPosition] = useState({ x: 0, y: 0 });
const [startMousePosition, setStartMousePosition] = useState({ x: 0, y: 0 });
const handlePointerDown = (e: FederatedMouseEvent) => {
setIsDragging(true);
setStartPosition({
x: position.x,
y: position.y
});
setStartMousePosition({
x: e.globalX,
y: e.globalY
});
e.stopPropagation();
};
const handlePointerMove = (e: FederatedMouseEvent) => {
if (!isDragging) return;
const dx = (e.globalX - startMousePosition.x) / scale / UP_SCALE;
const dy = (e.globalY - startMousePosition.y) / scale / UP_SCALE;
const cos = Math.cos(rotation);
const sin = Math.sin(rotation);
const newPosition = {
x: startPosition.x + dx * cos + dy * sin,
y: startPosition.y - dx * sin + dy * cos
};
setPosition(newPosition);
const coordinates = localToCoordinates(newPosition.x, newPosition.y);
setSightCoordinates(sight.id, coordinates.latitude, coordinates.longitude);
e.stopPropagation();
const handlePointerDown = (e: FederatedMouseEvent) => {
setIsDragging(true);
setStartPosition({
x: position.x,
y: position.y,
});
setStartMousePosition({
x: e.globalX,
y: e.globalY,
});
e.stopPropagation();
};
const handlePointerMove = (e: FederatedMouseEvent) => {
if (!isDragging) return;
const dx = (e.globalX - startMousePosition.x) / scale / UP_SCALE;
const dy = (e.globalY - startMousePosition.y) / scale / UP_SCALE;
const cos = Math.cos(rotation);
const sin = Math.sin(rotation);
const newPosition = {
x: startPosition.x + dx * cos + dy * sin,
y: startPosition.y - dx * sin + dy * cos,
};
setPosition(newPosition);
const coordinates = localToCoordinates(newPosition.x, newPosition.y);
setSightCoordinates(sight.id, coordinates.latitude, coordinates.longitude);
e.stopPropagation();
};
const handlePointerUp = (e: FederatedMouseEvent) => {
setIsDragging(false);
e.stopPropagation();
};
const handlePointerUp = (e: FederatedMouseEvent) => {
setIsDragging(false);
e.stopPropagation();
};
const [texture, setTexture] = useState(Texture.EMPTY);
useEffect(() => {
if (texture === Texture.EMPTY) {
Assets
.load('/SightIcon.png')
.then((result) => {
setTexture(result)
});
}
}, [texture]);
const [texture, setTexture] = useState(Texture.EMPTY);
useEffect(() => {
if (texture === Texture.EMPTY) {
Assets.load("/SightIcon.png").then((result) => {
setTexture(result);
});
}
}, [texture]);
function draw(g: Graphics) {
g.clear();
g.circle(0, 0, 20);
g.fill({color: COLORS.primary}); // Fill circle with primary color
}
function draw(g: Graphics) {
g.clear();
g.circle(0, 0, 20);
g.fill({ color: "#000" }); // Fill circle with primary color
}
if(!sight) {
console.error("sight is null");
return null;
}
if (!sight) {
console.error("sight is null");
return null;
}
const coordinates = coordinatesToLocal(sight.latitude, sight.longitude);
return (
<pixiContainer rotation={-rotation}
eventMode='static'
interactive
onPointerDown={handlePointerDown}
onGlobalPointerMove={handlePointerMove}
onPointerUp={handlePointerUp}
onPointerUpOutside={handlePointerUp}
x={position.x * UP_SCALE - SIGHT_SIZE/2} // Offset by half width to center
y={position.y * UP_SCALE - SIGHT_SIZE/2} // Offset by half height to center
>
<pixiSprite
texture={texture}
width={SIGHT_SIZE}
height={SIGHT_SIZE}
/>
<pixiGraphics
draw={draw}
x={SIGHT_SIZE}
y={0}
/>
<pixiText
text={`${id+1}`}
x={SIGHT_SIZE+1}
y={0}
anchor={0.5}
style={{
fontSize: 24,
fontWeight: 'bold',
fill: "#ffffff",
}}
/>
</pixiContainer>
);
}
return (
<pixiContainer
rotation={-rotation}
eventMode="static"
interactive
onPointerDown={handlePointerDown}
onGlobalPointerMove={handlePointerMove}
onPointerUp={handlePointerUp}
onPointerUpOutside={handlePointerUp}
x={position.x * UP_SCALE - SIGHT_SIZE / 2} // Offset by half width to center
y={position.y * UP_SCALE - SIGHT_SIZE / 2} // Offset by half height to center
>
<pixiSprite texture={texture} width={SIGHT_SIZE} height={SIGHT_SIZE} />
<pixiGraphics draw={draw} x={SIGHT_SIZE} y={0} />
<pixiText
text={`${id + 1}`}
x={SIGHT_SIZE + 1}
y={0}
anchor={0.5}
style={{
fontSize: 24,
fontWeight: "bold",
fill: "#ffffff",
}}
/>
</pixiContainer>
);
}

View File

@ -7,12 +7,11 @@ import {
UP_SCALE,
} from "./Constants";
import { useTransform } from "./TransformContext";
import { useCallback, useEffect, useRef, useState } from "react";
import { useCallback, useState } from "react";
import { StationData } from "./types";
import { useMapData } from "./MapDataContext";
import { coordinatesToLocal } from "./utils";
import { observer } from "mobx-react-lite";
import { languageStore } from "@shared";
interface StationProps {
station: StationData;
@ -47,7 +46,6 @@ export const Station = observer(
export const StationLabel = observer(
({ station, ruLabel }: Readonly<StationProps>) => {
const { language } = languageStore;
const { rotation, scale } = useTransform();
const { setStationOffset } = useMapData();

View File

@ -1,6 +1,6 @@
import { useRef, useEffect, useState } from "react";
import { Application, ApplicationRef, extend } from "@pixi/react";
import { Application, extend } from "@pixi/react";
import {
Container,
Graphics,
@ -13,7 +13,7 @@ import { Stack } from "@mui/material";
import { MapDataProvider, useMapData } from "./MapDataContext";
import { TransformProvider, useTransform } from "./TransformContext";
import { InfiniteCanvas } from "./InfiniteCanvas";
import { Sight } from "./Sight";
import { UP_SCALE } from "./Constants";
import { Station } from "./Station";
import { TravelPath } from "./TravelPath";