diff --git a/apps/app-frontend/src/pages/Browse.vue b/apps/app-frontend/src/pages/Browse.vue index c06279641..8f166430f 100644 --- a/apps/app-frontend/src/pages/Browse.vue +++ b/apps/app-frontend/src/pages/Browse.vue @@ -25,6 +25,7 @@ import { preferencesDiffer, provideBrowseManager, requestInstall, + resolveInstallPlan, stripServerRuntimeInstallFilters, stripServerRuntimeInstallOverrides, useBrowseSearch, @@ -798,6 +799,27 @@ async function chooseInstanceInstallVersion( return { versionId: selectedVersion.id } } +async function chooseFilterMatchingInstallVersion( + project: Labrinth.Search.v3.ResultSearchProject, + projectTypeValue: string, +) { + const plan = await resolveInstallPlan({ + project: { + project_id: project.project_id, + title: project.title, + icon_url: project.icon_url, + }, + contentType: projectTypeValue as BrowseInstallContentType, + selectedFilters: searchState.currentFilters.value, + providedFilters: combinedProvidedFilters.value, + overriddenProvidedFilterTypes: searchState.overriddenProvidedFilterTypes.value, + targetPreferences: {}, + getProjectVersions: getInstallProjectVersions, + }) + + return { versionId: plan.versionId } +} + function getCardActions( result: Labrinth.Search.v3.ResultSearchProject, currentProjectType: string, @@ -927,7 +949,9 @@ function getCardActions( try { const selectedInstall = instance.value ? await chooseInstanceInstallVersion(projectResult, currentProjectType) - : { versionId: null as string | null } + : isModpack + ? await chooseFilterMatchingInstallVersion(projectResult, currentProjectType) + : { versionId: null as string | null } if (selectedInstall === null) { setProjectInstalling(projectResult.project_id, false) return diff --git a/apps/app-frontend/src/providers/content-install.ts b/apps/app-frontend/src/providers/content-install.ts index b65399fdd..67471e76c 100644 --- a/apps/app-frontend/src/providers/content-install.ts +++ b/apps/app-frontend/src/providers/content-install.ts @@ -1,6 +1,11 @@ import type { Labrinth } from '@modrinth/api-client' import type { ContentInstallInstance, ContentInstallProjectInfo, ContentItem } from '@modrinth/ui' -import { createContext, defineMessage, useVIntl } from '@modrinth/ui' +import { + createContext, + defineMessage, + getLatestMatchingInstallVersion, + useVIntl, +} from '@modrinth/ui' import { convertFileSrc } from '@tauri-apps/api/core' import { openUrl } from '@tauri-apps/plugin-opener' import dayjs from 'dayjs' @@ -813,7 +818,22 @@ export function createContentInstall(opts: { } if (project.project_type === 'modpack') { - const version = versionId ?? project.versions[project.versions.length - 1] + let version = versionId ?? null + if (!version) { + const hasHints = !!(hints?.preferredGameVersion || hints?.preferredLoader) + if (hasHints) { + const versions = (await get_version_many( + project.versions, + 'must_revalidate', + )) as Labrinth.Versions.v2.Version[] + const matching = getLatestMatchingInstallVersion(versions, { + gameVersions: hints?.preferredGameVersion ? [hints.preferredGameVersion] : undefined, + loaders: hints?.preferredLoader ? [hints.preferredLoader] : undefined, + }) + version = matching?.id ?? null + } + version ??= project.versions[project.versions.length - 1] + } const packs = await list() const existingPack = packs.find((pack) => pack.link?.project_id === project.id)