1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-11-29 22:48:10 +02:00

All: Add plural forms for notes, users, hours, minutes, days (#12171)

This commit is contained in:
Mihai Vasiliu
2025-04-29 15:54:09 +03:00
committed by GitHub
parent 27be923fe6
commit c785388c51
6 changed files with 19 additions and 18 deletions

View File

@@ -1,6 +1,6 @@
import BaseCommand from './base-command'; import BaseCommand from './base-command';
import app from './app'; import app from './app';
import { _ } from '@joplin/lib/locale'; import { _, _n } from '@joplin/lib/locale';
import Note from '@joplin/lib/models/Note'; import Note from '@joplin/lib/models/Note';
import BaseModel, { DeleteOptions } from '@joplin/lib/BaseModel'; import BaseModel, { DeleteOptions } from '@joplin/lib/BaseModel';
import { NoteEntity } from '@joplin/lib/services/database/types'; import { NoteEntity } from '@joplin/lib/services/database/types';
@@ -31,13 +31,13 @@ class Command extends BaseCommand {
let ok = true; let ok = true;
if (!force && notes.length > 1) { if (!force && notes.length > 1) {
ok = await this.prompt(_('%d notes match this pattern. Delete them?', notes.length), { booleanAnswerDefault: 'n' }); ok = await this.prompt(_n('%d note matches this pattern. Delete it?', '%d notes match this pattern. Delete them?', notes.length, notes.length), { booleanAnswerDefault: 'n' });
} }
const permanent = (args.options?.permanent === true) || notes.every(n => !!n.deleted_time); const permanent = (args.options?.permanent === true) || notes.every(n => !!n.deleted_time);
if (!force && permanent) { if (!force && permanent) {
const message = ( const message = (
notes.length === 1 ? _('This will permanently delete the note "%s". Continue?', notes[0].title) : _('%d notes will be permanently deleted. Continue?', notes.length) _n('%d note will be permanently deleted. Continue?', '%d notes will be permanently deleted. Continue?', notes.length, notes.length)
); );
ok = await this.prompt(message, { booleanAnswerDefault: 'n' }); ok = await this.prompt(message, { booleanAnswerDefault: 'n' });
} }

View File

@@ -564,7 +564,7 @@ class ScreenHeaderComponent extends PureComponent<ScreenHeaderProps, ScreenHeade
const folder = await Folder.load(folderId); const folder = await Folder.load(folderId);
const ok = noteIds.length > 1 ? await shim.showConfirmationDialog(_('Move %d notes to notebook "%s"?', noteIds.length, folder.title)) : true; const ok = noteIds.length > 1 ? await shim.showConfirmationDialog(_n('Move %d note to notebook "%s"?', 'Move %d notes to notebook "%s"?', noteIds.length, noteIds.length, folder.title)) : true;
if (!ok) return; if (!ok) return;
this.props.dispatch({ type: 'NOTE_SELECTION_END' }); this.props.dispatch({ type: 'NOTE_SELECTION_END' });

View File

@@ -13,7 +13,7 @@ import Resource from './Resource';
import syncDebugLog from '../services/synchronizer/syncDebugLog'; import syncDebugLog from '../services/synchronizer/syncDebugLog';
import { toFileProtocolPath, toForwardSlashes } from '../path-utils'; import { toFileProtocolPath, toForwardSlashes } from '../path-utils';
const { pregQuote, substrWithEllipsis } = require('../string-utils.js'); const { pregQuote, substrWithEllipsis } = require('../string-utils.js');
const { _ } = require('../locale'); const { _, _n } = require('../locale');
import { pull, removeElement, unique } from '../ArrayUtils'; import { pull, removeElement, unique } from '../ArrayUtils';
import { LoadOptions, SaveOptions } from './utils/types'; import { LoadOptions, SaveOptions } from './utils/types';
import ActionLogger from '../utils/ActionLogger'; import ActionLogger from '../utils/ActionLogger';
@@ -941,7 +941,7 @@ export default class Note extends BaseItem {
if (!note) return null; if (!note) return null;
msg = _('Permanently delete note "%s"?', substrWithEllipsis(note.title, 0, 32)); msg = _('Permanently delete note "%s"?', substrWithEllipsis(note.title, 0, 32));
} else { } else {
msg = _('Permanently delete these %d notes?', noteIds.length); msg = _n('Permanently delete this note?', 'Permanently delete these %d notes?', noteIds.length, noteIds.length);
} }
return msg; return msg;
} }

View File

@@ -1,6 +1,6 @@
import { rtrimSlashes } from '@joplin/utils/path'; import { rtrimSlashes } from '@joplin/utils/path';
import SyncTargetRegistry from '../../SyncTargetRegistry'; import SyncTargetRegistry from '../../SyncTargetRegistry';
import { _, defaultLocale, supportedLocalesToLanguages } from '../../locale'; import { _, _n, defaultLocale, supportedLocalesToLanguages } from '../../locale';
import shim from '../../shim'; import shim from '../../shim';
import time from '../../time'; import time from '../../time';
import type SettingType from '../Setting'; import type SettingType from '../Setting';
@@ -1276,12 +1276,12 @@ const builtInMetadata = (Setting: typeof SettingType) => {
options: () => { options: () => {
return { return {
0: _('Disabled'), 0: _('Disabled'),
300: _('%d minutes', 5), 300: _n('%d minute', '%d minutes', 5, 5),
600: _('%d minutes', 10), 600: _n('%d minute', '%d minutes', 10, 10),
1800: _('%d minutes', 30), 1800: _n('%d minute', '%d minutes', 30, 30),
3600: _('%d hour', 1), 3600: _n('%d hour', '%d hours', 1, 1),
43200: _('%d hours', 12), 43200: _n('%d hour', '%d hours', 12, 12),
86400: _('%d hours', 24), 86400: _n('%d hour', '%d hours', 24, 24),
}; };
}, },
storage: SettingStorage.File, storage: SettingStorage.File,
@@ -1535,7 +1535,7 @@ const builtInMetadata = (Setting: typeof SettingType) => {
maximum: 365 * 2, maximum: 365 * 2,
step: 1, step: 1,
unitLabel: (value: number = null) => { unitLabel: (value: number = null) => {
return value === null ? _('days') : _('%d days', value); return value === null ? _('days') : _n('%d day', '%d days', value, value);
}, },
label: () => _('Keep note history for'), label: () => _('Keep note history for'),
storage: SettingStorage.File, storage: SettingStorage.File,
@@ -1811,7 +1811,7 @@ const builtInMetadata = (Setting: typeof SettingType) => {
maximum: 300, maximum: 300,
step: 1, step: 1,
unitLabel: (value: number = null) => { unitLabel: (value: number = null) => {
return value === null ? _('days') : _('%d days', value); return value === null ? _('days') : _n('%d day', '%d days', value, value);
}, },
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
show: (settings: any) => settings['trash.autoDeletionEnabled'], show: (settings: any) => settings['trash.autoDeletionEnabled'],

View File

@@ -7,7 +7,7 @@ import BaseModel from '../BaseModel';
import DecryptionWorker from './DecryptionWorker'; import DecryptionWorker from './DecryptionWorker';
import ResourceFetcher from './ResourceFetcher'; import ResourceFetcher from './ResourceFetcher';
import Resource from '../models/Resource'; import Resource from '../models/Resource';
import { _ } from '../locale'; import { _, _n } from '../locale';
const { toTitleCase } = require('../string-utils.js'); const { toTitleCase } = require('../string-utils.js');
enum CanRetryType { enum CanRetryType {
@@ -374,7 +374,8 @@ export default class ReportService {
}); });
for (let i = 0; i < folders.length; i++) { for (let i = 0; i < folders.length; i++) {
section.body.push(_('%s: %d notes', folders[i].title, await Folder.noteCount(folders[i].id))); const noteCount = await Folder.noteCount(folders[i].id);
section.body.push(_n('%s: %d note', '%s: %d notes', noteCount, folders[i].title, noteCount));
} }
sections.push(section); sections.push(section);

View File

@@ -405,7 +405,7 @@ export function getPlans(stripeConfig: StripePublicConfig): Record<PlanName, Pla
featureLabelsOff: getFeatureLabelsByPlan(PlanName.Teams, false), featureLabelsOff: getFeatureLabelsByPlan(PlanName.Teams, false),
cfaLabel: _('Try it now'), cfaLabel: _('Try it now'),
cfaUrl: '', cfaUrl: '',
footnote: _('Per user. Minimum of %d users.', 2), footnote: _('Per user. Minimum of 2 users.'),
}, },
}; };
} }