mirror of
https://github.com/modrinth/code.git
synced 2026-08-31 03:55:59 +00:00
refactor: use ts and also have modal own get project/versions queries
This commit is contained in:
@@ -14,8 +14,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { defineMessages, injectModrinthClient, useVIntl } from '@modrinth/ui'
|
import type { Labrinth } from '@modrinth/api-client'
|
||||||
|
import {
|
||||||
|
type CdnDownloadReason,
|
||||||
|
defineMessages,
|
||||||
|
injectModrinthClient,
|
||||||
|
useVIntl,
|
||||||
|
} from '@modrinth/ui'
|
||||||
|
import type { DisplayProjectType } from '@modrinth/utils'
|
||||||
import { useQuery } from '@tanstack/vue-query'
|
import { useQuery } from '@tanstack/vue-query'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
@@ -25,38 +32,49 @@ defineOptions({
|
|||||||
name: 'DownloadDependencies',
|
name: 'DownloadDependencies',
|
||||||
})
|
})
|
||||||
|
|
||||||
const props = defineProps({
|
type DownloadModalProject = Omit<Labrinth.Projects.v2.Project, 'project_type'> & {
|
||||||
dependencies: {
|
project_type: DisplayProjectType
|
||||||
type: Array,
|
actualProjectType: Labrinth.Projects.v2.ProjectType
|
||||||
default: null,
|
}
|
||||||
},
|
|
||||||
project: {
|
|
||||||
type: Object,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
selectedVersion: {
|
|
||||||
type: Object,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
currentGameVersion: {
|
|
||||||
type: [String, Boolean],
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
currentPlatform: {
|
|
||||||
type: [String, Boolean],
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
downloadReason: {
|
|
||||||
type: String,
|
|
||||||
default: 'standalone',
|
|
||||||
},
|
|
||||||
showTitle: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits(['download'])
|
type ResolvedContent = Labrinth.Content.v3.ResolvedContent | Labrinth.Content.v3.SkippedContent
|
||||||
|
|
||||||
|
interface DownloadDependencyRow {
|
||||||
|
key: string
|
||||||
|
name: string
|
||||||
|
icon?: string
|
||||||
|
projectHref?: string
|
||||||
|
downloadHref?: string
|
||||||
|
filename?: string
|
||||||
|
typeLabel: string
|
||||||
|
unavailableTooltip: string
|
||||||
|
dependencies: DownloadDependencyRow[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
dependencies?: DownloadDependencyRow[] | null
|
||||||
|
project?: DownloadModalProject | null
|
||||||
|
selectedVersion?: Labrinth.Versions.v3.Version | null
|
||||||
|
currentGameVersion?: string | null
|
||||||
|
currentPlatform?: string | null
|
||||||
|
downloadReason?: CdnDownloadReason
|
||||||
|
showTitle?: boolean
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
dependencies: null,
|
||||||
|
project: null,
|
||||||
|
selectedVersion: null,
|
||||||
|
currentGameVersion: null,
|
||||||
|
currentPlatform: null,
|
||||||
|
downloadReason: 'standalone',
|
||||||
|
showTitle: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
download: []
|
||||||
|
}>()
|
||||||
const client = injectModrinthClient()
|
const client = injectModrinthClient()
|
||||||
const { createProjectDownloadUrl } = useCdnDownloadContext()
|
const { createProjectDownloadUrl } = useCdnDownloadContext()
|
||||||
const { formatMessage } = useVIntl()
|
const { formatMessage } = useVIntl()
|
||||||
@@ -65,7 +83,7 @@ const shouldResolveDependencies = computed(
|
|||||||
() => !props.dependencies && !!props.project && !!props.selectedVersion,
|
() => !props.dependencies && !!props.project && !!props.selectedVersion,
|
||||||
)
|
)
|
||||||
|
|
||||||
const dependencyResolutionPreferences = computed(() => ({
|
const dependencyResolutionPreferences = computed<Labrinth.Content.v3.ResolutionPreferences>(() => ({
|
||||||
game_versions: props.selectedVersion?.game_versions || [],
|
game_versions: props.selectedVersion?.game_versions || [],
|
||||||
loaders: props.selectedVersion?.loaders || [],
|
loaders: props.selectedVersion?.loaders || [],
|
||||||
}))
|
}))
|
||||||
@@ -81,16 +99,16 @@ const { data: dependencyResolution } = useQuery({
|
|||||||
]),
|
]),
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
client.labrinth.content_v3.resolve({
|
client.labrinth.content_v3.resolve({
|
||||||
project_id: props.project.id,
|
project_id: props.project!.id,
|
||||||
version_id: props.selectedVersion.id,
|
version_id: props.selectedVersion!.id,
|
||||||
content_type: resolveContentType(props.project.project_type),
|
content_type: resolveContentType(props.project!.project_type),
|
||||||
selected: dependencyResolutionPreferences.value,
|
selected: dependencyResolutionPreferences.value,
|
||||||
target: dependencyResolutionPreferences.value,
|
target: dependencyResolutionPreferences.value,
|
||||||
}),
|
}),
|
||||||
enabled: shouldResolveDependencies,
|
enabled: shouldResolveDependencies,
|
||||||
})
|
})
|
||||||
|
|
||||||
const dependencyVersionIds = computed(() => {
|
const dependencyVersionIds = computed<string[]>(() => {
|
||||||
return [
|
return [
|
||||||
...new Set(
|
...new Set(
|
||||||
[
|
[
|
||||||
@@ -98,7 +116,7 @@ const dependencyVersionIds = computed(() => {
|
|||||||
...(dependencyResolution.value?.skipped || []),
|
...(dependencyResolution.value?.skipped || []),
|
||||||
]
|
]
|
||||||
.map((dependency) => dependency.version_id)
|
.map((dependency) => dependency.version_id)
|
||||||
.filter(Boolean),
|
.filter((versionId): versionId is string => !!versionId),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@@ -114,7 +132,7 @@ const { data: dependencyVersions } = useQuery({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const dependencyVersionById = computed(() => {
|
const dependencyVersionById = computed(() => {
|
||||||
const map = new Map()
|
const map = new Map<string, Labrinth.Versions.v3.Version>()
|
||||||
for (const version of dependencyVersions.value || []) {
|
for (const version of dependencyVersions.value || []) {
|
||||||
if (!version) continue
|
if (!version) continue
|
||||||
map.set(version.id, version)
|
map.set(version.id, version)
|
||||||
@@ -122,7 +140,7 @@ const dependencyVersionById = computed(() => {
|
|||||||
return map
|
return map
|
||||||
})
|
})
|
||||||
|
|
||||||
const dependencyProjectIds = computed(() => {
|
const dependencyProjectIds = computed<string[]>(() => {
|
||||||
return [
|
return [
|
||||||
...new Set(
|
...new Set(
|
||||||
[
|
[
|
||||||
@@ -130,7 +148,7 @@ const dependencyProjectIds = computed(() => {
|
|||||||
...(dependencyResolution.value?.skipped || []),
|
...(dependencyResolution.value?.skipped || []),
|
||||||
]
|
]
|
||||||
.map((dependency) => dependency.project_id)
|
.map((dependency) => dependency.project_id)
|
||||||
.filter(Boolean),
|
.filter((projectId): projectId is string => !!projectId),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@@ -146,7 +164,7 @@ const { data: dependencyProjects } = useQuery({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const dependencyProjectById = computed(() => {
|
const dependencyProjectById = computed(() => {
|
||||||
const map = new Map()
|
const map = new Map<string, Labrinth.Projects.v2.Project>()
|
||||||
for (const project of dependencyProjects.value || []) {
|
for (const project of dependencyProjects.value || []) {
|
||||||
map.set(project.id, project)
|
map.set(project.id, project)
|
||||||
}
|
}
|
||||||
@@ -154,7 +172,7 @@ const dependencyProjectById = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const dependenciesByParentVersionId = computed(() => {
|
const dependenciesByParentVersionId = computed(() => {
|
||||||
const map = new Map()
|
const map = new Map<string, ResolvedContent[]>()
|
||||||
|
|
||||||
for (const dependency of [
|
for (const dependency of [
|
||||||
...(dependencyResolution.value?.dependencies || []),
|
...(dependencyResolution.value?.dependencies || []),
|
||||||
@@ -170,7 +188,7 @@ const dependenciesByParentVersionId = computed(() => {
|
|||||||
return map
|
return map
|
||||||
})
|
})
|
||||||
|
|
||||||
const resolvedDependencyRows = computed(() => {
|
const resolvedDependencyRows = computed<DownloadDependencyRow[]>(() => {
|
||||||
const primaryVersionId =
|
const primaryVersionId =
|
||||||
dependencyResolution.value?.primary.version_id || props.selectedVersion?.id
|
dependencyResolution.value?.primary.version_id || props.selectedVersion?.id
|
||||||
if (!primaryVersionId) return []
|
if (!primaryVersionId) return []
|
||||||
@@ -180,44 +198,46 @@ const resolvedDependencyRows = computed(() => {
|
|||||||
return dependencies.map((dependency) => createDependencyRow(dependency))
|
return dependencies.map((dependency) => createDependencyRow(dependency))
|
||||||
})
|
})
|
||||||
|
|
||||||
const dependencyRows = computed(() => props.dependencies || resolvedDependencyRows.value)
|
const dependencyRows = computed<DownloadDependencyRow[]>(
|
||||||
|
() => props.dependencies || resolvedDependencyRows.value,
|
||||||
|
)
|
||||||
|
|
||||||
function primaryFileForVersion(version) {
|
function primaryFileForVersion(version?: Labrinth.Versions.v3.Version) {
|
||||||
return version?.files?.find((file) => file.primary) || version?.files?.[0]
|
return version?.files?.find((file) => file.primary) || version?.files?.[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDependencyRow(dependency) {
|
function createDependencyRow(dependency: ResolvedContent): DownloadDependencyRow {
|
||||||
const version = dependencyVersionById.value.get(dependency.version_id)
|
const versionId = dependency.version_id ?? undefined
|
||||||
|
const version = versionId ? dependencyVersionById.value.get(versionId) : undefined
|
||||||
const project = dependencyProjectById.value.get(dependency.project_id)
|
const project = dependencyProjectById.value.get(dependency.project_id)
|
||||||
const primaryFile = primaryFileForVersion(version)
|
const primaryFile = primaryFileForVersion(version)
|
||||||
const unavailableTooltip = dependency.reason
|
const unavailableTooltip =
|
||||||
? skippedReasonLabel(dependency.reason)
|
'reason' in dependency && dependency.reason
|
||||||
: formatMessage(messages.unavailableDependency)
|
? skippedReasonLabel(dependency.reason)
|
||||||
|
: formatMessage(messages.unavailableDependency)
|
||||||
const name =
|
const name =
|
||||||
project?.title ||
|
project?.title || version?.name || version?.version_number || versionId || dependency.project_id
|
||||||
version?.name ||
|
|
||||||
version?.version_number ||
|
|
||||||
dependency.version_id ||
|
|
||||||
dependency.project_id ||
|
|
||||||
'Dependency'
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key: `${dependency.project_id}-${dependency.version_id ?? 'unresolved'}-${dependency.reason ?? 'resolved'}`,
|
key: `${dependency.project_id}-${versionId ?? 'unresolved'}-${
|
||||||
|
'reason' in dependency ? dependency.reason : 'resolved'
|
||||||
|
}`,
|
||||||
name,
|
name,
|
||||||
icon: project?.icon_url,
|
icon: project?.icon_url,
|
||||||
projectHref: project ? `/${project.project_type}/${project.slug || project.id}` : undefined,
|
projectHref: project ? `/${project.project_type}/${project.slug || project.id}` : undefined,
|
||||||
downloadHref: dependency.reason || !primaryFile ? undefined : getDownloadUrl(primaryFile.url),
|
downloadHref:
|
||||||
|
'reason' in dependency || !primaryFile ? undefined : getDownloadUrl(primaryFile.url),
|
||||||
filename: primaryFile?.filename,
|
filename: primaryFile?.filename,
|
||||||
typeLabel: 'Required',
|
typeLabel: 'Required',
|
||||||
unavailableTooltip,
|
unavailableTooltip,
|
||||||
dependencies: (
|
dependencies: (versionId && dependenciesByParentVersionId.value.get(versionId)
|
||||||
(dependency.version_id && dependenciesByParentVersionId.value.get(dependency.version_id)) ||
|
? dependenciesByParentVersionId.value.get(versionId)!
|
||||||
[]
|
: []
|
||||||
).map((subDependency) => createDependencyRow(subDependency)),
|
).map((subDependency) => createDependencyRow(subDependency)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function skippedReasonLabel(reason) {
|
function skippedReasonLabel(reason: Labrinth.Content.v3.SkippedContent['reason']) {
|
||||||
return (
|
return (
|
||||||
{
|
{
|
||||||
already_installed: formatMessage(messages.alreadyInstalledDependency),
|
already_installed: formatMessage(messages.alreadyInstalledDependency),
|
||||||
@@ -230,13 +250,13 @@ function skippedReasonLabel(reason) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveContentType(projectType) {
|
function resolveContentType(projectType: DisplayProjectType): Labrinth.Content.v3.ContentType {
|
||||||
return ['mod', 'plugin', 'datapack', 'resourcepack', 'shader', 'modpack'].includes(projectType)
|
return ['mod', 'plugin', 'datapack', 'resourcepack', 'shader', 'modpack'].includes(projectType)
|
||||||
? projectType
|
? (projectType as Labrinth.Content.v3.ContentType)
|
||||||
: 'mod'
|
: 'mod'
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDownloadUrl(url) {
|
function getDownloadUrl(url: string) {
|
||||||
return createProjectDownloadUrl(url, {
|
return createProjectDownloadUrl(url, {
|
||||||
reason: props.downloadReason,
|
reason: props.downloadReason,
|
||||||
gameVersion: props.currentGameVersion ?? undefined,
|
gameVersion: props.currentGameVersion ?? undefined,
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { DownloadIcon, PackageIcon } from '@modrinth/assets'
|
import { DownloadIcon, PackageIcon } from '@modrinth/assets'
|
||||||
import { Avatar, ButtonStyled, TagItem } from '@modrinth/ui'
|
import { Avatar, ButtonStyled, TagItem } from '@modrinth/ui'
|
||||||
|
|
||||||
@@ -71,12 +71,23 @@ defineOptions({
|
|||||||
name: 'DownloadDependency',
|
name: 'DownloadDependency',
|
||||||
})
|
})
|
||||||
|
|
||||||
defineProps({
|
interface DownloadDependencyRow {
|
||||||
dependency: {
|
key: string
|
||||||
type: Object,
|
name: string
|
||||||
required: true,
|
icon?: string
|
||||||
},
|
projectHref?: string
|
||||||
})
|
downloadHref?: string
|
||||||
|
filename?: string
|
||||||
|
typeLabel: string
|
||||||
|
unavailableTooltip: string
|
||||||
|
dependencies: DownloadDependencyRow[]
|
||||||
|
}
|
||||||
|
|
||||||
const emit = defineEmits(['download'])
|
defineProps<{
|
||||||
|
dependency: DownloadDependencyRow
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
download: []
|
||||||
|
}>()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -100,6 +100,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<ButtonStyled v-if="selectedPrimaryFile" color="brand" circular>
|
<ButtonStyled v-if="selectedPrimaryFile" color="brand" circular>
|
||||||
<a
|
<a
|
||||||
|
v-tooltip="'Download'"
|
||||||
:href="selectedPrimaryFileDownloadUrl"
|
:href="selectedPrimaryFileDownloadUrl"
|
||||||
:download="selectedPrimaryFile.filename"
|
:download="selectedPrimaryFile.filename"
|
||||||
:aria-label="
|
:aria-label="
|
||||||
@@ -107,14 +108,13 @@
|
|||||||
version: selectedVersion.version_number,
|
version: selectedVersion.version_number,
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
v-tooltip="'Download'"
|
|
||||||
@click="emit('download')"
|
@click="emit('download')"
|
||||||
>
|
>
|
||||||
<DownloadIcon aria-hidden="true" />
|
<DownloadIcon aria-hidden="true" />
|
||||||
</a>
|
</a>
|
||||||
</ButtonStyled>
|
</ButtonStyled>
|
||||||
</div>
|
</div>
|
||||||
<p v-else-if="currentPlatform && currentGameVersion && !versionsLoading && versions.length > 0">
|
<p v-else-if="currentPlatform && currentGameVersion && versions.length > 0">
|
||||||
{{
|
{{
|
||||||
formatMessage(messages.noVersionsAvailable, {
|
formatMessage(messages.noVersionsAvailable, {
|
||||||
gameVersion: currentGameVersion,
|
gameVersion: currentGameVersion,
|
||||||
@@ -124,18 +124,22 @@
|
|||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
|
import type { Labrinth } from '@modrinth/api-client'
|
||||||
import { DownloadIcon } from '@modrinth/assets'
|
import { DownloadIcon } from '@modrinth/assets'
|
||||||
import {
|
import {
|
||||||
ButtonStyled,
|
ButtonStyled,
|
||||||
|
type CdnDownloadReason,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Combobox,
|
Combobox,
|
||||||
|
type ComboboxOption,
|
||||||
defineMessages,
|
defineMessages,
|
||||||
getTagMessage,
|
getTagMessage,
|
||||||
useDebugLogger,
|
useDebugLogger,
|
||||||
useVIntl,
|
useVIntl,
|
||||||
} from '@modrinth/ui'
|
} from '@modrinth/ui'
|
||||||
import VersionChannelTag from '@modrinth/ui/src/components/version/VersionChannelTag.vue'
|
import VersionChannelTag from '@modrinth/ui/src/components/version/VersionChannelTag.vue'
|
||||||
|
import type { DisplayProjectType } from '@modrinth/utils'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
@@ -143,48 +147,49 @@ defineOptions({
|
|||||||
name: 'DownloadProject',
|
name: 'DownloadProject',
|
||||||
})
|
})
|
||||||
|
|
||||||
const props = defineProps({
|
type DownloadModalProject = Omit<Labrinth.Projects.v2.Project, 'project_type'> & {
|
||||||
project: {
|
project_type: DisplayProjectType
|
||||||
type: Object,
|
actualProjectType: Labrinth.Projects.v2.ProjectType
|
||||||
required: true,
|
}
|
||||||
},
|
|
||||||
versions: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
versionsLoading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
tags: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
downloadReason: {
|
|
||||||
type: String,
|
|
||||||
default: 'standalone',
|
|
||||||
},
|
|
||||||
initialGameVersion: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
initialPlatform: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
resetKey: {
|
|
||||||
type: Number,
|
|
||||||
default: 0,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits(['download', 'selectGameVersion', 'selectPlatform', 'update:selection'])
|
type ProjectDownloadSelection = {
|
||||||
|
currentGameVersion: string | null
|
||||||
|
currentPlatform: string | null
|
||||||
|
selectedVersion: Labrinth.Versions.v3.Version | null
|
||||||
|
selectedPrimaryFile: Labrinth.Versions.v3.VersionFile | null
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
project: DownloadModalProject
|
||||||
|
versions?: Labrinth.Versions.v3.Version[]
|
||||||
|
downloadReason?: CdnDownloadReason
|
||||||
|
initialGameVersion?: string | null
|
||||||
|
initialPlatform?: string | null
|
||||||
|
resetKey?: number
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
versions: () => [],
|
||||||
|
downloadReason: 'standalone',
|
||||||
|
initialGameVersion: null,
|
||||||
|
initialPlatform: null,
|
||||||
|
resetKey: 0,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
download: []
|
||||||
|
selectGameVersion: [gameVersion: string]
|
||||||
|
selectPlatform: [platform: string]
|
||||||
|
'update:selection': [selection: ProjectDownloadSelection]
|
||||||
|
}>()
|
||||||
const { formatMessage } = useVIntl()
|
const { formatMessage } = useVIntl()
|
||||||
const { createProjectDownloadUrl } = useCdnDownloadContext()
|
const { createProjectDownloadUrl } = useCdnDownloadContext()
|
||||||
const debug = useDebugLogger('DownloadProject')
|
const debug = useDebugLogger('DownloadProject')
|
||||||
|
const tags = useGeneratedState()
|
||||||
|
|
||||||
const userSelectedGameVersion = ref(props.initialGameVersion)
|
const userSelectedGameVersion = ref<string | null>(props.initialGameVersion)
|
||||||
const userSelectedPlatform = ref(props.initialPlatform)
|
const userSelectedPlatform = ref<string | null>(props.initialPlatform)
|
||||||
const showAllVersions = ref(defaultShowAllVersions())
|
const showAllVersions = ref(defaultShowAllVersions())
|
||||||
const versionFilter = ref('')
|
const versionFilter = ref('')
|
||||||
|
|
||||||
@@ -197,39 +202,36 @@ const showAllVersionsModel = computed({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const currentGameVersion = computed(() => {
|
const currentGameVersion = computed<string | null>(() => {
|
||||||
return (
|
if (userSelectedGameVersion.value) return userSelectedGameVersion.value
|
||||||
userSelectedGameVersion.value ||
|
return props.project.game_versions.length === 1 ? props.project.game_versions[0] : null
|
||||||
(props.project.game_versions.length === 1 && props.project.game_versions[0])
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const possibleGameVersions = computed(() => {
|
const possibleGameVersions = computed<string[]>(() => {
|
||||||
return props.versions
|
return props.versions
|
||||||
.filter((x) => !currentPlatform.value || x.loaders.includes(currentPlatform.value))
|
.filter((x) => !currentPlatform.value || x.loaders.includes(currentPlatform.value))
|
||||||
.flatMap((x) => x.game_versions)
|
.flatMap((x) => x.game_versions)
|
||||||
})
|
})
|
||||||
|
|
||||||
const possiblePlatforms = computed(() => {
|
const possiblePlatforms = computed<string[]>(() => {
|
||||||
return props.versions
|
return props.versions
|
||||||
.filter((x) => !currentGameVersion.value || x.game_versions.includes(currentGameVersion.value))
|
.filter((x) => !currentGameVersion.value || x.game_versions.includes(currentGameVersion.value))
|
||||||
.flatMap((x) => x.loaders)
|
.flatMap((x) => x.loaders)
|
||||||
})
|
})
|
||||||
|
|
||||||
const currentPlatform = computed(() => {
|
const currentPlatform = computed<string | null>(() => {
|
||||||
return (
|
if (userSelectedPlatform.value) return userSelectedPlatform.value
|
||||||
userSelectedPlatform.value || (props.project.loaders.length === 1 && props.project.loaders[0])
|
return props.project.loaders.length === 1 ? props.project.loaders[0] : null
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const currentPlatformText = computed(() => {
|
const currentPlatformText = computed(() => {
|
||||||
if (!currentPlatform.value) return null
|
if (!currentPlatform.value) return ''
|
||||||
return formatMessage(getTagMessage(currentPlatform.value, 'loader'))
|
return loaderLabel(currentPlatform.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
const releaseVersions = computed(() => {
|
const releaseVersions = computed<Set<string>>(() => {
|
||||||
const set = new Set()
|
const set = new Set<string>()
|
||||||
for (const gameVersion of props.tags.gameVersions || []) {
|
for (const gameVersion of tags.value.gameVersions || []) {
|
||||||
if (gameVersion?.version && gameVersion.version_type === 'release') {
|
if (gameVersion?.version && gameVersion.version_type === 'release') {
|
||||||
set.add(gameVersion.version)
|
set.add(gameVersion.version)
|
||||||
}
|
}
|
||||||
@@ -237,9 +239,9 @@ const releaseVersions = computed(() => {
|
|||||||
return set
|
return set
|
||||||
})
|
})
|
||||||
|
|
||||||
const nonReleaseVersions = computed(() => {
|
const nonReleaseVersions = computed<Set<string>>(() => {
|
||||||
const set = new Set()
|
const set = new Set<string>()
|
||||||
for (const gameVersion of props.tags.gameVersions || []) {
|
for (const gameVersion of tags.value.gameVersions || []) {
|
||||||
if (gameVersion?.version && gameVersion.version_type !== 'release') {
|
if (gameVersion?.version && gameVersion.version_type !== 'release') {
|
||||||
set.add(gameVersion.version)
|
set.add(gameVersion.version)
|
||||||
}
|
}
|
||||||
@@ -275,29 +277,34 @@ const filteredGameVersions = computed(() => {
|
|||||||
.reverse()
|
.reverse()
|
||||||
})
|
})
|
||||||
|
|
||||||
const gameVersionOptions = computed(() => {
|
const gameVersionOptions = computed<ComboboxOption<string>[]>(() => {
|
||||||
return filteredGameVersions.value.map((gameVersion) => ({
|
return filteredGameVersions.value.map((gameVersion) => ({
|
||||||
value: gameVersion,
|
value: gameVersion,
|
||||||
label: gameVersion,
|
label: gameVersion,
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
const platformOptions = computed(() => {
|
const platformOptions = computed<ComboboxOption<string>[]>(() => {
|
||||||
return props.project.loaders
|
return props.project.loaders
|
||||||
.slice()
|
.slice()
|
||||||
.reverse()
|
.reverse()
|
||||||
.map((platform) => ({
|
.map((platform) => ({
|
||||||
value: platform,
|
value: platform,
|
||||||
label: formatMessage(getTagMessage(platform, 'loader')),
|
label: loaderLabel(platform),
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
const filteredVersions = computed(() => {
|
const filteredVersions = computed<Labrinth.Versions.v3.Version[]>(() => {
|
||||||
const result = props.versions.filter(
|
const gameVersion = currentGameVersion.value
|
||||||
(x) =>
|
if (!gameVersion) return []
|
||||||
x.game_versions?.includes(currentGameVersion.value) &&
|
|
||||||
(x.loaders?.includes(currentPlatform.value) || props.project.project_type === 'resourcepack'),
|
const platform = currentPlatform.value
|
||||||
)
|
const result = props.versions.filter((x) => {
|
||||||
|
const matchesPlatform =
|
||||||
|
props.project.project_type === 'resourcepack' || (!!platform && x.loaders.includes(platform))
|
||||||
|
|
||||||
|
return x.game_versions.includes(gameVersion) && matchesPlatform
|
||||||
|
})
|
||||||
debug('filteredVersions', {
|
debug('filteredVersions', {
|
||||||
total: props.versions.length,
|
total: props.versions.length,
|
||||||
filtered: result.length,
|
filtered: result.length,
|
||||||
@@ -308,11 +315,11 @@ const filteredVersions = computed(() => {
|
|||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
|
|
||||||
const filteredRelease = computed(() => {
|
const filteredRelease = computed<Labrinth.Versions.v3.Version | undefined>(() => {
|
||||||
return filteredVersions.value.find((x) => x.version_type === 'release')
|
return filteredVersions.value.find((x) => x.version_type === 'release')
|
||||||
})
|
})
|
||||||
|
|
||||||
const filteredBeta = computed(() => {
|
const filteredBeta = computed<Labrinth.Versions.v3.Version | undefined>(() => {
|
||||||
return filteredVersions.value.find(
|
return filteredVersions.value.find(
|
||||||
(x) =>
|
(x) =>
|
||||||
x.version_type === 'beta' &&
|
x.version_type === 'beta' &&
|
||||||
@@ -321,7 +328,7 @@ const filteredBeta = computed(() => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const filteredAlpha = computed(() => {
|
const filteredAlpha = computed<Labrinth.Versions.v3.Version | undefined>(() => {
|
||||||
return filteredVersions.value.find(
|
return filteredVersions.value.find(
|
||||||
(x) =>
|
(x) =>
|
||||||
x.version_type === 'alpha' &&
|
x.version_type === 'alpha' &&
|
||||||
@@ -332,18 +339,20 @@ const filteredAlpha = computed(() => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const selectedVersion = computed(() => {
|
const selectedVersion = computed<Labrinth.Versions.v3.Version | null>(() => {
|
||||||
return filteredRelease.value || filteredBeta.value || filteredAlpha.value
|
return filteredRelease.value || filteredBeta.value || filteredAlpha.value || null
|
||||||
})
|
})
|
||||||
|
|
||||||
const selectedPrimaryFile = computed(() => {
|
const selectedPrimaryFile = computed<Labrinth.Versions.v3.VersionFile | null>(() => {
|
||||||
return (
|
return (
|
||||||
selectedVersion.value?.files?.find((file) => file.primary) || selectedVersion.value?.files?.[0]
|
selectedVersion.value?.files?.find((file) => file.primary) ||
|
||||||
|
selectedVersion.value?.files?.[0] ||
|
||||||
|
null
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const selectedPrimaryFileDownloadUrl = computed(() => {
|
const selectedPrimaryFileDownloadUrl = computed(() => {
|
||||||
if (!selectedPrimaryFile.value) return null
|
if (!selectedPrimaryFile.value) return '#'
|
||||||
return getDownloadUrl(selectedPrimaryFile.value.url)
|
return getDownloadUrl(selectedPrimaryFile.value.url)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -370,17 +379,19 @@ watch(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
function selectGameVersion(gameVersion) {
|
function selectGameVersion(gameVersion?: string) {
|
||||||
|
if (!gameVersion) return
|
||||||
userSelectedGameVersion.value = gameVersion
|
userSelectedGameVersion.value = gameVersion
|
||||||
emit('selectGameVersion', gameVersion)
|
emit('selectGameVersion', gameVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPlatform(platform) {
|
function selectPlatform(platform?: string) {
|
||||||
|
if (!platform) return
|
||||||
userSelectedPlatform.value = platform
|
userSelectedPlatform.value = platform
|
||||||
emit('selectPlatform', platform)
|
emit('selectPlatform', platform)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDownloadUrl(url) {
|
function getDownloadUrl(url: string) {
|
||||||
return createProjectDownloadUrl(url, {
|
return createProjectDownloadUrl(url, {
|
||||||
reason: props.downloadReason,
|
reason: props.downloadReason,
|
||||||
gameVersion: currentGameVersion.value ?? undefined,
|
gameVersion: currentGameVersion.value ?? undefined,
|
||||||
@@ -388,7 +399,11 @@ function getDownloadUrl(url) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function isReleaseGameVersion(version) {
|
function loaderLabel(loader: string) {
|
||||||
|
return formatMessage(getTagMessage(loader, 'loader') ?? messages.unknownLoader)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isReleaseGameVersion(version: string) {
|
||||||
if (releaseVersions.value.has(version)) return true
|
if (releaseVersions.value.has(version)) return true
|
||||||
if (nonReleaseVersions.value.has(version)) return false
|
if (nonReleaseVersions.value.has(version)) return false
|
||||||
return true
|
return true
|
||||||
@@ -398,8 +413,8 @@ function defaultShowAllVersions() {
|
|||||||
return (
|
return (
|
||||||
props.project.game_versions.length > 0 &&
|
props.project.game_versions.length > 0 &&
|
||||||
props.project.game_versions.every((projectVersion) => {
|
props.project.game_versions.every((projectVersion) => {
|
||||||
const gameVersion = props.tags.gameVersions?.find((x) => x.version === projectVersion)
|
const gameVersion = tags.value.gameVersions?.find((x) => x.version === projectVersion)
|
||||||
return gameVersion?.version_type && gameVersion.version_type !== 'release'
|
return !!gameVersion?.version_type && gameVersion.version_type !== 'release'
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -441,5 +456,9 @@ const messages = defineMessages({
|
|||||||
id: 'project.download.show-all-versions',
|
id: 'project.download.show-all-versions',
|
||||||
defaultMessage: 'Show all versions',
|
defaultMessage: 'Show all versions',
|
||||||
},
|
},
|
||||||
|
unknownLoader: {
|
||||||
|
id: 'project.download.unknown-loader',
|
||||||
|
defaultMessage: 'Unknown loader',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -46,9 +46,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
|
import type { Labrinth } from '@modrinth/api-client'
|
||||||
import { ExternalIcon, ModrinthIcon } from '@modrinth/assets'
|
import { ExternalIcon, ModrinthIcon } from '@modrinth/assets'
|
||||||
import { defineMessages, useVIntl } from '@modrinth/ui'
|
import { defineMessages, useVIntl } from '@modrinth/ui'
|
||||||
|
import type { DisplayProjectType } from '@modrinth/utils'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
import Accordion from '~/components/ui/Accordion.vue'
|
import Accordion from '~/components/ui/Accordion.vue'
|
||||||
@@ -57,19 +59,18 @@ defineOptions({
|
|||||||
name: 'InstallWithModrinthApp',
|
name: 'InstallWithModrinthApp',
|
||||||
})
|
})
|
||||||
|
|
||||||
defineProps({
|
type DownloadModalProject = Omit<Labrinth.Projects.v2.Project, 'project_type'> & {
|
||||||
project: {
|
project_type: DisplayProjectType
|
||||||
type: Object,
|
actualProjectType: Labrinth.Projects.v2.ProjectType
|
||||||
required: true,
|
}
|
||||||
},
|
|
||||||
tags: {
|
defineProps<{
|
||||||
type: Object,
|
project: DownloadModalProject
|
||||||
required: true,
|
}>()
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const { formatMessage } = useVIntl()
|
const { formatMessage } = useVIntl()
|
||||||
const getModrinthAppAccordion = ref()
|
const tags = useGeneratedState()
|
||||||
|
const getModrinthAppAccordion = ref<InstanceType<typeof Accordion> | null>(null)
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
dontHaveModrinthApp: {
|
dontHaveModrinthApp: {
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<NewModal ref="modal" :on-show="onShow" :on-hide="onHide" width="544px">
|
<NewModal ref="modal" :on-show="onShow" :on-hide="onHide" width="544px">
|
||||||
<template #title>
|
<template v-if="project" #title>
|
||||||
<Avatar :src="project.icon_url" :alt="project.title" class="icon" size="32px" />
|
<Avatar :src="project.icon_url" :alt="project.title" class="icon" size="32px" />
|
||||||
<div class="truncate text-lg font-extrabold text-contrast">
|
<div class="truncate text-lg font-extrabold text-contrast">
|
||||||
{{ formatMessage(messages.downloadTitle, { title: project.title }) }}
|
{{ formatMessage(messages.downloadTitle, { title: project.title }) }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="mx-auto flex w-full flex-col gap-4">
|
<div v-if="project" class="mx-auto flex w-full flex-col gap-4">
|
||||||
<InstallWithModrinthApp :project="project" :tags="tags" />
|
<InstallWithModrinthApp :project="project" />
|
||||||
<DownloadProject
|
<DownloadProject
|
||||||
:project="project"
|
:project="project"
|
||||||
:versions="versions"
|
:versions="versions"
|
||||||
:versions-loading="versionsLoading"
|
|
||||||
:tags="tags"
|
|
||||||
:download-reason="downloadReason"
|
:download-reason="downloadReason"
|
||||||
:initial-game-version="initialGameVersion"
|
:initial-game-version="initialGameVersion"
|
||||||
:initial-platform="initialPlatform"
|
:initial-platform="initialPlatform"
|
||||||
@@ -76,77 +74,145 @@
|
|||||||
</NewModal>
|
</NewModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
|
import type { Labrinth } from '@modrinth/api-client'
|
||||||
import { DownloadIcon, FileIcon } from '@modrinth/assets'
|
import { DownloadIcon, FileIcon } from '@modrinth/assets'
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
|
type CdnDownloadReason,
|
||||||
defineMessages,
|
defineMessages,
|
||||||
|
injectModrinthClient,
|
||||||
NewModal,
|
NewModal,
|
||||||
ServersPromo,
|
ServersPromo,
|
||||||
useDebugLogger,
|
useDebugLogger,
|
||||||
useVIntl,
|
useVIntl,
|
||||||
} from '@modrinth/ui'
|
} from '@modrinth/ui'
|
||||||
|
import type { DisplayProjectType } from '@modrinth/utils'
|
||||||
|
import { useQuery } from '@tanstack/vue-query'
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
import { navigateTo } from '#app'
|
import { navigateTo } from '#app'
|
||||||
import { saveFeatureFlags } from '~/composables/featureFlags.ts'
|
import { saveFeatureFlags } from '~/composables/featureFlags.ts'
|
||||||
|
import { STALE_TIME, STALE_TIME_LONG } from '~/composables/queries/project'
|
||||||
|
|
||||||
import DownloadDependencies from './DownloadDependencies.vue'
|
import DownloadDependencies from './DownloadDependencies.vue'
|
||||||
import DownloadProject from './DownloadProject.vue'
|
import DownloadProject from './DownloadProject.vue'
|
||||||
import InstallWithModrinthApp from './InstallWithModrinthApp.vue'
|
import InstallWithModrinthApp from './InstallWithModrinthApp.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
type DownloadModalProject = Omit<Labrinth.Projects.v2.Project, 'project_type'> & {
|
||||||
project: {
|
project_type: DisplayProjectType
|
||||||
type: Object,
|
actualProjectType: Labrinth.Projects.v2.ProjectType
|
||||||
required: true,
|
}
|
||||||
},
|
|
||||||
versions: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
versionsLoading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
tags: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
downloadReason: {
|
|
||||||
type: String,
|
|
||||||
default: 'standalone',
|
|
||||||
},
|
|
||||||
loadVersions: {
|
|
||||||
type: Function,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits(['download'])
|
type ProjectDownloadSelection = {
|
||||||
|
currentGameVersion: string | null
|
||||||
|
currentPlatform: string | null
|
||||||
|
selectedVersion: Labrinth.Versions.v3.Version | null
|
||||||
|
selectedPrimaryFile: Labrinth.Versions.v3.VersionFile | null
|
||||||
|
}
|
||||||
|
|
||||||
|
type NewModalRef = {
|
||||||
|
show: (event?: MouseEvent) => void
|
||||||
|
hide: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
projectId: string
|
||||||
|
downloadReason?: CdnDownloadReason
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
downloadReason: 'standalone',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
download: []
|
||||||
|
}>()
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const flags = useFeatureFlags()
|
const flags = useFeatureFlags()
|
||||||
|
const tags = useGeneratedState()
|
||||||
|
const client = injectModrinthClient()
|
||||||
const { createProjectDownloadUrl } = useCdnDownloadContext()
|
const { createProjectDownloadUrl } = useCdnDownloadContext()
|
||||||
const { formatMessage } = useVIntl()
|
const { formatMessage } = useVIntl()
|
||||||
const debug = useDebugLogger('DownloadModal')
|
const debug = useDebugLogger('DownloadModal')
|
||||||
|
|
||||||
const modal = ref()
|
const modal = ref<NewModalRef | null>(null)
|
||||||
const modalOpen = ref(false)
|
const modalOpen = ref(false)
|
||||||
const downloadProjectResetKey = ref(0)
|
const downloadProjectResetKey = ref(0)
|
||||||
const projectDownloadSelection = ref({
|
const projectDownloadSelection = ref<ProjectDownloadSelection>({
|
||||||
currentGameVersion: null,
|
currentGameVersion: null,
|
||||||
currentPlatform: null,
|
currentPlatform: null,
|
||||||
selectedVersion: null,
|
selectedVersion: null,
|
||||||
selectedPrimaryFile: null,
|
selectedPrimaryFile: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { version, loader } = route.query
|
const routeProjectId = computed(() => props.projectId)
|
||||||
const initialGameVersion = ref(
|
|
||||||
typeof version === 'string' && props.project.game_versions.includes(version) ? version : null,
|
const { data: projectRaw, error: projectV2Error } = useQuery({
|
||||||
)
|
queryKey: computed(() => ['project', 'v2', routeProjectId.value]),
|
||||||
const initialPlatform = ref(
|
queryFn: () => client.labrinth.projects_v2.get(routeProjectId.value),
|
||||||
typeof loader === 'string' && props.project.loaders.includes(loader) ? loader : null,
|
staleTime: STALE_TIME,
|
||||||
)
|
})
|
||||||
|
|
||||||
|
const resolvedProjectId = computed(() => projectRaw.value?.id)
|
||||||
|
|
||||||
|
const project = computed<DownloadModalProject | null>(() => {
|
||||||
|
if (!projectRaw.value) return null
|
||||||
|
|
||||||
|
return {
|
||||||
|
...projectRaw.value,
|
||||||
|
actualProjectType: projectRaw.value.project_type,
|
||||||
|
project_type: getProjectTypeForUrl(projectRaw.value.project_type, projectRaw.value.loaders),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const versionsEnabled = ref(false)
|
||||||
|
const {
|
||||||
|
data: versionsV3,
|
||||||
|
error: _versionsV3Error,
|
||||||
|
isFetching: versionsV3Loading,
|
||||||
|
} = useQuery({
|
||||||
|
queryKey: computed(() => ['project', resolvedProjectId.value, 'versions', 'v3']),
|
||||||
|
queryFn: () =>
|
||||||
|
client.labrinth.versions_v3.getProjectVersions(resolvedProjectId.value!, {
|
||||||
|
include_changelog: false,
|
||||||
|
apiVersion: 3,
|
||||||
|
}),
|
||||||
|
staleTime: STALE_TIME_LONG,
|
||||||
|
enabled: computed(() => !!resolvedProjectId.value && versionsEnabled.value),
|
||||||
|
})
|
||||||
|
|
||||||
|
const versions = computed<Labrinth.Versions.v3.Version[]>(() => {
|
||||||
|
const isModpack =
|
||||||
|
project.value?.actualProjectType === 'modpack' || project.value?.project_type === 'modpack'
|
||||||
|
|
||||||
|
return (versionsV3.value ?? []).map((version) => {
|
||||||
|
const files = Array.isArray(version.files) ? version.files : []
|
||||||
|
const gameVersions = Array.isArray(version.game_versions) ? version.game_versions : []
|
||||||
|
const loaders = Array.isArray(version.loaders) ? version.loaders : []
|
||||||
|
const mrpackLoaders = Array.isArray(version.mrpack_loaders) ? version.mrpack_loaders : []
|
||||||
|
|
||||||
|
return {
|
||||||
|
...version,
|
||||||
|
files,
|
||||||
|
game_versions: gameVersions,
|
||||||
|
loaders: isModpack && mrpackLoaders.length ? mrpackLoaders : loaders,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const initialGameVersion = computed(() => {
|
||||||
|
const version = route.query.version
|
||||||
|
if (typeof version !== 'string' || !project.value?.game_versions.includes(version)) return null
|
||||||
|
return version
|
||||||
|
})
|
||||||
|
const initialPlatform = computed(() => {
|
||||||
|
const loader = route.query.loader
|
||||||
|
if (typeof loader !== 'string' || !project.value?.loaders.includes(loader)) return null
|
||||||
|
return loader
|
||||||
|
})
|
||||||
|
|
||||||
const currentGameVersion = computed(() => projectDownloadSelection.value.currentGameVersion)
|
const currentGameVersion = computed(() => projectDownloadSelection.value.currentGameVersion)
|
||||||
const currentPlatform = computed(() => projectDownloadSelection.value.currentPlatform)
|
const currentPlatform = computed(() => projectDownloadSelection.value.currentPlatform)
|
||||||
@@ -158,6 +224,12 @@ const additionalFiles = computed(() => {
|
|||||||
return selectedVersion.value.files.filter((file) => file !== selectedPrimaryFile.value)
|
return selectedVersion.value.files.filter((file) => file !== selectedPrimaryFile.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(projectV2Error, (error) => {
|
||||||
|
if (error) {
|
||||||
|
debug('project query failed', error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
downloadTitle: {
|
downloadTitle: {
|
||||||
id: 'project.download.title',
|
id: 'project.download.title',
|
||||||
@@ -169,17 +241,36 @@ const messages = defineMessages({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
function fileTypeLabel(type) {
|
const fileTypeLabels: Partial<Record<Labrinth.Versions.v3.FileType, string>> = {
|
||||||
return (
|
'required-resource-pack': 'Resourcepack',
|
||||||
{
|
'optional-resource-pack': 'Resourcepack',
|
||||||
'required-resource-pack': 'Resourcepack',
|
unknown: 'File',
|
||||||
'optional-resource-pack': 'Resourcepack',
|
|
||||||
unknown: 'File',
|
|
||||||
}[type] || 'File'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDownloadUrl(url) {
|
function fileTypeLabel(type?: Labrinth.Versions.v3.FileType) {
|
||||||
|
return fileTypeLabels[type ?? 'unknown'] || 'File'
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProjectTypeForUrl(
|
||||||
|
type: Labrinth.Projects.v2.ProjectType,
|
||||||
|
loaders: string[],
|
||||||
|
): DisplayProjectType {
|
||||||
|
if (type !== 'mod') return type as DisplayProjectType
|
||||||
|
|
||||||
|
const isMod = loaders.some((loader) => tags.value.loaderData.modLoaders.includes(loader))
|
||||||
|
const isPlugin = loaders.some((loader) => tags.value.loaderData.allPluginLoaders.includes(loader))
|
||||||
|
const isDataPack = loaders.some((loader) =>
|
||||||
|
tags.value.loaderData.dataPackLoaders.includes(loader),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isDataPack) return 'datapack'
|
||||||
|
if (isPlugin) return 'plugin'
|
||||||
|
if (isMod) return 'mod'
|
||||||
|
|
||||||
|
return 'mod'
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDownloadUrl(url: string) {
|
||||||
return createProjectDownloadUrl(url, {
|
return createProjectDownloadUrl(url, {
|
||||||
reason: props.downloadReason,
|
reason: props.downloadReason,
|
||||||
gameVersion: currentGameVersion.value ?? undefined,
|
gameVersion: currentGameVersion.value ?? undefined,
|
||||||
@@ -187,7 +278,13 @@ function getDownloadUrl(url) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateDownloadQuery({ gameVersion, platform }) {
|
function updateDownloadQuery({
|
||||||
|
gameVersion,
|
||||||
|
platform,
|
||||||
|
}: {
|
||||||
|
gameVersion: string | null
|
||||||
|
platform: string | null
|
||||||
|
}) {
|
||||||
navigateTo(
|
navigateTo(
|
||||||
{
|
{
|
||||||
query: {
|
query: {
|
||||||
@@ -205,14 +302,14 @@ function updateDownloadQuery({ gameVersion, platform }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectGameVersion(gameVersion) {
|
function selectGameVersion(gameVersion: string) {
|
||||||
updateDownloadQuery({
|
updateDownloadQuery({
|
||||||
gameVersion,
|
gameVersion,
|
||||||
platform: currentPlatform.value,
|
platform: currentPlatform.value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPlatform(platform) {
|
function selectPlatform(platform: string) {
|
||||||
updateDownloadQuery({
|
updateDownloadQuery({
|
||||||
gameVersion: currentGameVersion.value,
|
gameVersion: currentGameVersion.value,
|
||||||
platform,
|
platform,
|
||||||
@@ -222,7 +319,7 @@ function selectPlatform(platform) {
|
|||||||
function onShow() {
|
function onShow() {
|
||||||
modalOpen.value = true
|
modalOpen.value = true
|
||||||
debug('on-show fired')
|
debug('on-show fired')
|
||||||
props.loadVersions()
|
versionsEnabled.value = true
|
||||||
navigateTo({ query: route.query, hash: '#download' }, { replace: true })
|
navigateTo({ query: route.query, hash: '#download' }, { replace: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,15 +328,15 @@ function onHide() {
|
|||||||
navigateTo({ query: route.query, hash: '' }, { replace: true })
|
navigateTo({ query: route.query, hash: '' }, { replace: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
function show(event) {
|
function show(event?: MouseEvent) {
|
||||||
if (!modal.value || modalOpen.value) return
|
if (!modal.value || modalOpen.value) return
|
||||||
modalOpen.value = true
|
modalOpen.value = true
|
||||||
modal.value.show(event)
|
modal.value.show(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide(event) {
|
function hide() {
|
||||||
if (!modal.value || !modalOpen.value) return
|
if (!modal.value || !modalOpen.value) return
|
||||||
modal.value?.hide(event)
|
modal.value?.hide()
|
||||||
downloadProjectResetKey.value += 1
|
downloadProjectResetKey.value += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,9 +351,18 @@ function openFromHash() {
|
|||||||
show()
|
show()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route.hash === '#download' || version !== undefined || loader !== undefined) {
|
if (
|
||||||
debug('eager loadVersions from setup', { hash: route.hash, version, loader })
|
route.hash === '#download' ||
|
||||||
props.loadVersions()
|
route.query.version !== undefined ||
|
||||||
|
route.query.loader !== undefined
|
||||||
|
) {
|
||||||
|
debug('eager loadVersions from setup', {
|
||||||
|
hash: route.hash,
|
||||||
|
version: route.query.version,
|
||||||
|
loader: route.query.loader,
|
||||||
|
loading: versionsV3Loading.value,
|
||||||
|
})
|
||||||
|
versionsEnabled.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(modal, openFromHash)
|
watch(modal, openFromHash)
|
||||||
|
|||||||
@@ -90,12 +90,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<ProjectDownloadModal
|
<ProjectDownloadModal
|
||||||
ref="downloadModal"
|
ref="downloadModal"
|
||||||
:project="project"
|
:project-id="routeProjectId"
|
||||||
:versions="versions"
|
|
||||||
:versions-loading="versionsLoading"
|
|
||||||
:tags="tags"
|
|
||||||
:download-reason="downloadReason"
|
:download-reason="downloadReason"
|
||||||
:load-versions="loadVersions"
|
|
||||||
@download="triggerDownloadAnimation"
|
@download="triggerDownloadAnimation"
|
||||||
/>
|
/>
|
||||||
<CollectionCreateModal ref="modal_collection" :project-ids="[project.id]" />
|
<CollectionCreateModal ref="modal_collection" :project-ids="[project.id]" />
|
||||||
@@ -2240,8 +2236,8 @@ provideProjectPageContext({
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.over-the-top-download-animation {
|
.over-the-top-download-animation {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -2290,7 +2286,7 @@ provideProjectPageContext({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.servers-popup {
|
.servers-popup {
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 0 12px 1px rgba(0, 175, 92, 0.6),
|
0 0 12px 1px rgba(0, 175, 92, 0.6),
|
||||||
var(--shadow-floating);
|
var(--shadow-floating);
|
||||||
|
|||||||
Reference in New Issue
Block a user