Skip to content

Commit

Permalink
feat(Navigation): Add a list for managing waypoints, including deleti…
Browse files Browse the repository at this point in the history
…ng waypoints. Closes #389
  • Loading branch information
alexanderson1993 committed Aug 2, 2022
1 parent 51a15c7 commit 1228d67
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 13 deletions.
34 changes: 26 additions & 8 deletions client/src/cards/Navigation/data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export const requests = {
},
waypoints: (
context: DataContext,
params: {shipId?: number; systemId: number | null},
params: {shipId?: number; systemId: "all" | number | null},
publishParams: {shipId: number}
) => {
const shipId = params.shipId ?? context.ship?.id;
Expand All @@ -119,14 +119,16 @@ export const requests = {
(prev: Waypoint[], next) => {
if (
next.components.isWaypoint?.assignedShipId === shipId &&
next.components.position?.parentId === params.systemId
(params.systemId === "all" ||
next.components.position?.parentId === params.systemId)
) {
prev.push({
id: next.id,
name: next.components.identity?.name || "",
objectId: next.components.isWaypoint?.attachedObjectId,
position: next.components.position,
});
if (next.components.position)
prev.push({
id: next.id,
name: next.components.identity?.name || "",
objectId: next.components.isWaypoint?.attachedObjectId,
position: next.components.position,
});
}
return prev;
},
Expand Down Expand Up @@ -301,6 +303,22 @@ export const inputs = {

return newWaypoint;
},
waypointDelete(context: DataContext, params: {waypointId: number}) {
if (!context.flight) throw new Error("No flight in progress");
const ship = context.ship;
if (!ship) throw new Error("No ship selected.");
const shipId = ship.id;
const waypoint = context.flight.ecs.entities.find(
e => e.id === params.waypointId
);
if (!waypoint) throw new Error("No waypoint found.");
if (waypoint.components.isWaypoint?.assignedShipId !== shipId)
throw new Error("Waypoint is not assigned to this ship.");
context.flight.ecs.removeEntity(waypoint);
pubsub.publish("waypoints", {
shipId,
});
},
};

function getObjectOffsetPosition(object: Entity, ship: Entity) {
Expand Down
102 changes: 97 additions & 5 deletions client/src/cards/Navigation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
useCalculateVerticalDistance,
useGetStarmapStore,
} from "client/src/components/Starmap/starmapStore";
import {useEffect, useState} from "react";
import {useEffect, useRef, useState, Suspense} from "react";
import StarmapCanvas from "client/src/components/Starmap/StarmapCanvas";
import Input from "@thorium/ui/Input";
import {CardProps} from "client/src/components/Station/CardProps";
Expand All @@ -18,28 +18,120 @@ import {useDataStream} from "client/src/context/useDataStream";
import SearchableInput, {DefaultResultLabel} from "@thorium/ui/SearchableInput";
import {netRequest} from "client/src/context/useNetRequest";
import {capitalCase} from "change-case";

import {useSpring, a} from "@react-spring/web";
import SearchableList from "@thorium/ui/SearchableList";
import {useNetRequest} from "client/src/context/useNetRequest";
import {LoadingSpinner} from "@thorium/ui/LoadingSpinner";
import {FaBan} from "react-icons/fa";
export function Navigation(props: CardProps) {
useDataStream();
return (
<StarmapStoreProvider>
<div className="mx-auto h-full bg-black/70 border border-white/50 relative">
<CanvasWrapper shouldRender={props.cardLoaded} />
<Suspense fallback={<LoadingSpinner />}>
<CanvasWrapper shouldRender={props.cardLoaded} />
</Suspense>
<div className="grid grid-cols-2 grid-rows-2 absolute inset-0 pointer-events-none p-4">
<div className="pointer-events-auto max-w-sm">
<StarmapSearch />
</div>
<div className="w-96 self-start justify-self-end max-h-min">
<ObjectDetails />
<AddWaypoint />{" "}
<Suspense fallback={null}>
<ObjectDetails />
<AddWaypoint />{" "}
</Suspense>
</div>
<MapControls />
<Suspense fallback={null}>
<Waypoints />
</Suspense>
</div>
</div>
</StarmapStoreProvider>
);
}

function Waypoints() {
const useStarmapStore = useGetStarmapStore();
const [style, animate] = useSpring(() => ({height: "0px"}), []);
const [toggle, setToggle] = useState(false);
const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
animate({
height: (toggle ? 250 : 0) + "px",
});
}, [animate, ref, toggle]);
const waypoints = useNetRequest("waypoints", {systemId: "all"});
return (
<div className="self-end justify-self-end w-96 pointer-events-auto">
<Button className="btn-primary w-full" onClick={() => setToggle(t => !t)}>
{toggle ? "Hide" : "Show"} Waypoints
</Button>
<a.div
className="overflow-hidden w-full mt-2"
style={{
...style,
}}
>
<div ref={ref} className="flex flex-col h-full">
<SearchableList
items={
waypoints.length === 0
? [{id: -1, label: "No waypoints set."}]
: waypoints.map(w => ({
id: w.id,
label: w.name,
}))
}
renderItem={({id, label}) => (
<span className="flex">
<span className="flex-1">{label}</span>
{id > -1 && (
<button
className="appearance-none"
onClick={e => {
e.preventDefault();
e.stopPropagation();
netSend("waypointDelete", {waypointId: id});
}}
>
<FaBan className="text-red-500" />
</button>
)}
</span>
)}
setSelectedItem={async id => {
const waypoint = waypoints.find(w => w.id === id);
if (waypoint) {
if (
useStarmapStore.getState().currentSystem !==
waypoint?.position.parentId
) {
await useStarmapStore
.getState()
.setCurrentSystem(waypoint?.position.parentId);
}
console.log(waypoint);
useStarmapStore.setState({
selectedObjectId: waypoint.objectId || null,
});
const controls = useStarmapStore.getState().cameraControls;
controls?.current?.moveTo(
waypoint.position.x,
waypoint.position.y,
waypoint.position.z,
true
);
}
}}
/>
</div>
</a.div>
</div>
);
}

function AddWaypoint() {
const useStarmapStore = useGetStarmapStore();
const selectedObjectId = useStarmapStore(store => store.selectedObjectId);
Expand Down

0 comments on commit 1228d67

Please sign in to comment.