mirror of
https://github.com/modrinth/code.git
synced 2026-08-24 16:44:51 +00:00
qa: shared instances post release (#6893)
* fix: 20 user cap * qa: invite modal dropdown + other + clamp limits * fix: hide filters if just one type * feat: update req banner * feat: invite management frontend * fix: moderation issues with shared instances * feat: instance icon improvements * fix: better offline handling * fix: lint * feat: show avatar in install to play modal * feat: smaller qa points * fix: fmt * fix: fmt * fix: yeet svg * fix: 50 user limit
This commit is contained in:
@@ -604,13 +604,18 @@ async function loadSharedInstanceVersionContent(
|
||||
dependency.project_id ? [dependency.project_id] : [],
|
||||
)
|
||||
const projectIds = [
|
||||
...new Set([...versions.map((version) => version.project_id), ...dependencyProjectIds]),
|
||||
...new Set([
|
||||
...versions.map((version) => version.project_id),
|
||||
...dependencyProjectIds,
|
||||
...(modpackVersion ? [modpackVersion.project_id] : []),
|
||||
]),
|
||||
]
|
||||
const projects = projectIds.length
|
||||
? await client.labrinth.projects_v2.getMultiple(projectIds)
|
||||
: []
|
||||
const versionsById = new Map(versions.map((version) => [version.id, version]))
|
||||
const projectsById = new Map(projects.map((project) => [project.id, project]))
|
||||
const modpackProject = modpackVersion ? projectsById.get(modpackVersion.project_id) : undefined
|
||||
|
||||
const directContent: ContentItem[] = [...new Set(directVersionIds)].flatMap((versionId) => {
|
||||
const version = versionsById.get(versionId)
|
||||
@@ -633,13 +638,19 @@ async function loadSharedInstanceVersionContent(
|
||||
const fileName =
|
||||
primaryFile?.filename ?? dependency.file_name ?? project?.title ?? version?.name ?? 'Unknown'
|
||||
|
||||
return sharedInstanceContentItem(
|
||||
const item = sharedInstanceContentItem(
|
||||
version,
|
||||
project,
|
||||
fileName,
|
||||
dependency.project_id ?? fileName,
|
||||
!project && !version,
|
||||
)
|
||||
return modpackProject
|
||||
? {
|
||||
...item,
|
||||
source: { project: modpackProject },
|
||||
}
|
||||
: item
|
||||
})
|
||||
|
||||
const externalContent: ContentItem[] = instanceVersion.external_files.map((file, index) => ({
|
||||
|
||||
@@ -64,11 +64,18 @@
|
||||
</template>
|
||||
</div>
|
||||
<div v-else-if="report.item_type === 'shared-instance'" class="item-info">
|
||||
<div class="backed-svg" :class="{ raised: raised }">
|
||||
<Avatar
|
||||
v-if="report.shared_instance"
|
||||
:src="report.shared_instance.icon"
|
||||
size="xs"
|
||||
no-shadow
|
||||
:raised="raised"
|
||||
/>
|
||||
<div v-else class="backed-svg" :class="{ raised: raised }">
|
||||
<BoxesIcon />
|
||||
</div>
|
||||
<div class="stacked">
|
||||
<span class="title">Shared instance</span>
|
||||
<span class="title">{{ report.shared_instance?.name ?? 'Shared instance' }}</span>
|
||||
<span>
|
||||
Version {{ report.shared_instance_version_id ?? 'unknown' }} ·
|
||||
<CopyCode :text="report.item_id" />
|
||||
@@ -89,8 +96,7 @@
|
||||
<ThreadSummary
|
||||
v-if="thread"
|
||||
:thread="thread"
|
||||
class="thread-summary"
|
||||
:raised="raised"
|
||||
class="thread-summary !bg-surface-2"
|
||||
:link="`/${moderation ? 'moderation' : 'dashboard'}/report/${report.id}`"
|
||||
:auth="auth"
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="pb-20">
|
||||
<section>
|
||||
<Breadcrumbs
|
||||
v-if="breadcrumbsStack"
|
||||
@@ -111,6 +111,16 @@ const { data: project } = useQuery({
|
||||
enabled: computed(() => !!projectId.value),
|
||||
})
|
||||
|
||||
const sharedInstanceId = computed(() =>
|
||||
rawReport.value?.item_type === 'shared-instance' ? rawReport.value.item_id : null,
|
||||
)
|
||||
|
||||
const { data: sharedInstance } = useQuery({
|
||||
queryKey: computed(() => ['shared-instance', sharedInstanceId.value]),
|
||||
queryFn: () => client.sharedinstances.instances_v1.get(sharedInstanceId.value),
|
||||
enabled: computed(() => !!sharedInstanceId.value),
|
||||
})
|
||||
|
||||
// Assemble the full report object
|
||||
const report = computed(() => {
|
||||
if (!rawReport.value) return null
|
||||
@@ -118,6 +128,7 @@ const report = computed(() => {
|
||||
...rawReport.value,
|
||||
project: project.value ?? null,
|
||||
version: version.value ?? null,
|
||||
shared_instance: sharedInstance.value ?? null,
|
||||
reporterUser: (users.value || []).find((user) => user.id === rawReport.value.reporter),
|
||||
user:
|
||||
rawReport.value.item_type === 'user'
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
:moderation="moderation"
|
||||
raised
|
||||
:auth="auth"
|
||||
class="universal-card recessed"
|
||||
class="card-shadow mb-4 rounded-2xl border border-solid border-surface-4 bg-surface-3 p-4"
|
||||
/>
|
||||
<p v-if="filteredReports.length === 0">You don't have any active reports.</p>
|
||||
</template>
|
||||
@@ -51,7 +51,7 @@ const MAX_REPORTS = 1500
|
||||
|
||||
const { data: rawReportsData } = useQuery({
|
||||
queryKey: ['reports', MAX_REPORTS],
|
||||
queryFn: () => client.labrinth.reports_v3.list({ count: MAX_REPORTS }),
|
||||
queryFn: () => client.labrinth.reports_v3.list({ count: MAX_REPORTS, all: false }),
|
||||
placeholderData: [],
|
||||
})
|
||||
|
||||
@@ -67,6 +67,13 @@ const versionReports = computed(() =>
|
||||
const versionIds = computed(() => [
|
||||
...new Set(versionReports.value.map((report) => report.item_id)),
|
||||
])
|
||||
const sharedInstanceIds = computed(() => [
|
||||
...new Set(
|
||||
rawReports.value
|
||||
.filter((report) => report.item_type === 'shared-instance')
|
||||
.map((report) => report.item_id),
|
||||
),
|
||||
])
|
||||
const userIds = computed(() => [...new Set(reporterUsers.value.concat(reportedUsers.value))])
|
||||
const threadIds = computed(() => [
|
||||
...new Set(
|
||||
@@ -94,6 +101,21 @@ const { data: versions } = useQuery({
|
||||
placeholderData: [],
|
||||
})
|
||||
|
||||
const { data: sharedInstances } = useQuery({
|
||||
queryKey: computed(() => ['shared-instances', sharedInstanceIds.value]),
|
||||
queryFn: async () => {
|
||||
const results = await Promise.allSettled(
|
||||
sharedInstanceIds.value.map(async (id) => ({
|
||||
id,
|
||||
instance: await client.sharedinstances.instances_v1.get(id),
|
||||
})),
|
||||
)
|
||||
return results.flatMap((result) => (result.status === 'fulfilled' ? [result.value] : []))
|
||||
},
|
||||
enabled: computed(() => sharedInstanceIds.value.length > 0),
|
||||
placeholderData: [],
|
||||
})
|
||||
|
||||
const { data: threads } = useQuery({
|
||||
queryKey: computed(() => ['threads', threadIds.value]),
|
||||
queryFn: () =>
|
||||
@@ -123,6 +145,9 @@ const { data: projects } = useQuery({
|
||||
const userMap = computed(() => new Map(users.value.map((u) => [u.id, u])))
|
||||
const versionMap = computed(() => new Map(versions.value.map((v) => [v.id, v])))
|
||||
const projectMap = computed(() => new Map(projects.value.map((p) => [p.id, p])))
|
||||
const sharedInstanceMap = computed(
|
||||
() => new Map(sharedInstances.value.map(({ id, instance }) => [id, instance])),
|
||||
)
|
||||
const threadMap = computed(() => new Map(threads.value.map((t) => [t.id, t])))
|
||||
|
||||
const reports = computed(() =>
|
||||
@@ -136,6 +161,8 @@ const reports = computed(() =>
|
||||
} else if (report.item_type === 'version') {
|
||||
enrichedReport.version = versionMap.value.get(report.item_id)
|
||||
enrichedReport.project = projectMap.value.get(enrichedReport.version?.project_id)
|
||||
} else if (report.item_type === 'shared-instance') {
|
||||
enrichedReport.shared_instance = sharedInstanceMap.value.get(report.item_id)
|
||||
}
|
||||
if (report.thread_id) {
|
||||
const thread = threadMap.value.get(report.thread_id)
|
||||
@@ -149,7 +176,7 @@ const reports = computed(() =>
|
||||
const filteredReports = computed(() =>
|
||||
reports.value?.filter(
|
||||
(x) =>
|
||||
(props.moderation || x.reporterUser?.id === props.auth.user.id) &&
|
||||
(props.moderation || x.reporter === props.auth.user.id) &&
|
||||
(viewMode.value === 'open' ? x.open : !x.open) &&
|
||||
(reasonFilter.value === 'All' || reasonFilter.value === x.report_type),
|
||||
),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<section class="universal-card">
|
||||
<h2 class="text-2xl">{{ formatMessage(messages.reportsTitle) }}</h2>
|
||||
<ReportsList :auth="auth" />
|
||||
</section>
|
||||
<div class="flex flex-col gap-4 pb-20 lg:pl-4 lg:pt-1.5">
|
||||
<h2 class="m-0 text-xl font-semibold text-contrast md:text-2xl">
|
||||
{{ formatMessage(messages.reportsTitle) }}
|
||||
</h2>
|
||||
<ReportsList :auth="auth" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
|
||||
@@ -235,9 +235,12 @@ const { data: allReports } = await useLazyAsyncData('new-moderation-reports', as
|
||||
let reports: Labrinth.Reports.v3.Report[]
|
||||
let hasMoreReports = true
|
||||
while (hasMoreReports) {
|
||||
reports = (await useBaseFetch(`report?count=${REPORT_ENDPOINT_COUNT}&offset=${currentOffset}`, {
|
||||
apiVersion: 3,
|
||||
})) as Labrinth.Reports.v3.Report[]
|
||||
reports = (await useBaseFetch(
|
||||
`report?count=${REPORT_ENDPOINT_COUNT}&offset=${currentOffset}&all=true`,
|
||||
{
|
||||
apiVersion: 3,
|
||||
},
|
||||
)) as Labrinth.Reports.v3.Report[]
|
||||
|
||||
hasMoreReports = reports.length > 0
|
||||
if (!hasMoreReports) {
|
||||
|
||||
Reference in New Issue
Block a user