feat: i18n supports

This commit is contained in:
GyDi
2022-03-12 23:07:45 +08:00
parent 9f171a01e8
commit 97254a1e3a
19 changed files with 254 additions and 60 deletions

View File

@@ -1,5 +1,7 @@
import i18next from "i18next";
import useSWR, { SWRConfig, useSWRConfig } from "swr";
import { useEffect, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Route, Routes } from "react-router-dom";
import { alpha, createTheme, List, Paper, ThemeProvider } from "@mui/material";
import { listen } from "@tauri-apps/api/event";
@@ -16,6 +18,7 @@ import UpdateButton from "../components/layout/update-button";
const isMacos = navigator.userAgent.includes("Mac OS X");
const Layout = () => {
const { t } = useTranslation();
const { mutate } = useSWRConfig();
const { data } = useSWR("getVergeConfig", getVergeConfig);
@@ -37,6 +40,12 @@ const Layout = () => {
});
}, []);
useEffect(() => {
if (data?.language) {
i18next.changeLanguage(data.language);
}
}, [data?.language]);
const theme = useMemo(() => {
// const background = mode === "light" ? "#f5f5f5" : "#000";
const selectColor = mode === "light" ? "#f5f5f5" : "#d5d5d5";
@@ -87,7 +96,7 @@ const Layout = () => {
<List className="the-menu" data-windrag>
{routers.map((router) => (
<LayoutItem key={router.label} to={router.link}>
{router.label}
{t(router.label)}
</LayoutItem>
))}
</List>

View File

@@ -6,27 +6,27 @@ import ConnectionsPage from "./connections";
export const routers = [
{
label: "Proxies",
label: "Label-Proxies",
link: "/",
ele: ProxiesPage,
},
{
label: "Profiles",
label: "Label-Profiles",
link: "/profile",
ele: ProfilesPage,
},
{
label: "Connections",
label: "Label-Connections",
link: "/connections",
ele: ConnectionsPage,
},
{
label: "Logs",
label: "Label-Logs",
link: "/logs",
ele: LogsPage,
},
{
label: "Settings",
label: "Label-Settings",
link: "/settings",
ele: SettingsPage,
},

View File

@@ -1,6 +1,7 @@
import { useEffect, useState } from "react";
import { Paper } from "@mui/material";
import { Virtuoso } from "react-virtuoso";
import { useTranslation } from "react-i18next";
import { ApiType } from "../services/types";
import { getInfomation } from "../services/api";
import BasePage from "../components/base/base-page";
@@ -8,6 +9,8 @@ import ConnectionItem from "../components/connection/connection-item";
const ConnectionsPage = () => {
const initConn = { uploadTotal: 0, downloadTotal: 0, connections: [] };
const { t } = useTranslation();
const [conn, setConn] = useState<ApiType.Connections>(initConn);
useEffect(() => {
@@ -27,7 +30,7 @@ const ConnectionsPage = () => {
}, []);
return (
<BasePage title="Connections" contentStyle={{ height: "100%" }}>
<BasePage title={t("Connections")} contentStyle={{ height: "100%" }}>
<Paper sx={{ boxShadow: 2, height: "100%" }}>
<Virtuoso
data={conn.connections}

View File

@@ -1,16 +1,18 @@
import { useRecoilState } from "recoil";
import { Button, Paper } from "@mui/material";
import { Virtuoso } from "react-virtuoso";
import { useTranslation } from "react-i18next";
import { atomLogData } from "../services/states";
import BasePage from "../components/base/base-page";
import LogItem from "../components/log/log-item";
const LogPage = () => {
const { t } = useTranslation();
const [logData, setLogData] = useRecoilState(atomLogData);
return (
<BasePage
title="Logs"
title={t("Logs")}
contentStyle={{ height: "100%" }}
header={
<Button
@@ -19,7 +21,7 @@ const LogPage = () => {
variant="contained"
onClick={() => setLogData([])}
>
Clear
{t("Clear")}
</Button>
}
>

View File

@@ -2,6 +2,7 @@ import useSWR, { useSWRConfig } from "swr";
import { useLockFn } from "ahooks";
import { useEffect, useMemo, useState } from "react";
import { Box, Button, Grid, TextField } from "@mui/material";
import { useTranslation } from "react-i18next";
import {
getProfiles,
patchProfile,
@@ -19,6 +20,7 @@ import ProfileItem from "../components/profile/profile-item";
import ProfileMore from "../components/profile/profile-more";
const ProfilePage = () => {
const { t } = useTranslation();
const { mutate } = useSWRConfig();
const [url, setUrl] = useState("");
@@ -175,12 +177,12 @@ const ProfilePage = () => {
});
return (
<BasePage title="Profiles">
<BasePage title={t("Profiles")}>
<Box sx={{ display: "flex", mb: 2.5 }}>
<TextField
id="clas_verge_profile_url"
name="profile_url"
label="Profile URL"
label={t("Profile URL")}
size="small"
fullWidth
value={url}
@@ -193,10 +195,10 @@ const ProfilePage = () => {
onClick={onImport}
sx={{ mr: 1 }}
>
Import
{t("Import")}
</Button>
<Button variant="contained" onClick={() => setDialogOpen(true)}>
New
{t("New")}
</Button>
</Box>

View File

@@ -1,6 +1,7 @@
import useSWR, { useSWRConfig } from "swr";
import { useEffect } from "react";
import { useLockFn } from "ahooks";
import { useTranslation } from "react-i18next";
import { Button, ButtonGroup, List, Paper } from "@mui/material";
import { getClashConfig, updateConfigs } from "../services/api";
import { patchClashConfig } from "../services/cmds";
@@ -10,6 +11,7 @@ import ProxyGroup from "../components/proxy/proxy-group";
import ProxyGlobal from "../components/proxy/proxy-global";
const ProxyPage = () => {
const { t } = useTranslation();
const { mutate } = useSWRConfig();
const { data: proxiesData } = useSWR("getProxies", getProxies);
const { data: clashConfig } = useSWR("getClashConfig", getClashConfig);
@@ -45,7 +47,7 @@ const ProxyPage = () => {
return (
<BasePage
contentStyle={pageStyle}
title={showGroup ? "Proxy Groups" : "Proxies"}
title={showGroup ? t("Proxy Groups") : t("Proxies")}
header={
<ButtonGroup size="small">
{modeList.map((mode) => (
@@ -55,7 +57,7 @@ const ProxyPage = () => {
onClick={() => onChangeMode(mode)}
sx={{ textTransform: "capitalize" }}
>
{mode}
{t(mode)}
</Button>
))}
</ButtonGroup>

View File

@@ -1,4 +1,5 @@
import { Paper } from "@mui/material";
import { useTranslation } from "react-i18next";
import Notice from "../components/base/base-notice";
import BasePage from "../components/base/base-page";
import SettingVerge from "../components/setting/setting-verge";
@@ -6,12 +7,14 @@ import SettingClash from "../components/setting/setting-clash";
import SettingSystem from "../components/setting/setting-system";
const SettingPage = () => {
const onError = (error: any) => {
error && Notice.error(error.toString());
const { t } = useTranslation();
const onError = (err: any) => {
Notice.error(err?.message || err.toString());
};
return (
<BasePage title="Settings">
<BasePage title={t("Settings")}>
<Paper sx={{ borderRadius: 1, boxShadow: 2, mb: 3 }}>
<SettingClash onError={onError} />
</Paper>