Skip to content

i18n: count labels use fixed plural forms — retention durations ("%llu days/hours/…") and "%d members" / "%d attachments" render "1 members" and bypass plural rules #593

Description

@erskingardner

Severity

LOW (i18n grammar; wrong for n==1 in English and for the multiple plural categories in Russian/Turkish/Polish/etc.)

Summary

Several user-facing count labels are formatted with a single fixed plural noun via String(format:) rather than a plural rule. They render "1 members" for a one-element group and cannot produce the correct few/many forms in inflected languages, and are un-reorderable for translators. This is the same class as #504 ("N members added") but on strings that #504 does not cover; #533 only fixed the format-specifier width on these strings (%dCInt/CUnsignedLongLong), not their plural grammar.

Location / Evidence

  • Retention/disappearing-timer durations — whitenoise-mac/Core/MarmotMapping.swift:711,714,717,719 (retentionDurationLabel): "%llu days" / "%llu hours" / "%llu minutes" / "%llu seconds". Only the exact 1 second/minute/hour/day/week/month values are special-cased; every other value routes to a hard-coded plural noun.
  • Custom disappearing option — whitenoise-mac/Views/GroupViews.swift:789: "%llu seconds".
  • Group member count — whitenoise-mac/Models/MessengerModels.swift:237 (memberCountLabel): "%d members" → renders "1 members" for a single-member group (rendered in GroupViews.swift:49).
  • Attachment count — whitenoise-mac/Models/MessengerModels.swift:337: "%d attachments".
  • Compose flow — whitenoise-mac/Views/ComposeFlowViews.swift:228 and :331: "%d members" → "1 members" for a 2-person group (yourself + one invitee).

Failure scenario

  • A 25-second timer renders "25 seconds"; in Russian this must distinguish "22 секунды" (few) vs "25 секунд" (many), impossible from one "%llu seconds" form.
  • A single-member group renders "1 members"; a one-invitee compose flow footer renders "1 members".

Why this is not a duplicate

#504 is the plural rule for the distinct string "N members added"; #533 fixed only the %d/%llu specifier width on the count strings, leaving the plural grammar. No open/closed issue covers retentionDurationLabel, memberCountLabel, "%d attachments", or the compose-flow "%d members" plural forms.

Suggested fix

Move these count strings into Localizable.stringsdict with proper NSStringPluralRuleType variants (one entry per unit, plus members and attachments) and format via the plural key. A shared L10n.pluralString(_:count:) helper (mirroring whatever #504's fix introduces) can back all call sites; fold the special-cased 1 <unit> fast paths into the stringsdict one category.

Found during a full-codebase review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions