v0.1.36a: 三问题修复——成员弹框双排名/界面白屏防线/推进异常取证+出险保障
【Bug2 双排名】MemberModal 顶部与 ModalShell 壳顶重复渲染 (title+category 各两排) → children 内嵌 title/cat 移除(壳已承载),改 mm-brief 一行(寿数/根骨) 【Bug3 定制白屏】App 无错误边界 → 全树崩溃只剩背景 → AppErrorBoundary 一级防线(显示错误信息+重新加载按钮,不再白屏) 【Bug1 推进崩溃】advance 异常 toast 原文只写“已保存”——实为 Stash 静默吞错+双保险缺失 → ①toast 显示根错前 120 字(玩家可见——此前只有 console) ②出险保存双保险: Stash 失败时 localStorage 应急副本+明示“存储也失败”提示手动存档 ③speed timer 内 advance().catch 隔离 【验证】tsc 0 错/build 绿/7000 测试绿
This commit is contained in:
@@ -12,6 +12,29 @@ import { startFxLayer, spawnBurst, stopFxLayer } from './ui/fx-canvas'
|
||||
import { DriftLayer } from './ui/components/DriftLayer'
|
||||
import { seasonOf } from './game/data/season'
|
||||
|
||||
import { Component, type ReactNode, type ErrorInfo } from 'react'
|
||||
|
||||
interface EBState { err: Error | null }
|
||||
export class AppErrorBoundary extends Component<{ children: ReactNode }, EBState> {
|
||||
state: EBState = { err: null }
|
||||
static getDerivedStateFromError(err: Error): EBState { return { err } }
|
||||
componentDidCatch(err: Error, info: ErrorInfo): void {
|
||||
console.error('[ui-crash]', err, info.componentStack)
|
||||
}
|
||||
render(): ReactNode {
|
||||
if (this.state.err) {
|
||||
return (
|
||||
<div style={{ padding: 32, color: '#e8d9b0', fontFamily: 'serif' }}>
|
||||
<h2 style={{ color: '#d99a85' }}>界面出错了(游戏数据未受影响)</h2>
|
||||
<pre style={{ whiteSpace: 'pre-wrap', fontSize: '0.8rem', maxHeight: '50vh', overflow: 'auto' }}>{String(this.state.err?.message ?? this.state.err)}</pre>
|
||||
<button className="btn" onClick={() => location.reload()}>重新加载(回档到最近存点)</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return this.props.children
|
||||
}
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
const screen = useGameStore((s) => s.screen)
|
||||
const pendingEventId = useGameStore((s) => s.pendingEventId)
|
||||
|
||||
Reference in New Issue
Block a user