202 lines
6.5 KiB
JavaScript
202 lines
6.5 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import {
|
|
add_project_from_version,
|
|
check_installed,
|
|
get,
|
|
get_projects,
|
|
list,
|
|
remove_project,
|
|
} from '@/helpers/profile.js'
|
|
import { handleError } from '@/store/notifications.js'
|
|
import { get_project, get_version_many } from '@/helpers/cache.js'
|
|
import { create_profile_and_install as packInstall } from '@/helpers/pack.js'
|
|
import { trackEvent } from '@/helpers/analytics.js'
|
|
import dayjs from 'dayjs'
|
|
|
|
export const useInstall = defineStore('installStore', {
|
|
state: () => ({
|
|
installConfirmModal: null,
|
|
modInstallModal: null,
|
|
incompatibilityWarningModal: null,
|
|
}),
|
|
actions: {
|
|
setInstallConfirmModal(ref) {
|
|
this.installConfirmModal = ref
|
|
},
|
|
showInstallConfirmModal(project, version_id, onInstall, createInstanceCallback) {
|
|
this.installConfirmModal.show(project, version_id, onInstall, createInstanceCallback)
|
|
},
|
|
setIncompatibilityWarningModal(ref) {
|
|
this.incompatibilityWarningModal = ref
|
|
},
|
|
showIncompatibilityWarningModal(instance, project, versions, selected, onInstall) {
|
|
this.incompatibilityWarningModal.show(instance, project, versions, selected, onInstall)
|
|
},
|
|
setModInstallModal(ref) {
|
|
this.modInstallModal = ref
|
|
},
|
|
showModInstallModal(project, versions, onInstall) {
|
|
this.modInstallModal.show(project, versions, onInstall)
|
|
},
|
|
},
|
|
})
|
|
|
|
export const install = async (
|
|
projectId,
|
|
versionId,
|
|
instancePath,
|
|
source,
|
|
callback = () => {},
|
|
createInstanceCallback = () => {},
|
|
) => {
|
|
const project = await get_project(projectId, 'must_revalidate').catch(handleError)
|
|
|
|
if (project.project_type === 'modpack') {
|
|
const version = versionId ?? project.versions[project.versions.length - 1]
|
|
const packs = await list().catch(handleError)
|
|
|
|
if (packs.length === 0 || !packs.find((pack) => pack.linked_data?.project_id === project.id)) {
|
|
await packInstall(
|
|
project.id,
|
|
version,
|
|
project.title,
|
|
project.icon_url,
|
|
createInstanceCallback,
|
|
).catch(handleError)
|
|
|
|
trackEvent('PackInstall', {
|
|
id: project.id,
|
|
version_id: version,
|
|
title: project.title,
|
|
source,
|
|
})
|
|
|
|
callback(version)
|
|
} else {
|
|
const install = useInstall()
|
|
install.showInstallConfirmModal(project, version, callback, createInstanceCallback)
|
|
}
|
|
} else {
|
|
if (instancePath) {
|
|
const [instance, instanceProjects, versions] = await Promise.all([
|
|
await get(instancePath).catch(handleError),
|
|
await get_projects(instancePath).catch(handleError),
|
|
await get_version_many(project.versions, 'must_revalidate'),
|
|
])
|
|
|
|
const projectVersions = versions.sort(
|
|
(a, b) => dayjs(b.date_published) - dayjs(a.date_published),
|
|
)
|
|
|
|
let version
|
|
if (versionId) {
|
|
version = projectVersions.find((x) => x.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),
|
|
)
|
|
}
|
|
|
|
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)
|
|
) {
|
|
for (const [path, file] of Object.entries(instanceProjects)) {
|
|
if (file.metadata && file.metadata.project_id === project.id) {
|
|
await remove_project(instance.path, path)
|
|
}
|
|
}
|
|
|
|
await add_project_from_version(instance.path, version.id).catch(handleError)
|
|
await installVersionDependencies(instance, version)
|
|
|
|
trackEvent('ProjectInstall', {
|
|
loader: instance.loader,
|
|
game_version: instance.game_version,
|
|
id: project.id,
|
|
project_type: project.project_type,
|
|
version_id: version.id,
|
|
title: project.title,
|
|
source,
|
|
})
|
|
|
|
callback(version.id)
|
|
} else {
|
|
const install = useInstall()
|
|
install.showIncompatibilityWarningModal(
|
|
instance,
|
|
project,
|
|
projectVersions,
|
|
version,
|
|
callback,
|
|
)
|
|
}
|
|
} else {
|
|
const versions = (await get_version_many(project.versions).catch(handleError)).sort(
|
|
(a, b) => dayjs(b.date_published) - dayjs(a.date_published),
|
|
)
|
|
|
|
const install = useInstall()
|
|
install.showModInstallModal(project, versions, callback)
|
|
}
|
|
}
|
|
|
|
// If project is modpack:
|
|
// - We check all available instances if modpack is already installed
|
|
// If true: show confirmation modal
|
|
// If false: install it (latest version if passed version is null)
|
|
// If project is mod:
|
|
// - If instance is selected:
|
|
// - If project is already installed
|
|
// We first uninstall the project
|
|
// - 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
|
|
}
|
|
|
|
export const installVersionDependencies = async (profile, version) => {
|
|
for (const dep of version.dependencies) {
|
|
if (dep.dependency_type !== 'required') continue
|
|
// disallow fabric api install on quilt
|
|
if (dep.project_id === 'P7dR8mSH' && profile.loader === 'quilt') continue
|
|
if (dep.version_id) {
|
|
if (
|
|
dep.project_id &&
|
|
(await check_installed(profile.path, dep.project_id).catch(handleError))
|
|
)
|
|
continue
|
|
await add_project_from_version(profile.path, dep.version_id)
|
|
} else {
|
|
if (
|
|
dep.project_id &&
|
|
(await check_installed(profile.path, dep.project_id).catch(handleError))
|
|
)
|
|
continue
|
|
|
|
const depProject = await get_project(dep.project_id, 'must_revalidate').catch(handleError)
|
|
|
|
const depVersions = (
|
|
await get_version_many(depProject.versions, 'must_revalidate').catch(handleError)
|
|
).sort((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),
|
|
)
|
|
if (latest) {
|
|
await add_project_from_version(profile.path, latest.id).catch(handleError)
|
|
}
|
|
}
|
|
}
|
|
}
|