Use named tokens in frontend translate function

This commit is contained in:
Bogdan
2023-08-13 21:03:38 +03:00
parent 5dbb59dfaa
commit 31261f66ad
22 changed files with 57 additions and 51 deletions

View File

@@ -288,7 +288,7 @@ class AddIndexerModalContent extends Component {
<div className={styles.available}>
{
isPopulated ?
translate('CountIndexersAvailable', [filteredIndexers.length]) :
translate('CountIndexersAvailable', { count: filteredIndexers.length }) :
null
}
</div>

View File

@@ -37,7 +37,7 @@ function DeleteIndexerModalContent(props: DeleteIndexerModalContentProps) {
</ModalHeader>
<ModalBody>
{translate('AreYouSureYouWantToDeleteIndexer', [name])}
{translate('AreYouSureYouWantToDeleteIndexer', { name })}
</ModalBody>
<ModalFooter>

View File

@@ -48,7 +48,9 @@ function DeleteIndexerModalContent(props: DeleteIndexerModalContentProps) {
<ModalBody>
<div className={styles.message}>
{translate('DeleteSelectedIndexersMessageText', [indexers.length])}
{translate('DeleteSelectedIndexersMessageText', {
count: indexers.length,
})}
</div>
<ul>

View File

@@ -257,7 +257,7 @@ function EditIndexerModalContent(props: EditIndexerModalContentProps) {
<ModalFooter className={styles.modalFooter}>
<div className={styles.selected}>
{translate('CountIndexersSelected', [selectedCount])}
{translate('CountIndexersSelected', { count: selectedCount })}
</div>
<div>

View File

@@ -165,7 +165,7 @@ function IndexerIndexSelectFooter() {
</div>
<div className={styles.selected}>
{translate('CountIndexersSelected', [selectedCount])}
{translate('CountIndexersSelected', { count: selectedCount })}
</div>
<EditIndexerModal

View File

@@ -191,10 +191,10 @@ class SearchFooter extends Component {
icon = icons.SEARCH;
}
let footerLabel = searchIndexerIds.length === 0 ? translate('SearchAllIndexers') : translate('SearchCountIndexers', [searchIndexerIds.length]);
let footerLabel = searchIndexerIds.length === 0 ? translate('SearchAllIndexers') : translate('SearchCountIndexers', { count: searchIndexerIds.length });
if (isPopulated) {
footerLabel = selectedCount === 0 ? translate('FoundCountReleases', [itemCount]) : translate('SelectedCountOfCountReleases', [selectedCount, itemCount]);
footerLabel = selectedCount === 0 ? translate('FoundCountReleases', { itemCount }) : translate('SelectedCountOfCountReleases', { selectedCount, itemCount });
}
return (

View File

@@ -127,7 +127,7 @@ class Application extends Component {
isOpen={this.state.isDeleteApplicationModalOpen}
kind={kinds.DANGER}
title={translate('DeleteApplication')}
message={translate('DeleteApplicationMessageText', [name])}
message={translate('DeleteApplicationMessageText', { name })}
confirmLabel={translate('Delete')}
onConfirm={this.onConfirmDeleteApplication}
onCancel={this.onDeleteApplicationModalClose}

View File

@@ -114,7 +114,7 @@ function ManageApplicationsEditModalContent(
<ModalFooter className={styles.modalFooter}>
<div className={styles.selected}>
{translate('CountApplicationsSelected', [selectedCount])}
{translate('CountApplicationsSelected', { count: selectedCount })}
</div>
<div>

View File

@@ -268,9 +268,9 @@ function ManageApplicationsModalContent(
isOpen={isDeleteModalOpen}
kind={kinds.DANGER}
title={translate('DeleteSelectedApplications')}
message={translate('DeleteSelectedApplicationsMessageText', [
selectedIds.length,
])}
message={translate('DeleteSelectedApplicationsMessageText', {
count: selectedIds.length,
})}
confirmLabel={translate('Delete')}
onConfirm={onConfirmDelete}
onCancel={onDeleteModalClose}

View File

@@ -88,7 +88,7 @@ class Category extends Component {
message={
<div>
<div>
{translate('AreYouSureYouWantToDeleteCategory', [name])}
{translate('AreYouSureYouWantToDeleteCategory')}
</div>
</div>
}

View File

@@ -105,7 +105,7 @@ class DownloadClient extends Component {
isOpen={this.state.isDeleteDownloadClientModalOpen}
kind={kinds.DANGER}
title={translate('DeleteDownloadClient')}
message={translate('DeleteDownloadClientMessageText', [name])}
message={translate('DeleteDownloadClientMessageText', { name })}
confirmLabel={translate('Delete')}
onConfirm={this.onConfirmDeleteDownloadClient}
onCancel={this.onDeleteDownloadClientModalClose}

View File

@@ -129,7 +129,7 @@ function ManageDownloadClientsEditModalContent(
<ModalFooter className={styles.modalFooter}>
<div className={styles.selected}>
{translate('CountDownloadClientsSelected', [selectedCount])}
{translate('CountDownloadClientsSelected', { count: selectedCount })}
</div>
<div>

View File

@@ -226,9 +226,9 @@ function ManageDownloadClientsModalContent(
isOpen={isDeleteModalOpen}
kind={kinds.DANGER}
title={translate('DeleteSelectedDownloadClients')}
message={translate('DeleteSelectedDownloadClientsMessageText', [
selectedIds.length,
])}
message={translate('DeleteSelectedDownloadClientsMessageText', {
count: selectedIds.length,
})}
confirmLabel={translate('Delete')}
onConfirm={onConfirmDelete}
onCancel={onDeleteModalClose}

View File

@@ -122,7 +122,7 @@ class IndexerProxy extends Component {
isOpen={this.state.isDeleteIndexerProxyModalOpen}
kind={kinds.DANGER}
title={translate('DeleteIndexerProxy')}
message={translate('DeleteIndexerProxyMessageText', [name])}
message={translate('DeleteIndexerProxyMessageText', { name })}
confirmLabel={translate('Delete')}
onConfirm={this.onConfirmDeleteIndexerProxy}
onCancel={this.onDeleteIndexerProxyModalClose}

View File

@@ -137,7 +137,7 @@ class Notification extends Component {
isOpen={this.state.isDeleteNotificationModalOpen}
kind={kinds.DANGER}
title={translate('DeleteNotification')}
message={translate('DeleteNotificationMessageText', [name])}
message={translate('DeleteNotificationMessageText', { name })}
confirmLabel={translate('Delete')}
onConfirm={this.onConfirmDeleteNotification}
onCancel={this.onDeleteNotificationModalClose}

View File

@@ -130,7 +130,7 @@ class AppProfile extends Component {
isOpen={this.state.isDeleteAppProfileModalOpen}
kind={kinds.DANGER}
title={translate('DeleteAppProfile')}
message={translate('AppProfileDeleteConfirm', [name])}
message={translate('DeleteAppProfileMessageText', { name })}
confirmLabel={translate('Delete')}
isSpinning={isDeleting}
onConfirm={this.onConfirmDeleteAppProfile}

View File

@@ -137,7 +137,7 @@ class Tag extends Component {
isOpen={isDeleteTagModalOpen}
kind={kinds.DANGER}
title={translate('DeleteTag')}
message={translate('DeleteTagMessageText', [label])}
message={translate('DeleteTagMessageText', { label })}
confirmLabel={translate('Delete')}
onConfirm={this.onConfirmDeleteTag}
onCancel={this.onDeleteTagModalClose}

View File

@@ -147,7 +147,7 @@ class UISettings extends Component {
<FormInputGroup
type={inputTypes.SELECT}
name="theme"
helpText={translate('ThemeHelpText', ['Theme.Park'])}
helpText={translate('ThemeHelpText', { inspiredBy: 'Theme.Park' })}
values={themeOptions}
onChange={onInputChange}
{...settings.theme}

View File

@@ -138,7 +138,7 @@ class BackupRow extends Component {
isOpen={isConfirmDeleteModalOpen}
kind={kinds.DANGER}
title={translate('DeleteBackup')}
message={translate('DeleteBackupMessageText', [name])}
message={translate('DeleteBackupMessageText', { name })}
confirmLabel={translate('Delete')}
onConfirm={this.onConfirmDeletePress}
onCancel={this.onConfirmDeleteModalClose}

View File

@@ -114,7 +114,7 @@ class Updates extends Component {
/>
<div className={styles.message}>
{translate('TheLatestVersionIsAlreadyInstalled', ['Prowlarr'])}
{translate('TheLatestVersionIsAlreadyInstalled', { appName: 'Prowlarr' })}
</div>
{

View File

@@ -25,14 +25,19 @@ export async function fetchTranslations(): Promise<boolean> {
export default function translate(
key: string,
args?: (string | number | boolean)[]
tokens?: Record<string, string | number | boolean>
) {
const translation = translations[key] || key;
if (args) {
return translation.replace(/\{(\d+)\}/g, (match, index) => {
return String(args[index]) ?? match;
if (tokens) {
// Fallback to the old behaviour for translations not yet updated to use named tokens
Object.values(tokens).forEach((value, index) => {
tokens[index] = value;
});
return translation.replace(/\{([a-z0-9]+?)\}/gi, (match, tokenMatch) =>
String(tokens[tokenMatch] ?? match)
);
}
return translation;