From 3839853173c092c54c245a0c2207b0fd7aa98ad3 Mon Sep 17 00:00:00 2001 From: "Calum H. (IMB11)" Date: Tue, 16 Jun 2026 13:21:17 +0100 Subject: [PATCH] fix: update browse page when installing dependencies --- apps/app-frontend/src/pages/Browse.vue | 18 ++++++++++--- .../src/providers/content-install.ts | 27 +++++++++++-------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/apps/app-frontend/src/pages/Browse.vue b/apps/app-frontend/src/pages/Browse.vue index e256d5b024..57ad402831 100644 --- a/apps/app-frontend/src/pages/Browse.vue +++ b/apps/app-frontend/src/pages/Browse.vue @@ -805,10 +805,10 @@ function getCardActions( selectedInstall.versionId, instance.value ? instance.value.path : null, 'SearchCard', - (versionId) => { + (versionId, installedProjectIds) => { setProjectInstalling(projectResult.project_id, false) if (versionId) { - onSearchResultInstalled(projectResult.project_id) + onSearchResultsInstalled(installedProjectIds ?? [projectResult.project_id]) } }, (profile) => { @@ -834,7 +834,19 @@ function onSearchResultInstalled(id: string) { markServerProjectInstalled(id) return } - newlyInstalled.value.push(id) + if (!newlyInstalled.value.includes(id)) { + newlyInstalled.value = [...newlyInstalled.value, id] + } +} + +function onSearchResultsInstalled(ids: string[]) { + if (isServerContext.value) { + for (const id of ids) { + markServerProjectInstalled(id) + } + return + } + newlyInstalled.value = Array.from(new Set([...newlyInstalled.value, ...ids])) } async function search(requestParams: string) { diff --git a/apps/app-frontend/src/providers/content-install.ts b/apps/app-frontend/src/providers/content-install.ts index 656d7e9b2b..88d40a5d44 100644 --- a/apps/app-frontend/src/providers/content-install.ts +++ b/apps/app-frontend/src/providers/content-install.ts @@ -42,6 +42,8 @@ interface ModpackAlreadyInstalledModalRef { show: (instanceName: string, instancePath: string) => void } +export type ContentInstallCallback = (versionId?: string, installedProjectIds?: string[]) => void + const LOADER_ORDER = ['vanilla', 'fabric', 'quilt', 'neoforge', 'forge'] const SUPPORTED_LOADERS: Set = new Set(['vanilla', 'forge', 'fabric', 'quilt', 'neoforge']) const VANILLA_COMPATIBLE_LOADERS: Set = new Set(['minecraft', 'datapack']) @@ -102,7 +104,7 @@ export interface ContentInstallContext { versionId?: string | null, instancePath?: string | null, source?: string, - callback?: (versionId?: string) => void, + callback?: ContentInstallCallback, createInstanceCallback?: (profile: string) => void, hints?: { preferredLoader?: string; preferredGameVersion?: string; showProjectInfo?: boolean }, ) => Promise @@ -256,25 +258,25 @@ export function createContentInstall(opts: { let incompatibilityWarningModalRef: ModalRef | null = null let currentProject: Labrinth.Projects.v2.Project | null = null let currentVersions: Labrinth.Versions.v2.Version[] = [] - let currentCallback: (versionId?: string) => void = () => {} + let currentCallback: ContentInstallCallback = () => {} let profileMap: Record = {} let incompatibilityWarningInstance: GameInstance | null = null let incompatibilityWarningProject: Labrinth.Projects.v2.Project | null = null - let incompatibilityWarningCallback: (versionId?: string) => void = () => {} + let incompatibilityWarningCallback: ContentInstallCallback = () => {} let incompatibilityWarningInstalled = false let pendingModpackInstall: { project: Labrinth.Projects.v2.Project version: string source: string - callback: (versionId?: string) => void + callback: ContentInstallCallback createInstanceCallback: (profile: string) => void } | null = null async function showModInstallModal( project: Labrinth.Projects.v2.Project, versions: Labrinth.Versions.v2.Version[], - onInstall: (versionId?: string) => void, + onInstall: ContentInstallCallback, hints?: { preferredLoader?: string; preferredGameVersion?: string; showProjectInfo?: boolean }, ) { currentProject = project @@ -440,7 +442,10 @@ export function createContentInstall(opts: { if (versionId && storeInstance) { storeInstance.installed = true } - currentCallback(versionId) + currentCallback( + versionId, + versionId && currentProject ? [currentProject.id] : undefined, + ) } await showIncompatibilityWarning( profile, @@ -487,7 +492,7 @@ export function createContentInstall(opts: { title: currentProject!.title, source: 'ProjectInstallModal', }) - currentCallback(version.id) + currentCallback(version.id, installedProjectIds) } catch (err) { if (storeInstance) storeInstance.installing = false opts.handleError(err) @@ -501,7 +506,7 @@ export function createContentInstall(opts: { project: Labrinth.Projects.v2.Project, versions: Labrinth.Versions.v2.Version[], version: Labrinth.Versions.v2.Version, - callback: (versionId?: string) => void, + callback: ContentInstallCallback, ) { incompatibilityWarningInstance = instance incompatibilityWarningProject = project @@ -542,7 +547,7 @@ export function createContentInstall(opts: { incompatibilityWarningInstalling.value = false incompatibilityWarningInstalled = true - incompatibilityWarningCallback(version.id) + incompatibilityWarningCallback(version.id, [incompatibilityWarningProject.id]) incompatibilityWarningModalRef?.hide() trackEvent('ProjectInstall', { @@ -630,7 +635,7 @@ export function createContentInstall(opts: { versionId?: string | null, instancePath?: string | null, source: string = 'unknown', - callback: (versionId?: string) => void = () => {}, + callback: ContentInstallCallback = () => {}, createInstanceCallback: (profile: string) => void = () => {}, hints?: { preferredLoader?: string; preferredGameVersion?: string; showProjectInfo?: boolean }, ) { @@ -714,7 +719,7 @@ export function createContentInstall(opts: { title: project.title, source, }) - callback(version.id) + callback(version.id, installedProjectIds) } finally { removeInstallingItems(instancePath, installedProjectIds) }