add placeholder missing disclosure report type

This commit is contained in:
Prospector
2026-08-07 16:00:24 -07:00
parent 1fc69d0128
commit 8ab484a298
29 changed files with 154 additions and 204 deletions
@@ -278,11 +278,13 @@ import {
CollapsibleRegion,
type ContentItem,
CopyCode,
formatReportType,
getProjectTypeIcon,
injectModrinthClient,
injectNotificationManager,
useFormatDateTime,
useRelativeTime,
useVIntl,
} from '@modrinth/ui'
import { formatProjectType } from '@modrinth/utils'
import { computed, ref, watch } from 'vue'
@@ -297,6 +299,7 @@ import SharedInstanceReportContext, {
} from './SharedInstanceReportContext.vue'
const { addNotification } = injectNotificationManager()
const { formatMessage } = useVIntl()
const client = injectModrinthClient()
const auth = await useAuth()
@@ -787,13 +790,9 @@ const reportItemUrl = computed(() => {
}
})
const formattedReportType = computed(() => {
const reportType = props.report.report_type
// some are split by -, some are split by " "
const words = reportType.includes('-') ? reportType.split('-') : reportType.split(' ')
return words.map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(' ')
})
const formattedReportType = computed(() =>
formatReportType(formatMessage, props.report.report_type),
)
function copyId() {
navigator.clipboard.writeText(props.report.id).then(() => {
@@ -90,7 +90,14 @@
</div>
<div class="report-type">
<Badge v-if="report.closed" type="closed" />
<Badge :type="`Reported for ${report.report_type}`" color="orange" />
<Badge
:type="
formatMessage(messages.reportedFor, {
type: formatReportType(formatMessage, report.report_type),
})
"
color="orange"
/>
</div>
<div v-if="showMessage" class="markdown-body" v-html="renderHighlightedString(report.body)" />
<ThreadSummary
@@ -125,12 +132,22 @@
<script setup>
import { BoxesIcon, ReportIcon, UnknownIcon, VersionIcon } from '@modrinth/assets'
import { Avatar, Badge, CopyCode, useFormatDateTime, useRelativeTime } from '@modrinth/ui'
import {
Avatar,
Badge,
CopyCode,
defineMessages,
formatReportType,
useFormatDateTime,
useRelativeTime,
useVIntl,
} from '@modrinth/ui'
import { formatProjectType, renderHighlightedString } from '@modrinth/utils'
import ThreadSummary from '~/components/ui/thread/ThreadSummary.vue'
import { getProjectTypeForUrl } from '~/helpers/projects.js'
const { formatMessage } = useVIntl()
const formatRelativeTime = useRelativeTime()
const formatDateTime = useFormatDateTime({
timeStyle: 'short',
@@ -165,6 +182,13 @@ defineProps({
})
const flags = useFeatureFlags()
const messages = defineMessages({
reportedFor: {
id: 'report.reported-for',
defaultMessage: 'Reported for {type}',
},
})
</script>
<style lang="scss" scoped>
@@ -1,13 +1,20 @@
<template>
<template v-if="moderation">
<Chips v-model="reasonFilter" :items="reasons" />
<Chips
v-model="reasonFilter"
:items="reasons"
:format-label="formatReasonLabel"
:capitalize="false"
/>
<p v-if="reports.length === MAX_REPORTS" class="text-red">
There are at least {{ MAX_REPORTS }} open reports. This page is at its max reports and will
not show any more recent ones.
</p>
<p v-else-if="reasonFilter === 'All'">There are {{ filteredReports.length }} open reports.</p>
<p v-else>
There are {{ filteredReports.length }}/{{ reports.length }} open '{{ reasonFilter }}' reports.
There are {{ filteredReports.length }}/{{ reports.length }} open '{{
formatReportType(formatMessage, reasonFilter)
}}' reports.
</p>
</template>
<ReportInfo
@@ -24,7 +31,7 @@
<p v-if="filteredReports.length === 0">You don't have any active reports.</p>
</template>
<script setup>
import { Chips, injectModrinthClient } from '@modrinth/ui'
import { Chips, formatReportType, injectModrinthClient, useVIntl } from '@modrinth/ui'
import { useQuery } from '@tanstack/vue-query'
import { computed, ref } from 'vue'
@@ -43,10 +50,16 @@ const props = defineProps({
},
})
const { formatMessage } = useVIntl()
const client = injectModrinthClient()
const viewMode = ref('open')
const reasonFilter = ref('All')
const formatReasonLabel = (reason) => {
if (reason === 'All') return reason
return formatReportType(formatMessage, reason)
}
const MAX_REPORTS = 1500
const { data: rawReportsData } = useQuery({
@@ -4304,6 +4304,12 @@
"report.note.malicious.2": {
"message": "Summaries from Microsoft Defender, VirusTotal, or AI malware detection are not sufficient forms of evidence and will not be accepted."
},
"report.note.missing-disclosure.1": {
"message": "Content disclosures are a new feature we've just added. We're giving creators a grace period to get their disclosures up-to-date before we begin accepting reports for missing or incorrect disclosures."
},
"report.note.missing-disclosure.2": {
"message": "Check back later once the grace period has ended. Reports of this type are not being accepted at this time."
},
"report.please-report": {
"message": "Please report:"
},
@@ -4322,6 +4328,9 @@
"report.report-item": {
"message": "Report {title} to moderators"
},
"report.reported-for": {
"message": "Reported for {type}"
},
"report.submit": {
"message": "Submit report"
},
@@ -217,6 +217,7 @@ import {
Combobox,
type ComboboxOption,
commonMessages,
formatReportType,
injectModrinthClient,
MultiSelect,
type MultiSelectItem,
@@ -361,7 +362,13 @@ const reportIssueFilterTypes = computed<ComboboxOption<string>[]>(() => {
const issueTypes = new Set(allReports.value.map((report) => report.report_type))
const sortedTypes = Array.from(issueTypes).sort()
return [...base, ...sortedTypes.map((type) => ({ value: type, label: type }))]
return [
...base,
...sortedTypes.map((type) => ({
value: type,
label: formatReportType(formatMessage, type),
})),
]
})
type ReportedType<T> = T & { report_item_count: number }
+29 -8
View File
@@ -106,7 +106,7 @@
<div class="card-shadow flex flex-col gap-4 rounded-xl bg-bg-raised p-6">
<template v-if="!prefilled || !currentItemValid">
<div class="flex flex-col gap-2">
<span class="text-lg font-bold text-contrast">
<span class="text-lg font-semibold text-contrast">
{{ formatMessage(messages.whatContentType) }}
</span>
<RadioButtons
@@ -124,7 +124,7 @@
</RadioButtons>
</div>
<div class="flex flex-col gap-2" :class="{ hidden: !reportItem }">
<span class="text-lg font-bold text-contrast">
<span class="text-lg font-semibold text-contrast">
{{
formatMessage(messages.whatContentId, {
item: formatReportItemType(formatMessage, reportItem),
@@ -160,7 +160,7 @@
<AutoLink
:to="itemLink"
target="_blank"
class="flex items-center gap-1 font-bold text-contrast hover:underline"
class="flex items-center gap-1 font-semibold text-contrast hover:underline"
>
<Avatar
v-if="typeof itemIcon === 'string'"
@@ -203,7 +203,7 @@
</template>
<template v-else>
<div class="flex flex-col gap-2" :class="{ hidden: !reportItemID }">
<span class="text-lg font-bold text-contrast">
<span class="text-lg font-semibold text-contrast">
{{
formatMessage(messages.whatReportReason, {
item: formatReportItemType(formatMessage, reportItem),
@@ -211,7 +211,7 @@
}}
</span>
<RadioButtons v-slot="{ item }" v-model="reportType" :items="reportTypes">
{{ item === 'copyright' ? 'Reuploaded work' : capitalizeString(item) }}
{{ formatReportType(formatMessage, item) }}
</RadioButtons>
</div>
<div
@@ -236,7 +236,7 @@
</div>
</div>
<div :class="{ hidden: !reportType }">
<span class="text-lg font-bold text-contrast">
<span class="text-lg font-semibold text-contrast">
{{ formatMessage(messages.reportBodyTitle) }}
</span>
<p class="m-0 leading-tight text-secondary">
@@ -247,6 +247,7 @@
<MarkdownEditor
v-model="reportBody"
placeholder=""
:disabled="disableReporting"
:on-image-upload="onImageUpload"
/>
</div>
@@ -255,7 +256,7 @@
id="submit-button"
type="colored"
color="brand"
:disabled="submitLoading || !canSubmit"
:disabled="submitLoading || !canSubmit || disableReporting"
@click="submitReport"
>
<SendIcon aria-hidden="true" />
@@ -291,6 +292,7 @@ import {
defineMessage,
defineMessages,
formatReportItemType,
formatReportType,
injectNotificationManager,
IntlFormatted,
MarkdownEditor,
@@ -410,10 +412,18 @@ async function fetchItem() {
}
const reportItems = ['project', 'version', 'user']
const reportTypes = computed(() => tags.value.reportTypes)
const reportTypes = computed(() => {
const types = [...tags.value.reportTypes]
if (reportItem.value === 'project') {
types.push('missing-disclosure')
}
return types
})
const disableReporting = computed(() => reportType.value === 'missing-disclosure')
const canSubmit = computed(() => {
return (
!disableReporting.value &&
reportItem.value !== '' &&
reportItemID.value !== '' &&
reportType.value !== '' &&
@@ -546,6 +556,17 @@ const warnings: Record<string, MessageDescriptor[]> = {
'Summaries from Microsoft Defender, VirusTotal, or AI malware detection are not sufficient forms of evidence and will not be accepted.',
}),
],
'missing-disclosure': [
defineMessage({
id: 'report.note.missing-disclosure.1',
defaultMessage: `Content disclosures are a new feature we've just added. We're giving creators a grace period to get their disclosures up-to-date before we begin accepting reports for missing or incorrect disclosures.`,
}),
defineMessage({
id: 'report.note.missing-disclosure.2',
defaultMessage:
'Check back later once the grace period has ended. Reports of this type are not being accepted at this time.',
}),
],
}
const messages = defineMessages({