mirror of
https://github.com/modrinth/code.git
synced 2026-08-31 12:05:53 +00:00
feat: if only dependency project is listed, find latest compatible dependency version to download in version page
This commit is contained in:
@@ -311,11 +311,25 @@
|
||||
<template #dependencyActions="{ dependency }">
|
||||
<ButtonStyled circular>
|
||||
<nuxt-link
|
||||
v-if="createDependencyLink(dependency)"
|
||||
v-if="
|
||||
createDependencyLink({
|
||||
project: dependency.project,
|
||||
version: dependency.version ?? getDependencyVersion(dependency.dependency),
|
||||
})
|
||||
"
|
||||
v-tooltip="
|
||||
formatMessage(dependency.version ? messages.viewVersion : messages.viewProject)
|
||||
formatMessage(
|
||||
(dependency.version ?? getDependencyVersion(dependency.dependency))
|
||||
? messages.viewVersion
|
||||
: messages.viewProject,
|
||||
)
|
||||
"
|
||||
:to="
|
||||
createDependencyLink({
|
||||
project: dependency.project,
|
||||
version: dependency.version ?? getDependencyVersion(dependency.dependency),
|
||||
})
|
||||
"
|
||||
:to="createDependencyLink(dependency)"
|
||||
target="_blank"
|
||||
>
|
||||
<ExternalIcon />
|
||||
@@ -324,26 +338,29 @@
|
||||
<ButtonStyled circular color="brand" color-fill="text">
|
||||
<a
|
||||
v-if="
|
||||
dependency.version && dependency.dependency.dependency_type !== 'incompatible'
|
||||
(dependency.version ?? getDependencyVersion(dependency.dependency)) &&
|
||||
dependency.dependency.dependency_type !== 'incompatible'
|
||||
"
|
||||
v-tooltip="
|
||||
dependencyVersionPrimaryFiles[dependency.version.id]
|
||||
? dependencyVersionPrimaryFiles[dependency.version.id].filename +
|
||||
' (' +
|
||||
formatBytes(dependencyVersionPrimaryFiles[dependency.version.id].size) +
|
||||
')'
|
||||
: formatMessage(messages.noPrimaryFile)
|
||||
"
|
||||
:href="
|
||||
createProjectDownloadUrl(
|
||||
dependencyVersionPrimaryFiles[dependency.version.id].url,
|
||||
{
|
||||
reason: 'dependency',
|
||||
},
|
||||
getDependencyPrimaryFileTooltip(
|
||||
dependency.version ?? getDependencyVersion(dependency.dependency),
|
||||
)
|
||||
"
|
||||
:download="dependencyVersionPrimaryFiles[dependency.version.id].filename"
|
||||
:disabled="dependencyVersionPrimaryFiles[dependency.version.id].url === undefined"
|
||||
:href="
|
||||
getDependencyDownloadUrl(
|
||||
dependency.version ?? getDependencyVersion(dependency.dependency),
|
||||
)
|
||||
"
|
||||
:download="
|
||||
getDependencyPrimaryFile(
|
||||
dependency.version ?? getDependencyVersion(dependency.dependency),
|
||||
)?.filename
|
||||
"
|
||||
:disabled="
|
||||
!getDependencyPrimaryFile(
|
||||
dependency.version ?? getDependencyVersion(dependency.dependency),
|
||||
)?.url
|
||||
"
|
||||
>
|
||||
<DownloadIcon />
|
||||
</a>
|
||||
@@ -658,6 +675,73 @@ watch(
|
||||
|
||||
const enrichment = computed(() => contextDependencies.value ?? undefined)
|
||||
|
||||
const projectOnlyDependencyProjectIds = computed(() => {
|
||||
const projectIds = new Set<string>()
|
||||
for (const dependency of version.value?.dependencies ?? []) {
|
||||
if (
|
||||
dependency.project_id &&
|
||||
!dependency.version_id &&
|
||||
dependency.dependency_type !== 'incompatible'
|
||||
) {
|
||||
projectIds.add(dependency.project_id)
|
||||
}
|
||||
}
|
||||
return [...projectIds]
|
||||
})
|
||||
|
||||
const dependencyResolutionLoaders = computed(() => {
|
||||
if (!version.value) return []
|
||||
if (version.value.loaders.includes('mrpack')) {
|
||||
return (version.value.mrpack_loaders ?? []).filter((loader) => loader !== 'minecraft')
|
||||
}
|
||||
return version.value.loaders
|
||||
})
|
||||
|
||||
const { data: projectOnlyDependencyVersions } = useQuery({
|
||||
queryKey: computed(
|
||||
() =>
|
||||
[
|
||||
'version-page',
|
||||
'project-only-dependency-versions',
|
||||
version.value?.id,
|
||||
version.value?.game_versions ?? [],
|
||||
dependencyResolutionLoaders.value,
|
||||
projectOnlyDependencyProjectIds.value,
|
||||
] as const,
|
||||
),
|
||||
queryFn: async () => {
|
||||
const currentVersion = version.value!
|
||||
const entries = await Promise.all(
|
||||
projectOnlyDependencyProjectIds.value.map(async (projectId) => {
|
||||
let versions: Labrinth.Versions.v2.Version[] = []
|
||||
try {
|
||||
versions = await client.labrinth.versions_v2.getProjectVersions(projectId, {
|
||||
game_versions: currentVersion.game_versions,
|
||||
loaders: dependencyResolutionLoaders.value,
|
||||
include_changelog: false,
|
||||
limit: 1,
|
||||
})
|
||||
} catch {
|
||||
return [projectId, undefined] as const
|
||||
}
|
||||
|
||||
return [projectId, versions[0]] as const
|
||||
}),
|
||||
)
|
||||
|
||||
const versionsByProjectId: Record<string, Labrinth.Versions.v2.Version> = {}
|
||||
for (const [projectId, dependencyVersion] of entries) {
|
||||
if (dependencyVersion) {
|
||||
versionsByProjectId[projectId] = dependencyVersion
|
||||
}
|
||||
}
|
||||
|
||||
return versionsByProjectId
|
||||
},
|
||||
enabled: computed(() => !!version.value && projectOnlyDependencyProjectIds.value.length > 0),
|
||||
staleTime: STALE_TIME,
|
||||
})
|
||||
|
||||
const primaryFile = computed(
|
||||
() => version.value?.files?.find((file) => file.primary) ?? version.value?.files?.[0],
|
||||
)
|
||||
@@ -823,6 +907,10 @@ const messages = defineMessages({
|
||||
id: 'version.download.no-primary-file',
|
||||
defaultMessage: 'Error: No primary file found',
|
||||
},
|
||||
downloadVersion: {
|
||||
id: 'version.download.version',
|
||||
defaultMessage: 'Download {version} ({size})',
|
||||
},
|
||||
edit: {
|
||||
id: 'version.edit.button',
|
||||
defaultMessage: 'Edit',
|
||||
@@ -951,13 +1039,20 @@ const copyFileHash = async (
|
||||
file: Labrinth.Versions.v3.VersionFile,
|
||||
method: Labrinth.Versions.v3.FileHashType,
|
||||
) => {
|
||||
await navigator.clipboard.writeText(file.hashes[method])
|
||||
await copyToClipboard(file.hashes[method])
|
||||
}
|
||||
|
||||
async function copyToClipboard(text: string) {
|
||||
await navigator.clipboard.writeText(text)
|
||||
}
|
||||
|
||||
const dependencyVersionPrimaryFiles = computed(() => {
|
||||
const versions = enrichment.value?.versions
|
||||
const versions = [
|
||||
...(enrichment.value?.versions ?? []),
|
||||
...Object.values(projectOnlyDependencyVersions.value ?? {}),
|
||||
]
|
||||
const primaryFileMap: Record<string, Labrinth.Versions.v2.VersionFile> = {}
|
||||
versions?.forEach((depVersion) => {
|
||||
versions.forEach((depVersion) => {
|
||||
const depPrimaryFile = depVersion.files.find((file) => file.primary) ?? depVersion.files[0]
|
||||
|
||||
primaryFileMap[depVersion.id] = depPrimaryFile
|
||||
@@ -965,6 +1060,37 @@ const dependencyVersionPrimaryFiles = computed(() => {
|
||||
return primaryFileMap
|
||||
})
|
||||
|
||||
function getDependencyVersion(dependency: Labrinth.Versions.v3.Dependency) {
|
||||
if (dependency.version_id || !dependency.project_id) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return projectOnlyDependencyVersions.value?.[dependency.project_id]
|
||||
}
|
||||
|
||||
function getDependencyPrimaryFile(version?: Labrinth.Versions.v2.Version) {
|
||||
return version ? dependencyVersionPrimaryFiles.value[version.id] : undefined
|
||||
}
|
||||
|
||||
function getDependencyPrimaryFileTooltip(version?: Labrinth.Versions.v2.Version) {
|
||||
const dependencyPrimaryFile = getDependencyPrimaryFile(version)
|
||||
return dependencyPrimaryFile
|
||||
? formatMessage(messages.downloadVersion, {
|
||||
version: version?.name || version?.version_number || dependencyPrimaryFile.filename,
|
||||
size: formatBytes(dependencyPrimaryFile.size),
|
||||
})
|
||||
: formatMessage(messages.noPrimaryFile)
|
||||
}
|
||||
|
||||
function getDependencyDownloadUrl(version?: Labrinth.Versions.v2.Version) {
|
||||
const dependencyPrimaryFile = getDependencyPrimaryFile(version)
|
||||
return dependencyPrimaryFile?.url
|
||||
? createProjectDownloadUrl(dependencyPrimaryFile.url, {
|
||||
reason: 'dependency',
|
||||
})
|
||||
: undefined
|
||||
}
|
||||
|
||||
function createDependencyLink(context: {
|
||||
project?: Labrinth.Projects.v2.Project
|
||||
version?: Labrinth.Versions.v2.Version
|
||||
|
||||
Reference in New Issue
Block a user