Skip to content

feat: localize bot menus for all !list-langs languages #27

Description

@daopunk

Summary

Bot command menus (!help, !translation, !transcription, !privacy, thread help, etc.) are currently English-only. We need a durable way to manage menu language so that every language in !list-langs can have a localized menu, with bot-text UI for users to pick that language.

Today translation content can target the full catalog in translate_lang.rs (ALL_LANGUAGES / !list-langs), but UI copy lives in menu_locale.rs as static English strings. Per-group preference plumbing still assumes a tiny MenuLanguage enum (en / es only) in menu_language.rs; the old !set-en / !set-es handlers are being removed / deferred while menus stay EN-only.

Goals

  1. Parity with !list-langs — For each supported translation language code, the bot should be able to render menus in that language (or a clear fallback policy if a translation is missing).
  2. Selectable via bot text — Users must be able to choose menu language through Signal commands / menu UI (not only env or operator config). Prefer something that scales beyond two hard-coded !set-xx commands (e.g. !set-lang <code>, a language picker menu, or selection from !list-langs).
  3. Any language works — Design should not hard-limit UI locales to a small enum; adding a new code to ALL_LANGUAGES should be the main gate for both translation and menu locale availability (or document an explicit subset + path to full coverage).
  4. Preserve mobile menu layout — Localized strings must keep the stacked command-list standard in docs/solutions/signal-mobile-menus.md (title / section / !cmd + indented description).

Scope (product surfaces)

At minimum, localize (or define fallback for):

  • Hub / role !help
  • Language Thread !help
  • !translation product menu (including auto-translate disabled variant)
  • !transcription / pairing messages
  • !privacy (both roles)
  • Any footer / confirmation copy tied to menu-language changes

Out of scope unless it falls out naturally: translating user message content (already handled by translation product paths).

Open design questions

  • Storage: Keep per-group preference (current GroupPreferencesStore shape) vs per-user preference for DMs / mixed groups?
  • Authoring: Hand-maintained static strings per locale vs generate/translate from a single EN source (quality, TEE/privacy, review process)?
  • Fallback: Missing key → English? Missing locale → English? Partial coverage OK for MVP?
  • Discovery UX: How does a non-English speaker find the language picker if the default menu is English?
  • Scaling commands: !set-en / !set-es does not scale to ~30 codes; what replaces it?

Acceptance criteria

  • Documented approach for menu i18n (structure, where strings live, how new !list-langs codes get menus).
  • Bot-text UI to list and select menu language among supported codes.
  • Selecting a language persists (group and/or user — decide in design) and subsequent menus render in that language.
  • Coverage strategy covers all ALL_LANGUAGES codes (full strings or explicit fallback) without requiring a new Rust enum variant per language.
  • Mobile stacked layout preserved for all localized command lists.
  • Tests for selection, persistence, and at least one non-English menu render path.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions