Skip to content

Conversation

@Tug
Copy link
Contributor

@Tug Tug commented Feb 14, 2019

Requires wordpress-mobile/gutenberg-mobile#536

This PR adds a new property our react app will receive which will contain all the translations available for WPAndroid. The idea is to have translations in gutenberg-mobile available for the beta.

Testing Instructions

  • Checkout this branch locally (git fetch -a && git checkout add/i18n-cache) and make sure to update the submodules after that git submodule update --init --recursive
  • Remove this condition to test sending all the WPAndroid strings to gutenberg-mobile: https://github.com/wordpress-mobile/WordPress-Android/pull/9249/files#diff-02f567e707c1df878dfea548cfec3da7R151
  • In a terminal run cd libs/gutenberg-mobile && yarn install && yarn start:reset
  • Connect an android device or start a virtual device, then open another terminal, go to the WordPress-Android project root folder and run ./gradlew installWasabiDebug then adb shell am start -n "org.wordpress.android.beta/org.wordpress.android.ui.WPLaunchActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER (or boot the app with Android studio)
  • Make sure your app is in english
  • Open http://localhost:8081/debugger-ui/ on your computer and open the console in the devtools
  • Open a page or a post in the app
  • Look at the logs and check that the locale is en, and that translations is empty
  • Go to the user profile settings and switch to a different language (repeat the operation several times and test for languages with a regional code such as zh-cn or pt-br)
  • Open a page or a post
  • Look at the logs and check that the locale is correct (should be one of those https://github.com/wordpress-mobile/gutenberg-mobile/pull/536/files#diff-db716afdbf5160927b4465dba3e62535R8). For the locales for which we have a translation file in libs/gutenberg-mobile/i18n-cache/data/ you should see the translated strings.

@wpmobilebot
Copy link
Contributor

wpmobilebot commented Feb 14, 2019

2 Warnings
⚠️ PR is missing at least one label.
⚠️ PR is not assigned to a milestone.

Generated by 🚫 Danger

@peril-wordpress-mobile
Copy link

peril-wordpress-mobile bot commented Feb 19, 2019

Danger run resulted in 2 warnings; to find out more, see the checks page.

Generated by 🚫 dangerJS

@Tug Tug requested a review from hypest February 19, 2019 19:42
return mRetainedGutenbergContainerFragment;
}

public Bundle getTranslations() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a local method so we should change method access signature probably to private.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method name doesn't tell us enough information about what is the purpose of this method.
getTranslations() is too abstract I think ?

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
GutenbergContainerFragment gutenbergContainerFragment =
GutenbergContainerFragment.newInstance(isNewPost);
GutenbergContainerFragment.newInstance(isNewPost, localeSlug, this.getTranslations());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need for this in this.getTranslations()so we can remove it.

@marecar3
Copy link
Contributor

marecar3 commented Feb 19, 2019

Hey @Tug @hypest , I must admit that I am not 100% sure what should method getTranslations()return to us.

When I see the log, there is a bunch of strings that are not label related, e.g. SVG Path, fonts names, and also class names android.support.design.widget.AppBarLayout$ScrollingViewBehavior which is odd?

Please take a look at the file.

getTranslations.txt


public Bundle getTranslations() {
Bundle translations = new Bundle();
Locale defaultLocale = new Locale("en");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will always return English translation, is that idea?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The english locale yes, the idea is for getTranslations to return a mapping of english string => [ translated string ] so we feed it to the @wordpress/i18n lib.

try {
resourceId = stringField.getInt(R.string.class);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in Android it's always better to Log the error and not print stack trace so that we can easily find and see what is the error about.

@Tug
Copy link
Contributor Author

Tug commented Feb 20, 2019

When I see the log, there is a bunch of strings that are not label related, e.g. SVG Path, fonts names, and also class names android.support.design.widget.AppBarLayout$ScrollingViewBehavior which is odd?

It's not that odd given that we extract all the strings from R.string. It might not be the right approach so I'm open to alternatives.
I just added a filter to check for the prefix gutenberg_mobile_ before adding it to translations. Should limit the size of the object as well

@marecar3
Copy link
Contributor

marecar3 commented Feb 20, 2019

Hey @Tug, I have managed to get the strings from the main application. This is the example approach:

String packageName = getActivity().getApplication().getPackageName();
int gutenbergMobileTestStringId = getResources().getIdentifier("gutenberg_mobile_gutenberg_packages_block_library_src_paragraph_edit_native_js_115", "string", packageName);

String gutenbergMobileTestString = getResources().getString(gutenbergMobileTestStringId);

Probably you will notice that you will need to know the exact name of each string, so maybe you can define those names in WordPressEditor/srd/main/res/values/ids.xml. (it's not the best approach as we would need to maintain string names on two places...)

Let me know if you need any further help regarding this one.

return translations;
}

for (Field stringField : R_String.getDeclaredFields()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm interesting, I don't like hacky solutions generally 🙂
as it can just to stop working at some API levels.
Did you test it with different Android API levels?

Copy link
Contributor Author

@Tug Tug Feb 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it's hacky, especially the part where it assumes that the R class is in the same package as the main Application class.
I'm not sure what you mean by different Android API levels though so I guess I didn't test that.
In theory I think we would need to go get the strings as an argument from the main app instead of trying to access a package we should not have to be aware of here.
It's starting to become a lot of changes for this "temporary" i18n solution though...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding Android API I am thinking to try this code with some devices that have Lollipop, Marshmallow... Nougat,,, and especially EMUI (Huawei) installed.


DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
configuration.locale = defaultLocale;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused by this line... should we assign the desired locale here? Like, the same as the one passed down the the RN app? Instead, this line seems to again assign en 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nop this is required to get the default (english) resources. We'll need both the current resource which is whatever the app is set to at the moment and the english ones to generate our english => [ translated ] map

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, right. Yeah, I guess it would be useful if we add some line comments to describe what's going on in the various code paragraphs of this method.

// Show the GB informative dialog on editing GB posts
showGutenbergInformativeDialog();
return GutenbergEditorFragment.newInstance("", "", mIsNewPost);
String languageString = LocaleManager.getLanguage(EditPostActivity.this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, let's see, is there some specific reason we're using LocaleManager.getLanguage() here (which gets the device language) but we use Configuration.locale later in getTranslations() (which get's the current app locale)?

Unfortunately, the device and app locales can be out of sync unless the app is restarted so, this ends up having, for example, English UI (see top bar) but Spanish content strings (see the title placeholder):
screenshot-1550760388652

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Locale.getLanguage(context) will only return the device language if no custom app-level language is set in SharedPreferences.

return prefs.getString(LANGUAGE_KEY, LanguageUtils.getCurrentDeviceLanguageCode());

Bundle translations = new Bundle();
Locale defaultLocale = new Locale("en");
Resources currentResources = getResources();
Configuration configuration = currentResources.getConfiguration();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, but not it makes debugging this method easier: Let's rename this variable to currentConfiguration instead of just configuration and then at line 128 let's create a new one instead of reassigning the old one. Thanks!

@hypest
Copy link
Contributor

hypest commented Feb 21, 2019

Tested the PR at this stage by manually adding some gutenberg-mobile strings in the Spanish strings.xml file and verified that they get loaded in the RN app.

I think this PR is good to go.

Copy link
Contributor

@hypest hypest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@hypest
Copy link
Contributor

hypest commented Feb 21, 2019

@Tug , can you make a note to address any remaining review feedback in a follow a PR? Thanks!

@hypest
Copy link
Contributor

hypest commented Feb 21, 2019

Let's wait for the gutenberg-mobile PR to merge and update its hash here, then we can merge.

@hypest hypest merged commit 73f0497 into develop Feb 21, 2019
@hypest hypest deleted the update/send-gutenberg-translations branch February 21, 2019 21:58
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.

6 participants