@@ -1,9 +1,13 @@
|
||||
import { AnimatePresence, motion } from 'motion/react';
|
||||
import { lazy, Suspense } from 'react';
|
||||
|
||||
import type { CharacterChatUi, InventoryFlowUi, StoryGenerationNpcUi } from '../../hooks/useStoryGeneration';
|
||||
import type {
|
||||
CharacterChatUi,
|
||||
InventoryFlowUi,
|
||||
StoryGenerationNpcUi,
|
||||
} from '../../hooks/useStoryGeneration';
|
||||
import type { CompanionRenderState, GameState } from '../../types';
|
||||
import { CHROME_ICONS, getNineSliceStyle,UI_CHROME } from '../../uiAssets';
|
||||
import { CHROME_ICONS, getNineSliceStyle, UI_CHROME } from '../../uiAssets';
|
||||
import type { GameCanvasEntitySelection } from '../GameCanvas';
|
||||
import { PixelIcon } from '../PixelIcon';
|
||||
import { ModalLoadingFallback, PanelLoadingFallback } from './GameShellLoaders';
|
||||
@@ -120,7 +124,14 @@ export function GameShellOverlays({
|
||||
return (
|
||||
<>
|
||||
{shouldMountAdventureEntityModal && (
|
||||
<Suspense fallback={<ModalLoadingFallback label="正在加载冒险详情..." onClose={closeAdventureEntityModal} />}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<ModalLoadingFallback
|
||||
label="正在加载冒险详情..."
|
||||
onClose={closeAdventureEntityModal}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<AdventureEntityModal
|
||||
selection={selectedSceneEntity}
|
||||
gameState={gameState}
|
||||
@@ -146,10 +157,12 @@ export function GameShellOverlays({
|
||||
transition={{ duration: 0.18, ease: 'easeOut' }}
|
||||
className="pixel-nine-slice pixel-modal-shell flex max-h-[min(92vh,60rem)] w-full max-w-5xl flex-col overflow-hidden shadow-[0_24px_80px_rgba(0,0,0,0.55)]"
|
||||
style={getNineSliceStyle(UI_CHROME.modalPanel)}
|
||||
onClick={event => event.stopPropagation()}
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
>
|
||||
<div className="relative border-b border-white/10 px-4 py-3 sm:px-5 sm:py-4">
|
||||
<div className="min-w-0 pr-10 text-sm font-semibold text-white">{overlayPanel === 'character' ? '队伍' : '背包'}</div>
|
||||
<div className="min-w-0 pr-10 text-sm font-semibold text-white">
|
||||
{overlayPanel === 'character' ? '队伍' : '背包'}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={closeOverlayPanel}
|
||||
@@ -160,11 +173,14 @@ export function GameShellOverlays({
|
||||
</div>
|
||||
<div className="flex min-h-0 flex-1 p-5">
|
||||
{overlayPanel === 'character' ? (
|
||||
<Suspense fallback={<PanelLoadingFallback label="正在加载队伍面板" />}>
|
||||
<Suspense
|
||||
fallback={<PanelLoadingFallback label="正在加载队伍面板" />}
|
||||
>
|
||||
<CharacterPanel
|
||||
worldType={gameState.worldType}
|
||||
customWorldProfile={gameState.customWorldProfile}
|
||||
playerCharacter={gameState.playerCharacter}
|
||||
playerProgression={gameState.playerProgression ?? null}
|
||||
playerHp={gameState.playerHp}
|
||||
playerMaxHp={gameState.playerMaxHp}
|
||||
playerMana={gameState.playerMana}
|
||||
@@ -178,7 +194,7 @@ export function GameShellOverlays({
|
||||
closeOverlayPanel();
|
||||
openCampModal();
|
||||
}}
|
||||
onOpenCharacterChat={target => {
|
||||
onOpenCharacterChat={(target) => {
|
||||
closeOverlayPanel();
|
||||
characterChatUi.openChat(target);
|
||||
}}
|
||||
@@ -187,7 +203,9 @@ export function GameShellOverlays({
|
||||
/>
|
||||
</Suspense>
|
||||
) : (
|
||||
<Suspense fallback={<PanelLoadingFallback label="正在加载背包面板" />}>
|
||||
<Suspense
|
||||
fallback={<PanelLoadingFallback label="正在加载背包面板" />}
|
||||
>
|
||||
<InventoryPanel
|
||||
playerCharacter={gameState.playerCharacter}
|
||||
worldType={gameState.worldType}
|
||||
@@ -214,7 +232,14 @@ export function GameShellOverlays({
|
||||
</AnimatePresence>
|
||||
|
||||
{shouldMountCampModal && (
|
||||
<Suspense fallback={<ModalLoadingFallback label="正在加载队伍营地..." onClose={closeCampModal} />}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<ModalLoadingFallback
|
||||
label="正在加载队伍营地..."
|
||||
onClose={closeCampModal}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<CompanionCampModal
|
||||
isOpen={showTeamModal}
|
||||
playerCharacter={gameState.playerCharacter}
|
||||
@@ -229,13 +254,20 @@ export function GameShellOverlays({
|
||||
)}
|
||||
|
||||
{shouldMountMapModal && (
|
||||
<Suspense fallback={<ModalLoadingFallback label="正在加载地图..." onClose={() => setIsMapOpen(false)} />}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<ModalLoadingFallback
|
||||
label="正在加载地图..."
|
||||
onClose={() => setIsMapOpen(false)}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<MapModal
|
||||
isOpen={isMapOpen}
|
||||
currentScenePreset={gameState.currentScenePreset}
|
||||
worldType={gameState.worldType}
|
||||
canTravel={!gameState.inBattle && !isLoading}
|
||||
onTravelToScene={scene => {
|
||||
onTravelToScene={(scene) => {
|
||||
const triggered = handleMapTravelToScene(scene.id);
|
||||
if (triggered) {
|
||||
setIsMapOpen(false);
|
||||
@@ -248,7 +280,14 @@ export function GameShellOverlays({
|
||||
)}
|
||||
|
||||
{shouldMountCharacterChatModal && (
|
||||
<Suspense fallback={<ModalLoadingFallback label="正在加载角色聊天..." onClose={characterChatUi.closeChat} />}>
|
||||
<Suspense
|
||||
fallback={
|
||||
<ModalLoadingFallback
|
||||
label="正在加载角色聊天..."
|
||||
onClose={characterChatUi.closeChat}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<CharacterChatModal
|
||||
modal={characterChatUi.modal}
|
||||
onClose={characterChatUi.closeChat}
|
||||
@@ -261,7 +300,9 @@ export function GameShellOverlays({
|
||||
)}
|
||||
|
||||
{shouldMountNpcModals && (
|
||||
<Suspense fallback={<ModalLoadingFallback label="正在加载角色交互..." />}>
|
||||
<Suspense
|
||||
fallback={<ModalLoadingFallback label="正在加载角色交互..." />}
|
||||
>
|
||||
<NpcModals gameState={gameState} npcUi={npcUi} />
|
||||
</Suspense>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user