import { Canvas, useFrame } from "@react-three/fiber";
import { PlanetSphere } from "@thorium/components/Starmap/Planet";
import { Clouds } from "@thorium/components/Starmap/Planet/Clouds";
import Star from "@thorium/components/Starmap/Star/StarMesh";
import { useGetStarmapStore } from "@thorium/components/Starmap/starmapStore";
import { q } from "@thorium/context/AppContext";
import { useCardContext } from "@thorium/context/CardContext";
import useAnimationFrame from "@thorium/hooks/useAnimationFrame";
import { useStation } from "@thorium/routes/station/useStation";
import { cn } from "@thorium/utils/cn";
import { useLiveQuery } from "@thorium/utils/live-query/client";
import { getNavigationDistance } from "@thorium/utils/starmap/getNavigationDistance";
import { Suspense, useRef } from "react";
import { Color, type Group } from "three";
function getDistanceLabel(input: { distance: number; unit: string } | null) {
if (!input) return "Unknown";
return `${input.distance.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})} ${input.unit}`;
}
export const ObjectDetails = () => {
const useStarmapStore = useGetStarmapStore();
const selectedObjectIds = useStarmapStore((store) => store.selectedObjectIds);
return (
{selectedObjectIds[0] ? (
Accessing...}>
) : (
No Object Selected
)}
);
};
export const ObjectData = ({ objectId }: { objectId: number | string }) => {
const [object, distanceRef] = useObjectData(objectId);
if (!object) return null;
return (
{object.name}
{object.classification}
Distance:
);
};
export function useObjectData(objectId: number | string) {
const { shipId } = useStation();
const { cardLoaded } = useCardContext();
const [ship] = q.navigation.ship.useNetRequest({ shipId });
const { interpolate } = useLiveQuery();
const distanceRef = useRef(null);
const [requestData] = q.navigation.object.useNetRequest({
objectId: Number(objectId) || undefined,
shipId,
});
const [result] = q.sensors.scanResult.useNetRequest({
objectId: Number(objectId),
shipId,
});
const object = requestData.object;
const objectSystem = requestData.objectSystem;
const shipSystem = requestData.shipSystem;
useAnimationFrame(() => {
const objectPosition = interpolate(Number(objectId)) || object?.position;
if (distanceRef.current && objectPosition) {
const shipPosition = interpolate(ship.id);
const distance = getNavigationDistance(
objectPosition,
shipPosition,
objectSystem,
shipSystem,
);
distanceRef.current.innerText = getDistanceLabel(distance);
}
}, cardLoaded);
return [result.identification, distanceRef] as const;
}
export function ObjectImage({
objectImage,
className,
}: {
objectImage: NonNullable<
Awaited>["identification"]
>["image"];
className?: string;
}) {
if (!objectImage) return null;
return objectImage.type === "solarSystem" ? null : (
{objectImage.type === "planet" ? (
) : objectImage.type === "star" ? (
) : objectImage.type === "ship" ? (
) : null}
);
}
const PlanetGroup = ({
cloudMapAsset,
textureMapAsset,
}: {
cloudMapAsset?: string | null;
ringMapAsset?: string | null;
textureMapAsset: string;
}) => {
const planetRef = useRef(null);
useFrame(() => {
if (planetRef.current) {
planetRef.current.rotateY(0.002);
}
});
return (
{/* The ring really does not look goood. */}
{/* {ringMapAsset && } */}
{cloudMapAsset && }
);
};
const PlanetCanvas = ({
textureMapAsset,
...props
}: {
cloudMapAsset?: string | null;
ringMapAsset?: string | null;
textureMapAsset?: string | null;
}) => {
if (!textureMapAsset) return null;
return (
);
};
const StarCanvas = ({ hue, isWhite }: { hue: number; isWhite: boolean }) => {
const color1 = new Color(`hsl(${hue}, 100%, ${isWhite ? 100 : 50}%)`);
const color2 = new Color(`hsl(${hue + 20}, 100%, ${isWhite ? 100 : 50}%)`);
return (
);
};