From 88cd9e19c52b9bab38c8d0b08ef70c33fadd1a18 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Fri, 4 Mar 2022 18:34:01 -0800 Subject: [PATCH] Draw aircraft locations in the new map. https://github.com/dcs-liberation/dcs_liberation/issues/2039 --- client/src/api/eventstream.tsx | 7 ++++ client/src/api/flight.ts | 2 +- client/src/api/flightsSlice.ts | 7 ++++ client/src/app/store.ts | 2 +- client/src/components/aircraft/Aircraft.tsx | 32 +++++++++++++++++++ client/src/components/aircraft/index.ts | 1 + .../aircraftlayer/AircraftLayer.tsx | 18 +++++++++++ client/src/components/aircraftlayer/index.ts | 1 + .../liberationmap/LiberationMap.tsx | 4 +++ 9 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 client/src/components/aircraft/Aircraft.tsx create mode 100644 client/src/components/aircraft/index.ts create mode 100644 client/src/components/aircraftlayer/AircraftLayer.tsx create mode 100644 client/src/components/aircraftlayer/index.ts diff --git a/client/src/api/eventstream.tsx b/client/src/api/eventstream.tsx index 70cbbc3f..e2a1b3c0 100644 --- a/client/src/api/eventstream.tsx +++ b/client/src/api/eventstream.tsx @@ -9,6 +9,7 @@ import { selectFlight, unregisterFlight, updateFlight, + updateFlightPosition, } from "./flightsSlice"; import { addFrontLine, @@ -48,6 +49,12 @@ export const handleStreamedEvents = ( dispatch: AppDispatch, events: GameUpdateEvents ) => { + for (const [id, position] of Object.entries( + events.updated_flight_positions + )) { + dispatch(updateFlightPosition([id, position])); + } + for (const flight of events.new_flights) { dispatch(registerFlight(flight)); } diff --git a/client/src/api/flight.ts b/client/src/api/flight.ts index ac5933b9..2306117a 100644 --- a/client/src/api/flight.ts +++ b/client/src/api/flight.ts @@ -4,7 +4,7 @@ import { LatLng } from "leaflet"; export interface Flight { id: string; blue: boolean; - position: LatLng; + position: LatLng | null; sidc: string; waypoints: Waypoint[] | null; } diff --git a/client/src/api/flightsSlice.ts b/client/src/api/flightsSlice.ts index d582aeca..a7be6fab 100644 --- a/client/src/api/flightsSlice.ts +++ b/client/src/api/flightsSlice.ts @@ -1,6 +1,7 @@ import { RootState } from "../app/store"; import { Flight } from "./flight"; import { PayloadAction, createSlice } from "@reduxjs/toolkit"; +import { LatLng } from "leaflet"; interface FlightsState { blue: { [id: string]: Flight }; @@ -55,6 +56,11 @@ export const flightsSlice = createSlice({ const id = action.payload; state.selected = state.blue[id]; }, + updateFlightPosition: (state, action: PayloadAction<[string, LatLng]>) => { + const [id, position] = action.payload; + const ato = id in state.blue ? state.blue : state.red; + ato[id].position = position; + }, }, }); @@ -65,6 +71,7 @@ export const { updateFlight, deselectFlight, selectFlight, + updateFlightPosition, } = flightsSlice.actions; export const selectFlights = (state: RootState) => state.flights; diff --git a/client/src/app/store.ts b/client/src/app/store.ts index e23963ed..c91a140c 100644 --- a/client/src/app/store.ts +++ b/client/src/app/store.ts @@ -15,7 +15,7 @@ export const store = configureStore({ tgos: tgosReducer, }, // The logger middleware must be last or it won't log actions. - middleware: [logger], + //middleware: [logger], }); export type AppDispatch = typeof store.dispatch; diff --git a/client/src/components/aircraft/Aircraft.tsx b/client/src/components/aircraft/Aircraft.tsx new file mode 100644 index 00000000..2d283f35 --- /dev/null +++ b/client/src/components/aircraft/Aircraft.tsx @@ -0,0 +1,32 @@ +import { Flight } from "../../api/flight"; +import { Icon, Point } from "leaflet"; +import { Symbol } from "milsymbol"; +import { Marker } from "react-leaflet"; + +function iconForFlight(flight: Flight) { + const symbol = new Symbol(flight.sidc, { + size: 16, + }); + + return new Icon({ + iconUrl: symbol.toDataURL(), + iconAnchor: new Point(symbol.getAnchor().x, symbol.getAnchor().y), + }); +} + +interface AircraftProps { + flight: Flight; +} + +export default function Aircraft(props: AircraftProps) { + if (!props.flight.position) { + return <>; + } + + return ( + + ); +} diff --git a/client/src/components/aircraft/index.ts b/client/src/components/aircraft/index.ts new file mode 100644 index 00000000..e8019887 --- /dev/null +++ b/client/src/components/aircraft/index.ts @@ -0,0 +1 @@ +export { default } from "./Aircraft"; diff --git a/client/src/components/aircraftlayer/AircraftLayer.tsx b/client/src/components/aircraftlayer/AircraftLayer.tsx new file mode 100644 index 00000000..b44119bb --- /dev/null +++ b/client/src/components/aircraftlayer/AircraftLayer.tsx @@ -0,0 +1,18 @@ +import { selectFlights } from "../../api/flightsSlice"; +import { useAppSelector } from "../../app/hooks"; +import Aircraft from "../aircraft"; +import { LayerGroup } from "react-leaflet"; + +export default function AircraftLayer() { + const atos = useAppSelector(selectFlights); + return ( + + {Object.values(atos.blue).map((flight) => { + return ; + })} + {Object.values(atos.red).map((flight) => { + return ; + })} + + ); +} diff --git a/client/src/components/aircraftlayer/index.ts b/client/src/components/aircraftlayer/index.ts new file mode 100644 index 00000000..f250662a --- /dev/null +++ b/client/src/components/aircraftlayer/index.ts @@ -0,0 +1 @@ +export { default } from "./AircraftLayer"; diff --git a/client/src/components/liberationmap/LiberationMap.tsx b/client/src/components/liberationmap/LiberationMap.tsx index e5def583..8ed893a3 100644 --- a/client/src/components/liberationmap/LiberationMap.tsx +++ b/client/src/components/liberationmap/LiberationMap.tsx @@ -1,3 +1,4 @@ +import AircraftLayer from "../aircraftlayer"; import AirDefenseRangeLayer from "../airdefenserangelayer"; import ControlPointsLayer from "../controlpointslayer"; import FlightPlansLayer from "../flightplanslayer"; @@ -30,6 +31,9 @@ export default function LiberationMap(props: GameProps) { + + +