diff --git a/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue b/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue
index f33081a2d3..8b3307f6b3 100644
--- a/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue
+++ b/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue
@@ -1654,7 +1654,7 @@ function shouldShowStage(stage: Stage): boolean {
function shouldShowAction(action: Action): boolean {
if (typeof action.shouldShow === 'function') {
- return action.shouldShow(projectV2.value)
+ return action.shouldShow(projectV2.value, projectV3.value)
}
return true
@@ -1663,7 +1663,7 @@ function shouldShowAction(action: Action): boolean {
function getVisibleDropdownOptions(action: DropdownAction) {
return action.options.filter((option) => {
if (typeof option.shouldShow === 'function') {
- return option.shouldShow(projectV2.value)
+ return option.shouldShow(projectV2.value, projectV3.value)
}
return true
})
@@ -1672,7 +1672,7 @@ function getVisibleDropdownOptions(action: DropdownAction) {
function getVisibleMultiSelectOptions(action: MultiSelectChipsAction) {
return action.options.filter((option) => {
if (typeof option.shouldShow === 'function') {
- return option.shouldShow(projectV2.value)
+ return option.shouldShow(projectV2.value, projectV3.value)
}
return true
})
diff --git a/apps/frontend/src/pages/[type]/[id].vue b/apps/frontend/src/pages/[type]/[id].vue
index a841555603..72c78e66d5 100644
--- a/apps/frontend/src/pages/[type]/[id].vue
+++ b/apps/frontend/src/pages/[type]/[id].vue
@@ -1650,10 +1650,10 @@ const serverRequiredContent = computed(() => {
name: serverModpackProject.value.name,
versionNumber: serverModpackVersion.value?.version_number ?? '',
icon: serverModpackProject.value.icon_url,
- onclickName: () => router.push(`/project/${serverModpackProject.value.slug}`),
+ onclickName: () => navigateTo(`/modpack/${serverModpackProject.value.slug}`),
onclickVersion: () =>
- router.push(
- `/project/${serverModpackProject.value.slug}/version/${serverModpackVersion.value?.id}`,
+ navigateTo(
+ `/modpack/${serverModpackProject.value.slug}/version/${serverModpackVersion.value?.id}`,
),
onclickDownload: primaryFile?.url
? () => navigateTo(primaryFile.url, { external: true })
diff --git a/apps/frontend/src/pages/[type]/[id]/settings.vue b/apps/frontend/src/pages/[type]/[id]/settings.vue
index d132a937d7..9b51e4bb8d 100644
--- a/apps/frontend/src/pages/[type]/[id]/settings.vue
+++ b/apps/frontend/src/pages/[type]/[id]/settings.vue
@@ -138,8 +138,9 @@ watch(route, () => {
{
noLoad.value = false
- if (currentType.value === 'server') {
- console.log('[v3 search] hits:', (hits as Labrinth.Search.v3.SearchResults)?.hits)
- }
return hits as Labrinth.Search.v2.SearchResults
},
},
@@ -505,7 +502,11 @@ const getServerModpackContent = (hit: Labrinth.Search.v3.ResultSearchProject) =>
onclick:
project_id !== hit.project_id
? () => {
- router.push(`/project/${project_id}`)
+ navigateTo(
+ hit.slug
+ ? `/${hit.project_types[0]}/${hit.slug}`
+ : `/${hit.project_types[0]}/${hit.project_id}`,
+ )
}
: undefined,
showCustomModpackTooltip: project_id === hit.project_id,
diff --git a/packages/moderation/src/data/messages/checklist-text/links/server.md b/packages/moderation/src/data/messages/checklist-text/links/server.md
new file mode 100644
index 0000000000..2d95e284d2
--- /dev/null
+++ b/packages/moderation/src/data/messages/checklist-text/links/server.md
@@ -0,0 +1,4 @@
+**Website:** %PROJECT_SITE_URL% \
+**Store:** %PROJECT_STORE_URL% \
+**Wiki:** %PROJECT_WIKI_URL% \
+**Discord:** %PROJECT_DISCORD_URL%
diff --git a/packages/moderation/src/data/messages/status-alerts/private.md b/packages/moderation/src/data/messages/status-alerts/private.md
index ed82add51f..f167e345c4 100644
--- a/packages/moderation/src/data/messages/status-alerts/private.md
+++ b/packages/moderation/src/data/messages/status-alerts/private.md
@@ -1,6 +1,6 @@
## Private Use
-Under normal circumstances, your project would be rejected due to the issues listed below.
-However, since your project is not intended for public use, these requirements will be waived and your project will be unlisted. This means it will remain accessible through a direct link without appearing in public search results, allowing you to share it privately.
-If you're okay with this, or submitted your project to be unlisted already, than no further action is necessary.
+Under normal circumstances, your project would be rejected due to the issues listed below.
+However, since your project is not intended for public use, these requirements will be waived and your project will be unlisted. This means it will remain accessible through a direct link without appearing in public search results, allowing you to share it privately.
+If you're okay with this, or submitted your project to be unlisted already, than no further action is necessary.
If you would like to publish your project publicly, please address all moderation concerns before resubmitting this project.
diff --git a/packages/moderation/src/data/messages/status-alerts/serverpack.md b/packages/moderation/src/data/messages/status-alerts/serverpack.md
new file mode 100644
index 0000000000..56e3491434
--- /dev/null
+++ b/packages/moderation/src/data/messages/status-alerts/serverpack.md
@@ -0,0 +1,3 @@
+## Servers on Modrinth
+
+Since your project is intended for use on a specific Minecraft server, we strongly recommend uploading your content as linked server pack.
diff --git a/packages/moderation/src/data/messages/summary/repeat-ip.md b/packages/moderation/src/data/messages/summary/repeat-ip.md
new file mode 100644
index 0000000000..62c57a3680
--- /dev/null
+++ b/packages/moderation/src/data/messages/summary/repeat-ip.md
@@ -0,0 +1,7 @@
+## Insufficient Summary
+
+Currently, your summary includes your server's Address, this is redundant information that should instead be appropriately listed in your server's %PROJECT_SETTINGS_FLINK%.
+
+Your server's summary should provide a brief overview of your server that informs and entices players.
+
+This is the first thing most people will see about your listing other than the Icon, so it's important it be accurate, reasonably detailed, and exciting.
diff --git a/packages/moderation/src/data/messages/summary/repeat-title.md b/packages/moderation/src/data/messages/summary/repeat-title.md
index e16fc80529..cd2570ac08 100644
--- a/packages/moderation/src/data/messages/summary/repeat-title.md
+++ b/packages/moderation/src/data/messages/summary/repeat-title.md
@@ -4,4 +4,4 @@ Per section 5.3 of %RULES%, your Summary can not be the same as your project's T
Your project summary should provide a brief overview of your project that informs and entices users.
-This is the first thing most people will see about your mod other than the Logo, so it's important it be accurate, reasonably detailed, and exciting.
+This is the first thing most people will see about your mod other than the Icon, so it's important it be accurate, reasonably detailed, and exciting.
diff --git a/packages/moderation/src/data/modpack-permissions-stage.ts b/packages/moderation/src/data/modpack-permissions-stage.ts
index 379c82b32e..eb0311977b 100644
--- a/packages/moderation/src/data/modpack-permissions-stage.ts
+++ b/packages/moderation/src/data/modpack-permissions-stage.ts
@@ -11,7 +11,8 @@ export default {
// Replace me please.
guidance_url:
'https://www.notion.so/Content-Moderation-Cheat-Sheets-22d5ee711bf081a4920ef08879fe6bf5?source=copy_link#22d5ee711bf08116bd8bc1186f357062',
- shouldShow: (project: Labrinth.Projects.v2.Project) => project.project_type === 'modpack',
+ shouldShow: (project: Labrinth.Projects.v2.Project, projectV3) =>
+ project.project_type === 'modpack' && !projectV3?.minecraft_server,
actions: [
{
id: 'button',
diff --git a/packages/moderation/src/data/nags.ts b/packages/moderation/src/data/nags.ts
index 852321bd3f..ef24017e98 100644
--- a/packages/moderation/src/data/nags.ts
+++ b/packages/moderation/src/data/nags.ts
@@ -2,6 +2,13 @@ import type { Nag } from '../types/nags'
import { coreNags } from './nags/core'
import { descriptionNags } from './nags/description'
import { linksNags } from './nags/links'
+import { serverProjectsNags } from './nags/server-projects'
import { tagsNags } from './nags/tags'
-export default [...coreNags, ...linksNags, ...descriptionNags, ...tagsNags] as Nag[]
+export default [
+ ...coreNags,
+ ...linksNags,
+ ...descriptionNags,
+ ...tagsNags,
+ ...serverProjectsNags,
+] as Nag[]
diff --git a/packages/moderation/src/data/nags/core.ts b/packages/moderation/src/data/nags/core.ts
index 4725568b3d..2f4d6b1b87 100644
--- a/packages/moderation/src/data/nags/core.ts
+++ b/packages/moderation/src/data/nags/core.ts
@@ -37,7 +37,8 @@ export const coreNags: Nag[] = [
defaultMessage: 'At least one version is required for a project to be submitted for review.',
}),
status: 'required',
- shouldShow: (context: NagContext) => context.versions.length < 1,
+ shouldShow: (context: NagContext) =>
+ context.versions.length < 1 && !context.projectV3?.minecraft_server,
link: {
path: 'settings/versions',
title: defineMessage({
@@ -159,58 +160,6 @@ export const coreNags: Nag[] = [
shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-gallery',
},
},
- {
- id: 'select-tags',
- title: defineMessage({
- id: 'nags.select-tags.title',
- defaultMessage: 'Select tags',
- }),
- description: defineMessage({
- id: 'nags.select-tags.description',
- defaultMessage:
- 'Select the tags that correctly apply to your project to help the right users find it.',
- }),
- status: 'suggestion',
- shouldShow: (context: NagContext) =>
- context.project.versions.length > 0 && context.project.categories.length < 1,
- link: {
- path: 'settings/tags',
- title: defineMessage({
- id: 'nags.settings.tags.title',
- defaultMessage: 'Visit tag settings',
- }),
- shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-tags',
- },
- },
- {
- id: 'add-links',
- 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 source code, an issue tracker, or a Discord invite.',
- }),
- status: 'suggestion',
- shouldShow: (context: NagContext) =>
- !(
- context.project.issues_url ||
- context.project.source_url ||
- context.project.wiki_url ||
- context.project.discord_url ||
- context.project.donation_urls?.length
- ),
- link: {
- path: 'settings/links',
- title: defineMessage({
- id: 'nags.settings.links.title',
- defaultMessage: 'Visit links settings',
- }),
- shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-links',
- },
- },
{
id: 'select-license',
title: defineMessage({
@@ -232,7 +181,8 @@ export const coreNags: Nag[] = [
)
},
status: 'required',
- shouldShow: (context: NagContext) => context.project.license.id === 'LicenseRef-Unknown',
+ shouldShow: (context: NagContext) =>
+ context.project.license.id === 'LicenseRef-Unknown' && !context.projectV3?.minecraft_server,
link: {
path: 'settings/license',
title: defineMessage({
diff --git a/packages/moderation/src/data/nags/index.ts b/packages/moderation/src/data/nags/index.ts
index 8c056b4768..a66c6c0dbe 100644
--- a/packages/moderation/src/data/nags/index.ts
+++ b/packages/moderation/src/data/nags/index.ts
@@ -1,4 +1,5 @@
export * from './core'
export * from './description'
export * from './links'
+export * from './server-projects'
export * from './tags'
diff --git a/packages/moderation/src/data/nags/links.ts b/packages/moderation/src/data/nags/links.ts
index 4534c4bedf..b2264bfdc5 100644
--- a/packages/moderation/src/data/nags/links.ts
+++ b/packages/moderation/src/data/nags/links.ts
@@ -66,6 +66,65 @@ export function isUncommonLicenseUrl(url: string | null): boolean {
}
export const linksNags: Nag[] = [
+ {
+ id: 'add-links',
+ 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 source code, an issue tracker, or a Discord invite.',
+ }),
+ status: 'suggestion',
+ shouldShow: (context: NagContext) =>
+ !context.projectV3?.minecraft_server &&
+ !(
+ context.project.issues_url ||
+ context.project.source_url ||
+ context.project.wiki_url ||
+ context.project.discord_url ||
+ context.project.donation_urls?.length
+ ),
+ link: {
+ path: 'settings/links',
+ title: defineMessage({
+ id: 'nags.settings.links.title',
+ defaultMessage: 'Visit links settings',
+ }),
+ shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-links',
+ },
+ },
+ {
+ id: 'add-links-server',
+ title: defineMessage({
+ id: 'nags.add-links-server.title',
+ defaultMessage: 'Add external links',
+ }),
+ description: defineMessage({
+ id: 'nags.add-links-server.description',
+ defaultMessage:
+ 'Add any relevant links targeted outside of Modrinth, such as a website, store, or a Discord invite.',
+ }),
+ status: 'suggestion',
+ shouldShow: (context: NagContext) => {
+ return !(
+ context.projectV3?.link_urls?.site?.url ||
+ context.projectV3?.link_urls?.store?.url ||
+ context.projectV3?.link_urls?.discord?.url ||
+ context.projectV3?.link_urls?.wiki?.url
+ )
+ },
+ link: {
+ path: 'settings/links',
+ title: defineMessage({
+ id: 'nags.settings.links.title',
+ defaultMessage: 'Visit links settings',
+ }),
+ shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-links',
+ },
+ },
{
id: 'verify-external-links',
title: defineMessage({
@@ -109,7 +168,9 @@ export const linksNags: Nag[] = [
shouldShow: (context: NagContext) =>
isDiscordUrl(context.project.source_url ?? null) ||
isDiscordUrl(context.project.issues_url ?? null) ||
- isDiscordUrl(context.project.wiki_url ?? null),
+ isDiscordUrl(context.project.wiki_url ?? null) ||
+ isDiscordUrl(context.projectV3?.link_urls?.site?.url ?? null) ||
+ isDiscordUrl(context.projectV3?.link_urls?.store?.url ?? null),
link: {
path: 'settings/links',
title: defineMessage({
@@ -145,6 +206,8 @@ export const linksNags: Nag[] = [
isLinkShortener(context.project.issues_url ?? null) ||
isLinkShortener(context.project.wiki_url ?? null) ||
isLinkShortener(context.project.discord_url ?? null) ||
+ isLinkShortener(context.projectV3?.link_urls?.site?.url ?? null) ||
+ isLinkShortener(context.projectV3?.link_urls?.store?.url ?? null) ||
Boolean(context.project.license.url && isLinkShortener(context.project.license.url ?? null))
)
},
diff --git a/packages/moderation/src/data/nags/server-projects.ts b/packages/moderation/src/data/nags/server-projects.ts
new file mode 100644
index 0000000000..5c00d5e553
--- /dev/null
+++ b/packages/moderation/src/data/nags/server-projects.ts
@@ -0,0 +1,150 @@
+import { defineMessage } from '@modrinth/ui'
+import type { Nag, NagContext } from '../../types/nags'
+
+export const serverProjectsNags: Nag[] = [
+ /*
+ {
+ id: 'add-banner',
+ title: defineMessage({
+ id: 'nags.add-banner.title',
+ defaultMessage: 'Add a banner',
+ }),
+ description: defineMessage({
+ id: 'nags.add-banner.description',
+ defaultMessage:
+ "Add your server's banner.",
+ }),
+ status: 'suggestion',
+ shouldShow: (context: NagContext) => !!context.projectV3?.minecraft_server,
+ link: {
+ path: 'settings',
+ title: defineMessage({
+ id: 'nags.settings.title',
+ defaultMessage: 'Visit general settings',
+ }),
+ shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings',
+ },
+ },
+*/
+ {
+ id: 'select-country',
+ title: defineMessage({
+ id: 'nags.select-country.title',
+ defaultMessage: 'Select a country',
+ }),
+ description: defineMessage({
+ id: 'nags.select-country.description',
+ defaultMessage: 'Let players know what country your server is located in.',
+ }),
+ status: 'required',
+ shouldShow: (context: NagContext) =>
+ !!context.projectV3?.minecraft_server && !context.projectV3?.minecraft_server.country,
+ link: {
+ path: 'settings/server',
+ title: defineMessage({
+ id: 'nags.server.title',
+ defaultMessage: 'Visit server settings',
+ }),
+ shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-server',
+ },
+ },
+ {
+ id: 'select-language',
+ title: defineMessage({
+ id: 'nags.select-language.title',
+ defaultMessage: 'Select a language',
+ }),
+ description: defineMessage({
+ id: 'nags.select-language.description',
+ defaultMessage: 'List the language or languages supported by your server.',
+ }),
+ status: 'suggestion',
+ shouldShow: (context: NagContext) =>
+ !!context.projectV3?.minecraft_server &&
+ context.projectV3?.minecraft_server?.languages?.length === 0,
+ link: {
+ path: 'settings/server',
+ title: defineMessage({
+ id: 'nags.server.title',
+ defaultMessage: 'Visit server settings',
+ }),
+ shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-server',
+ },
+ },
+ {
+ id: 'add-java-address',
+ title: defineMessage({
+ id: 'nags.add-java-address.title',
+ defaultMessage: 'Add a Java address',
+ }),
+ description: defineMessage({
+ id: 'nags.add-java-address.description',
+ defaultMessage:
+ 'Add the IP address and port Java Edition players can use to join your server.',
+ }),
+ status: 'required',
+ shouldShow: (context: NagContext) =>
+ !!context.projectV3?.minecraft_server && !context.projectV3?.minecraft_java_server?.address,
+ link: {
+ path: 'settings/server',
+ title: defineMessage({
+ id: 'nags.server.title',
+ defaultMessage: 'Visit server settings',
+ }),
+ shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-server',
+ },
+ },
+ {
+ id: 'add-bedrock-address',
+ title: defineMessage({
+ id: 'nags.add-bedrock-address.title',
+ defaultMessage: 'Add a Bedrock address',
+ }),
+ description: defineMessage({
+ id: 'nags.add-bedrock-address.description',
+ defaultMessage:
+ 'If your server supports connections from Bedrock Edition players, add the IP address and port they can use to join.',
+ }),
+ status: 'suggestion',
+ shouldShow: (context: NagContext) =>
+ !!context.projectV3?.minecraft_server &&
+ !context.projectV3?.minecraft_bedrock_server?.address,
+ link: {
+ path: 'settings/server',
+ title: defineMessage({
+ id: 'nags.server.title',
+ defaultMessage: 'Visit server settings',
+ }),
+ shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-server',
+ },
+ },
+ {
+ id: 'select-compatibility',
+ title: defineMessage({
+ id: 'nags.select-compatibility.title',
+ defaultMessage: 'Select compatibility',
+ }),
+ description: defineMessage({
+ id: 'nags.select-compatibility.description',
+ defaultMessage:
+ 'Select what versions your server supports, choose a Modpack, or upload your own.',
+ }),
+ status: 'required',
+ shouldShow: (context: NagContext) => {
+ if (
+ context.projectV3?.minecraft_java_server?.content?.kind === 'vanilla' &&
+ !context.projectV3?.minecraft_java_server?.content?.recommended_game_version
+ )
+ return true
+ return false
+ },
+ link: {
+ path: 'settings/server',
+ title: defineMessage({
+ id: 'nags.server.title',
+ defaultMessage: 'Visit server settings',
+ }),
+ shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-server',
+ },
+ },
+]
diff --git a/packages/moderation/src/data/nags/tags.ts b/packages/moderation/src/data/nags/tags.ts
index 103869250c..14058ddb77 100644
--- a/packages/moderation/src/data/nags/tags.ts
+++ b/packages/moderation/src/data/nags/tags.ts
@@ -6,6 +6,7 @@ import type { Nag, NagContext } from '../../types/nags'
const allResolutionTags = ['8x-', '16x', '32x', '48x', '64x', '128x', '256x', '512x+']
const MAX_TAG_COUNT = 8
+const MAX_TAG_COUNT_SERVER = 18
function getCategories(
project: Labrinth.Projects.v2.Project & { actualProjectType: string },
@@ -23,6 +24,29 @@ function getCategories(
}
export const tagsNags: Nag[] = [
+ {
+ id: 'select-tags',
+ title: defineMessage({
+ id: 'nags.select-tags.title',
+ defaultMessage: 'Select tags',
+ }),
+ description: defineMessage({
+ id: 'nags.select-tags.description',
+ defaultMessage:
+ 'Select the tags that correctly apply to your project to help the right users find it.',
+ }),
+ status: 'suggestion',
+ shouldShow: (context: NagContext) =>
+ context.project.versions.length > 0 && context.project.categories.length < 1,
+ link: {
+ path: 'settings/tags',
+ title: defineMessage({
+ id: 'nags.settings.tags.title',
+ defaultMessage: 'Visit tag settings',
+ }),
+ shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-tags',
+ },
+ },
{
id: 'too-many-tags',
title: defineMessage({
@@ -48,10 +72,50 @@ export const tagsNags: Nag[] = [
)
},
status: 'warning',
+ shouldShow: (context: NagContext) => {
+ if (context.projectV3?.minecraft_java_server) return false
+ const tagCount =
+ context.project.categories.length + (context.project.additional_categories?.length || 0)
+ return tagCount > MAX_TAG_COUNT && !context.projectV3?.minecraft_server
+ },
+ link: {
+ path: 'settings/tags',
+ title: defineMessage({
+ id: 'nags.edit-tags.title',
+ defaultMessage: 'Edit tags',
+ }),
+ shouldShow: (context: NagContext) => context.currentRoute !== 'type-id-settings-tags',
+ },
+ },
+ {
+ id: 'too-many-tags-server',
+ title: defineMessage({
+ id: 'nags.too-many-tags-server.title',
+ defaultMessage: 'Select accurate tags',
+ }),
+ description: (context: NagContext) => {
+ const { formatMessage } = useVIntl()
+ const tagCount =
+ context.project.categories.length + (context.project.additional_categories?.length || 0)
+ const maxTagCount = MAX_TAG_COUNT_SERVER
+
+ return formatMessage(
+ defineMessage({
+ id: 'nags.too-many-tags-server.description',
+ defaultMessage:
+ "You've selected {tagCount, plural, one {# tag} other {# tags}}. Please reduce to {maxTagCount} or fewer to make sure your server appears in relevant search results.",
+ }),
+ {
+ tagCount,
+ maxTagCount,
+ },
+ )
+ },
+ status: 'required',
shouldShow: (context: NagContext) => {
const tagCount =
context.project.categories.length + (context.project.additional_categories?.length || 0)
- return tagCount > MAX_TAG_COUNT
+ return tagCount > MAX_TAG_COUNT_SERVER && context.projectV3?.minecraft_server != null
},
link: {
path: 'settings/tags',
diff --git a/packages/moderation/src/data/stages/environment/environment-multiple.ts b/packages/moderation/src/data/stages/environment/environment-multiple.ts
index 357ed9e85a..00fb553ac2 100644
--- a/packages/moderation/src/data/stages/environment/environment-multiple.ts
+++ b/packages/moderation/src/data/stages/environment/environment-multiple.ts
@@ -11,7 +11,8 @@ const environmentMultiple: Stage = {
guidance_url: 'https://modrinth.com/legal/rules#miscellaneous',
text: async () =>
(await import('../../messages/checklist-text/environment/environment-multiple.md?raw')).default,
- shouldShow: (project, projectV3) => (projectV3?.environment?.length ?? 0) !== 1,
+ shouldShow: (project, projectV3) =>
+ (projectV3?.environment?.length ?? 0) !== 1 && !projectV3?.minecraft_server,
actions: [
{
id: 'side_types_inaccurate',
diff --git a/packages/moderation/src/data/stages/environment/environment.ts b/packages/moderation/src/data/stages/environment/environment.ts
index d2a51e9785..1a15b4f14f 100644
--- a/packages/moderation/src/data/stages/environment/environment.ts
+++ b/packages/moderation/src/data/stages/environment/environment.ts
@@ -11,7 +11,8 @@ const environment: Stage = {
guidance_url: 'https://modrinth.com/legal/rules#miscellaneous',
text: async () =>
(await import('../../messages/checklist-text/environment/environment.md?raw')).default,
- shouldShow: (project, projectV3) => (projectV3?.environment?.length ?? 0) === 1,
+ shouldShow: (project, projectV3) =>
+ (projectV3?.environment?.length ?? 0) === 1 && !projectV3?.minecraft_server,
actions: [
{
id: 'side_types_inaccurate',
diff --git a/packages/moderation/src/data/stages/license.ts b/packages/moderation/src/data/stages/license.ts
index 27b9b41cc6..3e62278eb3 100644
--- a/packages/moderation/src/data/stages/license.ts
+++ b/packages/moderation/src/data/stages/license.ts
@@ -26,6 +26,9 @@ const licenseStage: Stage = {
icon: BookTextIcon,
guidance_url: 'https://modrinth.com/legal/rules#miscellaneous',
navigate: '/settings/license',
+ shouldShow(project, projectV3) {
+ return !projectV3?.minecraft_server
+ },
actions: [
{
id: 'license_invalid_link',
diff --git a/packages/moderation/src/data/stages/links.ts b/packages/moderation/src/data/stages/links.ts
index 7e6004d9c1..bc3b497619 100644
--- a/packages/moderation/src/data/stages/links.ts
+++ b/packages/moderation/src/data/stages/links.ts
@@ -9,18 +9,23 @@ const links: Stage = {
icon: LinkIcon,
guidance_url: 'https://modrinth.com/legal/rules',
navigate: '/settings/links',
- shouldShow: (project) =>
+ shouldShow: (project, projectV3) =>
Boolean(
project.issues_url ||
project.source_url ||
project.wiki_url ||
project.discord_url ||
+ projectV3?.link_urls?.site ||
+ projectV3?.link_urls?.store ||
project.donation_urls.length > 0,
),
- text: async (project) => {
- let text = (await import('../messages/checklist-text/links/base.md?raw')).default
+ text: async (project, projectV3) => {
+ let text
+ if (!!projectV3?.minecraft_server)
+ text = (await import('../messages/checklist-text/links/server.md?raw')).default
+ else text = (await import('../messages/checklist-text/links/base.md?raw')).default
- if (project.donation_urls.length > 0) {
+ if (project.donation_urls && project.donation_urls.length > 0) {
text += (await import('../messages/checklist-text/links/donation/donations.md?raw')).default
for (const donation of project.donation_urls) {
diff --git a/packages/moderation/src/data/stages/reupload.ts b/packages/moderation/src/data/stages/reupload.ts
index 467f737c0e..6fcab77b41 100644
--- a/packages/moderation/src/data/stages/reupload.ts
+++ b/packages/moderation/src/data/stages/reupload.ts
@@ -8,6 +8,7 @@ const reupload: Stage = {
id: 'reupload',
icon: CopyrightIcon,
guidance_url: 'https://modrinth.com/legal/rules',
+ shouldShow: (project, projectV3) => !projectV3?.minecraft_server,
actions: [
{
id: 'reupload_reupload',
diff --git a/packages/moderation/src/data/stages/status-alerts.ts b/packages/moderation/src/data/stages/status-alerts.ts
index 2a6336c2d8..a39b72cc25 100644
--- a/packages/moderation/src/data/stages/status-alerts.ts
+++ b/packages/moderation/src/data/stages/status-alerts.ts
@@ -40,8 +40,19 @@ const statusAlerts: Stage = {
weight: -999999,
suggestedStatus: 'flagged',
disablesActions: ['status_corrections_applied', 'status_account_issues'],
+ shouldShow: (project, projectV3) => !projectV3?.minecraft_server,
message: async () => (await import('../messages/status-alerts/private.md?raw')).default,
} as ButtonAction,
+ {
+ id: 'status_server_use',
+ type: 'button',
+ label: 'Server use',
+ weight: -999999,
+ suggestedStatus: 'flagged',
+ disablesActions: ['status_corrections_applied', 'status_account_issues'],
+ shouldShow: (project) => project.project_type === 'modpack',
+ message: async () => (await import('../messages/status-alerts/serverpack.md?raw')).default,
+ } as ButtonAction,
{
id: 'status_account_issues',
type: 'button',
diff --git a/packages/moderation/src/data/stages/summary.ts b/packages/moderation/src/data/stages/summary.ts
index 680951c1b2..a2c17c6fde 100644
--- a/packages/moderation/src/data/stages/summary.ts
+++ b/packages/moderation/src/data/stages/summary.ts
@@ -48,6 +48,16 @@ const summary: Stage = {
severity: 'medium',
message: async () => (await import('../messages/summary/non-english.md?raw')).default,
} as ButtonAction,
+ {
+ id: 'summary_repeat_ip',
+ type: 'button',
+ label: 'Repeat of IP',
+ weight: 303,
+ suggestedStatus: 'flagged',
+ severity: 'medium',
+ shouldShow: (project, projectV3) => !!projectV3?.minecraft_server,
+ message: async () => (await import('../messages/summary/repeat-ip.md?raw')).default,
+ },
],
}
diff --git a/packages/moderation/src/data/stages/title-slug.ts b/packages/moderation/src/data/stages/title-slug.ts
index b2a4215d87..97813a29b2 100644
--- a/packages/moderation/src/data/stages/title-slug.ts
+++ b/packages/moderation/src/data/stages/title-slug.ts
@@ -69,6 +69,7 @@ const titleSlug: Stage = {
{
label: 'Forked project',
weight: 112,
+ shouldShow: (project, projectV3) => !projectV3?.minecraft_server,
message: async () =>
(await import('../messages/title/similarities-fork.md?raw')).default,
},
diff --git a/packages/moderation/src/data/stages/undefined-project.ts b/packages/moderation/src/data/stages/undefined-project.ts
index 3890065264..3d0f18566f 100644
--- a/packages/moderation/src/data/stages/undefined-project.ts
+++ b/packages/moderation/src/data/stages/undefined-project.ts
@@ -8,7 +8,7 @@ const undefinedProjectStage: Stage = {
icon: XIcon,
guidance_url: 'https://modrinth.com/legal/rules#miscellaneous',
navigate: '/versions',
- shouldShow: (project) => project.versions.length === 0,
+ shouldShow: (project, projectV3) => project.versions.length === 0 && !projectV3?.minecraft_server,
actions: [
{
id: 'undefined_no_versions',
diff --git a/packages/moderation/src/data/stages/versions.ts b/packages/moderation/src/data/stages/versions.ts
index 404c766468..b87916df35 100644
--- a/packages/moderation/src/data/stages/versions.ts
+++ b/packages/moderation/src/data/stages/versions.ts
@@ -9,6 +9,7 @@ const versions: Stage = {
icon: VersionIcon,
guidance_url: 'https://modrinth.com/legal/rules#miscellaneous',
navigate: '/versions',
+ shouldShow: (project, projectV3) => !projectV3?.minecraft_server,
actions: [
{
id: 'versions_incorrect_additional',
diff --git a/packages/moderation/src/types/actions.ts b/packages/moderation/src/types/actions.ts
index e6174116ba..3c6877fd95 100644
--- a/packages/moderation/src/types/actions.ts
+++ b/packages/moderation/src/types/actions.ts
@@ -60,7 +60,10 @@ export interface BaseAction {
*
* By default, it returns `true`, meaning the action is always shown.
*/
- shouldShow?: (project: Labrinth.Projects.v2.Project) => boolean
+ shouldShow?: (
+ project: Labrinth.Projects.v2.Project,
+ projectV3: Labrinth.Projects.v3.Project,
+ ) => boolean
}
/**
@@ -165,7 +168,10 @@ export interface DropdownActionOption extends WeightedMessage {
*
* By default, it returns `true`, meaning the option is always shown.
*/
- shouldShow?: (project: Labrinth.Projects.v2.Project) => boolean
+ shouldShow?: (
+ project: Labrinth.Projects.v2.Project,
+ projectV3: Labrinth.Projects.v3.Project,
+ ) => boolean
}
export interface DropdownAction extends BaseAction {
@@ -198,7 +204,10 @@ export interface MultiSelectChipsOption extends WeightedMessage {
*
* By default, it returns `true`, meaning the option is always shown.
*/
- shouldShow?: (project: Labrinth.Projects.v2.Project) => boolean
+ shouldShow?: (
+ project: Labrinth.Projects.v2.Project,
+ projectV3: Labrinth.Projects.v3.Project,
+ ) => boolean
}
export interface MultiSelectChipsAction extends BaseAction {
diff --git a/packages/moderation/src/utils.ts b/packages/moderation/src/utils.ts
index 2d3655e466..be8c5b4df5 100644
--- a/packages/moderation/src/utils.ts
+++ b/packages/moderation/src/utils.ts
@@ -376,5 +376,8 @@ export function flattenProjectV3Variables(
vars['PROJECT_V3_REVIEW_STATUS'] = projectV3.side_types_migration_review_status
vars['PROJECT_V3_TYPES'] = projectV3.project_types.join(', ')
+ vars['PROJECT_SITE_URL'] = projectV3.link_urls?.site?.url || 'None'
+ vars['PROJECT_STORE_URL'] = projectV3.link_urls?.store?.url || 'None'
+
return vars
}