Something went wrong. Try again.
Starship Simulator Controls thoriumsim.com
Something went wrong. Try again.
6.2 kB · 232 lines
TSX
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233import { keepPreviousData } from "@tanstack/react-query";import { q } from "@thorium/context/AppContext";import { pickStarmapShip } from "@thorium/cores/StarmapCore/pickShip";import { useLocalStorage } from "@thorium/hooks/useLocalStorage";import { useStation } from "@thorium/routes/station/useStation";import Button from "@thorium/ui/Button";import Checkbox from "@thorium/ui/Checkbox";import { InputField, OutputField } from "@thorium/ui/Core";import InfoTip from "@thorium/ui/InfoTip";import Select from "@thorium/ui/Select";import { cn } from "@thorium/utils/cn";import { Suspense } from "react";
import { shortRangeStateMap } from "./shared";export function ShortRangeCommCore() { const { shipId } = useStation(); const [shortRangeComm] = q.shortRangeComm.get.useNetRequest({ shipId }); const [{ allowOtherParticipants }, setAllowOtherParticipants] = useLocalStorage( "core-short-range-allow-other-participants", { allowOtherParticipants: false, }, );
if (!shortRangeComm) return ( <div className="text-sm"> No Short Range Comm <ConversationSelect /> </div> ); return ( <div className="h-full text-sm"> <div className="flex"> <OutputField className="flex-1" alert={shortRangeComm.state !== "idle"}> {shortRangeStateMap[shortRangeComm.state]} <Suspense> <ConversationName conversationId={shortRangeComm.conversationId} /> </Suspense> </OutputField> <InputField className="px-2 tabular-nums" prompt={ <> What would you like to set the frequency to? <br /> 100 - 350 </> } onClick={(value) => { if (Number.isNaN(Number(value))) return; q.shortRangeComm.setFrequency.netSend({ shipId, frequency: Math.min(350, Math.max(100, Number(value))), }); }} promptValue={shortRangeComm.frequency} > {shortRangeComm.frequency.toFixed(2)} MHz </InputField> </div>
<Suspense> <ConversationSelect /> </Suspense> <Checkbox label={ <> Allow Other Participants <InfoTip> Allow another participant to join the conversation after it is connected. </InfoTip> </> } checked={allowOtherParticipants} onChange={(event) => setAllowOtherParticipants({ allowOtherParticipants: event.currentTarget.checked, }) } /> {shortRangeComm.state === "idle" ? ( <Button className="btn-xs btn-info w-full" onClick={() => { pickStarmapShip("Pick a ship to hail.", (targetId) => { if (!targetId || targetId === shipId) return; q.shortRangeComm.hail.netSend({ shipId, targetId, allowOtherParticipants, conversationTemplateId: shortRangeComm.templateConversationId, }); }); }} > Hail... </Button> ) : shortRangeComm.state === "hailing" && shortRangeComm.conversationId ? ( <Suspense> <HailingButtons conversationId={shortRangeComm.conversationId} /> </Suspense> ) : ( <Button className="btn-xs btn-error w-full" onClick={() => q.shortRangeComm.disconnect.netSend({ shipId })} > Disconnect </Button> )} <IncomingHails /> </div> );}
function ConversationName({ conversationId }: { conversationId: number | null | undefined }) { const { shipId } = useStation(); const [conversation] = q.shortRangeComm.conversation.useNetRequest( { conversationId }, { placeholderData: keepPreviousData }, );
return ( <> {conversation ? `: ${conversation.participants .filter((p) => p.id !== shipId) .map((p) => p.name) .join(", ")}` : ""} </> );}
function HailingButtons({ conversationId }: { conversationId: number }) { const { shipId } = useStation();
const [conversation] = q.shortRangeComm.conversation.useNetRequest({ conversationId, });
return ( <div className="flex"> <Button className={cn("btn-xs btn-warning flex-auto", { "rounded-r-none": conversation?.targetId, })} onClick={() => q.shortRangeComm.disconnect.netSend({ shipId })} > Cancel </Button> {conversation?.targetId ? ( <> <Button className="btn-xs btn-error flex-auto rounded-none" onClick={() => { q.shortRangeComm.reject.netSend({ conversationId, }); }} > Reject </Button> <Button className="btn-xs btn-success flex-auto rounded-l-none" onClick={() => { q.shortRangeComm.connect.netSend({ conversationId, shipId: conversation.targetId, }); }} > Connect </Button> </> ) : null} </div> );}
function ConversationSelect() { const { shipId } = useStation(); const [conversationTemplates] = q.conversation.conversationTemplates.useNetRequest(); const [shortRangeComm] = q.shortRangeComm.get.useNetRequest({ shipId });
return ( <Select size="xs" items={conversationTemplates .map((c) => ({ id: c.id, label: c.name })) .concat({ id: null as any, label: "None" })} label="Conversation Template" selected={shortRangeComm?.templateConversationId || null} setSelected={(value) => q.shortRangeComm.setTemplateConversation.netSend({ shipId, templateConversationId: typeof value === "string" ? null : value, }) } /> );}
function IncomingHails() { const { shipId } = useStation(); const [incomingHails] = q.shortRangeComm.incomingHailConversations.useNetRequest({ shipId });
if (incomingHails.length === 0) return null; return ( <div> <p>Incoming Hails</p> {incomingHails.map((c) => ( <div className="flex" key={c.id}> <span className="flex-auto"> {c.hostName} ({c.frequency}MHz){" "} </span> <Button className="btn-xs btn-error rounded-r-none" onClick={() => q.shortRangeComm.reject.netSend({ conversationId: c.id, shipId })} > Reject </Button> <Button className="btn-xs btn-success rounded-l-none" onClick={() => q.shortRangeComm.connect.netSend({ conversationId: c.id, shipId })} > Connect </Button> </div> ))} </div> );}