import { useState } from "react"; import type { ReactNode } from "react"; import { WelcomeCards } from "../components/Welcome"; import { SpendingFloor } from "../components/IndependentPilots"; import { resetMapView } from "../map/camera"; import { About } from "./AboutSettings"; import { CompanyName, NewCompany } from "./CompanySettings"; import { DevTools } from "./DevTools"; import { ExportSave, ImportSave } from "./SaveSettings"; import { content } from "@deadhead/content"; import { sleepLabel } from "../components/FleetSleep"; import { errorMessage, useGameAction, useLoadedPlayer } from "../state/actions"; import { usePreferences, type ClockFormat, type CountdownFormat } from "../state/preferences"; import { Button, Panel, Screen, ScreenHeader } from "../ui"; /** Developer tools only exist in non-production builds (CR-011). */ export function isDevBuild(): boolean { return !import.meta.env.PROD; } /** Settings (CR-011): company, display, help, about and, in development, developer tools. */ export function Settings() { const state = useLoadedPlayer(); const prefs = usePreferences(); const [howToPlay, setHowToPlay] = useState(false); return (
label="Clock" value={prefs.clock} options={[ ["locale", "Device"], ["12h", "12-hour"], ["24h", "24-hour"], ]} onChange={(clock) => prefs.set({ clock })} /> label="Countdowns" value={prefs.countdown} options={[ ["real", "Real time"], ["game", "Game time"], ["both", "Both"], ]} onChange={(countdown) => prefs.set({ countdown })} /> label="Reduced motion" value={prefs.reducedMotion === null ? "device" : prefs.reducedMotion ? "on" : "off"} options={[ ["device", "Device"], ["on", "On"], ["off", "Off"], ]} onChange={(v) => prefs.set({ reducedMotion: v === "device" ? null : v === "on" })} />
label="Arrivals, radio calls, rest, upgrades and a quiet fleet" value={prefs.notifications ? "on" : "off"} options={[ ["on", "On"], ["off", "Off"], ]} onChange={(v) => prefs.set({ notifications: v === "on" })} />

On the iOS and Android apps only.

{/* The welcome cards again, ending in Close (decision 0.5.132). */} {howToPlay && setHowToPlay(false)} />}
{isDevBuild() && (
)}
); } function Section({ title, children }: { title: string; children: ReactNode }) { const id = `settings-${title.toLowerCase()}`; return (

{title}

{children}
); } /** "Fleet goes quiet after": the sleep threshold (decision 0.5.137), a company setting. */ function SleepThreshold() { const state = useLoadedPlayer(); const save = useGameAction("setSleepThreshold"); if (state.tutorial) return null; return (
label="Fleet goes quiet after" value={String(state.fleetSleep.afterHours)} options={content.config.fleetSleep.optionsHours.map((h) => [String(h), sleepLabel(h)])} onChange={(value) => save.mutate({ hours: Number(value) })} />

Without any orders from you for this long, Independent pilots stop taking new jobs.

{save.isError && (

{errorMessage(save.error)}

)}
); } /** A labelled radio group of a few options, styled as a segmented control. */ function Choice(props: { label: string; value: T; options: [T, string][]; onChange: (value: T) => void; }) { return (
{props.label}
{props.options.map(([value, text]) => ( ))}
); }