fix: website visual issues (#5675)
* fix no modpack loader showing as resource pack loader
* fix table overflow, add game version tags "+ {num}" overflow menu
* pnpm prepr
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
v-if="!isServerProject"
|
v-if="!isServerProject"
|
||||||
:project="data"
|
:project="data"
|
||||||
:tags="{ loaders: allLoaders, gameVersions: allGameVersions }"
|
:tags="{ loaders: allLoaders, gameVersions: allGameVersions }"
|
||||||
:v3-metadata="projectV3"
|
:project-v3="projectV3"
|
||||||
class="project-sidebar-section"
|
class="project-sidebar-section"
|
||||||
/>
|
/>
|
||||||
<ProjectSidebarServerInfo
|
<ProjectSidebarServerInfo
|
||||||
|
|||||||
@@ -877,7 +877,7 @@
|
|||||||
v-if="projectV3Loaded && !isServerProject"
|
v-if="projectV3Loaded && !isServerProject"
|
||||||
:project="project"
|
:project="project"
|
||||||
:tags="tags"
|
:tags="tags"
|
||||||
:v3-metadata="projectV3"
|
:project-v3="projectV3"
|
||||||
class="card flex-card experimental-styles-within"
|
class="card flex-card experimental-styles-within"
|
||||||
/>
|
/>
|
||||||
<AdPlaceholder v-if="!auth.user && tags.approvedStatuses.includes(project.status)" />
|
<AdPlaceholder v-if="!auth.user && tags.approvedStatuses.includes(project.status)" />
|
||||||
|
|||||||
@@ -341,7 +341,8 @@
|
|||||||
<div v-if="project.project_type !== 'resourcepack'">
|
<div v-if="project.project_type !== 'resourcepack'">
|
||||||
<h4>Loaders</h4>
|
<h4>Loaders</h4>
|
||||||
|
|
||||||
<Categories :categories="version.loaders" :type="project.project_type" />
|
<span v-if="noModpackLoader">No mod loader</span>
|
||||||
|
<Categories v-else :categories="version.loaders ?? []" :type="project.project_type" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4>Game versions</h4>
|
<h4>Game versions</h4>
|
||||||
@@ -698,6 +699,25 @@ const title = computed(
|
|||||||
() => `${isCreating.value ? 'Create Version' : version.value.name} - ${project.value.title}`,
|
() => `${isCreating.value ? 'Create Version' : version.value.name} - ${project.value.title}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const modpackLoaders = computed<string[]>(() => {
|
||||||
|
if (project.value.project_type !== 'modpack') {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(version.value.mrpack_loaders) && version.value.mrpack_loaders.length > 0) {
|
||||||
|
return version.value.mrpack_loaders
|
||||||
|
}
|
||||||
|
|
||||||
|
return (version.value.loaders ?? []).filter((loader: string) => loader !== 'mrpack')
|
||||||
|
})
|
||||||
|
|
||||||
|
const noModpackLoader = computed(
|
||||||
|
() =>
|
||||||
|
project.value.project_type === 'modpack' &&
|
||||||
|
modpackLoaders.value.length === 1 &&
|
||||||
|
modpackLoaders.value[0] === 'minecraft',
|
||||||
|
)
|
||||||
|
|
||||||
const description = computed(
|
const description = computed(
|
||||||
() =>
|
() =>
|
||||||
`Download ${project.value.title} ${
|
`Download ${project.value.title} ${
|
||||||
|
|||||||
@@ -593,6 +593,7 @@ export namespace Labrinth {
|
|||||||
categories: string[]
|
categories: string[]
|
||||||
additional_categories: string[]
|
additional_categories: string[]
|
||||||
loaders: string[]
|
loaders: string[]
|
||||||
|
mrpack_loaders: string[]
|
||||||
versions: string[]
|
versions: string[]
|
||||||
icon_url?: string
|
icon_url?: string
|
||||||
link_urls: Record<string, Link>
|
link_urls: Record<string, Link>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="flex flex-wrap justify-between gap-2">
|
<div class="flex flex-wrap justify-between gap-2">
|
||||||
<VersionFilterControl
|
<VersionFilterControl
|
||||||
ref="versionFilters"
|
ref="versionFilters"
|
||||||
:versions="versions"
|
:versions="normalizedVersions"
|
||||||
:game-versions="gameVersions"
|
:game-versions="gameVersions"
|
||||||
:base-id="`${baseId}-filter`"
|
:base-id="`${baseId}-filter`"
|
||||||
@update:query="updateQuery"
|
@update:query="updateQuery"
|
||||||
@@ -110,13 +110,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="pointer-events-none relative z-[1] flex flex-col justify-center"
|
class="pointer-events-none relative z-[1] flex flex-col justify-center overflow-hidden min-w-32"
|
||||||
:class="{
|
:class="{
|
||||||
'group-hover:underline': !!versionLink,
|
'group-hover:underline': !!versionLink,
|
||||||
}"
|
}"
|
||||||
|
title="`${version.version_number} - ${version.name}`"
|
||||||
>
|
>
|
||||||
<div class="font-bold text-contrast">{{ version.version_number }}</div>
|
<div class="font-bold text-contrast text-ellipsis overflow-hidden">
|
||||||
<div class="text-xs font-medium">{{ version.name }}</div>
|
{{ version.version_number }}
|
||||||
|
</div>
|
||||||
|
<div class="text-xs font-medium text-ellipsis overflow-hidden">
|
||||||
|
{{ version.name }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col justify-center gap-2 sm:contents">
|
<div class="flex flex-col justify-center gap-2 sm:contents">
|
||||||
@@ -127,7 +132,7 @@
|
|||||||
v-for="gameVersion in formatVersionsForDisplay(
|
v-for="gameVersion in formatVersionsForDisplay(
|
||||||
version.game_versions,
|
version.game_versions,
|
||||||
gameVersions,
|
gameVersions,
|
||||||
)"
|
).slice(0, maxGameVersionTags)"
|
||||||
:key="`version-tag-${gameVersion}`"
|
:key="`version-tag-${gameVersion}`"
|
||||||
v-tooltip="`Toggle filter for ${gameVersion}`"
|
v-tooltip="`Toggle filter for ${gameVersion}`"
|
||||||
class="z-[1]"
|
class="z-[1]"
|
||||||
@@ -137,21 +142,61 @@
|
|||||||
>
|
>
|
||||||
{{ gameVersion }}
|
{{ gameVersion }}
|
||||||
</TagItem>
|
</TagItem>
|
||||||
|
<Menu
|
||||||
|
v-if="
|
||||||
|
formatVersionsForDisplay(version.game_versions, gameVersions).length >
|
||||||
|
maxGameVersionTags
|
||||||
|
"
|
||||||
|
:delay="{ hide: 50, show: 0 }"
|
||||||
|
no-auto-focus
|
||||||
|
class="z-[1] cursor-default"
|
||||||
|
>
|
||||||
|
<TagItem tabindex="0">
|
||||||
|
+{{
|
||||||
|
formatVersionsForDisplay(version.game_versions, gameVersions).length -
|
||||||
|
maxGameVersionTags
|
||||||
|
}}
|
||||||
|
</TagItem>
|
||||||
|
<template #popper>
|
||||||
|
<div class="flex gap-1 flex-wrap max-w-[20rem]">
|
||||||
|
<TagItem
|
||||||
|
v-for="gameVersion in formatVersionsForDisplay(
|
||||||
|
version.game_versions,
|
||||||
|
gameVersions,
|
||||||
|
).slice(maxGameVersionTags)"
|
||||||
|
:key="`overflow-version-tag-${gameVersion}`"
|
||||||
|
:action="
|
||||||
|
() =>
|
||||||
|
versionFilters?.toggleFilters('gameVersion', version.game_versions)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ gameVersion }}
|
||||||
|
</TagItem>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="flex flex-wrap gap-1">
|
<div class="flex flex-wrap gap-1">
|
||||||
<TagItem
|
<template v-if="version.noModLoader">
|
||||||
v-for="platform in version.loaders"
|
<TagItem class="z-[1] border !border-solid border-surface-5">
|
||||||
:key="`platform-tag-${platform}`"
|
No mod loader
|
||||||
v-tooltip="`Toggle filter for ${platform}`"
|
</TagItem>
|
||||||
class="z-[1]"
|
</template>
|
||||||
:style="`--_color: var(--color-platform-${platform})`"
|
<template v-else>
|
||||||
:action="() => versionFilters?.toggleFilter('platform', platform)"
|
<TagItem
|
||||||
>
|
v-for="platform in version.loaders"
|
||||||
<component :is="getLoaderIcon(platform)" v-if="getLoaderIcon(platform)" />
|
:key="`platform-tag-${platform}`"
|
||||||
<FormattedTag :tag="platform" enforce-type="loader" />
|
v-tooltip="`Toggle filter for ${platform}`"
|
||||||
</TagItem>
|
class="z-[1]"
|
||||||
|
:style="`--_color: var(--color-platform-${platform})`"
|
||||||
|
:action="() => versionFilters?.toggleFilter('platform', platform)"
|
||||||
|
>
|
||||||
|
<component :is="getLoaderIcon(platform)" v-if="getLoaderIcon(platform)" />
|
||||||
|
<FormattedTag :tag="platform" enforce-type="loader" />
|
||||||
|
</TagItem>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="hasMultipleEnvironments" class="flex items-center">
|
<div v-if="hasMultipleEnvironments" class="flex items-center">
|
||||||
@@ -162,7 +207,7 @@
|
|||||||
class="z-[1] text-center"
|
class="z-[1] text-center"
|
||||||
>
|
>
|
||||||
<component :is="tag.icon" />
|
<component :is="tag.icon" />
|
||||||
{{ formatMessage(tag.label) }}
|
{{ formatMessage(tag.label).replace('and', '&') }}
|
||||||
</TagItem>
|
</TagItem>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -233,6 +278,7 @@ import {
|
|||||||
type GameVersionTag,
|
type GameVersionTag,
|
||||||
type Version,
|
type Version,
|
||||||
} from '@modrinth/utils'
|
} from '@modrinth/utils'
|
||||||
|
import { Menu } from 'floating-vue'
|
||||||
import { computed, type Ref, ref } from 'vue'
|
import { computed, type Ref, ref } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
@@ -251,6 +297,11 @@ const formatDateTime = useFormatDateTime({
|
|||||||
type VersionWithDisplayUrlEnding = Version & {
|
type VersionWithDisplayUrlEnding = Version & {
|
||||||
displayUrlEnding: string
|
displayUrlEnding: string
|
||||||
environment?: Labrinth.Projects.v3.Environment
|
environment?: Labrinth.Projects.v3.Environment
|
||||||
|
mrpack_loaders?: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
type DisplayVersion = VersionWithDisplayUrlEnding & {
|
||||||
|
noModLoader: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
@@ -278,6 +329,39 @@ const props = withDefaults(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
function getModpackLoaders(version: VersionWithDisplayUrlEnding): string[] {
|
||||||
|
if (props.project.project_type !== 'modpack') {
|
||||||
|
return version.loaders
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version.mrpack_loaders?.length) {
|
||||||
|
return version.mrpack_loaders
|
||||||
|
}
|
||||||
|
|
||||||
|
return version.loaders.filter((loader) => loader !== 'mrpack')
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNoModLoader(loaders: string[]): boolean {
|
||||||
|
return (
|
||||||
|
props.project.project_type === 'modpack' && loaders.length === 1 && loaders[0] === 'minecraft'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedVersions = computed<DisplayVersion[]>(() =>
|
||||||
|
props.versions.map((version) => {
|
||||||
|
const loaders = getModpackLoaders(version)
|
||||||
|
const noModLoader = hasNoModLoader(loaders)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...version,
|
||||||
|
loaders: noModLoader ? [] : loaders,
|
||||||
|
noModLoader,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const maxGameVersionTags = 6
|
||||||
|
|
||||||
const currentPage: Ref<number> = ref(1)
|
const currentPage: Ref<number> = ref(1)
|
||||||
const pageSize: Ref<number> = ref(20)
|
const pageSize: Ref<number> = ref(20)
|
||||||
const versionFilters: Ref<InstanceType<typeof VersionFilterControl> | null> = ref(null)
|
const versionFilters: Ref<InstanceType<typeof VersionFilterControl> | null> = ref(null)
|
||||||
@@ -296,7 +380,7 @@ const hasMultipleEnvironments = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const filteredVersions = computed(() => {
|
const filteredVersions = computed(() => {
|
||||||
return props.versions.filter(
|
return normalizedVersions.value.filter(
|
||||||
(version) =>
|
(version) =>
|
||||||
hasAnySelected(version.game_versions, selectedGameVersions.value) &&
|
hasAnySelected(version.game_versions, selectedGameVersions.value) &&
|
||||||
hasAnySelected(version.loaders, selectedPlatforms.value) &&
|
hasAnySelected(version.loaders, selectedPlatforms.value) &&
|
||||||
|
|||||||
@@ -15,15 +15,22 @@
|
|||||||
<section v-if="project.project_type !== 'resourcepack'" class="flex flex-col gap-2">
|
<section v-if="project.project_type !== 'resourcepack'" class="flex flex-col gap-2">
|
||||||
<h3 class="text-primary text-base m-0">{{ formatMessage(messages.platforms) }}</h3>
|
<h3 class="text-primary text-base m-0">{{ formatMessage(messages.platforms) }}</h3>
|
||||||
<div class="flex flex-wrap gap-1">
|
<div class="flex flex-wrap gap-1">
|
||||||
<TagItem
|
<template v-if="noModpackLoader">
|
||||||
v-for="platform in project.loaders"
|
<TagItem class="border !border-solid border-surface-5 hover:no-underline">
|
||||||
:key="`platform-tag-${platform}`"
|
No mod loader
|
||||||
:action="() => router.push(`/${project.project_type}s?g=categories:${platform}`)"
|
</TagItem>
|
||||||
:style="`--_color: var(--color-platform-${platform})`"
|
</template>
|
||||||
>
|
<template v-else>
|
||||||
<component :is="getLoaderIcon(platform)" v-if="getLoaderIcon(platform)" />
|
<TagItem
|
||||||
<FormattedTag :tag="platform" enforce-type="loader" />
|
v-for="platform in project.loaders"
|
||||||
</TagItem>
|
:key="`platform-tag-${platform}`"
|
||||||
|
:action="() => router.push(`/${project.project_type}s?g=categories:${platform}`)"
|
||||||
|
:style="`--_color: var(--color-platform-${platform})`"
|
||||||
|
>
|
||||||
|
<component :is="getLoaderIcon(platform)" v-if="getLoaderIcon(platform)" />
|
||||||
|
<FormattedTag :tag="platform" enforce-type="loader" />
|
||||||
|
</TagItem>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section v-if="showEnvironments" class="flex flex-col gap-2">
|
<section v-if="showEnvironments" class="flex flex-col gap-2">
|
||||||
@@ -85,6 +92,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { Labrinth } from '@modrinth/api-client'
|
||||||
import {
|
import {
|
||||||
ClientIcon,
|
ClientIcon,
|
||||||
getLoaderIcon,
|
getLoaderIcon,
|
||||||
@@ -93,7 +101,7 @@ import {
|
|||||||
UserIcon,
|
UserIcon,
|
||||||
} from '@modrinth/assets'
|
} from '@modrinth/assets'
|
||||||
import { FormattedTag, TagItem } from '@modrinth/ui'
|
import { FormattedTag, TagItem } from '@modrinth/ui'
|
||||||
import type { EnvironmentV3, GameVersionTag, PlatformTag, ProjectV3Partial } from '@modrinth/utils'
|
import type { EnvironmentV3, GameVersionTag, PlatformTag } from '@modrinth/utils'
|
||||||
import { getVersionsToDisplay } from '@modrinth/utils'
|
import { getVersionsToDisplay } from '@modrinth/utils'
|
||||||
import { type Component, computed } from 'vue'
|
import { type Component, computed } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
@@ -128,17 +136,24 @@ const props = defineProps<{
|
|||||||
gameVersions: GameVersionTag[]
|
gameVersions: GameVersionTag[]
|
||||||
loaders: PlatformTag[]
|
loaders: PlatformTag[]
|
||||||
}
|
}
|
||||||
v3Metadata?: ProjectV3Partial
|
projectV3?: Labrinth.Projects.v3.Project
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const noModpackLoader = computed(
|
||||||
|
() =>
|
||||||
|
props.projectV3?.project_types.includes('modpack') &&
|
||||||
|
props.projectV3?.mrpack_loaders.length === 1 &&
|
||||||
|
props.projectV3?.mrpack_loaders[0] === 'minecraft',
|
||||||
|
)
|
||||||
|
|
||||||
const showEnvironments = computed(
|
const showEnvironments = computed(
|
||||||
() =>
|
() =>
|
||||||
TYPES_WITH_ENVS.some((x) => props.v3Metadata?.project_types.includes(x)) &&
|
TYPES_WITH_ENVS.some((x) => props.projectV3?.project_types.includes(x)) &&
|
||||||
primaryEnvironment.value,
|
primaryEnvironment.value,
|
||||||
)
|
)
|
||||||
|
|
||||||
const primaryEnvironment = computed<EnvironmentV3 | undefined>(() =>
|
const primaryEnvironment = computed<EnvironmentV3 | undefined>(() =>
|
||||||
props.v3Metadata?.environment?.find((x) => x !== 'unknown'),
|
props.projectV3?.environment?.find((x) => x !== 'unknown'),
|
||||||
)
|
)
|
||||||
|
|
||||||
type EnvironmentTag = {
|
type EnvironmentTag = {
|
||||||
|
|||||||
Reference in New Issue
Block a user