From 1bc7fee0f1c0045897fdf56813d642838322795a Mon Sep 17 00:00:00 2001 From: Jerozgen Date: Fri, 6 Mar 2026 16:54:26 +0300 Subject: [PATCH 1/5] Translate and sort server filters --- .../src/pages/[type]/[id]/settings/server.vue | 81 +++--- packages/assets/generated-icons.ts | 221 ++++++++--------- packages/moderation/src/data/nags/core.ts | 2 +- .../src/data/nags/server-projects.ts | 1 + packages/moderation/src/data/stages/links.ts | 2 +- .../project/ProjectSidebarServerInfo.vue | 45 +--- .../project/server/ServerRegion.vue | 20 +- packages/ui/src/locales/en-US/index.json | 173 ++++++++++++- packages/ui/src/utils/server-search.ts | 231 ++++++++++++++---- packages/ui/src/utils/tag-messages.ts | 8 +- packages/utils/utils.ts | 3 + 11 files changed, 507 insertions(+), 280 deletions(-) diff --git a/apps/frontend/src/pages/[type]/[id]/settings/server.vue b/apps/frontend/src/pages/[type]/[id]/settings/server.vue index af88816222..bbf482b7b8 100644 --- a/apps/frontend/src/pages/[type]/[id]/settings/server.vue +++ b/apps/frontend/src/pages/[type]/[id]/settings/server.vue @@ -168,13 +168,17 @@ import { injectProjectPageContext, StyledInput, UnsavedChangesPopup, + useVIntl, } from '@modrinth/ui' +import { SERVER_LANGUAGES, SERVER_REGIONS } from '@modrinth/ui/src/utils/server-search.ts' import { Multiselect } from 'vue-multiselect' import CompatibilityCard from '~/components/ui/project-settings/CompatibilityCard.vue' const PING_TIMEOUT_MS = 5000 +const { formatMessage, locale } = useVIntl() + const client = injectModrinthClient() const { addNotification } = injectNotificationManager() const { projectV3, currentMember, patchProjectV3 } = injectProjectPageContext() @@ -262,58 +266,31 @@ if (projectV3.value) { ) } -const regionOptions = [ - { value: 'us_east', label: 'US East' }, - { value: 'us_west', label: 'US West' }, - { value: 'europe', label: 'Europe' }, - { value: 'asia', label: 'Asia' }, - { value: 'australia', label: 'Australia' }, - { value: 'south_america', label: 'South America' }, - { value: 'middle_east', label: 'Middle East' }, - { value: 'russia', label: 'Russia' }, -] - -const languageOptions = [ - { value: 'en', label: 'English' }, - { value: 'es', label: 'Spanish' }, - { value: 'pt', label: 'Portuguese' }, - { value: 'fr', label: 'French' }, - { value: 'de', label: 'German' }, - { value: 'it', label: 'Italian' }, - { value: 'nl', label: 'Dutch' }, - { value: 'ru', label: 'Russian' }, - { value: 'uk', label: 'Ukrainian' }, - { value: 'pl', label: 'Polish' }, - { value: 'cs', label: 'Czech' }, - { value: 'sk', label: 'Slovak' }, - { value: 'hu', label: 'Hungarian' }, - { value: 'ro', label: 'Romanian' }, - { value: 'bg', label: 'Bulgarian' }, - { value: 'hr', label: 'Croatian' }, - { value: 'sr', label: 'Serbian' }, - { value: 'el', label: 'Greek' }, - { value: 'tr', label: 'Turkish' }, - { value: 'ar', label: 'Arabic' }, - { value: 'he', label: 'Hebrew' }, - { value: 'hi', label: 'Hindi' }, - { value: 'bn', label: 'Bengali' }, - { value: 'ur', label: 'Urdu' }, - { value: 'zh', label: 'Chinese' }, - { value: 'ja', label: 'Japanese' }, - { value: 'ko', label: 'Korean' }, - { value: 'th', label: 'Thai' }, - { value: 'vi', label: 'Vietnamese' }, - { value: 'id', label: 'Indonesian' }, - { value: 'ms', label: 'Malay' }, - { value: 'tl', label: 'Filipino' }, - { value: 'sv', label: 'Swedish' }, - { value: 'no', label: 'Norwegian' }, - { value: 'da', label: 'Danish' }, - { value: 'fi', label: 'Finnish' }, - { value: 'lt', label: 'Lithuanian' }, - { value: 'lv', label: 'Latvian' }, - { value: 'et', label: 'Estonian' }, -] +const regionOptions = computed(() => + Object.entries(SERVER_REGIONS) + .sort(([_, a], [__, b]) => { + const aFormatted = formatMessage(a) + const bFormatted = formatMessage(b) + return aFormatted.localeCompare(bFormatted, locale.value) + }) + .map(([code, name]) => ({ + value: code, + label: formatMessage(name), + })), +) + +const languageOptions = computed(() => + Object.entries(SERVER_LANGUAGES) + .sort(([_, a], [__, b]) => { + const aFormatted = formatMessage(a) + const bFormatted = formatMessage(b) + return aFormatted.localeCompare(bFormatted, locale.value) + }) + .map(([code, name]) => ({ + value: code, + label: formatMessage(name), + })), +) const javaServerPatchData = computed(() => { const addressChanged = diff --git a/packages/assets/generated-icons.ts b/packages/assets/generated-icons.ts index 8c77ae7360..7acc69fc9a 100644 --- a/packages/assets/generated-icons.ts +++ b/packages/assets/generated-icons.ts @@ -3,8 +3,6 @@ import type { FunctionalComponent, SVGAttributes } from 'vue' -export type IconComponent = FunctionalComponent - import _AffiliateIcon from './icons/affiliate.svg?component' import _AlignLeftIcon from './icons/align-left.svg?component' import _ArchiveIcon from './icons/archive.svg?component' @@ -380,6 +378,8 @@ import _XCircleIcon from './icons/x-circle.svg?component' import _ZoomInIcon from './icons/zoom-in.svg?component' import _ZoomOutIcon from './icons/zoom-out.svg?component' +export type IconComponent = FunctionalComponent + export const AffiliateIcon = _AffiliateIcon export const AlignLeftIcon = _AlignLeftIcon export const ArchiveIcon = _ArchiveIcon @@ -755,140 +755,141 @@ export const XCircleIcon = _XCircleIcon export const ZoomInIcon = _ZoomInIcon export const ZoomOutIcon = _ZoomOutIcon + export const categoryIconMap: Record = { - adventure: TagCategoryAdventureIcon, - atmosphere: TagCategoryAtmosphereIcon, - audio: TagCategoryAudioIcon, - backpack: TagCategoryBackpackIcon, - badge: TagCategoryBadgeIcon, + 'adventure': TagCategoryAdventureIcon, + 'atmosphere': TagCategoryAtmosphereIcon, + 'audio': TagCategoryAudioIcon, + 'backpack': TagCategoryBackpackIcon, + 'badge': TagCategoryBadgeIcon, 'badge-check': TagCategoryBadgeCheckIcon, 'bed-double': TagCategoryBedDoubleIcon, - blocks: TagCategoryBlocksIcon, - bloom: TagCategoryBloomIcon, + 'blocks': TagCategoryBlocksIcon, + 'bloom': TagCategoryBloomIcon, 'building-2': TagCategoryBuilding2Icon, - camera: TagCategoryCameraIcon, - cartoon: TagCategoryCartoonIcon, - castle: TagCategoryCastleIcon, - challenging: TagCategoryChallengingIcon, - clapperboard: TagCategoryClapperboardIcon, - cloud: TagCategoryCloudIcon, + 'camera': TagCategoryCameraIcon, + 'cartoon': TagCategoryCartoonIcon, + 'castle': TagCategoryCastleIcon, + 'challenging': TagCategoryChallengingIcon, + 'clapperboard': TagCategoryClapperboardIcon, + 'cloud': TagCategoryCloudIcon, 'colored-lighting': TagCategoryColoredLightingIcon, - combat: TagCategoryCombatIcon, - compass: TagCategoryCompassIcon, + 'combat': TagCategoryCombatIcon, + 'compass': TagCategoryCompassIcon, 'core-shaders': TagCategoryCoreShadersIcon, - crown: TagCategoryCrownIcon, - cursed: TagCategoryCursedIcon, - decoration: TagCategoryDecorationIcon, - dices: TagCategoryDicesIcon, - economy: TagCategoryEconomyIcon, - entities: TagCategoryEntitiesIcon, - environment: TagCategoryEnvironmentIcon, - equipment: TagCategoryEquipmentIcon, - fantasy: TagCategoryFantasyIcon, - film: TagCategoryFilmIcon, - flag: TagCategoryFlagIcon, - foliage: TagCategoryFoliageIcon, - fonts: TagCategoryFontsIcon, - food: TagCategoryFoodIcon, - footprints: TagCategoryFootprintsIcon, + 'crown': TagCategoryCrownIcon, + 'cursed': TagCategoryCursedIcon, + 'decoration': TagCategoryDecorationIcon, + 'dices': TagCategoryDicesIcon, + 'economy': TagCategoryEconomyIcon, + 'entities': TagCategoryEntitiesIcon, + 'environment': TagCategoryEnvironmentIcon, + 'equipment': TagCategoryEquipmentIcon, + 'fantasy': TagCategoryFantasyIcon, + 'film': TagCategoryFilmIcon, + 'flag': TagCategoryFlagIcon, + 'foliage': TagCategoryFoliageIcon, + 'fonts': TagCategoryFontsIcon, + 'food': TagCategoryFoodIcon, + 'footprints': TagCategoryFootprintsIcon, 'game-mechanics': TagCategoryGameMechanicsIcon, 'gamepad-2': TagCategoryGamepad2Icon, - gauge: TagCategoryGaugeIcon, - globe: TagCategoryGlobeIcon, + 'gauge': TagCategoryGaugeIcon, + 'globe': TagCategoryGlobeIcon, 'grid-3x3': TagCategoryGrid3x3Icon, - gui: TagCategoryGuiIcon, - handshake: TagCategoryHandshakeIcon, + 'gui': TagCategoryGuiIcon, + 'handshake': TagCategoryHandshakeIcon, 'heart-crack': TagCategoryHeartCrackIcon, 'heart-pulse': TagCategoryHeartPulseIcon, - high: TagCategoryHighIcon, - house: TagCategoryHouseIcon, - items: TagCategoryItemsIcon, + 'high': TagCategoryHighIcon, + 'house': TagCategoryHouseIcon, + 'items': TagCategoryItemsIcon, 'kitchen-sink': TagCategoryKitchenSinkIcon, - library: TagCategoryLibraryIcon, - lightweight: TagCategoryLightweightIcon, - locale: TagCategoryLocaleIcon, - lock: TagCategoryLockIcon, - low: TagCategoryLowIcon, - magic: TagCategoryMagicIcon, - management: TagCategoryManagementIcon, + 'library': TagCategoryLibraryIcon, + 'lightweight': TagCategoryLightweightIcon, + 'locale': TagCategoryLocaleIcon, + 'lock': TagCategoryLockIcon, + 'low': TagCategoryLowIcon, + 'magic': TagCategoryMagicIcon, + 'management': TagCategoryManagementIcon, 'map-pinned': TagCategoryMapPinnedIcon, - medium: TagCategoryMediumIcon, - minigame: TagCategoryMinigameIcon, - mobs: TagCategoryMobsIcon, - modded: TagCategoryModdedIcon, - models: TagCategoryModelsIcon, - multiplayer: TagCategoryMultiplayerIcon, - network: TagCategoryNetworkIcon, - optimization: TagCategoryOptimizationIcon, - palette: TagCategoryPaletteIcon, + 'medium': TagCategoryMediumIcon, + 'minigame': TagCategoryMinigameIcon, + 'mobs': TagCategoryMobsIcon, + 'modded': TagCategoryModdedIcon, + 'models': TagCategoryModelsIcon, + 'multiplayer': TagCategoryMultiplayerIcon, + 'network': TagCategoryNetworkIcon, + 'optimization': TagCategoryOptimizationIcon, + 'palette': TagCategoryPaletteIcon, 'path-tracing': TagCategoryPathTracingIcon, 'paw-print': TagCategoryPawPrintIcon, - pbr: TagCategoryPbrIcon, - pickaxe: TagCategoryPickaxeIcon, - potato: TagCategoryPotatoIcon, - quests: TagCategoryQuestsIcon, - realistic: TagCategoryRealisticIcon, - reflections: TagCategoryReflectionsIcon, + 'pbr': TagCategoryPbrIcon, + 'pickaxe': TagCategoryPickaxeIcon, + 'potato': TagCategoryPotatoIcon, + 'quests': TagCategoryQuestsIcon, + 'realistic': TagCategoryRealisticIcon, + 'reflections': TagCategoryReflectionsIcon, 'refresh-ccw': TagCategoryRefreshCcwIcon, - screenshot: TagCategoryScreenshotIcon, + 'screenshot': TagCategoryScreenshotIcon, 'scroll-text': TagCategoryScrollTextIcon, 'semi-realistic': TagCategorySemiRealisticIcon, - shadows: TagCategoryShadowsIcon, - shield: TagCategoryShieldIcon, - simplistic: TagCategorySimplisticIcon, - skull: TagCategorySkullIcon, - social: TagCategorySocialIcon, - square: TagCategorySquareIcon, - storage: TagCategoryStorageIcon, - sword: TagCategorySwordIcon, - swords: TagCategorySwordsIcon, - target: TagCategoryTargetIcon, - technology: TagCategoryTechnologyIcon, - terminal: TagCategoryTerminalIcon, - theater: TagCategoryTheaterIcon, - themed: TagCategoryThemedIcon, - transportation: TagCategoryTransportationIcon, + 'shadows': TagCategoryShadowsIcon, + 'shield': TagCategoryShieldIcon, + 'simplistic': TagCategorySimplisticIcon, + 'skull': TagCategorySkullIcon, + 'social': TagCategorySocialIcon, + 'square': TagCategorySquareIcon, + 'storage': TagCategoryStorageIcon, + 'sword': TagCategorySwordIcon, + 'swords': TagCategorySwordsIcon, + 'target': TagCategoryTargetIcon, + 'technology': TagCategoryTechnologyIcon, + 'terminal': TagCategoryTerminalIcon, + 'theater': TagCategoryTheaterIcon, + 'themed': TagCategoryThemedIcon, + 'transportation': TagCategoryTransportationIcon, 'tree-pine': TagCategoryTreePineIcon, - trophy: TagCategoryTrophyIcon, - tweaks: TagCategoryTweaksIcon, - users: TagCategoryUsersIcon, - utility: TagCategoryUtilityIcon, + 'trophy': TagCategoryTrophyIcon, + 'tweaks': TagCategoryTweaksIcon, + 'users': TagCategoryUsersIcon, + 'utility': TagCategoryUtilityIcon, 'vanilla-like': TagCategoryVanillaLikeIcon, 'wand-sparkles': TagCategoryWandSparklesIcon, 'wifi-off': TagCategoryWifiOffIcon, - worldgen: TagCategoryWorldgenIcon, - zap: TagCategoryZapIcon, + 'worldgen': TagCategoryWorldgenIcon, + 'zap': TagCategoryZapIcon, } export const loaderIconMap: Record = { - babric: TagLoaderBabricIcon, + 'babric': TagLoaderBabricIcon, 'bta-babric': TagLoaderBtaBabricIcon, - bukkit: TagLoaderBukkitIcon, - bungeecord: TagLoaderBungeecordIcon, - canvas: TagLoaderCanvasIcon, - datapack: TagLoaderDatapackIcon, - fabric: TagLoaderFabricIcon, - folia: TagLoaderFoliaIcon, - forge: TagLoaderForgeIcon, - geyser: TagLoaderGeyserIcon, - iris: TagLoaderIrisIcon, + 'bukkit': TagLoaderBukkitIcon, + 'bungeecord': TagLoaderBungeecordIcon, + 'canvas': TagLoaderCanvasIcon, + 'datapack': TagLoaderDatapackIcon, + 'fabric': TagLoaderFabricIcon, + 'folia': TagLoaderFoliaIcon, + 'forge': TagLoaderForgeIcon, + 'geyser': TagLoaderGeyserIcon, + 'iris': TagLoaderIrisIcon, 'java-agent': TagLoaderJavaAgentIcon, 'legacy-fabric': TagLoaderLegacyFabricIcon, - liteloader: TagLoaderLiteloaderIcon, - minecraft: TagLoaderMinecraftIcon, - modloader: TagLoaderModloaderIcon, - mrpack: TagLoaderMrpackIcon, - neoforge: TagLoaderNeoforgeIcon, - nilloader: TagLoaderNilloaderIcon, - optifine: TagLoaderOptifineIcon, - ornithe: TagLoaderOrnitheIcon, - paper: TagLoaderPaperIcon, - purpur: TagLoaderPurpurIcon, - quilt: TagLoaderQuiltIcon, - rift: TagLoaderRiftIcon, - spigot: TagLoaderSpigotIcon, - sponge: TagLoaderSpongeIcon, - vanilla: TagLoaderVanillaIcon, - velocity: TagLoaderVelocityIcon, - waterfall: TagLoaderWaterfallIcon, + 'liteloader': TagLoaderLiteloaderIcon, + 'minecraft': TagLoaderMinecraftIcon, + 'modloader': TagLoaderModloaderIcon, + 'mrpack': TagLoaderMrpackIcon, + 'neoforge': TagLoaderNeoforgeIcon, + 'nilloader': TagLoaderNilloaderIcon, + 'optifine': TagLoaderOptifineIcon, + 'ornithe': TagLoaderOrnitheIcon, + 'paper': TagLoaderPaperIcon, + 'purpur': TagLoaderPurpurIcon, + 'quilt': TagLoaderQuiltIcon, + 'rift': TagLoaderRiftIcon, + 'spigot': TagLoaderSpigotIcon, + 'sponge': TagLoaderSpongeIcon, + 'vanilla': TagLoaderVanillaIcon, + 'velocity': TagLoaderVelocityIcon, + 'waterfall': TagLoaderWaterfallIcon, } diff --git a/packages/moderation/src/data/nags/core.ts b/packages/moderation/src/data/nags/core.ts index 23ea9f7af9..a2af5fb9f9 100644 --- a/packages/moderation/src/data/nags/core.ts +++ b/packages/moderation/src/data/nags/core.ts @@ -148,7 +148,7 @@ export const coreNags: Nag[] = [ }), status: 'suggestion', shouldShow: (context: NagContext) => { - if (!!context.projectV3?.minecraft_server) return false + if (context.projectV3?.minecraft_server) return false const featuredGalleryImage = context.project.gallery?.find((img) => img.featured) return context.project?.gallery?.length === 0 || !featuredGalleryImage }, diff --git a/packages/moderation/src/data/nags/server-projects.ts b/packages/moderation/src/data/nags/server-projects.ts index caf092fcaa..affeac28c9 100644 --- a/packages/moderation/src/data/nags/server-projects.ts +++ b/packages/moderation/src/data/nags/server-projects.ts @@ -1,4 +1,5 @@ import { defineMessage } from '@modrinth/ui' + import type { Nag, NagContext } from '../../types/nags' export const serverProjectsNags: Nag[] = [ diff --git a/packages/moderation/src/data/stages/links.ts b/packages/moderation/src/data/stages/links.ts index bc3b497619..bbed9b57be 100644 --- a/packages/moderation/src/data/stages/links.ts +++ b/packages/moderation/src/data/stages/links.ts @@ -21,7 +21,7 @@ const links: Stage = { ), text: async (project, projectV3) => { let text - if (!!projectV3?.minecraft_server) + 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 diff --git a/packages/ui/src/components/project/ProjectSidebarServerInfo.vue b/packages/ui/src/components/project/ProjectSidebarServerInfo.vue index a9f841ad34..e8abcdf164 100644 --- a/packages/ui/src/components/project/ProjectSidebarServerInfo.vue +++ b/packages/ui/src/components/project/ProjectSidebarServerInfo.vue @@ -66,7 +66,7 @@

Languages

- {{ languageDisplay.find((l) => l.value === language)?.label ?? language }} + {{ SERVER_LANGUAGES[language] ? formatMessage(SERVER_LANGUAGES[language]) : language }}
@@ -75,6 +75,7 @@