Azure IoT Explorerを日本語化する

# TL;DR

結論としてはできてません。
日本語のリソースを読み込むところまではできているので、あとは英語から翻訳する必要があります。逆に言えば、翻訳さえできれば終わりということでもあります。

下記リポジトリを参照してください。

- [hydrangeas/azure-iot-explorer](https://github.com/hydrangeas/azure-iot-explorer/tree/develop)

# UIを変更する

## `src/app/settings/components/settingsPane.tsx`

UIといいつつ、まずは準備から。
データ（言語設定）の永続化先はlocal storageにします。

```typescript
    const [ darkTheme, setDarkTheme ] = React.useState<boolean>(false);
    // ↑ここまで同じ ↓ここから追加
    const userLanguage = JSON.parse(localStorage.getItem('userLanguage')) || 'en';
    const [ language, setLanguage ] = React.useState<string>(userLanguage);
    const { t, i18n } = useTranslation();
```

データが存在しなければ`'en'`を設定。
データが存在すれば、それを利用します。

```typescript
    React.useEffect(() => {
        const theme = localStorage.getItem(THEME_SELECTION);
        setDarkTheme(theme === Theme.dark || theme === Theme.highContrastBlack);
    },              [darkTheme]);
    // ↑第2引数の配列にdarkThemeを追加 ↓ここから追加
    React.useEffect(() => {
        i18n.changeLanguage(language);
        localStorage.setItem('userLanguage', JSON.stringify(language));
        // tslint:disable-next-line:no-console
        console.log(language);
    },              [language, i18n]);
```

darkThemeの設定は無条件に行われるようになっていたので、トグルボタンを操作したときだけ変更されるよう、第2引数を追加

言語設定については、変数が変化したときに、[i18next.changeLanguage](https://www.i18next.com/overview/api#changelanguage)を呼び出せるようにする。同時にlocal storageに保存する。（`console`は消し忘れた模様・・）

```typescript
    const toggleTheme = () => {
        const newDarkTheme = !darkTheme;
        setDarkTheme(newDarkTheme);
        updateTheme(newDarkTheme);
    };
    // ↑ここまでそのまま ↓ここから追加
    const handleChange = (newValue: React.SetStateAction<string>) => {
        setLanguage(newValue);
    };
```

```html
                <section aria-label={t(ResourceKeys.settings.theme.headerText)}>
                    <h3 role="heading" aria-level={1}>{t(ResourceKeys.settings.theme.headerText)}</h3>
                    <Toggle
                        onText={t(ResourceKeys.settings.theme.darkTheme)}
                        offText={t(ResourceKeys.settings.theme.lightTheme)}
                        onChange={toggleTheme}
                        checked={darkTheme}
                    />
                </section>
                <!-- ↑ここまでそのまま ↓ここから追加 -->
                <section aria-label="Language">
                    <h3 role="heading" aria-level={1}>Language</h3>
                    <select
                        value={language}
                        onChange={e => handleChange(e.target.value)}
                    >
                        <option key="en" value="en">English</option>
                        <option key="ja" value="ja">日本語</option>
                    </select>
                </section>
```

`onChange`に`setLanguage`を設定すると、なぜかエラーになる。なぜ？
なお、`onChange`にラムダ式を書くためには、`tslint.json`ファイル内で`"jsx-no-lambda": false,`となっていないとエラーになるので注意。

## `src/localization/resources.ts`

```typescript
/***********************************************************
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License
 **********************************************************/
const en = require('./locales/en.json'); // tslint:disable-line: no-var-requires
// ↓追加
const ja = require('./locales/ja.json'); // tslint:disable-line: no-var-requires

export interface AllowedLanguage {
    key: string;
    text: string;
}

export const ALLOWED_LANGUAGES: AllowedLanguage[] = [
    {
        key: 'en',
        text: 'English',
    },
    // ↓追加
    {
        key: 'ja',
        text: 'Japanese',
    },
];

const resources = {
    en: { translation: en },
    // ↓追加
    ja: { translation: ja },
};

export default resources;
```

日本語用のリソースを読み込めるように設定

## `src/localization/locales/ja.json`

`en.json`からコピーして作成。
`applicationName`がヘッダー部に表示されるので、とりあえずここだけ日本語化しておくと、確認に便利。

# 雑感

自習以外でちゃんとしたReactプロジェクトを触るのは初めてでしたが、Vueの知識も少しは生きましたし、なんとか無事にできてよかったなー、と。でも、もっとちゃんとReact勉強しなきゃだめだと反省しました。

日本語化のデータを作るのはそこそこ面倒そうなので、時間をかけて作ります。

今日はここまで。