@@ -5,14 +5,17 @@ import {
55 type BrowseSelectedProject ,
66 createContext ,
77 type CreationFlowContextValue ,
8- flushInstallQueue ,
8+ flushStoredServerAddonInstallQueue ,
9+ getStoredServerAddonInstallQueue ,
910 injectModrinthClient ,
1011 injectNotificationManager ,
1112 type PendingServerContentInstall ,
1213 type PendingServerContentInstallType ,
1314 readPendingServerContentInstalls ,
15+ readStoredServerInstallQueue ,
1416 removePendingServerContentInstall ,
1517 writePendingServerContentInstallBaseline ,
18+ writeStoredServerInstallQueue ,
1619} from '@modrinth/ui'
1720import { computed , type ComputedRef , nextTick , type Ref , ref , watch } from 'vue'
1821import { useRoute , useRouter } from 'vue-router'
@@ -89,37 +92,6 @@ function readQueryString(value: unknown): string | null {
8992 return typeof value === 'string' && value . length > 0 ? value : null
9093}
9194
92- function getQueueStorageKey ( serverId : string | null , worldId : string | null ) {
93- if ( ! serverId || ! worldId ) return null
94- return `server-install-queue:${ serverId } :${ worldId } `
95- }
96-
97- function readStoredQueue ( serverId : string | null , worldId : string | null ) {
98- const key = getQueueStorageKey ( serverId , worldId )
99- if ( ! key ) return new Map < string , BrowseInstallPlan < InstallableSearchResult > > ( )
100- try {
101- const raw = localStorage . getItem ( key )
102- if ( ! raw ) return new Map < string , BrowseInstallPlan < InstallableSearchResult > > ( )
103- return new Map < string , BrowseInstallPlan < InstallableSearchResult > > ( JSON . parse ( raw ) )
104- } catch {
105- return new Map < string , BrowseInstallPlan < InstallableSearchResult > > ( )
106- }
107- }
108-
109- function writeStoredQueue (
110- serverId : string | null ,
111- worldId : string | null ,
112- plans : Map < string , BrowseInstallPlan < InstallableSearchResult > > ,
113- ) {
114- const key = getQueueStorageKey ( serverId , worldId )
115- if ( ! key ) return
116- if ( plans . size === 0 ) {
117- localStorage . removeItem ( key )
118- return
119- }
120- localStorage . setItem ( key , JSON . stringify ( Array . from ( plans . entries ( ) ) ) )
121- }
122-
12395function getQueuedInstallOwnerFallback ( project : InstallableSearchResult ) {
12496 if ( project . organization ) {
12597 const ownerId = project . organization_id ?? project . organization
@@ -235,7 +207,7 @@ export function createServerInstallContent(opts: {
235207 const route = useRoute ( )
236208 const router = useRouter ( )
237209 const client = injectModrinthClient ( )
238- const { addNotification , handleError } = injectNotificationManager ( )
210+ const { handleError } = injectNotificationManager ( )
239211
240212 const serverIdQuery = computed ( ( ) => readQueryString ( route . query . sid ) )
241213 const worldIdQuery = computed ( ( ) => readQueryString ( route . query . wid ) )
@@ -340,7 +312,7 @@ export function createServerInstallContent(opts: {
340312 }
341313
342314 if ( resolvedWorldId ) {
343- queuedServerInstalls . value = readStoredQueue ( sid , resolvedWorldId )
315+ queuedServerInstalls . value = readStoredServerInstallQueue ( sid , resolvedWorldId )
344316 await refreshServerInstalledContent ( sid , resolvedWorldId )
345317 }
346318 }
@@ -358,7 +330,7 @@ export function createServerInstallContent(opts: {
358330 if ( sid !== prevSid ) {
359331 serverContentProjectIds . value = new Set ( )
360332 serverContentInstallKeys . value = new Set ( )
361- queuedServerInstalls . value = readStoredQueue ( sid , wid )
333+ queuedServerInstalls . value = readStoredServerInstallQueue ( sid , wid )
362334 try {
363335 serverContextServerData . value = await client . archon . servers_v0 . get ( sid )
364336 } catch ( err ) {
@@ -367,7 +339,7 @@ export function createServerInstallContent(opts: {
367339 }
368340
369341 if ( wid !== prevWid ) {
370- queuedServerInstalls . value = readStoredQueue ( sid , wid )
342+ queuedServerInstalls . value = readStoredServerInstallQueue ( sid , wid )
371343 }
372344
373345 if ( wid && ( sid !== prevSid || wid !== prevWid ) ) {
@@ -432,62 +404,75 @@ export function createServerInstallContent(opts: {
432404 setQueuedServerInstallPlans ( nextPlans )
433405 }
434406
407+ function setStoredServerInstallPlans (
408+ serverId : string ,
409+ worldId : string ,
410+ plans : Map < string , BrowseInstallPlan < InstallableSearchResult > > ,
411+ ) {
412+ if ( serverId === serverIdQuery . value && worldId === effectiveServerWorldId . value ) {
413+ queuedServerInstalls . value = plans
414+ }
415+ writeStoredServerInstallQueue ( serverId , worldId , plans )
416+ }
417+
435418 async function flushQueuedServerInstalls (
436419 serverId : string | null = serverIdQuery . value ,
437420 worldId : string | null = effectiveServerWorldId . value ,
438421 ) {
439- if ( queuedServerInstalls . value . size === 0 ) return true
440422 if ( isInstallingQueuedServerInstalls . value ) return false
441423
442424 if ( ! serverId || ! worldId ) {
443425 handleError ( new Error ( 'No server world is available for install.' ) )
444426 return false
445427 }
446428
447- const installedProjectIds = new Set < string > ( )
429+ const queuedPlans = getStoredServerAddonInstallQueue < InstallableSearchResult > ( serverId , worldId )
430+ if ( queuedPlans . size === 0 ) return true
431+
448432 isInstallingQueuedServerInstalls . value = true
449433 queuedInstallProgress . value = {
450434 completed : 0 ,
451- total : queuedServerInstalls . value . size ,
435+ total : queuedPlans . size ,
452436 }
453437
454438 try {
455- const result = await flushInstallQueue ( {
456- queue : {
457- get : ( ) => queuedServerInstalls . value ,
458- set : ( plans : Map < string , BrowseInstallPlan < InstallableSearchResult > > ) => {
459- queuedServerInstalls . value = plans
460- writeStoredQueue ( serverId , worldId , plans )
461- } ,
462- } ,
463- install : async ( plan ) => {
464- await client . archon . content_v1 . addAddon ( serverId , worldId , {
465- project_id : plan . projectId ,
466- version_id : plan . versionId ,
467- } )
468- installedProjectIds . add ( plan . projectId )
469- } ,
470- onError : ( error , plan ) => {
471- removePendingServerContentInstall ( serverId , worldId , plan . projectId )
472- handleError ( error as Error )
473- } ,
474- onProgress : ( completed , total ) => {
475- queuedInstallProgress . value = { completed, total }
476- } ,
439+ const result = await flushStoredServerAddonInstallQueue ( {
440+ serverId,
441+ worldId,
442+ install : ( plans ) =>
443+ client . archon . content_v1 . addAddons (
444+ serverId ,
445+ worldId ,
446+ plans . map ( ( plan ) => ( {
447+ project_id : plan . projectId ,
448+ version_id : plan . versionId ,
449+ } ) ) ,
450+ ) ,
451+ onQueueChange : ( plans ) => setStoredServerInstallPlans ( serverId , worldId , plans ) ,
477452 } )
478453
479- if ( installedProjectIds . size > 0 ) {
480- serverContentProjectIds . value = new Set ( [
481- ...serverContentProjectIds . value ,
482- ...installedProjectIds ,
483- ] )
484- serverContentInstallKeys . value = new Set ( [
485- ...serverContentInstallKeys . value ,
486- ...installedProjectIds ,
487- ] )
454+ if ( ! result . ok ) {
455+ for ( const plan of result . attemptedPlans ) {
456+ removePendingServerContentInstall ( serverId , worldId , plan . projectId )
457+ }
458+ handleError ( result . error as Error )
459+ return false
488460 }
489461
490- return result . ok
462+ queuedInstallProgress . value = {
463+ completed : result . flushedPlans . length ,
464+ total : result . flushedPlans . length ,
465+ }
466+ serverContentProjectIds . value = new Set ( [
467+ ...serverContentProjectIds . value ,
468+ ...result . flushedPlans . map ( ( plan ) => plan . projectId ) ,
469+ ] )
470+ serverContentInstallKeys . value = new Set ( [
471+ ...serverContentInstallKeys . value ,
472+ ...result . flushedPlans . map ( ( plan ) => plan . projectId ) ,
473+ ] )
474+
475+ return true
491476 } finally {
492477 isInstallingQueuedServerInstalls . value = false
493478 queuedInstallProgress . value = { completed : 0 , total : 0 }
@@ -522,17 +507,7 @@ export function createServerInstallContent(opts: {
522507 . catch ( ( err ) => handleError ( err as Error ) )
523508 }
524509 await router . push ( backUrl )
525-
526- const ok = await flushQueuedServerInstalls ( sid , wid )
527- if ( ! ok ) {
528- queuedServerInstalls . value = new Map ( )
529- writeStoredQueue ( sid , wid , new Map ( ) )
530- addNotification ( {
531- type : 'error' ,
532- title : 'Some projects failed to install' ,
533- text : 'Failed projects were not added. You can try installing them again.' ,
534- } )
535- }
510+ void flushQueuedServerInstalls ( sid , wid )
536511
537512 return true
538513 }
@@ -545,7 +520,7 @@ export function createServerInstallContent(opts: {
545520 plans : Map < string , BrowseInstallPlan < InstallableSearchResult > > ,
546521 ) {
547522 queuedServerInstalls . value = plans
548- writeStoredQueue ( serverIdQuery . value , effectiveServerWorldId . value , plans )
523+ writeStoredServerInstallQueue ( serverIdQuery . value , effectiveServerWorldId . value , plans )
549524 }
550525
551526 function onServerFlowBack ( ) {
0 commit comments