Deduplicate common strings in translation (#5085)

* deduplicate common strings, part 1

* deduplicate common strings, part 2

* typo and general import mess fixes

* detail common string

* fix lint

* fix lint TWO

* adress review concerns + lint

* app lint too

* actually leave privateLabel untouched

* lint fix THREE

* fix: broken msg

* fix: lint

---------

Co-authored-by: Calum H. <contact@cal.engineer>
Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
This commit is contained in:
lumiscosity
2026-01-28 19:10:50 +01:00
committed by GitHub
parent 400c571fe6
commit 6d68d50699
31 changed files with 279 additions and 624 deletions

View File

@@ -9,7 +9,7 @@
<div class="iconified-input">
<label for="email" hidden>
{{ formatMessage(methodChoiceMessages.emailUsernameLabel) }}
{{ formatMessage(commonMessages.emailUsernameLabel) }}
</label>
<MailIcon />
<input
@@ -18,7 +18,7 @@
type="text"
autocomplete="username"
class="auth-form__input"
:placeholder="formatMessage(methodChoiceMessages.emailUsernamePlaceholder)"
:placeholder="formatMessage(commonMessages.emailLabel)"
/>
</div>
@@ -81,14 +81,6 @@ const methodChoiceMessages = defineMessages({
defaultMessage:
"Enter your email below and we'll send a recovery link to allow you to recover your account.",
},
emailUsernameLabel: {
id: 'auth.reset-password.method-choice.email-username.label',
defaultMessage: 'Email or username',
},
emailUsernamePlaceholder: {
id: 'auth.reset-password.method-choice.email-username.placeholder',
defaultMessage: 'Email',
},
action: {
id: 'auth.reset-password.method-choice.action',
defaultMessage: 'Send recovery email',

View File

@@ -63,7 +63,7 @@
<section class="auth-form">
<div class="iconified-input">
<label for="email" hidden>{{ formatMessage(messages.emailUsernameLabel) }}</label>
<label for="email" hidden>{{ formatMessage(commonMessages.emailUsernameLabel) }}</label>
<MailIcon />
<input
id="email"
@@ -72,12 +72,12 @@
inputmode="email"
autocomplete="username"
class="auth-form__input"
:placeholder="formatMessage(messages.emailUsernameLabel)"
:placeholder="formatMessage(commonMessages.emailUsernameLabel)"
/>
</div>
<div class="iconified-input">
<label for="password" hidden>{{ formatMessage(messages.passwordLabel) }}</label>
<label for="password" hidden>{{ formatMessage(commonMessages.passwordLabel) }}</label>
<KeyIcon />
<input
id="password"
@@ -85,7 +85,7 @@
type="password"
autocomplete="current-password"
class="auth-form__input"
:placeholder="formatMessage(messages.passwordLabel)"
:placeholder="formatMessage(commonMessages.passwordLabel)"
/>
</div>
@@ -162,14 +162,6 @@ const messages = defineMessages({
defaultMessage:
'<forgot-password-link>Forgot password?</forgot-password-link> • <create-account-link>Create an account</create-account-link>',
},
emailUsernameLabel: {
id: 'auth.sign-in.email-username.label',
defaultMessage: 'Email or username',
},
passwordLabel: {
id: 'auth.sign-in.password.label',
defaultMessage: 'Password',
},
signInWithLabel: {
id: 'auth.sign-in.sign-in-with',
defaultMessage: 'Sign in with',

View File

@@ -33,7 +33,7 @@
<section class="auth-form">
<div class="iconified-input">
<label for="email" hidden>{{ formatMessage(messages.emailLabel) }}</label>
<label for="email" hidden>{{ formatMessage(commonMessages.emailLabel) }}</label>
<MailIcon />
<input
id="email"
@@ -41,12 +41,12 @@
type="email"
autocomplete="username"
class="auth-form__input"
:placeholder="formatMessage(messages.emailLabel)"
:placeholder="formatMessage(commonMessages.emailLabel)"
/>
</div>
<div class="iconified-input">
<label for="username" hidden>{{ formatMessage(messages.usernameLabel) }}</label>
<label for="username" hidden>{{ formatMessage(commonMessages.usernameLabel) }}</label>
<UserIcon />
<input
id="username"
@@ -54,12 +54,12 @@
type="text"
autocomplete="username"
class="auth-form__input"
:placeholder="formatMessage(messages.usernameLabel)"
:placeholder="formatMessage(commonMessages.usernameLabel)"
/>
</div>
<div class="iconified-input">
<label for="password" hidden>{{ formatMessage(messages.passwordLabel) }}</label>
<label for="password" hidden>{{ formatMessage(commonMessages.passwordLabel) }}</label>
<KeyIcon />
<input
id="password"
@@ -67,12 +67,14 @@
class="auth-form__input"
type="password"
autocomplete="new-password"
:placeholder="formatMessage(messages.passwordLabel)"
:placeholder="formatMessage(commonMessages.passwordLabel)"
/>
</div>
<div class="iconified-input">
<label for="confirm-password" hidden>{{ formatMessage(messages.passwordLabel) }}</label>
<label for="confirm-password" hidden>{{
formatMessage(commonMessages.passwordLabel)
}}</label>
<KeyIcon />
<input
id="confirm-password"
@@ -80,7 +82,7 @@
type="password"
autocomplete="new-password"
class="auth-form__input"
:placeholder="formatMessage(messages.confirmPasswordLabel)"
:placeholder="formatMessage(commonMessages.confirmPasswordLabel)"
/>
</div>
@@ -173,22 +175,6 @@ const messages = defineMessages({
id: 'auth.sign-up.title.create-account',
defaultMessage: 'Or create an account yourself',
},
emailLabel: {
id: 'auth.sign-up.email.label',
defaultMessage: 'Email',
},
usernameLabel: {
id: 'auth.sign-up.label.username',
defaultMessage: 'Username',
},
passwordLabel: {
id: 'auth.sign-up.password.label',
defaultMessage: 'Password',
},
confirmPasswordLabel: {
id: 'auth.sign-up.confirm-password.label',
defaultMessage: 'Confirm password',
},
subscribeLabel: {
id: 'auth.sign-up.subscribe.label',
defaultMessage: 'Subscribe to updates about Modrinth',

View File

@@ -25,7 +25,7 @@
</ButtonStyled>
<ButtonStyled v-else>
<NuxtLink to="/auth/sign-in">
{{ formatMessage(messages.signIn) }}
{{ formatMessage(commonMessages.signInButton) }}
<RightArrowIcon />
</NuxtLink>
</ButtonStyled>
@@ -54,7 +54,7 @@
<ButtonStyled v-else color="brand">
<NuxtLink to="/auth/sign-in">
{{ formatMessage(messages.signIn) }}
{{ formatMessage(commonMessages.signInButton) }}
<RightArrowIcon />
</NuxtLink>
</ButtonStyled>
@@ -64,7 +64,13 @@
</template>
<script setup>
import { RightArrowIcon, SettingsIcon } from '@modrinth/assets'
import { ButtonStyled, defineMessages, injectNotificationManager, useVIntl } from '@modrinth/ui'
import {
ButtonStyled,
commonMessages,
defineMessages,
injectNotificationManager,
useVIntl,
} from '@modrinth/ui'
const { addNotification } = injectNotificationManager()
const { formatMessage } = useVIntl()
@@ -78,10 +84,6 @@ const messages = defineMessages({
id: 'auth.verify-email.action.account-settings',
defaultMessage: 'Account settings',
},
signIn: {
id: 'auth.verify-email.action.sign-in',
defaultMessage: 'Sign in',
},
})
const alreadyVerifiedMessages = defineMessages({

View File

@@ -237,7 +237,7 @@
<AdPlaceholder v-if="!auth.user" />
<SidebarCard
v-if="collection.id !== 'following'"
:title="formatMessage(messages.detailsLabel)"
:title="formatMessage(commonMessages.detailsLabel)"
>
<div class="flex flex-col gap-2">
<span
@@ -458,14 +458,6 @@ const messages = defineMessages({
id: 'collection.label.curated-by',
defaultMessage: 'Curated by',
},
descriptionLabel: {
id: 'collection.label.description',
defaultMessage: 'Description',
},
detailsLabel: {
id: 'collection.label.details',
defaultMessage: 'Details',
},
deleteModalDescription: {
id: 'collection.delete-modal.description',
defaultMessage: 'This will permanently delete this collection. This action cannot be undone.',

View File

@@ -93,7 +93,7 @@
<div class="search-controls">
<div class="iconified-input">
<label class="hidden" for="search">{{
formatMessage(messages.searchLabel)
formatMessage(commonMessages.searchLabel)
}}</label>
<SearchIcon aria-hidden="true" />
<input
@@ -101,13 +101,13 @@
v-model="searchQuery"
type="search"
name="search"
:placeholder="formatMessage(messages.searchPlaceholder)"
:placeholder="formatMessage(commonMessages.searchPlaceholder)"
autocomplete="off"
@input="updateSearchProjects"
/>
</div>
<div class="sort-by">
<span class="label">{{ formatMessage(messages.sortByLabel) }}</span>
<span class="label">{{ formatMessage(commonMessages.sortByLabel) }}</span>
<Multiselect
v-model="sortType"
placeholder="Select one"
@@ -155,7 +155,7 @@
</div>
<div class="blob-demonstration gradient-border">
<div class="notifs-demo">
<h3>{{ formatMessage(messages.notificationsHeading) }}</h3>
<h3>{{ formatMessage(commonMessages.notificationsLabel) }}</h3>
<div class="notifications">
<div
v-for="(notification, index) in notifications"
@@ -567,18 +567,6 @@ const messages = defineMessages({
defaultMessage:
"Modrinth's open-source API lets launchers add deep integration with Modrinth. You can use Modrinth through <link>our own app</link> and some of the most popular launchers like ATLauncher, MultiMC, and Prism Launcher.",
},
searchPlaceholder: {
id: 'landing.search.placeholder',
defaultMessage: 'Search...',
},
searchLabel: {
id: 'landing.search.label',
defaultMessage: 'Search',
},
sortByLabel: {
id: 'landing.search.sort-by.label',
defaultMessage: 'Sort by',
},
notificationsHeading: {
id: 'landing.notifications.heading',
defaultMessage: 'Notifications',

View File

@@ -9,7 +9,7 @@
autocomplete="off"
spellcheck="false"
type="text"
:placeholder="formatMessage(messages.searchPlaceholder)"
:placeholder="formatMessage(commonMessages.searchPlaceholder)"
@input="goToPage(1)"
/>
<Button v-if="query" class="r-btn" @click="() => (query = '')">
@@ -28,7 +28,7 @@
v-model="currentFilterType"
class="!w-full flex-grow sm:!w-[280px] sm:flex-grow-0 lg:!w-[280px]"
:options="filterTypes"
:placeholder="formatMessage(messages.filterBy)"
:placeholder="formatMessage(commonMessages.filterByLabel)"
@select="goToPage(1)"
>
<template #selected>
@@ -45,7 +45,7 @@
v-model="currentSortType"
class="!w-full flex-grow sm:!w-[150px] sm:flex-grow-0 lg:!w-[150px]"
:options="sortTypes"
:placeholder="formatMessage(messages.sortBy)"
:placeholder="formatMessage(commonMessages.sortByLabel)"
@select="goToPage(1)"
>
<template #selected>
@@ -112,6 +112,7 @@ import {
ButtonStyled,
Combobox,
type ComboboxOption,
commonMessages,
defineMessages,
injectNotificationManager,
Pagination,
@@ -145,18 +146,6 @@ if (import.meta.client && history && history.state && history.state.confetti) {
}
const messages = defineMessages({
searchPlaceholder: {
id: 'moderation.search.placeholder',
defaultMessage: 'Search...',
},
filterBy: {
id: 'moderation.filter.by',
defaultMessage: 'Filter by',
},
sortBy: {
id: 'moderation.sort.by',
defaultMessage: 'Sort by',
},
moderate: {
id: 'moderation.moderate',
defaultMessage: 'Moderate',

View File

@@ -9,7 +9,7 @@
autocomplete="off"
spellcheck="false"
type="text"
:placeholder="formatMessage(messages.searchPlaceholder)"
:placeholder="formatMessage(commonMessages.searchPlaceholder)"
@input="goToPage(1)"
/>
<Button v-if="query" class="r-btn" @click="() => (query = '')">
@@ -26,7 +26,7 @@
v-model="currentFilterType"
class="!w-full flex-grow sm:!w-[280px] sm:flex-grow-0 lg:!w-[280px]"
:options="filterTypes"
:placeholder="formatMessage(messages.filterBy)"
:placeholder="formatMessage(commonMessages.filterByLabel)"
@select="goToPage(1)"
>
<template #selected>
@@ -43,7 +43,7 @@
v-model="currentSortType"
class="!w-full flex-grow sm:!w-[150px] sm:flex-grow-0 lg:!w-[150px]"
:options="sortTypes"
:placeholder="formatMessage(messages.sortBy)"
:placeholder="formatMessage(commonMessages.sortByLabel)"
@select="goToPage(1)"
>
<template #selected>
@@ -82,7 +82,7 @@ import {
Button,
Combobox,
type ComboboxOption,
defineMessages,
commonMessages,
Pagination,
useVIntl,
} from '@modrinth/ui'
@@ -98,21 +98,6 @@ const { formatMessage } = useVIntl()
const route = useRoute()
const router = useRouter()
const messages = defineMessages({
searchPlaceholder: {
id: 'moderation.search.placeholder',
defaultMessage: 'Search...',
},
filterBy: {
id: 'moderation.filter.by',
defaultMessage: 'Filter by',
},
sortBy: {
id: 'moderation.sort.by',
defaultMessage: 'Sort by',
},
})
const { data: allReports } = await useLazyAsyncData('new-moderation-reports', async () => {
const startTime = performance.now()
let currentOffset = 0

View File

@@ -13,7 +13,7 @@ import {
Button,
Combobox,
type ComboboxOption,
defineMessages,
commonMessages,
FloatingPanel,
injectModrinthClient,
Pagination,
@@ -163,21 +163,6 @@ function handleLoadFileSources(reportId: string): void {
}
}
const messages = defineMessages({
searchPlaceholder: {
id: 'moderation.search.placeholder',
defaultMessage: 'Search...',
},
filterBy: {
id: 'moderation.filter.by',
defaultMessage: 'Filter by',
},
sortBy: {
id: 'moderation.sort.by',
defaultMessage: 'Sort by',
},
})
const query = ref(route.query.q?.toString() || '')
watch(
@@ -534,7 +519,7 @@ watch([currentSortType, currentResponseFilter, inOtherQueueFilter, currentFilter
autocomplete="off"
spellcheck="false"
type="text"
:placeholder="formatMessage(messages.searchPlaceholder)"
:placeholder="formatMessage(commonMessages.searchPlaceholder)"
@input="goToPage(1)"
/>
<Button v-if="query" class="r-btn" @click="() => (query = '')">
@@ -572,7 +557,7 @@ watch([currentSortType, currentResponseFilter, inOtherQueueFilter, currentFilter
v-model="currentSortType"
class="!w-full flex-grow sm:!w-[215px] sm:flex-grow-0"
:options="sortTypes"
:placeholder="formatMessage(messages.sortBy)"
:placeholder="formatMessage(commonMessages.sortByLabel)"
>
<template #selected>
<span class="flex flex-row gap-2 align-middle font-semibold">
@@ -602,7 +587,7 @@ watch([currentSortType, currentResponseFilter, inOtherQueueFilter, currentFilter
v-model="currentFilterType"
class="!w-full"
:options="filterTypes"
:placeholder="formatMessage(messages.filterBy)"
:placeholder="formatMessage(commonMessages.filterByLabel)"
searchable
>
<template #selected>

View File

@@ -516,18 +516,18 @@
<div class="font-bold text-contrast">
<template v-if="method.type === 'card'">
{{
formatMessage(messages.paymentMethodCardDisplay, {
formatMessage(paymentMethodMessages.paymentMethodCardDisplay, {
card_brand:
formatMessage(paymentMethodTypes[method.card.brand]) ??
formatMessage(paymentMethodTypes.unknown),
formatMessage(paymentMethodMessages[method.card.brand]) ??
formatMessage(paymentMethodMessages.unknown),
last_four: method.card.last4,
})
}}
</template>
<template v-else>
{{
formatMessage(paymentMethodTypes[method.type]) ??
formatMessage(paymentMethodTypes.unknown)
formatMessage(paymentMethodMessages[method.type]) ??
formatMessage(paymentMethodMessages.unknown)
}}
</template>
</div>
@@ -621,6 +621,7 @@ import {
getPaymentMethodIcon,
injectNotificationManager,
OverflowMenu,
paymentMethodMessages,
PurchaseModal,
ServerListing,
useVIntl,
@@ -721,10 +722,6 @@ const messages = defineMessages({
id: 'settings.billing.payment_method.action.primary',
defaultMessage: 'Make primary',
},
paymentMethodCardDisplay: {
id: 'settings.billing.payment_method.card_display',
defaultMessage: '{card_brand} ending in {last_four}',
},
paymentMethodCardExpiry: {
id: 'settings.billing.payment_method.card_expiry',
defaultMessage: 'Expires {month}/{year}',
@@ -739,33 +736,6 @@ const messages = defineMessages({
},
})
const paymentMethodTypes = defineMessages({
visa: {
id: 'settings.billing.payment_method_type.visa',
defaultMessage: 'Visa',
},
amex: { id: 'settings.billing.payment_method_type.amex', defaultMessage: 'American Express' },
diners: { id: 'settings.billing.payment_method_type.diners', defaultMessage: 'Diners Club' },
discover: { id: 'settings.billing.payment_method_type.discover', defaultMessage: 'Discover' },
eftpos: { id: 'settings.billing.payment_method_type.eftpos', defaultMessage: 'EFTPOS' },
jcb: { id: 'settings.billing.payment_method_type.jcb', defaultMessage: 'JCB' },
mastercard: {
id: 'settings.billing.payment_method_type.mastercard',
defaultMessage: 'MasterCard',
},
unionpay: { id: 'settings.billing.payment_method_type.unionpay', defaultMessage: 'UnionPay' },
paypal: { id: 'settings.billing.payment_method_type.paypal', defaultMessage: 'PayPal' },
cashapp: { id: 'settings.billing.payment_method_type.cashapp', defaultMessage: 'Cash App' },
amazon_pay: {
id: 'settings.billing.payment_method_type.amazon_pay',
defaultMessage: 'Amazon Pay',
},
unknown: {
id: 'settings.billing.payment_method_type.unknown',
defaultMessage: 'Unknown payment method',
},
})
const [
{ data: paymentMethods, refresh: refreshPaymentMethods },
{ data: charges, refresh: refreshCharges },

View File

@@ -46,12 +46,12 @@
"
>
<UndoIcon />
{{ formatMessage(messages.profilePictureReset) }}
{{ formatMessage(commonMessages.resetButton) }}
</Button>
</div>
</div>
<label for="username-field">
<span class="label__title">{{ formatMessage(messages.usernameTitle) }}</span>
<span class="label__title">{{ formatMessage(commonMessages.usernameLabel) }}</span>
<span class="label__description">
{{ formatMessage(messages.usernameDescription) }}
</span>
@@ -120,14 +120,6 @@ const messages = defineMessages({
id: 'settings.profile.profile-picture.title',
defaultMessage: 'Profile picture',
},
profilePictureReset: {
id: 'settings.profile.profile-picture.reset',
defaultMessage: 'Reset',
},
usernameTitle: {
id: 'settings.profile.username.title',
defaultMessage: 'Username',
},
usernameDescription: {
id: 'settings.profile.username.description',
defaultMessage: 'A unique case-insensitive name to identify your profile.',

View File

@@ -34,7 +34,7 @@
<div class="flex flex-col gap-3">
<div v-if="isAdmin(auth.user)" class="flex flex-col gap-1">
<span class="text-lg font-bold text-primary">{{
formatMessage(messages.emailLabel)
formatMessage(commonMessages.emailLabel)
}}</span>
<div>
<span
@@ -61,8 +61,8 @@
<XIcon v-else class="h-4 w-4 text-red" />
{{
user.email_verified
? formatMessage(messages.yesLabel)
: formatMessage(messages.noLabel)
? formatMessage(commonMessages.yesLabel)
: formatMessage(commonMessages.noLabel)
}}
</span>
</div>
@@ -97,7 +97,9 @@
}}</span>
<span>
{{
user.has_password ? formatMessage(messages.yesLabel) : formatMessage(messages.noLabel)
user.has_password
? formatMessage(commonMessages.yesLabel)
: formatMessage(commonMessages.noLabel)
}}
</span>
</div>
@@ -107,7 +109,11 @@
formatMessage(messages.hasTotpLabel)
}}</span>
<span>
{{ user.has_totp ? formatMessage(messages.yesLabel) : formatMessage(messages.noLabel) }}
{{
user.has_totp
? formatMessage(commonMessages.yesLabel)
: formatMessage(commonMessages.noLabel)
}}
</span>
</div>
</div>
@@ -575,14 +581,6 @@ const messages = defineMessages({
id: 'profile.details.label.has-totp',
defaultMessage: 'Has TOTP',
},
yesLabel: {
id: 'profile.label.yes',
defaultMessage: 'Yes',
},
noLabel: {
id: 'profile.label.no',
defaultMessage: 'No',
},
bioFallbackUser: {
id: 'profile.bio.fallback.user',
defaultMessage: 'A Modrinth user.',
@@ -604,10 +602,6 @@ const messages = defineMessages({
id: 'profile.user-id',
defaultMessage: 'User ID: {id}',
},
profileDetails: {
id: 'profile.label.details',
defaultMessage: 'Details',
},
profileOrganizations: {
id: 'profile.label.organizations',
defaultMessage: 'Organizations',