Skip to content

Disambiguate "Dismiss" localizations #19028

Description

@mokagio

Problem

While smoke testing version 20.2, sharp eyed @tiagomar noticed an issue. In the QR code login screen, the English copy for the message and button are "Tap dismiss and..." and "Dismiss" respectively, but the Italian translation was inconsistent:

image

This happened because there is no clear relationship between the "Dismiss" used in the message and the one used in the button, so it's up to the translator or translators that happened to pick up the string to use the translation they think makes more sense given the limited context provided by the developer comment.

To make matter worse, we have 20 usages of the "Dismiss" across the app:

/* Accessibility label for button to dismiss a bottom sheet
Accessibility label for the transparent space above the login dialog which acts as a button to dismiss the dialog.
Accessibility label for the transparent space above the signup dialog which acts as a button to dismiss the dialog.
Action shown in a bottom notice to dismiss it.
Action to show on alert when view asset fails.
Button label that dismisses the qr log in flow and returns the user back to the previous screen
Customize Insights button title
Dismiss a view. Verb
Dismiss button title
Dismiss button title.
Dismiss the AlertView
Share extension error dialog cancel button label.
Spoken accessibility label
The title of a button to close the classic editor deprecation notice alert dialog.
Title for button that will dismiss the Grow Your Audience card.
User action to dismiss featured media options.
User action to dismiss media options.
Verb. Button title. Tapping dismisses a prmopt.
Verb. Dismisses the blogging prompt notification.
Verb. User action to dismiss error alert when failing to load media item. */
"Dismiss" = "Dismiss";

While "Dismiss" might work in English in all those instances, we cannot assume whichever translation "Dismiss" happens to have in one locale is appropriate in all the instances for that locale as well. As a matter of fact, that is exactly the case for the Italian locale, where "Dismiss" got translated to "Respinto" ("Reject"), but then translated to "Ignora" ("Ignore") in the context of the "Tap dismiss and..." copy for the QR code screen.

Proposed Solution

We need to disambiguate between the various context in which "Dismiss" is used.

One option would be to use replace each NSLocalizedString("Dismiss", "...") definition with ones using reverse DNS notation for the key, e.g. NSLocalizedString("qr_code_login.verify_authorization.dismiss_button", "..."). This approach would result in dedicated entries for each "Dismiss" usage and should give translators more flexibility.

This approach (kudos @AliSoftware for making it happen) is already in use, for example in StatSection.swift:

return NSLocalizedString("stats.insights.mostPopularCard.title", value: "🔥 Most Popular Time", comment: "Insights 'Most Popular Time' header. Fire emoji should remain part of the string.")

If we had this setup in place at the time of the issue described above, we could have fixed the translation for the button and message in the QR code screen to be in line and consistent, that is with a better Italian translation that actually signifies dismiss, like "Dismetti". Instead, we had to edit the message translation to use "Respinto" because we couldn't risk changing the button translation as it was used in 19 other screens.

And alternative to ensure consistency, albeit without extra flexibility, would be to use string interpolation:

static let subtitle = NSLocalizedString(
  "Tap %@ and head back to your web browser to continue.", 
  comment: "Subtitle instructing the user to tap the dismiss button to leave the log in flow. %@ is a placeholder for the dismiss button name"
)
 
static let confirmButton = NSLocalizedString(
  "Dismiss",
  comment: "Button label that dismisses the qr log in flow and returns the user back to the previous screen"
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions