Skip to content

Commit

Permalink
feat(i18n): add translations of titles (#750)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyrious authored Jun 18, 2021
1 parent 9ce795f commit 7ee2c13
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 85 deletions.
2 changes: 1 addition & 1 deletion desktop/renderer-app/src/AppRoutes/AppRouteContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ErrorPage } from "flat-components";
import React from "react";
import { RouteComponentProps } from "react-router-dom";
import { ErrorPage } from "flat-components";
import { ipcAsyncByMainWindow } from "../utils/ipc";

export interface AppRouteContainerProps {
Expand Down
67 changes: 29 additions & 38 deletions desktop/renderer-app/src/AppRoutes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,35 @@
import React from "react";
import React, { FC } from "react";
import { useTranslation } from "react-i18next";
import { HashRouter, Route, Switch } from "react-router-dom";
import { message } from "antd";
import { LastLocationProvider } from "react-router-last-location";
import { RouteConfig, routeConfig } from "../route-config";
import { AppRouteContainer } from "./AppRouteContainer";
import { I18nextProvider } from "react-i18next";
import { i18n } from "../utils/i18n";

export class AppRoutes extends React.Component {
public componentDidCatch(error: any): void {
void message.error(`网页加载发生错误:${error}`);
}

public render(): React.ReactElement {
return (
<HashRouter>
<I18nextProvider i18n={i18n}>
<LastLocationProvider watchOnlyPathname>
<Switch>
{Object.keys(routeConfig).map(((name: keyof RouteConfig) => {
const { path, component, title } = routeConfig[name];
return (
<Route
key={name}
exact={true}
path={path}
render={routeProps => (
<AppRouteContainer
Comp={component}
title={title}
routeProps={routeProps}
/>
)}
export const AppRoutes: FC = () => {
const { t } = useTranslation();
return (
<HashRouter>
<LastLocationProvider watchOnlyPathname>
<Switch>
{Object.keys(routeConfig).map(((name: keyof RouteConfig) => {
const { path, component, title } = routeConfig[name];
return (
<Route
key={name}
exact={true}
path={path}
render={routeProps => (
<AppRouteContainer
Comp={component}
title={t("title-" + title)}
routeProps={routeProps}
/>
);
}) as (name: string) => React.ReactElement)}
</Switch>
</LastLocationProvider>
</I18nextProvider>
</HashRouter>
);
}
}
)}
/>
);
}) as (name: string) => React.ReactElement)}
</Switch>
</LastLocationProvider>
</HashRouter>
);
};
44 changes: 22 additions & 22 deletions desktop/renderer-app/src/route-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,112 +50,112 @@ export enum RouteNameType {

export const routeConfig = {
[RouteNameType.SplashPage]: {
title: "Flat",
title: "SplashPage",
path: "/",
component: SplashPage,
},
[RouteNameType.LoginPage]: {
title: "Flat",
title: "LoginPage",
path: "/login/",
component: LoginPage,
},
[RouteNameType.HomePage]: {
title: "Flat",
title: "HomePage",
path: "/user/",
component: HomePage,
},
[RouteNameType.SmallClassPage]: {
title: "小班课",
title: "SmallClassPage",
path: "/classroom/SmallClass/:roomUUID/:ownerUUID/",
component: SmallClassPage,
},
[RouteNameType.OneToOnePage]: {
title: "一对一",
title: "OneToOnePage",
path: "/classroom/OneToOne/:roomUUID/:ownerUUID/",
component: OneToOnePage,
},
[RouteNameType.BigClassPage]: {
title: "大班课",
title: "BigClassPage",
path: "/classroom/BigClass/:roomUUID/:ownerUUID/",
component: BigClassPage,
},
[RouteNameType.RoomDetailPage]: {
title: "房间详情",
title: "RoomDetailPage",
path: "/user/room/:roomUUID/:periodicUUID?/",
component: RoomDetailPage,
},
[RouteNameType.UserScheduledPage]: {
title: "预定房间",
title: "UserScheduledPage",
path: "/user/scheduled/",
component: UserScheduledPage,
},
[RouteNameType.ScheduleRoomDetailPage]: {
title: "周期性房间详情",
title: "ScheduleRoomDetailPage",
path: "/user/scheduled/info/:periodicUUID",
component: ScheduleRoomDetailPage,
},
[RouteNameType.PeriodicRoomDetailPage]: {
title: "周期性房间详情",
title: "PeriodicRoomDetailPage",
path: "/user/periodic/info/:periodicUUID",
component: PeriodicRoomDetailPage,
},
[RouteNameType.ReplayPage]: {
title: "房间回放",
title: "ReplayPage",
path: "/replay/:roomType/:roomUUID/:ownerUUID/",
component: ReplayPage,
},
[RouteNameType.ModifyOrdinaryRoomPage]: {
title: "修改房间",
title: "ModifyOrdinaryRoomPage",
path: "/modify/:roomUUID/:periodicUUID?/",
component: ModifyOrdinaryRoomPage,
},
[RouteNameType.ModifyPeriodicRoomPage]: {
title: "修改周期性房间",
title: "ModifyPeriodicRoomPage",
path: "/modify/periodic/room/:periodicUUID/",
component: ModifyPeriodicRoomPage,
},
[RouteNameType.CloudStoragePage]: {
title: "Flat",
title: "CloudStoragePage",
path: "/pan/",
component: CloudStoragePage,
},
[RouteNameType.SystemCheckPage]: {
title: "系统检测",
title: "SystemCheckPage",
path: "/device/system/",
component: SystemCheckPage,
},
[RouteNameType.CameraCheckPage]: {
title: "摄像头检测",
title: "CameraCheckPage",
path: "/device/camera/",
component: CameraCheckPage,
},
[RouteNameType.SpeakerCheckPage]: {
title: "扬声器检测",
title: "SpeakerCheckPage",
path: "/device/speaker/",
component: SpeakerCheckPage,
},
[RouteNameType.MicrophoneCheckPage]: {
title: "麦克风检测",
title: "MicrophoneCheckPage",
path: "/device/microphone/",
component: MicrophoneCheckPage,
},
[RouteNameType.GeneralSettingPage]: {
title: "常规设置",
title: "GeneralSettingPage",
path: "/general-settings/",
component: GeneralSettingPage,
},
[RouteNameType.HotKeySettingPage]: {
title: "热键设置",
title: "HotKeySettingPage",
path: "/hotkey/",
component: HotKeySettingPage,
},
[RouteNameType.FeedbackPage]: {
title: "吐个槽",
title: "FeedbackPage",
path: "/feedback/",
component: FeedbackPage,
},
[RouteNameType.AboutPage]: {
title: "关于我们",
title: "AboutPage",
path: "/about/",
component: AboutPage,
},
Expand Down
73 changes: 55 additions & 18 deletions desktop/renderer-app/src/tasks/Init-ui.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,70 @@
import React from "react";
import ReactDOM from "react-dom";
import "flat-components/build/style.css";
import "../theme.less";

import { ConfigProvider } from "antd";
import enUS from "antd/lib/locale/en_US";
import zhCN from "antd/lib/locale/zh_CN";

import React, { useEffect, useMemo } from "react";
import ReactDOM from "react-dom";

import { I18nextProvider } from "react-i18next";
import { useUpdate } from "react-use";

import { i18n } from "../utils/i18n";
import { AppRoutes } from "../AppRoutes";
import { StoreProvider } from "../components/StoreProvider";

import "../theme.less";
import "flat-components/build/style.css";

/** configure right after import */
import { configure } from "mobx";
configure({
isolateGlobalState: true,
});

const initUI = (): void => {
ReactDOM.render(
<ConfigProvider
autoInsertSpaceInButton={false}
locale={zhCN}
// let popups scrolls with container parent
getPopupContainer={trigger => trigger?.parentElement || document.body}
>
<StoreProvider>
<AppRoutes />
</StoreProvider>
</ConfigProvider>,
document.getElementById("root") as HTMLElement,
const App: React.FC = () => {
const forceUpdate = useUpdate();

const antdLocale = useMemo(
() => (i18n.language.startsWith("zh") ? zhCN : enUS),
// eslint-disable-next-line react-hooks/exhaustive-deps
[i18n.language],
);

useEffect(() => {
const onLangChanged = (): void => {
forceUpdate();
};

i18n.on("languageChanged", onLangChanged);

return () => {
i18n.off("languageChanged", onLangChanged);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<I18nextProvider i18n={i18n}>
<ConfigProvider
autoInsertSpaceInButton={false}
locale={antdLocale}
// let popups scrolls with container parent
getPopupContainer={getPopupContainer}
>
<StoreProvider>
<AppRoutes />
</StoreProvider>
</ConfigProvider>
</I18nextProvider>
);
};

function getPopupContainer(trigger?: HTMLElement): HTMLElement {
return trigger?.parentElement || document.body;
}

const initUI = (): void => {
ReactDOM.render(<App />, document.getElementById("root"));
};

export default initUI;
24 changes: 23 additions & 1 deletion packages/flat-i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,27 @@
"new-version-tips": "Found a new version: {{version}}, please update to the latest version for a better product experience",
"update-failed-tips": "Update failed, please reopen the program",
"update-now": "Update immediately",
"version-updates": "New version update"
"version-updates": "New version update",
"title-SplashPage": "Flat",
"title-LoginPage": "Flat",
"title-HomePage": "Flat",
"title-SmallClassPage": "Small Class",
"title-OneToOnePage": "One To One",
"title-BigClassPage": "Big Class",
"title-RoomDetailPage": "Room Detail",
"title-UserScheduledPage": "Schedule Room",
"title-ScheduleRoomDetailPage": "Room Detail",
"title-PeriodicRoomDetailPage": "Room Detail",
"title-ReplayPage": "Replay",
"title-ModifyOrdinaryRoomPage": "Edit Room",
"title-ModifyPeriodicRoomPage": "Edit Periodic Room",
"title-CloudStoragePage": "Flat",
"title-SystemCheckPage": "System Check",
"title-CameraCheckPage": "Camera Check",
"title-SpeakerCheckPage": "Speaker Check",
"title-MicrophoneCheckPage": "Microphone Check",
"title-GeneralSettingPage": "General Settings",
"title-HotKeySettingPage": "HotKey Settings",
"title-FeedbackPage": "Feedback",
"title-AboutPage": "About"
}
24 changes: 23 additions & 1 deletion packages/flat-i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,27 @@
"downloading": "下载中",
"update-failed-tips": "更新失败,请重新打开程序",
"update-now": "立即更新",
"new-version-tips": "发现新版本:{{version}}, 请更新到最新版本获取更好的产品体验"
"new-version-tips": "发现新版本:{{version}}, 请更新到最新版本获取更好的产品体验",
"title-SplashPage": "Flat",
"title-LoginPage": "Flat",
"title-HomePage": "Flat",
"title-SmallClassPage": "小班课",
"title-OneToOnePage": "一对一",
"title-BigClassPage": "大班课",
"title-RoomDetailPage": "房间详情",
"title-UserScheduledPage": "预定房间",
"title-ScheduleRoomDetailPage": "周期性房间详情",
"title-PeriodicRoomDetailPage": "周期性房间详情",
"title-ReplayPage": "房间回放",
"title-ModifyOrdinaryRoomPage": "修改房间",
"title-ModifyPeriodicRoomPage": "修改周期性房间",
"title-CloudStoragePage": "Flat",
"title-SystemCheckPage": "系统检测",
"title-CameraCheckPage": "摄像头检测",
"title-SpeakerCheckPage": "扬声器检测",
"title-MicrophoneCheckPage": "麦克风检测",
"title-GeneralSettingPage": "常规设置",
"title-HotKeySettingPage": "热键设置",
"title-FeedbackPage": "吐个槽",
"title-AboutPage": "关于我们"
}
6 changes: 4 additions & 2 deletions web/flat-web/src/AppRoutes/AppRouteContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import loadable from "@loadable/component";
import React, { ComponentType, FC, useContext, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { RouteComponentProps } from "react-router-dom";
import { useIsomorphicLayoutEffect } from "react-use";
import { PageStoreContext } from "../components/StoreProvider";
Expand All @@ -20,17 +21,18 @@ export const AppRouteContainer: FC<AppRouteContainerProps> = ({
routeProps,
}) => {
const pageStore = useContext(PageStoreContext);
const { t } = useTranslation();

useIsomorphicLayoutEffect(() => {
pageStore.setName(name);
}, [name, pageStore]);

useEffect(() => {
document.title = title;
document.title = t("title-" + title);

// clear selection
window.getSelection()?.removeAllRanges();
}, [title]);
}, [t, title]);

return <AppRouteErrorBoundary Comp={loadable(Comp)} {...{ title, routeProps }} />;
};
Loading

0 comments on commit 7ee2c13

Please sign in to comment.