Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Locale-Specific Settings

What would be the best way to include locale-specific Settings pages in my app? I have an app which can display text in one of three languages (based on the user's locale) but my Settings page is in English only. I'd like to be able to display a language-specific settings page in my app. Can I have multiple .jsx files in the /settings folder, or can I embed script within a .jsx file to detect the locale and render the correct text? For example:

import { locale } from "user-settings";
let title = "";
switch (locale.language) {
case "en-GB":
title = "Demo";
break;
case "fr-FR":
title = "Manif";
break;
default:
title = "Demo";
}

function mySettings(props) {
return (
<Page>
<Section title={<Text bold align="center">${title}</Text>}>
<Toggle settingsKey="toggle" label="Toggle Switch" />
</Section>
</Page>
);
}

registerSettingsPage(mySettings);

Would this approach work?

Best Answer
0 Votes
16 REPLIES 16

I see you got some help on Discord with this. Can you share your solution with others? Thanks!

Best Answer
0 Votes

I'm very close to having this working - just working on getting the localized text to show in the Settings page. I'll share once I've done it.

Best Answer
0 Votes

I'm very interested in that.

What is the actual status of this? Could you solve this?

Best Answer
0 Votes

The strategy I used to do this (and there may be better ways of doing it) is as follows:

  1. In index.js for the companion app, I get the user's language from the user-settings API, then immediately save that in settingsStorage.
  2. In index.jsx for the settings page, I retrieve the stored language then I have a function that returns a JSON object containing the language-specific strings I need for my settings page, for example:

    let settings = getUIStrings(lang);

     

    function getUIStrings(lang) {

    switch(lang) {
        case "de-DE" :
          return { "text1": "Uhrformat"
                  , "text2": "Verwenden Sie 12-Stunden-Uhr"
                  , "text3": "Thema Wählen"
                 };
        case "en-GB" :
          return { "text1": "Time Format"
                  , "text2": "Use 12-hour time"
                  , "text3": "Choose Theme"
                 };
    }

  3. The settings object can then be referenced within the page as follows:

    function mySettings(props) {
      return (
        <Page>

          <Section
            title={<Text bold align="left">{settings.text1}</Text>}>
            <Toggle
              label={settings.text2}
              settingsKey="format"
            />
          </Section>

      </Page>
    );
    }

Best Answer

Thanks a lot for your reply.

I just got to the same, that you have to do that via a setting given by the companion section.

Strange enough, my method works fine with emulator and side loaded at the Ionic, but the released version downloaded via Fitbit app doesn't work.

Best Answer
0 Votes

I haven't tried this, but a variation might be to do the equivalent of getUIStrings() in companion/index.js, and save each of the translated strings into a separate setting. This would simplify index.jsx.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

@Gondwana Thanks for that. Yes I need to do some refactoring and take the function out of index.jsx and put it into index.js. I’ve got some a couple of bugs I need to iron out at the same time.

@ppsberlin Make sure you have default values for the text in your settings page in case the user’s locale doesn’t match one of your cases. Also be aware that on the phone the language is returned with an underscore and not a hyphen e.g. “de_DE” and not “de-DE” which is different to how it behaves on the watch (in OS v1 anyway).

Best Answer

@CoulterJameswrote:
... Also be aware that on the phone the language is returned with an underscore and not a hyphen e.g. “de_DE” and not “de-DE” which is different to how it behaves on the watch (in OS v1 anyway).

That's the reason I use this to simplify that matter:

import { locale } from "user-settings";
var sprache = locale.language; 
if (sprache.indexOf("de") != -1) {

 

Best Answer
0 Votes

@CoulterJames wrote:

The strategy I used to do this (and there may be better ways of doing it) is as follows:

  1. In index.js for the companion app, I get the user's language from the user-settings API, then immediately save that in settingsStorage.

Thanks for this instruction! ..but how can I store variables in the settingsStorage?

 

Capitano

Best Answer
0 Votes

@Capitanoin the companion app, you need to put a reference to the settingsStorage API at the top of your index.js file:

import { settingsStorage } from "settings";

Then when you want to save something in settings, you use the .setItem method, like so:

settingsStorage.setItem("myKey", "myValue");

Then you can retrieve the value later using the .getItem method:

console.log(settingsStorage.getItem("myKey"));

Settings are stored as key-value pairs, so if you want to store the user's language for example, you might give it a key called "language":

settingsStorage.setItem("language", locale.language);

Then when you want to retrieve it later, you just supply the relevant key:

let lang = settingsStorage.getItem("language");

Look at the reference material at: https://dev.fitbit.com/build/reference/companion-api/settings/ for further details.

Best Answer
0 Votes

Thanks a lot for your quick answer! -

 

This works fine in the companion/index.js

 

But if I use

   let companionSprache = settingsStorage.getItem("companionSprache");

in the settings/index.jsx
I get an error:

  • [20:13:40]ReferenceError: settingsStorage is not defined
  • [20:13:40]Uncaught ReferenceError: settingsStorage is not defined

If I try to import the settingsStorage in the settings/index.jsx with

     import { settingsStorage } from "settings";

 

I get the error

   settings is imported by settings/index.js, but could not be resolved

 

Can you give me a further hint?

 

Best Answer
0 Votes

Got it now!

 

Thanks!

 

Capitano

Best Answer
0 Votes

Hi Capitano, 

how did you manage to get it work? I got the same error like you before 'settings is imported by settings/index.jsx, but could not be resolved'.

Can you please show us your index.jsx ?

 

Thanks in advance

Chris

Best Answer
0 Votes

settingsStorage is a property passed to your settings component, not an import. See for example: https://github.com/Fitbit/sdk-photo-picker/blob/master/settings/index.jsx#L2

Best Answer
0 Votes

Hi @FischerChris,

 

I don't need to import the settingsStorage in the settings/index.jsx. I just use

import { settingsStorage } from "settings";

in the companion\index.js

There I also fetch and store the language:

let sprache = locale.language.substr(0, 2); 
settingsStorage.setItem("companionSprache", sprache);

At least in the settings/index.jsx I read the language with:

function mySettings(props) {  
  companionSprache = props.settingsStorage.getItem("companionSprache");
  switch (companionSprache) {
    case "de": 
(...) break; default: (...) };

Hope that helps.

 

Regards

Capitano

 

Best Answer
0 Votes

Hi @Capitano

 

Thanks for your quick response. I will try your suggestion in a couple of days. 

 

Regards

Chris

Best Answer
0 Votes