Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicitly declare app language and support per-app language preferences #6634

Closed
wants to merge 4 commits into from

Conversation

auroursa
Copy link
Contributor

Based #6567

It seems that CFBundleLocalizations is not the only factor affecting iOS when providing a localized text input context menu. According to this documentation, we also need to create a Localization.strings file to list the supported languages for the app.

On Android, the system language settings determine the localized text input context menu, not by app’s declaration. But creating a language list file can enable per-app language preferences on Android.

By introducing this react-native-localization-settings package, we can generate the language list files for both Android and iOS, while it also performing additional tasks to compatibility with system APIs.

In the Chinese section of the language list, following up on #6621, I used the RFC 4646 standard, as both iOS and Android prefer it, and it also complies with IETF BCP 47.

This should fix #6162 again.

screenshot2024-11-22 19 24 32

@gaearon
Copy link
Contributor

gaearon commented Nov 22, 2024

Do we still need CFBundleLocalizations? It would be nice to reduce the duplication.

@auroursa
Copy link
Contributor Author

auroursa commented Nov 22, 2024

Do we still need CFBundleLocalizations? It would be nice to reduce the duplication.

We should no longer need to specify CFBundleLocalizations in app.config.js, as this package can handles language support lists for both Android and iOS.

If adding a new package is not desirable, I might need to update the current CFBundleLocalizations for Chinese, as iOS has stopped using the RFC 1766 standard since iOS 9.

@gaearon
Copy link
Contributor

gaearon commented Nov 22, 2024

We should no longer need to specify CFBundleLocalizations in app.config.js, as this package can handles language support lists for both Android and iOS.

Let's remove that config then.

@auroursa
Copy link
Contributor Author

We should no longer need to specify CFBundleLocalizations in app.config.js, as this package can handles language support lists for both Android and iOS.

Let's remove that config then.

Done.

@gaearon
Copy link
Contributor

gaearon commented Nov 22, 2024

seems like there are some bugs in that package jakex7/react-native-localization-settings#10

@auroursa
Copy link
Contributor Author

auroursa commented Nov 22, 2024

seems like there are some bugs in that package jakex7/react-native-localization-settings#10

It seems we won’t encounter this issue. Earlier when I reviewing the deviceLocales.ts code, I noticed that we have our own preferred app language logic defined in src/state/persisted/schema.ts. We don’t directly use this package’s language preference handling, only rely on it to generate the necessary language list files.

The language list file told to system which languages our app supports, enabling per-app language preferences. This allows users to set a specific language for each app without changing the system language. When calling getLocales().languageTag, we always get the language the user wants to switch to, and then switch accordingly based on schema.ts.

It somewhat replaces the app’s built-in display language switching feature but provides a more native language-switching experience for users. I can’t say for sure what Bluesky’s future plans are, so per-app language preferences simply offer a possibility.

Here’s a demonstration of per-app language preferences on Android. iOS also provides per-app language preferences feature in the system settings, with behavior identical to that on Android.

example.mp4

@auroursa
Copy link
Contributor Author

Here in src/state/persisted/schema.ts L148, I think we always get the first language in the user’s language list, so we shouldn’t encounter that issue.

Sorry about the incorrect line number earlier.

screenshot2024-11-23 00 07 20

@gaearon
Copy link
Contributor

gaearon commented Nov 22, 2024

Just to clarify, with this PR, does this mean both the system per-app setting and the in-app setting work? Which one takes precedence? It would help to know specific before/after behaviors.

@auroursa
Copy link
Contributor Author

auroursa commented Nov 22, 2024

Just to clarify, with this PR, does this mean both the system per-app setting and the in-app setting work? Which one takes precedence? It would help to know specific before/after behaviors.

Both are valid, depending on which was updated last.
Update: This is incorrect. The app tends to apply within app display language settings.

The system’s per-app language preferences only affect the value of getLocales().languageTag, we follow to change app language when only this value changes, it only happens when the user manually changes the app language in system settings, or when the system language is changed. User still can freely switch languages within the app.

@auroursa
Copy link
Contributor Author

I did some cross-checking today and here’s what I observed:

A. When the user has never manually switched the display language within app, the system’s per-app language preferences always works.

B. When the user has manually changed the display language within the app, the system’s per-app language preferences no longer apply, and only the within app display language setting takes effect.

It seems to be related to src/locale/i18n.ts, after the user manually changes the language within the app, a value appears to be written, and the app seems to prioritize reading that value. It only reads getLocales().languageTag when the value is empty (i.e., when the user has never manually changed the display language within app).

@gaearon
Copy link
Contributor

gaearon commented Nov 23, 2024

So it seems confusing to allow configuring in system preferences if those aren't always 1:1 in sync with the app, right? How do other apps solve this?

@auroursa
Copy link
Contributor Author

This is indeed confusing.

I looked into some other apps, and as you mentioned, apps typically only choose one method for language switching. For example, apps like X and Mastodon, which support the system’s per-app language preferences, they don’t include an in-app display language settings.

So yes, if the decision is to use the more native per-app language preferences, we should hide the in-app display language switch on native.

The pros and cons are quite clear, because the web still need display language settings, If we do this, we will be maintain two sets of app language lists. But it would provide a better experience for native users, such as enabling more refined language support.

Anyway, this is beyond the scope of this PR. I will close it and leave the idea here. Thank you so much for taking the time to work through this with me.

@auroursa auroursa closed this Nov 23, 2024
@auroursa auroursa deleted the localization-settings branch November 24, 2024 01:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Localizations for Context Menus in TextInput(Copy, Paste, AutoFill, etc) in CFBundleLocalizations for iOS
2 participants