1
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-20 15:45:14 +08:00
parent 8a7bd90458
commit 1c72066bab
73 changed files with 7814 additions and 1018 deletions

View File

@@ -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>
)}