@@ -28,6 +28,7 @@ import { SettingsPage } from "./pages/SettingsPage";
2828import { VersionSelectPage } from "./pages/VersionSelectPage" ;
2929import VersionSettingsPage from "./pages/VersionSettingsPage" ;
3030import ModsPage from "./pages/ModsPage" ;
31+ import UpdatingPage from "./pages/UpdatingPage" ;
3132import FileManagerPage from "./pages/FileManagerPage" ;
3233import ContentPage from "./pages/ContentPage" ;
3334import WorldsListPage from "./pages/WorldsListPage" ;
@@ -41,7 +42,6 @@ import ReactMarkdown from "react-markdown";
4142import remarkGfm from "remark-gfm" ;
4243
4344function App ( ) {
44- // Splash visibility + reveal orchestration for smoother transition
4545 const [ splashVisible , setSplashVisible ] = useState ( true ) ;
4646 const [ revealStarted , setRevealStarted ] = useState ( false ) ;
4747 const [ isFirstLoad , setIsFirstLoad ] = useState ( false ) ;
@@ -57,8 +57,6 @@ function App() {
5757 const [ updateBody , setUpdateBody ] = useState < string > ( "" ) ;
5858 const [ updateLoading , setUpdateLoading ] = useState < boolean > ( false ) ;
5959
60- // language selection moved into Settings modal
61-
6260 const refresh = ( ) => {
6361 setCount ( ( prevCount ) => {
6462 return prevCount + 1 ;
@@ -71,11 +69,21 @@ function App() {
7169 } ) ;
7270 } ;
7371
72+ const location = useLocation ( ) ;
73+ const navigate = useNavigate ( ) ;
74+ const isUpdatingMode = String ( location ?. pathname || "" ) === "/updating" ;
75+ useEffect ( ( ) => {
76+ if ( isUpdatingMode ) setNavLocked ( true ) ;
77+ } , [ isUpdatingMode ] ) ;
78+
7479 useEffect ( ( ) => {
75- // Let splash show briefly, then fade overlay out.
76- // Only reveal header after overlay fade completes to avoid visual overlap.
80+ if ( isUpdatingMode ) {
81+ setSplashVisible ( false ) ;
82+ setRevealStarted ( true ) ;
83+ return ;
84+ }
7785 const splashDurationMs = 1400 ;
78- const overlayFadeMs = 600 ; // matches AnimatePresence exit duration
86+ const overlayFadeMs = 600 ;
7987
8088 setIsFirstLoad ( false ) ;
8189
@@ -88,50 +96,34 @@ function App() {
8896 clearTimeout ( tHide ) ;
8997 clearTimeout ( tHeader ) ;
9098 } ;
91- } , [ ] ) ;
99+ } , [ isUpdatingMode ] ) ;
92100
93- // Listen for nav lock changes triggered by InstallPage
94101 useEffect ( ( ) => {
95102 try {
96103 setNavLocked ( Boolean ( ( window as any ) . llNavLock ) ) ;
97104 } catch { }
98105 const handler = ( e : any ) => {
99106 try {
107+ if ( isUpdatingMode ) return ;
100108 setNavLocked ( Boolean ( e ?. detail ?. lock ?? ( window as any ) . llNavLock ) ) ;
101109 } catch { }
102110 } ;
103111 window . addEventListener ( "ll-nav-lock-changed" , handler as any ) ;
104112 return ( ) =>
105113 window . removeEventListener ( "ll-nav-lock-changed" , handler as any ) ;
106- } , [ ] ) ;
114+ } , [ isUpdatingMode ] ) ;
107115
108- // First-launch Terms modal gating (after splash & header reveal)
109116 useEffect ( ( ) => {
117+ if ( ! hasBackend ) return ;
118+ if ( ! revealStarted ) return ;
119+ if ( isUpdatingMode ) return ;
110120 try {
111121 const accepted = localStorage . getItem ( "ll.termsAccepted" ) ;
112- if ( ! accepted && revealStarted ) {
122+ if ( ! accepted ) {
113123 setTermsOpen ( true ) ;
114124 setNavLocked ( true ) ;
125+ return ;
115126 }
116- } catch { }
117- } , [ revealStarted ] ) ;
118-
119- // Terms modal: start 10s countdown when opened to prevent instant accept
120- useEffect ( ( ) => {
121- if ( ! termsOpen ) return ;
122- setTermsCountdown ( 10 ) ;
123- const iv = setInterval ( ( ) => {
124- setTermsCountdown ( ( v ) => ( v > 0 ? v - 1 : 0 ) ) ;
125- } , 1000 ) ;
126- return ( ) => clearInterval ( iv ) ;
127- } , [ termsOpen ] ) ;
128-
129- // Startup update check (after splash & terms)
130- useEffect ( ( ) => {
131- if ( ! hasBackend ) return ;
132- if ( ! revealStarted ) return ;
133- if ( termsOpen ) return ;
134- try {
135127 const ignored = localStorage . getItem ( "ll.ignoreVersion" ) || "" ;
136128 minecraft ?. CheckUpdate ?.( )
137129 . then ( ( res : any ) => {
@@ -147,9 +139,19 @@ function App() {
147139 } )
148140 . catch ( ( ) => { } ) ;
149141 } catch { }
150- } , [ hasBackend , revealStarted , termsOpen ] ) ;
142+ } , [ hasBackend , revealStarted , isUpdatingMode ] ) ;
143+
144+ useEffect ( ( ) => {
145+ if ( ! termsOpen ) return ;
146+ setTermsCountdown ( 10 ) ;
147+ const iv = setInterval ( ( ) => {
148+ setTermsCountdown ( ( v ) => ( v > 0 ? v - 1 : 0 ) ) ;
149+ } , 1000 ) ;
150+ return ( ) => clearInterval ( iv ) ;
151+ } , [ termsOpen ] ) ;
152+
153+
151154
152- // Lock background scroll when update modal is open
153155 useEffect ( ( ) => {
154156 try {
155157 if ( updateOpen ) {
@@ -192,10 +194,8 @@ function App() {
192194 } catch { }
193195 } , [ hasBackend ] ) ;
194196
195- const location = useLocation ( ) ;
196- const navigate = useNavigate ( ) ;
197+
197198
198- // 全局兜底:注册 msixvc 下载事件监听,防止后端提示“无监听器”
199199 useEffect ( ( ) => {
200200 if ( ! hasBackend ) return ;
201201
@@ -219,7 +219,6 @@ function App() {
219219 } ;
220220 } , [ hasBackend ] ) ;
221221
222- // Global: prevent browser default on file drag/drop anywhere in the app
223222 useEffect ( ( ) => {
224223 const isFileDrag = ( e : DragEvent ) => {
225224 try {
@@ -253,7 +252,6 @@ function App() {
253252
254253 return (
255254 < VersionStatusProvider >
256- { /* Splash overlay with animated exit */ }
257255 < AnimatePresence >
258256 { splashVisible && (
259257 < motion . div
@@ -430,7 +428,6 @@ function App() {
430428 </ div >
431429 </ motion . div >
432430
433- { /* spacer to offset fixed top bar height */ }
434431 < div className = "h-[68px]" />
435432
436433 < motion . div
@@ -461,6 +458,7 @@ function App() {
461458 element = { < VersionSettingsPage /> }
462459 />
463460 < Route path = "/mods" element = { < ModsPage /> } />
461+ < Route path = "/updating" element = { < UpdatingPage /> } />
464462 < Route path = "/filemanager" element = { < FileManagerPage /> } />
465463 < Route path = "/content" element = { < ContentPage /> } />
466464 < Route path = "/content/worlds" element = { < WorldsListPage /> } />
@@ -476,7 +474,6 @@ function App() {
476474 ) ) }
477475 </ motion . div >
478476
479- { /* First-launch Terms Modal (priority over other modals) */ }
480477 < Modal
481478 size = "lg"
482479 isOpen = { termsOpen }
@@ -523,7 +520,6 @@ function App() {
523520 </ ModalContent >
524521 </ Modal >
525522
526- { /* Update Modal */ }
527523 < Modal size = "md" isOpen = { updateOpen } hideCloseButton >
528524 < ModalContent >
529525 { ( onClose ) => (
0 commit comments