fix: make search use v3 everywhere (#6840)

This commit is contained in:
Calum H.
2026-07-23 22:16:23 +00:00
committed by GitHub
parent 5c697f675c
commit 0512e0b62b
17 changed files with 241 additions and 149 deletions
@@ -51,7 +51,7 @@ export interface ServerInstallModalHandle {
ctx?: CreationFlowContextValue | null
}
export interface ServerInstallSearchResult extends Labrinth.Search.v2.ResultSearchProject {
export interface ServerInstallSearchResult extends Labrinth.Search.v3.ResultSearchProject {
installed?: boolean
}
@@ -128,6 +128,11 @@ export function useServerInstallContent({
const { handleError } = injectNotificationManager()
let browseSearchState: ServerInstallBrowseSearchState | null = null
function getInstallProjectName(project: ServerInstallSearchResult) {
const legacyTitle = (project as ServerInstallSearchResult & { title?: string }).title
return project.name || legacyTitle || formatMessage(commonMessages.projectLabel)
}
const currentServerId = computed(() => queryAsString(route.query.sid) || null)
const fromContext = computed(() => queryAsString(route.query.from) || null)
const currentWorldId = computed(() => queryAsString(route.query.wid) || null)
@@ -177,7 +182,7 @@ export function useServerInstallContent({
const selectedServerInstallProjects = computed(() =>
Array.from(queuedServerInstalls.value.values()).map((plan) => ({
id: plan.projectId,
name: plan.project.title ?? formatMessage(commonMessages.projectLabel),
name: getInstallProjectName(plan.project),
iconUrl: plan.project.icon_url ?? null,
})),
)
@@ -261,7 +266,7 @@ export function useServerInstallContent({
projectId: plan.projectId,
versionId: plan.versionId,
contentType: plan.contentType as PendingServerContentInstallType,
title: plan.project.title ?? formatMessage(commonMessages.projectLabel),
title: getInstallProjectName(plan.project),
versionName: plan.versionName ?? null,
versionNumber: plan.versionNumber ?? null,
fileName: plan.fileName ?? null,
@@ -635,7 +640,7 @@ export function useServerInstallContent({
ctx.modpackSelection.value = {
projectId: plan.projectId,
versionId: plan.versionId,
name: plan.project.title,
name: getInstallProjectName(plan.project),
iconUrl: plan.project.icon_url ?? undefined,
}
ctx.modal.value?.setStage('final-config')
@@ -66,7 +66,7 @@ const auth = await useAuth()
let prefetchTimeout: ReturnType<typeof useTimeoutFn> | null = null
const HOVER_DURATION_TO_PREFETCH_MS = 500
const handleProjectMouseEnter = (result: Labrinth.Search.v2.ResultSearchProject) => {
const handleProjectMouseEnter = (result: Labrinth.Search.v3.ResultSearchProject) => {
const slug = result.slug || result.project_id
prefetchTimeout = useTimeoutFn(
() => {
@@ -199,24 +199,6 @@ function getServerModpackContent(project: Labrinth.Search.v3.ResultSearchProject
return undefined
}
type DiscoverProjectSearchHit = Labrinth.Search.v2.ResultSearchProject & {
version_id?: string | null
}
function mapV3ProjectHit(hit: Labrinth.Search.v3.ResultSearchProject): DiscoverProjectSearchHit {
return {
...hit,
project_type: hit.project_types[0] ?? projectTypeId.value,
title: hit.name,
description: hit.summary,
versions: hit.version_id ? [hit.version_id] : [],
latest_version: hit.version_id,
icon_url: hit.icon_url ?? '',
client_side: 'unknown',
server_side: 'unknown',
}
}
const hostingContextQuery = computed(() => {
const query: LocationQueryRaw = {}
@@ -234,6 +216,18 @@ function withHostingContext(path: string) {
return hostingContextQuery.value ? { path, query: hostingContextQuery.value } : path
}
function parseSearchParams(requestParams: string): Labrinth.Search.SearchParams {
const params = new URLSearchParams(requestParams.replace(/^\?/, ''))
return {
query: params.get('query') ?? undefined,
offset: params.get('offset') ?? undefined,
index: params.get('index') ?? undefined,
limit: params.get('limit') ?? undefined,
new_filters: params.get('new_filters') ?? undefined,
}
}
async function fetchSearch(requestParams: string) {
debug('search() called', {
requestParams: requestParams.substring(0, 100),
@@ -241,11 +235,7 @@ async function fetchSearch(requestParams: string) {
projectTypeId: projectTypeId.value,
})
const raw = await client.request<Labrinth.Search.v3.SearchResults>('/search', {
api: 'labrinth',
version: 3,
method: 'GET',
params: Object.fromEntries(new URLSearchParams(requestParams.replace(/^\?/, ''))),
const raw = await client.labrinth.projects_v3.search(parseSearchParams(requestParams), {
headers: withLabrinthCanaryHeader(),
})
@@ -261,7 +251,7 @@ async function fetchSearch(requestParams: string) {
}
return {
projectHits: raw.hits.map(mapV3ProjectHit),
projectHits: raw.hits,
serverHits: [],
total_hits: raw.total_hits,
per_page: raw.hits_per_page,
@@ -277,7 +267,7 @@ async function search(requestParams: string) {
}
function getCardActions(
result: Labrinth.Search.v2.ResultSearchProject | Labrinth.Search.v3.ResultSearchProject,
result: Labrinth.Search.v3.ResultSearchProject,
currentProjectType: string,
): CardAction[] {
if (currentProjectType === 'server') return []
@@ -492,7 +482,7 @@ provideBrowseManager({
tags,
projectType: projectTypeId,
...searchState,
getProjectLink: (result: Labrinth.Search.v2.ResultSearchProject) =>
getProjectLink: (result: Labrinth.Search.v3.ResultSearchProject) =>
withHostingContext(
`/${projectType.value?.id ?? 'project'}/${result.slug ? result.slug : result.project_id}`,
),
@@ -183,14 +183,7 @@
:downloads="project.downloads"
:followers="project.followers"
:tags="project.categories"
:environment="
project.client_side && project.server_side
? {
clientSide: project.client_side,
serverSide: project.server_side,
}
: undefined
"
:environment="project.environment?.[0]"
:status="
auth.user && (auth.user.id! === user.id || tags.staffRoles.includes(auth.user.role))
? (project.status as ProjectStatus)
@@ -266,10 +259,7 @@ import {
import { isPermission } from '~/utils/permissions.ts'
import { projectUserSorting } from '~/utils/projects.ts'
type ProjectV3 = Labrinth.Projects.v3.Project & {
client_side: 'required' | 'optional' | 'unsupported'
server_side: 'required' | 'optional' | 'unsupported'
}
type ProjectV3 = Labrinth.Projects.v3.Project
const vintl = useVIntl()
const { formatMessage } = vintl
@@ -353,31 +343,7 @@ const {
categories = categories.concat(project.mrpack_loaders as string[])
}
const singleplayer = project.singleplayer && (project.singleplayer as string[])[0]
const clientAndServer =
project.client_and_server && (project.client_and_server as string[])[0]
const clientOnly = project.client_only && (project.client_only as string[])[0]
const serverOnly = project.server_only && (project.server_only as string[])[0]
let client_side: ProjectV3['client_side'] | undefined
let server_side: ProjectV3['server_side'] | undefined
// quick and dirty hack to show envs as legacy
if (singleplayer && clientAndServer && !clientOnly && !serverOnly) {
client_side = 'required'
server_side = 'required'
} else if (singleplayer && clientAndServer && clientOnly && !serverOnly) {
client_side = 'required'
server_side = 'unsupported'
} else if (singleplayer && clientAndServer && !clientOnly && serverOnly) {
client_side = 'unsupported'
server_side = 'required'
} else if (singleplayer && clientAndServer && clientOnly && serverOnly) {
client_side = 'optional'
server_side = 'optional'
}
return { ...project, categories, client_side, server_side }
return { ...project, categories }
})
},
placeholderData: [],