fix: final content tab qa (#5611)

* fix: queued admonition always showing

* fix: dont apply grayscale to checkbox in content card item

* fix: actual stable id for disable/enable/bulk state

* fix: vue-router resolve workaround

* fix: show disable/enable btns same time

* fix: remove mr-2 on toggle

* fix: type errors + add ModpackAlreadyInstalledModal

* fix: bulk actions + overflow menu hitting ad container

* fix: responsiveness of ContentSelectionBar

* feat: better backup naming for inline backups + sorting fixes

* fix: lint

* fix: typo
This commit is contained in:
Calum H.
2026-03-18 18:03:55 +00:00
committed by GitHub
parent cf1b5f5e2d
commit 1d10af09f5
35 changed files with 503 additions and 215 deletions

View File

@@ -26,6 +26,7 @@ import {
remove_project,
} from '@/helpers/profile.js'
import { get_game_versions } from '@/helpers/tags'
import type { GameInstance, InstanceLoader } from '@/helpers/types'
import {
findPreferredVersion,
installVersionDependencies,
@@ -37,13 +38,8 @@ interface ModalRef {
hide: () => void
}
interface InstallConfirmModalRef {
show: (
project: Labrinth.Projects.v2.Project,
version: string,
callback: (versionId?: string) => void,
createInstanceCallback: (profile: string) => void,
) => void
interface ModpackAlreadyInstalledModalRef {
show: (instanceName: string, instancePath: string) => void
}
interface IncompatibilityWarningModalRef {
@@ -92,7 +88,9 @@ export interface ContentInstallContext {
handleNavigate: (instance: ContentInstallInstance) => void
handleCancel: () => void
setContentInstallModal: (ref: ModalRef) => void
setInstallConfirmModal: (ref: InstallConfirmModalRef) => void
setModpackAlreadyInstalledModal: (ref: ModpackAlreadyInstalledModalRef) => void
handleModpackDuplicateCreateAnyway: () => Promise<void>
handleModpackDuplicateGoToInstance: (instancePath: string) => void
setIncompatibilityWarningModal: (ref: IncompatibilityWarningModalRef) => void
install: (
projectId: string,
@@ -140,12 +138,13 @@ export function createContentInstall(opts: {
) {
const primaryFile = version?.files?.find((f) => f.primary) ?? version?.files?.[0]
const placeholder: ContentItem = {
id: `__installing_${project.id}`,
file_name: `__installing_${project.id}`,
project: {
id: project.id,
slug: project.slug ?? null,
slug: project.slug ?? '',
title: project.title,
icon_url: project.icon_url ?? null,
icon_url: project.icon_url ?? undefined,
},
version: version
? {
@@ -183,18 +182,26 @@ export function createContentInstall(opts: {
}
let modalRef: ModalRef | null = null
let installConfirmModalRef: InstallConfirmModalRef | null = null
let modpackAlreadyInstalledModalRef: ModpackAlreadyInstalledModalRef | null = null
let incompatibilityWarningModalRef: IncompatibilityWarningModalRef | null = null
let currentProject: Labrinth.Projects.v2.Project | null = null
let currentVersions: Labrinth.Versions.v2.Version[] = []
let currentCallback: (versionId?: string) => void = () => {}
let profileMap: Record<string, GameInstance> = {}
let pendingModpackInstall: {
project: Labrinth.Projects.v2.Project
version: string
source: string
callback: (versionId?: string) => void
createInstanceCallback: (profile: string) => void
} | null = null
async function showModInstallModal(
project: Labrinth.Projects.v2.Project,
versions: Labrinth.Versions.v2.Version[],
onInstall: (versionId?: string) => void,
hints?: { preferredLoader?: string; preferredGameVersion?: string },
hints?: { preferredLoader?: string; preferredGameVersion?: string; showProjectInfo?: boolean },
) {
currentProject = project
currentVersions = versions
@@ -379,10 +386,10 @@ export function createContentInstall(opts: {
trackEvent('ProjectInstall', {
loader: profile.loader,
game_version: profile.game_version,
id: currentProject.id,
id: currentProject!.id,
version_id: version.id,
project_type: currentProject.project_type,
title: currentProject.title,
project_type: currentProject!.project_type,
title: currentProject!.title,
source: 'ProjectInstallModal',
})
currentCallback(version.id)
@@ -433,10 +440,10 @@ export function createContentInstall(opts: {
trackEvent('ProjectInstall', {
loader: data.loader,
game_version: data.gameVersion,
id: currentProject.id,
id: currentProject!.id,
version_id: version.id,
project_type: currentProject.project_type,
title: currentProject.title,
project_type: currentProject!.project_type,
title: currentProject!.title,
source: 'ProjectInstallModal',
})
@@ -470,28 +477,28 @@ export function createContentInstall(opts: {
if (project.project_type === 'modpack') {
const version = versionId ?? project.versions[project.versions.length - 1]
const packs = await list()
const existingPack = packs.find((pack) => pack.linked_data?.project_id === project.id)
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,
)
trackEvent('PackInstall', {
id: project.id,
version_id: version,
title: project.title,
source,
})
callback(version)
} else {
installConfirmModalRef?.show(project, version, callback, createInstanceCallback)
if (existingPack) {
pendingModpackInstall = { project, version, source, callback, createInstanceCallback }
modpackAlreadyInstalledModalRef?.show(existingPack.name, existingPack.path)
return
}
await packInstall(
project.id,
version,
project.title,
project.icon_url,
createInstanceCallback,
)
trackEvent('PackInstall', {
id: project.id,
version_id: version,
title: project.title,
source,
})
callback(version)
} else if (instancePath) {
const [instanceOrNull, instanceProjects, versions] = await Promise.all([
get(instancePath),
@@ -577,8 +584,31 @@ export function createContentInstall(opts: {
setContentInstallModal(ref: ModalRef) {
modalRef = ref
},
setInstallConfirmModal(ref: InstallConfirmModalRef) {
installConfirmModalRef = ref
setModpackAlreadyInstalledModal(ref: ModpackAlreadyInstalledModalRef) {
modpackAlreadyInstalledModalRef = ref
},
async handleModpackDuplicateCreateAnyway() {
if (!pendingModpackInstall) return
const { project, version, source, callback, createInstanceCallback } = pendingModpackInstall
pendingModpackInstall = null
await packInstall(
project.id,
version,
project.title,
project.icon_url,
createInstanceCallback,
)
trackEvent('PackInstall', {
id: project.id,
version_id: version,
title: project.title,
source,
})
callback(version)
},
handleModpackDuplicateGoToInstance(instancePath: string) {
pendingModpackInstall = null
opts.router.push(`/instance/${encodeURIComponent(instancePath)}/`)
},
setIncompatibilityWarningModal(ref: IncompatibilityWarningModalRef) {
incompatibilityWarningModalRef = ref