diff --git a/packages/moderation/data/nags/core.i18n.ts b/packages/moderation/data/nags/core.i18n.ts deleted file mode 100644 index d3c89f248..000000000 --- a/packages/moderation/data/nags/core.i18n.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { defineMessages } from '@vintl/vintl' - -export default defineMessages({ - moderatorFeedbackTitle: { - id: 'nags.moderator-feedback.title', - defaultMessage: 'Review moderator feedback', - }, - moderatorFeedbackDescription: { - id: 'nags.moderator-feedback.description', - defaultMessage: - 'Review any feedback from moderators regarding your project before resubmitting.', - }, - moderationTitle: { - id: 'nags.moderation.title', - defaultMessage: 'Visit moderation thread', - }, - uploadVersionTitle: { - id: 'nags.upload-version.title', - defaultMessage: 'Upload a version', - }, - uploadVersionDescription: { - id: 'nags.upload-version.description', - defaultMessage: 'At least one version is required for a project to be submitted for review.', - }, - versionsTitle: { - id: 'nags.versions.title', - defaultMessage: 'Visit versions page', - }, - addDescriptionTitle: { - id: 'nags.add-description.title', - defaultMessage: 'Add a description', - }, - addDescriptionDescription: { - id: 'nags.add-description.description', - defaultMessage: - "A description that clearly describes the project's purpose and function is required.", - }, - settingsDescriptionTitle: { - id: 'nags.settings.description.title', - defaultMessage: 'Visit description settings', - }, - addIconTitle: { - id: 'nags.add-icon.title', - defaultMessage: 'Add an icon', - }, - addIconDescription: { - id: 'nags.add-icon.description', - defaultMessage: - 'Your project should have a nice-looking icon to uniquely identify your project at a glance.', - }, - settingsTitle: { - id: 'nags.settings.title', - defaultMessage: 'Visit general settings', - }, - featureGalleryImageTitle: { - id: 'nags.feature-gallery-image.title', - defaultMessage: 'Feature a gallery image', - }, - featureGalleryImageDescription: { - id: 'nags.feature-gallery-image.description', - defaultMessage: 'Featured gallery images may be the first impression of many users.', - }, - galleryTitle: { - id: 'nags.gallery.title', - defaultMessage: 'Visit gallery page', - }, - selectTagsTitle: { - id: 'nags.select-tags.title', - defaultMessage: 'Select tags', - }, - selectTagsDescription: { - id: 'nags.select-tags.description', - defaultMessage: 'Select all tags that apply to your project.', - }, - settingsTagsTitle: { - id: 'nags.settings.tags.title', - defaultMessage: 'Visit tag settings', - }, - addLinksTitle: { - id: 'nags.add-links.title', - defaultMessage: 'Add external links', - }, - addLinksDescription: { - id: 'nags.add-links.description', - defaultMessage: - 'Add any relevant links targeted outside of Modrinth, such as sources, issues, or a Discord invite.', - }, - settingsLinksTitle: { - id: 'nags.settings.links.title', - defaultMessage: 'Visit links settings', - }, - selectEnvironmentsTitle: { - id: 'nags.select-environments.title', - defaultMessage: 'Select supported environments', - }, - selectEnvironmentsDescription: { - id: 'nags.select-environments.description', - defaultMessage: `Select if the {projectType} functions on the client-side and/or server-side.`, - }, - settingsEnvironmentsTitle: { - id: 'nags.settings.environments.title', - defaultMessage: 'Visit general settings', - }, - selectLicenseTitle: { - id: 'nags.select-license.title', - defaultMessage: 'Select license', - }, - selectLicenseDescription: { - id: 'nags.select-license.description', - defaultMessage: 'Select the license your {projectType} is distributed under.', - }, - settingsLicenseTitle: { - id: 'nags.settings.license.title', - defaultMessage: 'Visit license settings', - }, -}) diff --git a/packages/moderation/data/nags/core.ts b/packages/moderation/data/nags/core.ts index dff2b4501..067a773b0 100644 --- a/packages/moderation/data/nags/core.ts +++ b/packages/moderation/data/nags/core.ts @@ -1,64 +1,107 @@ import type { Nag, NagContext } from '../../types/nags' import { formatProjectType } from '@modrinth/utils' -import { useVIntl } from '@vintl/vintl' - -import messages from './core.i18n' +import { useVIntl, defineMessage } from '@vintl/vintl' export const coreNags: Nag[] = [ { id: 'moderator-feedback', - title: messages.moderatorFeedbackTitle, - description: messages.moderatorFeedbackDescription, + title: defineMessage({ + id: 'nags.moderator-feedback.title', + defaultMessage: 'Review moderator feedback', + }), + description: defineMessage({ + id: 'nags.moderator-feedback.description', + defaultMessage: + 'Review any feedback from moderators regarding your project before resubmitting.', + }), status: 'suggestion', shouldShow: (context: NagContext) => context.tags.rejectedStatuses.includes(context.project.status), link: { path: 'moderation', - title: messages.moderationTitle, + title: defineMessage({ + id: 'nags.moderation.title', + defaultMessage: 'Visit moderation thread', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-moderation', }, }, { id: 'upload-version', - title: messages.uploadVersionTitle, - description: messages.uploadVersionDescription, + title: defineMessage({ + id: 'nags.upload-version.title', + defaultMessage: 'Upload a version', + }), + description: defineMessage({ + id: 'nags.upload-version.description', + defaultMessage: 'At least one version is required for a project to be submitted for review.', + }), status: 'required', shouldShow: (context: NagContext) => context.versions.length < 1, link: { path: 'versions', - title: messages.versionsTitle, + title: defineMessage({ + id: 'nags.versions.title', + defaultMessage: 'Visit versions page', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-versions', }, }, { id: 'add-description', - title: messages.addDescriptionTitle, - description: messages.addDescriptionDescription, + title: defineMessage({ + id: 'nags.add-description.title', + defaultMessage: 'Add a description', + }), + description: defineMessage({ + id: 'nags.add-description.description', + defaultMessage: + "A description that clearly describes the project's purpose and function is required.", + }), status: 'required', shouldShow: (context: NagContext) => context.project.body === '' || context.project.body.startsWith('# Placeholder description'), link: { path: 'settings/description', - title: messages.settingsDescriptionTitle, + title: defineMessage({ + id: 'nags.settings.description.title', + defaultMessage: 'Visit description settings', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-description', }, }, { id: 'add-icon', - title: messages.addIconTitle, - description: messages.addIconDescription, + title: defineMessage({ + id: 'nags.add-icon.title', + defaultMessage: 'Add an icon', + }), + description: defineMessage({ + id: 'nags.add-icon.description', + defaultMessage: + 'Your project should have a nice-looking icon to uniquely identify your project at a glance.', + }), status: 'suggestion', shouldShow: (context: NagContext) => !context.project.icon_url, link: { path: 'settings', - title: messages.settingsTitle, + title: defineMessage({ + id: 'nags.settings.title', + defaultMessage: 'Visit general settings', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings', }, }, { id: 'feature-gallery-image', - title: messages.featureGalleryImageTitle, - description: messages.featureGalleryImageDescription, + title: defineMessage({ + id: 'nags.feature-gallery-image.title', + defaultMessage: 'Feature a gallery image', + }), + description: defineMessage({ + id: 'nags.feature-gallery-image.description', + defaultMessage: 'Featured gallery images may be the first impression of many users.', + }), status: 'suggestion', shouldShow: (context: NagContext) => { const featuredGalleryImage = context.project.gallery?.find((img) => img.featured) @@ -66,27 +109,46 @@ export const coreNags: Nag[] = [ }, link: { path: 'gallery', - title: messages.galleryTitle, + title: defineMessage({ + id: 'nags.gallery.title', + defaultMessage: 'Visit gallery page', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-gallery', }, }, { id: 'select-tags', - title: messages.selectTagsTitle, - description: messages.selectTagsDescription, + title: defineMessage({ + id: 'nags.select-tags.title', + defaultMessage: 'Select tags', + }), + description: defineMessage({ + id: 'nags.select-tags.description', + defaultMessage: 'Select all tags that apply to your project.', + }), status: 'suggestion', shouldShow: (context: NagContext) => context.project.versions.length > 0 && context.project.categories.length < 1, link: { path: 'settings/tags', - title: messages.settingsTagsTitle, + title: defineMessage({ + id: 'nags.settings.tags.title', + defaultMessage: 'Visit tag settings', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-tags', }, }, { id: 'add-links', - title: messages.addLinksTitle, - description: messages.addLinksDescription, + title: defineMessage({ + id: 'nags.add-links.title', + defaultMessage: 'Add external links', + }), + description: defineMessage({ + id: 'nags.add-links.description', + defaultMessage: + 'Add any relevant links targeted outside of Modrinth, such as sources, issues, or a Discord invite.', + }), status: 'suggestion', shouldShow: (context: NagContext) => !( @@ -98,19 +160,31 @@ export const coreNags: Nag[] = [ ), link: { path: 'settings/links', - title: messages.settingsLinksTitle, + title: defineMessage({ + id: 'nags.settings.links.title', + defaultMessage: 'Visit links settings', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-links', }, }, { id: 'select-environments', - title: messages.selectEnvironmentsTitle, + title: defineMessage({ + id: 'nags.select-environments.title', + defaultMessage: 'Select supported environments', + }), description: (context: NagContext) => { const { formatMessage } = useVIntl() - return formatMessage(messages.selectEnvironmentsDescription, { - projectType: formatProjectType(context.project.project_type).toLowerCase(), - }) + return formatMessage( + defineMessage({ + id: 'nags.select-environments.description', + defaultMessage: `Select if the {projectType} functions on the client-side and/or server-side.`, + }), + { + projectType: formatProjectType(context.project.project_type).toLowerCase(), + }, + ) }, status: 'required', shouldShow: (context: NagContext) => { @@ -126,25 +200,40 @@ export const coreNags: Nag[] = [ }, link: { path: 'settings', - title: messages.settingsEnvironmentsTitle, + title: defineMessage({ + id: 'nags.settings.environments.title', + defaultMessage: 'Visit general settings', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings', }, }, { id: 'select-license', - title: messages.selectLicenseTitle, + title: defineMessage({ + id: 'nags.select-license.title', + defaultMessage: 'Select license', + }), description: (context: NagContext) => { const { formatMessage } = useVIntl() - return formatMessage(messages.selectLicenseDescription, { - projectType: formatProjectType(context.project.project_type).toLowerCase(), - }) + return formatMessage( + defineMessage({ + id: 'nags.select-license.description', + defaultMessage: 'Select the license your {projectType} is distributed under.', + }), + { + projectType: formatProjectType(context.project.project_type).toLowerCase(), + }, + ) }, status: 'required', shouldShow: (context: NagContext) => context.project.license.id === 'LicenseRef-Unknown', link: { path: 'settings/license', - title: messages.settingsLicenseTitle, + title: defineMessage({ + id: 'nags.settings.license.title', + defaultMessage: 'Visit license settings', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-license', }, }, diff --git a/packages/moderation/data/nags/description.i18n.ts b/packages/moderation/data/nags/description.i18n.ts deleted file mode 100644 index 4fa37414a..000000000 --- a/packages/moderation/data/nags/description.i18n.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { defineMessages } from '@vintl/vintl' - -export default defineMessages({ - descriptionTooShortTitle: { - id: 'nags.description-too-short.title', - defaultMessage: 'Description may be insufficient', - }, - descriptionTooShortDescription: { - id: 'nags.description-too-short.description', - defaultMessage: - "Your description is {length} characters. It's recommended to have at least {minChars} characters to provide users with enough information about your project.", - }, - longHeadersTitle: { - id: 'nags.long-headers.title', - defaultMessage: 'Headers are too long', - }, - longHeadersDescription: { - id: 'nags.long-headers.description', - defaultMessage: - '{count, plural, one {# header} other {# headers}} in your description {count, plural, one {is} other {are}} too long. Headers should be concise and act as section titles, not full sentences.', - }, - summaryTooShortTitle: { - id: 'nags.summary-too-short.title', - defaultMessage: 'Summary may be insufficient', - }, - summaryTooShortDescription: { - id: 'nags.summary-too-short.description', - defaultMessage: - "Your summary is {length} characters. It's recommended to have at least {minChars} characters to provide users with enough information about your project.", - }, - minecraftTitleClauseTitle: { - id: 'nags.minecraft-title-clause.title', - defaultMessage: 'Title contains "Minecraft"', - }, - minecraftTitleClauseDescription: { - id: 'nags.minecraft-title-clause.description', - defaultMessage: - 'Please remove "Minecraft" from your title. You cannot use "Minecraft" in your title for legal reasons.', - }, - titleContainsTechnicalInfoTitle: { - id: 'nags.title-contains-technical-info.title', - defaultMessage: 'Title contains loader or version info', - }, - titleContainsTechnicalInfoDescription: { - id: 'nags.title-contains-technical-info.description', - defaultMessage: - 'Removing these helps keep titles clean and makes your project easier to find. Version and loader information is automatically displayed alongside your project.', - }, - summarySameAsTitleTitle: { - id: 'nags.summary-same-as-title.title', - defaultMessage: 'Summary is project name', - }, - summarySameAsTitleDescription: { - id: 'nags.summary-same-as-title.description', - defaultMessage: - "Your summary is the same as your project name. Please change it. It's recommended to have a unique summary to provide more context about your project.", - }, - imageHeavyDescriptionTitle: { - id: 'nags.image-heavy-description.title', - defaultMessage: 'Description is mostly images', - }, - imageHeavyDescriptionDescription: { - id: 'nags.image-heavy-description.description', - defaultMessage: - 'Please add more descriptive text to help users understand your project, especially those using screen readers or with slow internet connections.', - }, - missingAltTextTitle: { - id: 'nags.missing-alt-text.title', - defaultMessage: 'Images missing alt text', - }, - missingAltTextDescription: { - id: 'nags.missing-alt-text.description', - defaultMessage: - 'Some of your images are missing alt text, which is important for accessibility, especially for visually impaired users.', - }, - editDescriptionTitle: { - id: 'nags.edit-description.title', - defaultMessage: 'Edit description', - }, - editSummaryTitle: { - id: 'nags.edit-summary.title', - defaultMessage: 'Edit summary', - }, - editTitleTitle: { - id: 'nags.edit-title.title', - defaultMessage: 'Edit title', - }, -}) diff --git a/packages/moderation/data/nags/description.ts b/packages/moderation/data/nags/description.ts index abd53914d..b5d135079 100644 --- a/packages/moderation/data/nags/description.ts +++ b/packages/moderation/data/nags/description.ts @@ -1,7 +1,5 @@ import type { Nag, NagContext } from '../../types/nags' -import { useVIntl } from '@vintl/vintl' - -import messages from './description.i18n' +import { useVIntl, defineMessage } from '@vintl/vintl' export const MIN_DESCRIPTION_CHARS = 500 export const MAX_HEADER_LENGTH = 100 @@ -73,14 +71,24 @@ function analyzeImageContent(markdown: string): { imageHeavy: boolean; hasEmptyA export const descriptionNags: Nag[] = [ { id: 'description-too-short', - title: messages.descriptionTooShortTitle, + title: defineMessage({ + id: 'nags.description-too-short.title', + defaultMessage: 'Description may be insufficient', + }), description: (context: NagContext) => { const { formatMessage } = useVIntl() - return formatMessage(messages.descriptionTooShortDescription, { - length: context.project.body?.length || 0, - minChars: MIN_DESCRIPTION_CHARS, - }) + return formatMessage( + defineMessage({ + id: 'nags.description-too-short.description', + defaultMessage: + "Your description is {length} characters. It's recommended to have at least {minChars} characters to provide users with enough information about your project.", + }), + { + length: context.project.body?.length || 0, + minChars: MIN_DESCRIPTION_CHARS, + }, + ) }, status: 'warning', shouldShow: (context: NagContext) => { @@ -89,21 +97,34 @@ export const descriptionNags: Nag[] = [ }, link: { path: 'settings/description', - title: messages.editDescriptionTitle, + title: defineMessage({ + id: 'nags.edit-description.title', + defaultMessage: 'Edit description', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-description', }, }, { id: 'long-headers', - title: messages.longHeadersTitle, + title: defineMessage({ + id: 'nags.long-headers.title', + defaultMessage: 'Headers are too long', + }), description: (context: NagContext) => { const { formatMessage } = useVIntl() const { longHeaders } = analyzeHeaderLength(context.project.body || '') const count = longHeaders.length - return formatMessage(messages.longHeadersDescription, { - count, - }) + return formatMessage( + defineMessage({ + id: 'nags.long-headers.description', + defaultMessage: + '{count, plural, one {# header} other {# headers}} in your description {count, plural, one {is} other {are}} too long. Headers should be concise and act as section titles, not full sentences.', + }), + { + count, + }, + ) }, status: 'warning', shouldShow: (context: NagContext) => { @@ -112,20 +133,33 @@ export const descriptionNags: Nag[] = [ }, link: { path: 'settings/description', - title: messages.editDescriptionTitle, + title: defineMessage({ + id: 'nags.edit-description.title', + defaultMessage: 'Edit description', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-description', }, }, { id: 'summary-too-short', - title: messages.summaryTooShortTitle, + title: defineMessage({ + id: 'nags.summary-too-short.title', + defaultMessage: 'Summary may be insufficient', + }), description: (context: NagContext) => { const { formatMessage } = useVIntl() - return formatMessage(messages.summaryTooShortDescription, { - length: context.project.description?.length || 0, - minChars: MIN_SUMMARY_CHARS, - }) + return formatMessage( + defineMessage({ + id: 'nags.summary-too-short.description', + defaultMessage: + "Your summary is {length} characters. It's recommended to have at least {minChars} characters to provide users with enough information about your project.", + }), + { + length: context.project.description?.length || 0, + minChars: MIN_SUMMARY_CHARS, + }, + ) }, status: 'warning', shouldShow: (context: NagContext) => { @@ -134,14 +168,24 @@ export const descriptionNags: Nag[] = [ }, link: { path: 'settings', - title: messages.editSummaryTitle, + title: defineMessage({ + id: 'nags.edit-summary.title', + defaultMessage: 'Edit summary', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings', }, }, { id: 'minecraft-title-clause', - title: messages.minecraftTitleClauseTitle, - description: messages.minecraftTitleClauseDescription, + title: defineMessage({ + id: 'nags.minecraft-title-clause.title', + defaultMessage: 'Title contains "Minecraft"', + }), + description: defineMessage({ + id: 'nags.minecraft-title-clause.description', + defaultMessage: + 'Please remove "Minecraft" from your title. You cannot use "Minecraft" in your title for legal reasons.', + }), status: 'required', shouldShow: (context: NagContext) => { const title = context.project.title?.toLowerCase() || '' @@ -150,14 +194,24 @@ export const descriptionNags: Nag[] = [ }, link: { path: 'settings', - title: messages.editTitleTitle, + title: defineMessage({ + id: 'nags.edit-title.title', + defaultMessage: 'Edit title', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings', }, }, { id: 'title-contains-technical-info', - title: messages.titleContainsTechnicalInfoTitle, - description: messages.titleContainsTechnicalInfoDescription, + title: defineMessage({ + id: 'nags.title-contains-technical-info.title', + defaultMessage: 'Title contains loader or version info', + }), + description: defineMessage({ + id: 'nags.title-contains-technical-info.description', + defaultMessage: + 'Removing these helps keep titles clean and makes your project easier to find. Version and loader information is automatically displayed alongside your project.', + }), status: 'warning', shouldShow: (context: NagContext) => { const title = context.project.title?.toLowerCase() || '' @@ -173,14 +227,24 @@ export const descriptionNags: Nag[] = [ }, link: { path: 'settings', - title: messages.editTitleTitle, + title: defineMessage({ + id: 'nags.edit-title.title', + defaultMessage: 'Edit title', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings', }, }, { id: 'summary-same-as-title', - title: messages.summarySameAsTitleTitle, - description: messages.summarySameAsTitleDescription, + title: defineMessage({ + id: 'nags.summary-same-as-title.title', + defaultMessage: 'Summary is project name', + }), + description: defineMessage({ + id: 'nags.summary-same-as-title.description', + defaultMessage: + "Your summary is the same as your project name. Please change it. It's recommended to have a unique summary to provide more context about your project.", + }), status: 'required', shouldShow: (context: NagContext) => { const title = context.project.title?.trim() || '' @@ -189,14 +253,24 @@ export const descriptionNags: Nag[] = [ }, link: { path: 'settings', - title: messages.editSummaryTitle, + title: defineMessage({ + id: 'nags.edit-summary.title', + defaultMessage: 'Edit summary', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings', }, }, { id: 'image-heavy-description', - title: messages.imageHeavyDescriptionTitle, - description: messages.imageHeavyDescriptionDescription, + title: defineMessage({ + id: 'nags.image-heavy-description.title', + defaultMessage: 'Description is mostly images', + }), + description: defineMessage({ + id: 'nags.image-heavy-description.description', + defaultMessage: + 'Please add more descriptive text to help users understand your project, especially those using screen readers or with slow internet connections.', + }), status: 'warning', shouldShow: (context: NagContext) => { const { imageHeavy } = analyzeImageContent(context.project.body || '') @@ -204,14 +278,24 @@ export const descriptionNags: Nag[] = [ }, link: { path: 'settings/description', - title: messages.editDescriptionTitle, + title: defineMessage({ + id: 'nags.edit-description.title', + defaultMessage: 'Edit description', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-description', }, }, { id: 'missing-alt-text', - title: messages.missingAltTextTitle, - description: messages.missingAltTextDescription, + title: defineMessage({ + id: 'nags.missing-alt-text.title', + defaultMessage: 'Images missing alt text', + }), + description: defineMessage({ + id: 'nags.missing-alt-text.description', + defaultMessage: + 'Some of your images are missing alt text, which is important for accessibility, especially for visually impaired users.', + }), status: 'warning', shouldShow: (context: NagContext) => { const { hasEmptyAltText } = analyzeImageContent(context.project.body || '') @@ -219,7 +303,10 @@ export const descriptionNags: Nag[] = [ }, link: { path: 'settings/description', - title: messages.editDescriptionTitle, + title: defineMessage({ + id: 'nags.edit-description.title', + defaultMessage: 'Edit description', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-description', }, }, diff --git a/packages/moderation/data/nags/links.i18n.ts b/packages/moderation/data/nags/links.i18n.ts deleted file mode 100644 index facaec25a..000000000 --- a/packages/moderation/data/nags/links.i18n.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { defineMessages } from '@vintl/vintl' - -export default defineMessages({ - verifyExternalLinksTitle: { - id: 'nags.verify-external-links.title', - defaultMessage: 'Verify external links', - }, - verifyExternalLinksDescription: { - id: 'nags.verify-external-links.description', - defaultMessage: - "Some of your external links may be using domains that aren't recognized as common for their link type.", - }, - invalidLicenseUrlTitle: { - id: 'nags.invalid-license-url.title', - defaultMessage: 'Invalid license URL', - }, - invalidLicenseUrlDescriptionDefault: { - id: 'nags.invalid-license-url.description.default', - defaultMessage: 'License URL is invalid.', - }, - invalidLicenseUrlDescriptionDomain: { - id: 'nags.invalid-license-url.description.domain', - defaultMessage: - 'Your license URL points to {domain}, which is not appropriate for license information. License URLs should link to the actual license text or legal documentation, not social media, gaming platforms etc.', - }, - invalidLicenseUrlDescriptionMalformed: { - id: 'nags.invalid-license-url.description.malformed', - defaultMessage: - 'Your license URL appears to be malformed. Please provide a valid URL to your license text.', - }, - gplLicenseSourceRequiredTitle: { - id: 'nags.gpl-license-source-required.title', - defaultMessage: 'GPL license requires source', - }, - gplLicenseSourceRequiredDescription: { - id: 'nags.gpl-license-source-required.description', - defaultMessage: - 'Your {projectType} uses a GPL license which requires source code to be available. Please provide a source code link or consider using a different license.', - }, - visitLinksSettingsTitle: { - id: 'nags.visit-links-settings.title', - defaultMessage: 'Visit links settings', - }, - editLicenseTitle: { - id: 'nags.edit-license.title', - defaultMessage: 'Edit license', - }, -}) diff --git a/packages/moderation/data/nags/links.ts b/packages/moderation/data/nags/links.ts index 569097786..b2282b3b6 100644 --- a/packages/moderation/data/nags/links.ts +++ b/packages/moderation/data/nags/links.ts @@ -1,8 +1,6 @@ import type { Nag, NagContext } from '../../types/nags' import { formatProjectType } from '@modrinth/utils' -import { useVIntl } from '@vintl/vintl' - -import messages from './links.i18n' +import { useVIntl, defineMessage } from '@vintl/vintl' export const commonLinkDomains = { source: ['github.com', 'gitlab.com', 'bitbucket.org', 'codeberg.org', 'git.sr.ht'], @@ -52,8 +50,15 @@ export function isUncommonLicenseUrl(url: string | undefined, domains: string[]) export const linksNags: Nag[] = [ { id: 'verify-external-links', - title: messages.verifyExternalLinksTitle, - description: messages.verifyExternalLinksDescription, + title: defineMessage({ + id: 'nags.verify-external-links.title', + defaultMessage: 'Verify external links', + }), + description: defineMessage({ + id: 'nags.verify-external-links.description', + defaultMessage: + "Some of your external links may be using domains that aren't recognized as common for their link type.", + }), status: 'warning', shouldShow: (context: NagContext) => { return ( @@ -64,26 +69,50 @@ export const linksNags: Nag[] = [ }, link: { path: 'settings/links', - title: messages.visitLinksSettingsTitle, + title: defineMessage({ + id: 'nags.visit-links-settings.title', + defaultMessage: 'Visit links settings', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-links', }, }, { id: 'invalid-license-url', - title: messages.invalidLicenseUrlTitle, + title: defineMessage({ + id: 'nags.invalid-license-url.title', + defaultMessage: 'Invalid license URL', + }), description: (context: NagContext) => { const { formatMessage } = useVIntl() const licenseUrl = context.project.license.url if (!licenseUrl) { - return formatMessage(messages.invalidLicenseUrlDescriptionDefault) + return formatMessage( + defineMessage({ + id: 'nags.invalid-license-url.description.default', + defaultMessage: 'License URL is invalid.', + }), + ) } try { const domain = new URL(licenseUrl).hostname.toLowerCase() - return formatMessage(messages.invalidLicenseUrlDescriptionDomain, { domain }) + return formatMessage( + defineMessage({ + id: 'nags.invalid-license-url.description.domain', + defaultMessage: + 'Your license URL points to {domain}, which is not appropriate for license information. License URLs should link to the actual license text or legal documentation, not social media, gaming platforms etc.', + }), + { domain }, + ) } catch { - return formatMessage(messages.invalidLicenseUrlDescriptionMalformed) + return formatMessage( + defineMessage({ + id: 'nags.invalid-license-url.description.malformed', + defaultMessage: + 'Your license URL appears to be malformed. Please provide a valid URL to your license text.', + }), + ) } }, status: 'required', @@ -102,19 +131,32 @@ export const linksNags: Nag[] = [ }, link: { path: 'settings', - title: messages.editLicenseTitle, + title: defineMessage({ + id: 'nags.edit-license.title', + defaultMessage: 'Edit license', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings', }, }, { id: 'gpl-license-source-required', - title: messages.gplLicenseSourceRequiredTitle, + title: defineMessage({ + id: 'nags.gpl-license-source-required.title', + defaultMessage: 'GPL license requires source', + }), description: (context: NagContext) => { const { formatMessage } = useVIntl() - return formatMessage(messages.gplLicenseSourceRequiredDescription, { - projectType: formatProjectType(context.project.project_type).toLowerCase(), - }) + return formatMessage( + defineMessage({ + id: 'nags.gpl-license-source-required.description', + defaultMessage: + 'Your {projectType} uses a GPL license which requires source code to be available. Please provide a source code link or consider using a different license.', + }), + { + projectType: formatProjectType(context.project.project_type).toLowerCase(), + }, + ) }, status: 'required', shouldShow: (context: NagContext) => { @@ -148,7 +190,10 @@ export const linksNags: Nag[] = [ }, link: { path: 'settings/links', - title: messages.visitLinksSettingsTitle, + title: defineMessage({ + id: 'nags.visit-links-settings.title', + defaultMessage: 'Visit links settings', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-links', }, }, diff --git a/packages/moderation/data/nags/tags.i18n.ts b/packages/moderation/data/nags/tags.i18n.ts deleted file mode 100644 index cd1940ec3..000000000 --- a/packages/moderation/data/nags/tags.i18n.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { defineMessages } from '@vintl/vintl' - -export default defineMessages({ - tooManyTagsTitle: { - id: 'nags.too-many-tags.title', - defaultMessage: 'Too many tags selected', - }, - tooManyTagsDescription: { - id: 'nags.too-many-tags.description', - defaultMessage: - "You've selected {tagCount} tags. Consider reducing to 5 or fewer to keep your project focused and easier to discover.", - }, - multipleResolutionTagsTitle: { - id: 'nags.multiple-resolution-tags.title', - defaultMessage: 'Multiple resolution tags selected', - }, - multipleResolutionTagsDescription: { - id: 'nags.multiple-resolution-tags.description', - defaultMessage: - "You've selected {count} resolution tags ({tags}). Resource packs should typically only have one resolution tag that matches their primary resolution.", - }, - allTagsSelectedTitle: { - id: 'nags.all-tags-selected.title', - defaultMessage: 'All tags selected', - }, - allTagsSelectedDescription: { - id: 'nags.all-tags-selected.description', - defaultMessage: - "You've selected all {totalAvailableTags} available tags. This defeats the purpose of tags, which are meant to help users find relevant projects. Please select only the tags that truly apply to your project.", - }, - editTagsTitle: { - id: 'nags.edit-tags.title', - defaultMessage: 'Edit tags', - }, -}) diff --git a/packages/moderation/data/nags/tags.ts b/packages/moderation/data/nags/tags.ts index 2ea30392b..a6b0a04c4 100644 --- a/packages/moderation/data/nags/tags.ts +++ b/packages/moderation/data/nags/tags.ts @@ -1,8 +1,6 @@ import type { Project } from '@modrinth/utils' import type { Nag, NagContext } from '../../types/nags' -import { useVIntl } from '@vintl/vintl' - -import messages from './tags.i18n' +import { useVIntl, defineMessage } from '@vintl/vintl' function getCategories( project: Project & { actualProjectType: string }, @@ -22,15 +20,25 @@ function getCategories( export const tagsNags: Nag[] = [ { id: 'too-many-tags', - title: messages.tooManyTagsTitle, + title: defineMessage({ + id: 'nags.too-many-tags.title', + defaultMessage: 'Too many tags selected', + }), description: (context: NagContext) => { const { formatMessage } = useVIntl() const tagCount = context.project.categories.length + (context.project.additional_categories?.length || 0) - return formatMessage(messages.tooManyTagsDescription, { - tagCount, - }) + return formatMessage( + defineMessage({ + id: 'nags.too-many-tags.description', + defaultMessage: + "You've selected {tagCount} tags. Consider reducing to 5 or fewer to keep your project focused and easier to discover.", + }), + { + tagCount, + }, + ) }, status: 'warning', shouldShow: (context: NagContext) => { @@ -40,23 +48,36 @@ export const tagsNags: Nag[] = [ }, link: { path: 'settings/tags', - title: messages.editTagsTitle, + title: defineMessage({ + id: 'nags.edit-tags.title', + defaultMessage: 'Edit tags', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-tags', }, }, { id: 'multiple-resolution-tags', - title: messages.multipleResolutionTagsTitle, + title: defineMessage({ + id: 'nags.multiple-resolution-tags.title', + defaultMessage: 'Multiple resolution tags selected', + }), description: (context: NagContext) => { const { formatMessage } = useVIntl() const resolutionTags = context.project.categories.filter((tag: string) => ['16x', '32x', '48x', '64x', '128x', '256x', '512x', '1024x'].includes(tag), ) - return formatMessage(messages.multipleResolutionTagsDescription, { - count: resolutionTags.length, - tags: resolutionTags.join(', '), - }) + return formatMessage( + defineMessage({ + id: 'nags.multiple-resolution-tags.description', + defaultMessage: + "You've selected {count} resolution tags ({tags}). Resource packs should typically only have one resolution tag that matches their primary resolution.", + }), + { + count: resolutionTags.length, + tags: resolutionTags.join(', '), + }, + ) }, status: 'warning', shouldShow: (context: NagContext) => { @@ -69,13 +90,19 @@ export const tagsNags: Nag[] = [ }, link: { path: 'settings/tags', - title: messages.editTagsTitle, + title: defineMessage({ + id: 'nags.edit-tags.title', + defaultMessage: 'Edit tags', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-tags', }, }, { id: 'all-tags-selected', - title: messages.allTagsSelectedTitle, + title: defineMessage({ + id: 'nags.all-tags-selected.title', + defaultMessage: 'All tags selected', + }), description: (context: NagContext) => { const { formatMessage } = useVIntl() const categoriesForProjectType = getCategories( @@ -84,9 +111,16 @@ export const tagsNags: Nag[] = [ ) const totalAvailableTags = categoriesForProjectType.length - return formatMessage(messages.allTagsSelectedDescription, { - totalAvailableTags, - }) + return formatMessage( + defineMessage({ + id: 'nags.all-tags-selected.description', + defaultMessage: + "You've selected all {totalAvailableTags} available tags. This defeats the purpose of tags, which are meant to help users find relevant projects. Please select only the tags that truly apply to your project.", + }), + { + totalAvailableTags, + }, + ) }, status: 'required', shouldShow: (context: NagContext) => { @@ -100,7 +134,10 @@ export const tagsNags: Nag[] = [ }, link: { path: 'settings/tags', - title: messages.editTagsTitle, + title: defineMessage({ + id: 'nags.edit-tags.title', + defaultMessage: 'Edit tags', + }), shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-tags', }, },