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) {
+
+
+