frontend: migrate genai functionality disclosure

This commit is contained in:
Prospector
2026-08-26 10:58:09 -07:00
parent 3ed7ed1bf9
commit e79d925047
30 changed files with 168 additions and 114 deletions
@@ -25,7 +25,7 @@ const emit = defineEmits<{
const { formatMessage } = useVIntl()
const AI_USES: AiUsage[] = ['code', 'assets', 'text', 'functionality']
const AI_USES: AiUsage[] = ['code', 'assets', 'text']
const messages = defineMessages({
title: {
@@ -35,9 +35,8 @@ const messages = defineMessages({
description: {
id: 'project.settings.disclosures.ai.description',
defaultMessage: `You must enable this if this project contains a substantial amount of AI-generated code, any
assets that are substantially AI-generated, the project's functionality relies on the use of
generative AI, or if any element of your project's page such as description or publishing
relies on generative AI.`,
assets that are substantially AI-generated, or if any element of your project's page such as
description or publishing relies on generative AI.`,
},
contentRules: {
id: 'project.settings.disclosures.ai.content-rules',
@@ -0,0 +1,68 @@
<script setup lang="ts">
import { BrainCircuitIcon } from '@modrinth/assets'
import {
commonMessages,
defineMessages,
SettingsFormGroup,
StyledInput,
useVIntl,
} from '@modrinth/ui'
import DisclosureToggleCard from './DisclosureToggleCard.vue'
import type { DisclosureCardMetaProps, DisclosureLockStatus, NoteDisclosure } from './types'
const model = defineModel<NoteDisclosure>({ required: true })
const props = defineProps<DisclosureCardMetaProps>()
const emit = defineEmits<{
setLockStatus: [status: DisclosureLockStatus]
}>()
const { formatMessage } = useVIntl()
const messages = defineMessages({
title: {
id: 'project.settings.disclosures.ai-functionality.title',
defaultMessage: 'Contains generative AI functionality',
},
description: {
id: 'project.settings.disclosures.ai-functionality.description',
defaultMessage: 'Placeholder',
},
notePlaceholder: {
id: 'project.settings.disclosures.ai-functionality.note-placeholder',
defaultMessage:
'e.g. The in-game assistant uses generative AI to generate dialogue.',
},
})
</script>
<template>
<DisclosureToggleCard
v-bind="props"
v-model="model.enabled"
:icon="BrainCircuitIcon"
:title="formatMessage(messages.title)"
:description="formatMessage(messages.description)"
@set-lock-status="emit('setLockStatus', $event)"
>
<template #expanded>
<SettingsFormGroup
:title="formatMessage(commonMessages.explanationLabel)"
title-for="ai-functionality-disclosure-note"
optional
>
<StyledInput
id="ai-functionality-disclosure-note"
v-model="model.note"
multiline
:rows="3"
class="max-w-[40rem]"
:disabled="disabled"
:placeholder="formatMessage(messages.notePlaceholder)"
/>
</SettingsFormGroup>
</template>
</DisclosureToggleCard>
</template>
@@ -22,7 +22,7 @@ function findDisclosure<T extends DisclosureType>(
return disclosures.find((disclosure): disclosure is DisclosureOf<T> => disclosure.type === type)
}
type NoteDisclosureType = 'advertisements' | 'epilepsy_triggers' | 'archived'
type NoteDisclosureType = 'ai_functionality' | 'advertisements' | 'epilepsy_triggers' | 'archived'
function createNoteModel(
disclosures: ProjectDisclosureData[],
@@ -66,6 +66,7 @@ export function disclosuresToForm(disclosures: ProjectDisclosureData[]): Disclos
uses: ai ? [...(ai.uses ?? [])] : [],
note: ai?.note ?? '',
},
aiFunctionality: createNoteModel(disclosures, 'ai_functionality'),
advertising: createNoteModel(disclosures, 'advertisements'),
paidFeatures: {
enabled: isActiveDisclosure(paidFeatures),
@@ -110,6 +111,8 @@ export function formToDisclosure(
uses: [...form.ai.uses],
note: form.ai.note.trim() || null,
}
case 'ai_functionality':
return { type: 'ai_functionality', note: form.aiFunctionality.note.trim() || null }
case 'advertisements':
return { type: 'advertisements', note: form.advertising.note.trim() || null }
case 'paid_features':
@@ -151,6 +154,9 @@ export function formToDisclosures(form: DisclosureFormState): ProjectDisclosure[
if (form.ai.enabled) {
set.push(formToDisclosure(form, 'ai_content'))
}
if (form.aiFunctionality.enabled) {
set.push(formToDisclosure(form, 'ai_functionality'))
}
if (form.advertising.enabled) {
set.push(formToDisclosure(form, 'advertisements'))
}
@@ -1,5 +1,6 @@
export { default as AdvertisingDisclosureCard } from './AdvertisingDisclosureCard.vue'
export { default as AiDisclosureCard } from './AiDisclosureCard.vue'
export { default as AiFunctionalityDisclosureCard } from './AiFunctionalityDisclosureCard.vue'
export { default as ArchivedDisclosureCard } from './ArchivedDisclosureCard.vue'
export { default as DerivativeDisclosureCard } from './DerivativeDisclosureCard.vue'
export { default as DisclosureToggleCard } from './DisclosureToggleCard.vue'
@@ -44,6 +44,7 @@ export type DerivativeDisclosure = {
export type DisclosureFormState = {
ai: AiDisclosure
aiFunctionality: NoteDisclosure
advertising: NoteDisclosure
paidFeatures: PaidFeaturesDisclosure
telemetry: TelemetryDisclosure
+10 -1
View File
@@ -3839,11 +3839,20 @@
"project.settings.disclosures.advertising.title": {
"message": "Contains advertisements"
},
"project.settings.disclosures.ai-functionality.description": {
"message": "Placeholder description."
},
"project.settings.disclosures.ai-functionality.note-placeholder": {
"message": "e.g. This project includes an in-game assistant powered by a generative AI API."
},
"project.settings.disclosures.ai-functionality.title": {
"message": "Contains generative AI functionality"
},
"project.settings.disclosures.ai.content-rules": {
"message": "Please refer to Section 6 of <rules>Modrinth's Content Rules</rules> for more information."
},
"project.settings.disclosures.ai.description": {
"message": "You must enable this if this project contains a substantial amount of AI-generated code, any\n\t\t\t\tassets that are substantially AI-generated, the project's functionality relies on the use of\n\t\t\t\tgenerative AI, or if any element of your project's page such as description or publishing\n\t\t\t\trelies on generative AI."
"message": "You must enable this if this project contains a substantial amount of AI-generated code, any\n\t\t\t\tassets that are substantially AI-generated, or if any element of your project's page such as\n\t\t\t\tdescription or publishing relies on generative AI."
},
"project.settings.disclosures.ai.note-placeholder": {
"message": "e.g. The Chinese and Arabic translations are AI-generated."
@@ -22,6 +22,7 @@ import { computed, watch } from 'vue'
import {
AdvertisingDisclosureCard,
AiDisclosureCard,
AiFunctionalityDisclosureCard,
ArchivedDisclosureCard,
DerivativeDisclosureCard,
type DisclosureFormIssue,
@@ -293,6 +294,14 @@ const { confirmLeaveModal } = usePageLeaveSafety(hasChanges)
(status: DisclosureLockStatus) => setDisclosureLockStatus('ai_content', status)
"
/>
<AiFunctionalityDisclosureCard
v-if="isDisclosureVisible('ai_functionality')"
v-model="current.aiFunctionality"
v-bind="disclosureUpdateProps('ai_functionality')"
@set-lock-status="
(status: DisclosureLockStatus) => setDisclosureLockStatus('ai_functionality', status)
"
/>
<AdvertisingDisclosureCard
v-if="isDisclosureVisible('advertisements')"
v-model="current.advertising"