@@ -73,6 +73,9 @@ export const useLauncher = (args: any) => {
7373 ) ;
7474 const [ isLoadingVersions , setIsLoadingVersions ] =
7575 React . useState < boolean > ( false ) ;
76+ const [ registerAction , setRegisterAction ] = React . useState <
77+ "register" | "unregister"
78+ > ( "register" ) ;
7679 const fetchingLogos = React . useRef < Set < string > > ( new Set ( ) ) ;
7780 const fetchingLeviLaminaStatuses = React . useRef < Set < string > > ( new Set ( ) ) ;
7881 const [ tipIndex , setTipIndex ] = React . useState < number > ( 0 ) ;
@@ -461,15 +464,68 @@ export const useLauncher = (args: any) => {
461464 } ) ;
462465 } , [ ] ) ;
463466
467+ const applyOptimisticUnregisterState = React . useCallback ( ( name : string ) => {
468+ if ( ! name ) return ;
469+ setLocalVersionMap ( ( prev ) => {
470+ const target = prev . get ( name ) ;
471+ if ( ! target || ! target . isRegistered ) return prev ;
472+ const next = new Map ( prev ) ;
473+ next . set ( name , { ...target , isRegistered : false } ) ;
474+ return next ;
475+ } ) ;
476+ } , [ ] ) ;
477+
464478 const doRegister = React . useCallback ( async ( ) => {
465479 if ( ! currentVersion ) return ;
480+ const isCurrentlyRegistered = Boolean (
481+ localVersionMap . get ( currentVersion ) ?. isRegistered ,
482+ ) ;
466483 try {
467484 const ok = await IsGDKInstalled ( ) ;
468485 if ( ! ok ) {
469486 gdkMissingDisclosure . onOpen ( ) ;
470487 return ;
471488 }
472489 } catch { }
490+ if ( isCurrentlyRegistered ) {
491+ setRegisterAction ( "unregister" ) ;
492+ registerInstallingDisclosure . onOpen ( ) ;
493+ try {
494+ const fn = ( versionService as any ) ?. UnregisterVersionByName ;
495+ if ( typeof fn !== "function" ) {
496+ registerInstallingDisclosure . onClose ( ) ;
497+ setLaunchErrorCode ( "ERR_UNREGISTER_FAILED" ) ;
498+ registerFailedDisclosure . onOpen ( ) ;
499+ return ;
500+ }
501+ const result = await fn ( currentVersion ) ;
502+ registerInstallingDisclosure . onClose ( ) ;
503+ if ( result === "" ) {
504+ applyOptimisticUnregisterState ( currentVersion ) ;
505+ const synced = await syncRegisteredFlags ( ) ;
506+ if ( ! synced ) {
507+ applyOptimisticUnregisterState ( currentVersion ) ;
508+ }
509+ window . setTimeout ( ( ) => {
510+ void syncRegisteredFlags ( ) ;
511+ } , 1200 ) ;
512+ args . refresh ( ) ;
513+ return ;
514+ }
515+ if ( result === "ERR_GDK_MISSING" ) {
516+ gdkMissingDisclosure . onOpen ( ) ;
517+ } else {
518+ setLaunchErrorCode ( result ) ;
519+ registerFailedDisclosure . onOpen ( ) ;
520+ }
521+ } catch {
522+ registerInstallingDisclosure . onClose ( ) ;
523+ setLaunchErrorCode ( "ERR_UNREGISTER_FAILED" ) ;
524+ registerFailedDisclosure . onOpen ( ) ;
525+ }
526+ return ;
527+ }
528+ setRegisterAction ( "register" ) ;
473529 registerInstallingDisclosure . onOpen ( ) ;
474530 try {
475531 const isPreview = localVersionMap . get ( currentVersion ) ?. isPreview || false ;
@@ -517,10 +573,12 @@ export const useLauncher = (args: any) => {
517573 registerFailedDisclosure . onOpen ( ) ;
518574 }
519575 } , [
576+ args ,
520577 currentVersion ,
521578 localVersionMap ,
522579 navigate ,
523580 applyOptimisticRegisterState ,
581+ applyOptimisticUnregisterState ,
524582 gdkMissingDisclosure ,
525583 registerInstallingDisclosure ,
526584 registerSuccessDisclosure ,
@@ -1136,6 +1194,7 @@ export const useLauncher = (args: any) => {
11361194 setVersionQuery,
11371195 logoByName,
11381196 isLoadingVersions,
1197+ registerAction,
11391198 tipIndex,
11401199 hasBackend,
11411200
0 commit comments