From a3220cf3ddaa381bd65c8ae1a0cd8fbc92cd0696 Mon Sep 17 00:00:00 2001 From: Juhan Oskar Hennoste Date: Sat, 23 Aug 2025 22:20:20 +0300 Subject: [PATCH 1/3] Fix and unify version selection when installing mods --- .../ui/install_flow/ModInstallModal.vue | 24 +++----- apps/app-frontend/src/store/install.js | 57 ++++++++++++------- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/apps/app-frontend/src/components/ui/install_flow/ModInstallModal.vue b/apps/app-frontend/src/components/ui/install_flow/ModInstallModal.vue index ccf6586ed5..18ae987937 100644 --- a/apps/app-frontend/src/components/ui/install_flow/ModInstallModal.vue +++ b/apps/app-frontend/src/components/ui/install_flow/ModInstallModal.vue @@ -22,7 +22,7 @@ import { get, list, } from '@/helpers/profile' -import { installVersionDependencies } from '@/store/install.js' +import { isVersionCompatible, findPreferredVersion, installVersionDependencies } from '@/store/install.js' const { handleError } = injectNotificationManager() const router = useRouter() @@ -49,14 +49,11 @@ const shownProfiles = computed(() => return profile.name.toLowerCase().includes(searchFilter.value.toLowerCase()) }) .filter((profile) => { - const loaders = versions.value.flatMap((v) => v.loaders) - - return ( - versions.value.flatMap((v) => v.game_versions).includes(profile.game_version) && - (project.value.project_type === 'mod' - ? loaders.includes(profile.loader) || loaders.includes('minecraft') - : true) - ) + const version = { + game_versions: versions.value.flatMap((v) => v.game_versions), + loaders: versions.value.flatMap((v) => v.loaders), + } + return isVersionCompatible(version, project.value, profile) }), ) @@ -94,14 +91,7 @@ defineExpose({ async function install(instance) { instance.installing = true - const version = versions.value.find((v) => { - return ( - v.game_versions.includes(instance.game_version) && - (project.value.project_type === 'mod' - ? v.loaders.includes(instance.loader) || v.loaders.includes('minecraft') - : true) - ) - }) + const version = findPreferredVersion(versions.value, project.value, instance) if (!version) { instance.installing = false diff --git a/apps/app-frontend/src/store/install.js b/apps/app-frontend/src/store/install.js index 1e9f9486a2..6a9e6a05d9 100644 --- a/apps/app-frontend/src/store/install.js +++ b/apps/app-frontend/src/store/install.js @@ -41,6 +41,34 @@ export const useInstall = defineStore('installStore', { }, }) +export const findPreferredVersion = ( + versions, + project, + instance, +) => { + // If we can find a version using strictly the instance loader then prefer that + let version = versions.find((v) => v.game_versions.includes(instance.game_version) && + (project.project_type === 'mod' ? v.loaders.includes(instance.loader) : true)) + + if (!version) { + // Otherwise use first compatible version (in addition to versions with the instance loader this includes datapacks) + version = versions.find((v) => isVersionCompatible(v, project, instance)) + } + + return version +} + +export const isVersionCompatible = ( + version, + project, + instance, +) => { + return version.game_versions.includes(instance.game_version) && + (project.project_type === 'mod' + ? version.loaders.includes(instance.loader) || version.loaders.includes('datapack') + : true) +} + export const install = async ( projectId, versionId, @@ -90,27 +118,16 @@ export const install = async ( let version if (versionId) { - version = projectVersions.find((x) => x.id === versionId) + version = projectVersions.find((v) => v.id === versionId) } else { - version = projectVersions.find( - (v) => - v.game_versions.includes(instance.game_version) && - (project.project_type === 'mod' - ? v.loaders.includes(instance.loader) || v.loaders.includes('minecraft') - : true), - ) + version = findPreferredVersion(projectVersions, project, instance) } if (!version) { version = projectVersions[0] } - if ( - version.game_versions.includes(instance.game_version) && - (project.project_type === 'mod' - ? version.loaders.includes(instance.loader) || version.loaders.includes('minecraft') - : true) - ) { + if (isVersionCompatible(version, project, instance, true)) { for (const [path, file] of Object.entries(instanceProjects)) { if (file.metadata && file.metadata.project_id === project.id) { await remove_project(instance.path, path) @@ -142,10 +159,14 @@ export const install = async ( ) } } else { - const versions = (await get_version_many(project.versions)).sort( + let versions = (await get_version_many(project.versions)).sort( (a, b) => dayjs(b.date_published) - dayjs(a.date_published), ) + if (versionId) { + versions = versions.filter((v) => v.id === versionId) + } + const install = useInstall() install.showModInstallModal(project, versions, callback) } @@ -162,7 +183,7 @@ export const install = async ( // - If no version is selected, we look check the instance for versions to select based on the versions // - If there are no versions, we show the incompat modal // - If a version is selected, and the version is incompatible, we show the incompat modal - // - Version is inarlled, as well as version dependencies + // - Version is installed, as well as version dependencies } export const installVersionDependencies = async (profile, version) => { @@ -182,9 +203,7 @@ export const installVersionDependencies = async (profile, version) => { (a, b) => dayjs(b.date_published) - dayjs(a.date_published), ) - const latest = depVersions.find( - (v) => v.game_versions.includes(profile.game_version) && v.loaders.includes(profile.loader), - ) + const latest = findPreferredVersion(depVersions, dep, profile) if (latest) { await add_project_from_version(profile.path, latest.id) } From 13f3c693c45af7e633d45d1c39305d4291740fd2 Mon Sep 17 00:00:00 2001 From: Juhan Oskar Hennoste Date: Sun, 24 Aug 2025 00:04:01 +0300 Subject: [PATCH 2/3] Update version list filters to match install version selection logic --- apps/app-frontend/src/pages/project/Index.vue | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/app-frontend/src/pages/project/Index.vue b/apps/app-frontend/src/pages/project/Index.vue index fee1f25269..0844ca550f 100644 --- a/apps/app-frontend/src/pages/project/Index.vue +++ b/apps/app-frontend/src/pages/project/Index.vue @@ -96,7 +96,7 @@ label: 'Versions', href: { path: `/project/${$route.params.id}/versions`, - query: { l: instance?.loader, g: instance?.game_version }, + query: instanceFilters, }, subpages: ['version'], }, @@ -154,7 +154,7 @@ import { import { openUrl } from '@tauri-apps/plugin-opener' import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' -import { ref, shallowRef, watch } from 'vue' +import { computed, ref, shallowRef, watch } from 'vue' import { useRoute, useRouter } from 'vue-router' import ContextMenu from '@/components/ui/ContextMenu.vue' @@ -186,6 +186,24 @@ const instanceProjects = ref(null) const installed = ref(false) const installedVersion = ref(null) +const instanceFilters = computed(() => { + if (!instance.value) { + return {} + } + + const loaders = [] + if (data.value.project_type === 'mod') { + if (instance.value.loader !== 'vanilla') { + loaders.push(instance.value.loader) + } + if (instance.value.loader === 'vanilla' || data.value.loaders.includes('datapack')) { + loaders.push('datapack') + } + } + + return { l: loaders, g: instance.value.game_version } +}) + const [allLoaders, allGameVersions] = await Promise.all([ get_loaders().catch(handleError).then(ref), get_game_versions().catch(handleError).then(ref), From 9d75097bd1127b699b8dc56ffca8e80707602ba2 Mon Sep 17 00:00:00 2001 From: Juhan Oskar Hennoste Date: Wed, 27 Aug 2025 16:23:08 +0300 Subject: [PATCH 3/3] Fix lint issues --- .../ui/install_flow/ModInstallModal.vue | 6 ++++- apps/app-frontend/src/store/install.js | 23 ++++++++----------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/apps/app-frontend/src/components/ui/install_flow/ModInstallModal.vue b/apps/app-frontend/src/components/ui/install_flow/ModInstallModal.vue index 18ae987937..db93af5684 100644 --- a/apps/app-frontend/src/components/ui/install_flow/ModInstallModal.vue +++ b/apps/app-frontend/src/components/ui/install_flow/ModInstallModal.vue @@ -22,7 +22,11 @@ import { get, list, } from '@/helpers/profile' -import { isVersionCompatible, findPreferredVersion, installVersionDependencies } from '@/store/install.js' +import { + findPreferredVersion, + installVersionDependencies, + isVersionCompatible, +} from '@/store/install.js' const { handleError } = injectNotificationManager() const router = useRouter() diff --git a/apps/app-frontend/src/store/install.js b/apps/app-frontend/src/store/install.js index 6a9e6a05d9..14988763aa 100644 --- a/apps/app-frontend/src/store/install.js +++ b/apps/app-frontend/src/store/install.js @@ -41,14 +41,13 @@ export const useInstall = defineStore('installStore', { }, }) -export const findPreferredVersion = ( - versions, - project, - instance, -) => { +export const findPreferredVersion = (versions, project, instance) => { // If we can find a version using strictly the instance loader then prefer that - let version = versions.find((v) => v.game_versions.includes(instance.game_version) && - (project.project_type === 'mod' ? v.loaders.includes(instance.loader) : true)) + let version = versions.find( + (v) => + v.game_versions.includes(instance.game_version) && + (project.project_type === 'mod' ? v.loaders.includes(instance.loader) : true), + ) if (!version) { // Otherwise use first compatible version (in addition to versions with the instance loader this includes datapacks) @@ -58,15 +57,13 @@ export const findPreferredVersion = ( return version } -export const isVersionCompatible = ( - version, - project, - instance, -) => { - return version.game_versions.includes(instance.game_version) && +export const isVersionCompatible = (version, project, instance) => { + return ( + version.game_versions.includes(instance.game_version) && (project.project_type === 'mod' ? version.loaders.includes(instance.loader) || version.loaders.includes('datapack') : true) + ) } export const install = async (