import { useMemo, useState, type CSSProperties } from "react"; import { CLASSES, PLAYABLE_RACES, classById, contentCategoryForClass, FACTIONS, raceById } from "../app/characterCatalog"; import { contentCategoryById } from "../app/contentCategories"; import { selectedCharacter, useShellStore } from "../app/shellStore"; import { DualDisplayFrame } from "../components/DualDisplayFrame"; import { useMenuController, type MenuAction } from "../input/useMenuController"; import { CharacterPreview } from "./CharacterPreview"; import { ControllerButton } from "./ControllerButton"; import { BrandMark, ControllerLegend, FrontSurface } from "./FrontSurface"; import { LazyLocalCompanionPanel } from "./LazyLocalCompanionPanel"; function formatLastPlayed(timestamp: number): string { const seconds = Math.max(0, Math.round((Date.now() - timestamp) / 1000)); if (seconds < 60) return "Just now"; const minutes = Math.round(seconds / 60); if (minutes < 60) return `${minutes}m ago`; const hours = Math.round(minutes / 60); if (hours < 48) return `${hours}h ago`; return new Date(timestamp).toLocaleDateString(); } export function CharacterSelectScreen() { const characters = useShellStore((state) => state.characters); const session = useShellStore((state) => state.session); const selectedId = useShellStore((state) => state.selectedCharacterId); const selected = useShellStore(selectedCharacter); const notice = useShellStore((state) => state.notice); const select = useShellStore((state) => state.selectCharacter); const openCreator = useShellStore((state) => state.openCreator); const openMainMenu = useShellStore((state) => state.openMainMenu); const deleteSelected = useShellStore((state) => state.deleteSelectedCharacter); const signOut = useShellStore((state) => state.signOut); const [confirmDelete, setConfirmDelete] = useState(false); const continueWithCharacter = () => { openMainMenu(); }; const actions = useMemo(() => confirmDelete ? [ { id: "cancel-delete", run: () => setConfirmDelete(false) }, { id: "confirm-delete", run: () => { deleteSelected(); setConfirmDelete(false); } }, ] : [ ...characters.map((character) => ({ id: `character-${character.id}`, run: () => select(character.id) })), { id: "new-character", run: openCreator }, { id: "continue-character", run: continueWithCharacter, enabled: Boolean(selected) }, { id: "delete-character", run: () => setConfirmDelete(true), enabled: Boolean(selected) }, { id: "sign-out", run: signOut }, ], [characters, confirmDelete, selected, selectedId]); const controller = useMenuController(actions, { initialId: selectedId ? `character-${selectedId}` : "new-character" }); const race = selected ? raceById(selected.raceId) : null; const characterClass = selected ? classById(selected.classId) : null; return (
{session?.kind === "offline" ? "Offline expedition" : `Local account / ${session?.displayName}`}Choose your adventurer
{selected && race && characterClass && ( <>

{FACTIONS[race.faction].name} / {selected.gender}

{selected.name}

{race.name} {characterClass.name}{selected.secondaryClassId ? ` / ${classById(selected.secondaryClassId).name}` : ""} {characterClass.description}
Continue as {selected.name} )}
{confirmDelete && selected && (

Permanent local action

Delete {selected.name}?

This removes the character from this device. It cannot be undone.

setConfirmDelete(false)}>Keep character { deleteSelected(); setConfirmDelete(false); }}>Delete permanently
)} } bottom={} /> ); }