mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Update the react map for some new events.
This commit is contained in:
@@ -4,11 +4,11 @@ import { ControlPoint } from "./controlpoint";
|
||||
import { RootState } from "../app/store";
|
||||
|
||||
interface ControlPointsState {
|
||||
controlPoints: ControlPoint[];
|
||||
controlPoints: { [key: number]: ControlPoint };
|
||||
}
|
||||
|
||||
const initialState: ControlPointsState = {
|
||||
controlPoints: [],
|
||||
controlPoints: {},
|
||||
};
|
||||
|
||||
export const controlPointsSlice = createSlice({
|
||||
@@ -16,12 +16,20 @@ export const controlPointsSlice = createSlice({
|
||||
initialState,
|
||||
reducers: {
|
||||
setControlPoints: (state, action: PayloadAction<ControlPoint[]>) => {
|
||||
state.controlPoints = action.payload;
|
||||
state.controlPoints = {};
|
||||
for (const cp of action.payload) {
|
||||
state.controlPoints[cp.id] = cp;
|
||||
}
|
||||
},
|
||||
updateControlPoint: (state, action: PayloadAction<ControlPoint>) => {
|
||||
const cp = action.payload;
|
||||
state.controlPoints[cp.id] = cp;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { setControlPoints } = controlPointsSlice.actions;
|
||||
export const { setControlPoints, updateControlPoint } =
|
||||
controlPointsSlice.actions;
|
||||
|
||||
export const selectControlPoints = (state: RootState) => state.controlPoints;
|
||||
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { deselectFlight, selectFlight } from "./flightsSlice";
|
||||
|
||||
import { AppDispatch } from "../app/store";
|
||||
import { ControlPoint } from "./controlpoint";
|
||||
import { Flight } from "./flight";
|
||||
import FrontLine from "./frontline";
|
||||
import { LatLng } from "leaflet";
|
||||
import Tgo from "./tgo";
|
||||
import backend from "./backend";
|
||||
import { updateControlPoint } from "./controlPointsSlice";
|
||||
import { updateTgo } from "./tgosSlice";
|
||||
|
||||
// Placeholder. We don't use this yet. This is just here so we can flesh out the
|
||||
// update events model.
|
||||
@@ -21,6 +27,11 @@ interface GameUpdateEvents {
|
||||
deleted_flights: string[];
|
||||
selected_flight: string | null;
|
||||
deselected_flight: boolean;
|
||||
new_front_lines: FrontLine[];
|
||||
updated_front_lines: string[];
|
||||
deleted_front_lines: string[];
|
||||
updated_tgos: string[];
|
||||
updated_control_points: number[];
|
||||
}
|
||||
|
||||
export const handleStreamedEvents = (
|
||||
@@ -33,4 +44,16 @@ export const handleStreamedEvents = (
|
||||
if (events.selected_flight != null) {
|
||||
dispatch(selectFlight(events.selected_flight));
|
||||
}
|
||||
for (const id of events.updated_tgos) {
|
||||
backend.get(`/tgos/${id}`).then((response) => {
|
||||
const tgo = response.data as Tgo;
|
||||
dispatch(updateTgo(tgo));
|
||||
});
|
||||
}
|
||||
for (const id of events.updated_control_points) {
|
||||
backend.get(`/control-points/${id}`).then((response) => {
|
||||
const cp = response.data as ControlPoint;
|
||||
dispatch(updateControlPoint(cp));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
import { LatLng } from "leaflet";
|
||||
|
||||
export enum TgoType {
|
||||
AIR_DEFENSE = "Air defenses",
|
||||
FACTORY = "Factories",
|
||||
SHIP = "Ships",
|
||||
OTHER = "Other ground objects",
|
||||
}
|
||||
|
||||
export interface Tgo {
|
||||
id: string;
|
||||
name: string;
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
|
||||
import { Tgo, TgoType } from "./tgo";
|
||||
|
||||
import { RootState } from "../app/store";
|
||||
import { Tgo } from "./tgo";
|
||||
|
||||
interface TgosState {
|
||||
tgosByType: { [key: string]: Tgo[] };
|
||||
tgos: { [key: string]: Tgo };
|
||||
}
|
||||
|
||||
const initialState: TgosState = {
|
||||
tgosByType: Object.fromEntries(
|
||||
Object.values(TgoType).map((key) => [key, []])
|
||||
),
|
||||
tgos: {},
|
||||
};
|
||||
|
||||
export const tgosSlice = createSlice({
|
||||
@@ -18,33 +16,19 @@ export const tgosSlice = createSlice({
|
||||
initialState,
|
||||
reducers: {
|
||||
setTgos: (state, action: PayloadAction<Tgo[]>) => {
|
||||
state.tgosByType = initialState.tgosByType;
|
||||
for (const key of Object.values(TgoType)) {
|
||||
state.tgosByType[key] = [];
|
||||
}
|
||||
state.tgos = {};
|
||||
for (const tgo of action.payload) {
|
||||
var type;
|
||||
switch (tgo.category) {
|
||||
case "aa":
|
||||
type = TgoType.AIR_DEFENSE;
|
||||
break;
|
||||
case "factory":
|
||||
type = TgoType.FACTORY;
|
||||
break;
|
||||
case "ship":
|
||||
type = TgoType.SHIP;
|
||||
break;
|
||||
default:
|
||||
type = TgoType.OTHER;
|
||||
break;
|
||||
}
|
||||
state.tgosByType[type].push(tgo);
|
||||
state.tgos[tgo.id] = tgo;
|
||||
}
|
||||
},
|
||||
updateTgo: (state, action: PayloadAction<Tgo>) => {
|
||||
const tgo = action.payload;
|
||||
state.tgos[tgo.id] = tgo;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { setTgos } = tgosSlice.actions;
|
||||
export const { setTgos, updateTgo } = tgosSlice.actions;
|
||||
|
||||
export const selectTgos = (state: RootState) => state.tgos;
|
||||
|
||||
|
||||
@@ -49,19 +49,12 @@ interface AirDefenseRangeLayerProps {
|
||||
}
|
||||
|
||||
export const AirDefenseRangeLayer = (props: AirDefenseRangeLayerProps) => {
|
||||
const tgos = useAppSelector(selectTgos);
|
||||
var allTgos: Tgo[] = [];
|
||||
for (const tgoType of Object.values(tgos.tgosByType)) {
|
||||
for (const tgo of tgoType) {
|
||||
if (tgo.blue === props.blue) {
|
||||
allTgos.push(tgo);
|
||||
}
|
||||
}
|
||||
}
|
||||
const tgos = Object.values(useAppSelector(selectTgos).tgos);
|
||||
var tgosForSide = tgos.filter((tgo) => tgo.blue === props.blue);
|
||||
|
||||
return (
|
||||
<LayerGroup>
|
||||
{allTgos.map((tgo) => {
|
||||
{tgosForSide.map((tgo) => {
|
||||
return (
|
||||
<TgoRangeCircles key={tgo.id} tgo={tgo} {...props}></TgoRangeCircles>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Marker, Tooltip } from "react-leaflet";
|
||||
|
||||
import { ControlPoint as ControlPointModel } from "../../api/controlpoint";
|
||||
import { Symbol as MilSymbol } from "milsymbol";
|
||||
import backend from "../../api/backend";
|
||||
|
||||
function iconForControlPoint(cp: ControlPointModel) {
|
||||
const symbol = new MilSymbol(cp.sidc, {
|
||||
@@ -29,6 +30,16 @@ export default function ControlPoint(props: ControlPointProps) {
|
||||
// other markers are helpful so we want to keep them, but make sure the CP
|
||||
// is always the clickable thing.
|
||||
zIndexOffset={1000}
|
||||
eventHandlers={{
|
||||
click: () => {
|
||||
backend.post(`/qt/info/control-point/${props.controlPoint.id}`);
|
||||
},
|
||||
contextmenu: () => {
|
||||
backend.post(
|
||||
`/qt/create-package/control-point/${props.controlPoint.id}`
|
||||
);
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Tooltip>
|
||||
<h3 style={{ margin: 0 }}>{props.controlPoint.name}</h3>
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function ControlPointsLayer() {
|
||||
const controlPoints = useAppSelector(selectControlPoints);
|
||||
return (
|
||||
<LayerGroup>
|
||||
{controlPoints.controlPoints.map((controlPoint) => {
|
||||
{Object.values(controlPoints.controlPoints).map((controlPoint) => {
|
||||
return (
|
||||
<ControlPoint key={controlPoint.name} controlPoint={controlPoint} />
|
||||
);
|
||||
|
||||
@@ -9,7 +9,6 @@ import FlightPlansLayer from "../flightplanslayer";
|
||||
import FrontLinesLayer from "../frontlineslayer";
|
||||
import { LatLng } from "leaflet";
|
||||
import SupplyRoutesLayer from "../supplyrouteslayer";
|
||||
import { TgoType } from "../../api/tgo";
|
||||
import TgosLayer from "../tgoslayer/TgosLayer";
|
||||
|
||||
interface GameProps {
|
||||
@@ -33,13 +32,18 @@ export default function LiberationMap(props: GameProps) {
|
||||
<LayersControl.Overlay name="Control points" checked>
|
||||
<ControlPointsLayer />
|
||||
</LayersControl.Overlay>
|
||||
{Object.values(TgoType).map((type, idx) => {
|
||||
return (
|
||||
<LayersControl.Overlay key={idx} name={type} checked>
|
||||
<TgosLayer type={type as TgoType} />
|
||||
</LayersControl.Overlay>
|
||||
);
|
||||
})}
|
||||
<LayersControl.Overlay name="Air defenses" checked>
|
||||
<TgosLayer categories={["aa"]} />
|
||||
</LayersControl.Overlay>
|
||||
<LayersControl.Overlay name="Factories" checked>
|
||||
<TgosLayer categories={["factory"]} />
|
||||
</LayersControl.Overlay>
|
||||
<LayersControl.Overlay name="Ships" checked>
|
||||
<TgosLayer categories={["ship"]} />
|
||||
</LayersControl.Overlay>
|
||||
<LayersControl.Overlay name="Other ground objects" checked>
|
||||
<TgosLayer categories={["aa", "factories", "ships"]} exclude />
|
||||
</LayersControl.Overlay>
|
||||
<LayersControl.Overlay name="Supply routes" checked>
|
||||
<SupplyRoutesLayer />
|
||||
</LayersControl.Overlay>
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { LayerGroup } from "react-leaflet";
|
||||
import Tgo from "../tgos/Tgo";
|
||||
import { TgoType } from "../../api/tgo";
|
||||
import { selectTgos } from "../../api/tgosSlice";
|
||||
import { useAppSelector } from "../../app/hooks";
|
||||
|
||||
interface TgosLayerProps {
|
||||
type: TgoType;
|
||||
categories?: string[];
|
||||
exclude?: true;
|
||||
}
|
||||
|
||||
export default function TgosLayer(props: TgosLayerProps) {
|
||||
const allTgos = useAppSelector(selectTgos);
|
||||
const tgos = allTgos.tgosByType[props.type];
|
||||
const allTgos = Object.values(useAppSelector(selectTgos).tgos);
|
||||
const categoryFilter = props.categories ?? [];
|
||||
const tgos = allTgos.filter(
|
||||
(tgo) => categoryFilter.includes(tgo.category) === (props.exclude ?? false)
|
||||
);
|
||||
return (
|
||||
<LayerGroup>
|
||||
{tgos.map((tgo) => {
|
||||
|
||||
Reference in New Issue
Block a user