90 lines
2.7 KiB
TypeScript
90 lines
2.7 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
|
|
import type { GameState } from '../../types';
|
|
import type { GameCanvasEntitySelection } from '../GameCanvas';
|
|
import type { SelectionStage } from './PreGameSelectionFlow';
|
|
|
|
type OverlayPanel = 'character' | 'inventory' | null;
|
|
|
|
function useLazyModalMount(active: boolean) {
|
|
const [shouldMount, setShouldMount] = useState(active);
|
|
|
|
useEffect(() => {
|
|
if (active) {
|
|
setShouldMount(true);
|
|
}
|
|
}, [active]);
|
|
|
|
return shouldMount;
|
|
}
|
|
|
|
export function useGameShellViewModel(params: {
|
|
gameState: GameState;
|
|
isMapOpen: boolean;
|
|
characterChatModalOpen: boolean;
|
|
hasNpcModalOpen: boolean;
|
|
}) {
|
|
const {
|
|
gameState,
|
|
isMapOpen,
|
|
characterChatModalOpen,
|
|
hasNpcModalOpen,
|
|
} = params;
|
|
const [selectionStage, setSelectionStage] = useState<SelectionStage>('platform');
|
|
const [overlayPanel, setOverlayPanel] = useState<OverlayPanel>(null);
|
|
const [selectedSceneEntity, setSelectedSceneEntity] = useState<GameCanvasEntitySelection | null>(null);
|
|
const [showTeamModal, setShowTeamModal] = useState(false);
|
|
|
|
useEffect(() => {
|
|
setSelectedSceneEntity(null);
|
|
}, [gameState.currentScenePreset?.id, gameState.playerCharacter?.id]);
|
|
|
|
const shouldMountAdventureEntityModal = useLazyModalMount(Boolean(selectedSceneEntity));
|
|
const shouldMountCampModal = useLazyModalMount(showTeamModal);
|
|
const shouldMountMapModal = useLazyModalMount(isMapOpen);
|
|
const shouldMountCharacterChatModal = useLazyModalMount(characterChatModalOpen);
|
|
const shouldMountNpcModals = useLazyModalMount(hasNpcModalOpen);
|
|
|
|
const openOverlayPanel = (panel: Exclude<OverlayPanel, null>) => {
|
|
setSelectedSceneEntity(null);
|
|
setOverlayPanel(panel);
|
|
};
|
|
|
|
const closeOverlayPanel = () => setOverlayPanel(null);
|
|
const openPartyMemberDetails = (selection: GameCanvasEntitySelection) => setSelectedSceneEntity(selection);
|
|
const closeAdventureEntityModal = () => setSelectedSceneEntity(null);
|
|
const openCampModal = () => setShowTeamModal(true);
|
|
const closeCampModal = () => setShowTeamModal(false);
|
|
|
|
const resetSelectionFlow = () => setSelectionStage('platform');
|
|
|
|
const resetForSaveAndExit = () => {
|
|
setSelectedSceneEntity(null);
|
|
setOverlayPanel(null);
|
|
setShowTeamModal(false);
|
|
setSelectionStage('platform');
|
|
};
|
|
|
|
return {
|
|
selectionStage,
|
|
setSelectionStage,
|
|
resetSelectionFlow,
|
|
overlayPanel,
|
|
openOverlayPanel,
|
|
closeOverlayPanel,
|
|
selectedSceneEntity,
|
|
setSelectedSceneEntity,
|
|
openPartyMemberDetails,
|
|
closeAdventureEntityModal,
|
|
showTeamModal,
|
|
openCampModal,
|
|
closeCampModal,
|
|
resetForSaveAndExit,
|
|
shouldMountAdventureEntityModal,
|
|
shouldMountCampModal,
|
|
shouldMountMapModal,
|
|
shouldMountCharacterChatModal,
|
|
shouldMountNpcModals,
|
|
};
|
|
}
|