chore: tooltips and locales

This commit is contained in:
dongchengjie 2024-06-26 05:33:06 +08:00
parent 709a23cf09
commit 1f422afe3d
21 changed files with 108 additions and 32 deletions

View File

@ -1,5 +1,6 @@
import { alpha, Box, Typography } from "@mui/material"; import { alpha, Box, Typography } from "@mui/material";
import { InboxRounded } from "@mui/icons-material"; import { InboxRounded } from "@mui/icons-material";
import { useTranslation } from "react-i18next";
interface Props { interface Props {
text?: React.ReactNode; text?: React.ReactNode;
@ -8,6 +9,7 @@ interface Props {
export const BaseEmpty = (props: Props) => { export const BaseEmpty = (props: Props) => {
const { text = "Empty", extra } = props; const { text = "Empty", extra } = props;
const { t } = useTranslation();
return ( return (
<Box <Box
@ -22,7 +24,7 @@ export const BaseEmpty = (props: Props) => {
})} })}
> >
<InboxRounded sx={{ fontSize: "4em" }} /> <InboxRounded sx={{ fontSize: "4em" }} />
<Typography sx={{ fontSize: "1.25em" }}>{text}</Typography> <Typography sx={{ fontSize: "1.25em" }}>{t(`${text}`)}</Typography>
{extra} {extra}
</Box> </Box>
); );

View File

@ -13,6 +13,7 @@ import { useVisibility } from "@/hooks/use-visibility";
import parseTraffic from "@/utils/parse-traffic"; import parseTraffic from "@/utils/parse-traffic";
import useSWRSubscription from "swr/subscription"; import useSWRSubscription from "swr/subscription";
import { createSockette } from "@/utils/websocket"; import { createSockette } from "@/utils/websocket";
import { useTranslation } from "react-i18next";
interface MemoryUsage { interface MemoryUsage {
inuse: number; inuse: number;
@ -21,6 +22,7 @@ interface MemoryUsage {
// setup the traffic // setup the traffic
export const LayoutTraffic = () => { export const LayoutTraffic = () => {
const { t } = useTranslation();
const { clashInfo } = useClashInfo(); const { clashInfo } = useClashInfo();
const { verge } = useVerge(); const { verge } = useVerge();
@ -115,7 +117,6 @@ export const LayoutTraffic = () => {
}; };
const valStyle: any = { const valStyle: any = {
component: "span", component: "span",
// color: "primary",
textAlign: "center", textAlign: "center",
sx: { flex: "1 1 56px", userSelect: "none" }, sx: { flex: "1 1 56px", userSelect: "none" },
}; };
@ -128,15 +129,23 @@ export const LayoutTraffic = () => {
}; };
return ( return (
<Box position="relative" onClick={trafficRef.current?.toggleStyle}> <Box position="relative">
{trafficGraph && pageVisible && ( {trafficGraph && pageVisible && (
<div style={{ width: "100%", height: 60, marginBottom: 6 }}> <div
style={{ width: "100%", height: 60, marginBottom: 6 }}
onClick={trafficRef.current?.toggleStyle}
>
<TrafficGraph ref={trafficRef} /> <TrafficGraph ref={trafficRef} />
</div> </div>
)} )}
<Box display="flex" flexDirection="column" gap={0.75}> <Box display="flex" flexDirection="column" gap={0.75}>
<Box display="flex" alignItems="center" whiteSpace="nowrap"> <Box
display="flex"
alignItems="center"
whiteSpace="nowrap"
title={t("Upload Speed")}
>
<ArrowUpward <ArrowUpward
{...iconStyle} {...iconStyle}
color={+up > 0 ? "secondary" : "disabled"} color={+up > 0 ? "secondary" : "disabled"}
@ -147,7 +156,12 @@ export const LayoutTraffic = () => {
<Typography {...unitStyle}>{upUnit}/s</Typography> <Typography {...unitStyle}>{upUnit}/s</Typography>
</Box> </Box>
<Box display="flex" alignItems="center" whiteSpace="nowrap"> <Box
display="flex"
alignItems="center"
whiteSpace="nowrap"
title={t("Download Speed")}
>
<ArrowDownward <ArrowDownward
{...iconStyle} {...iconStyle}
color={+down > 0 ? "primary" : "disabled"} color={+down > 0 ? "primary" : "disabled"}
@ -163,7 +177,7 @@ export const LayoutTraffic = () => {
display="flex" display="flex"
alignItems="center" alignItems="center"
whiteSpace="nowrap" whiteSpace="nowrap"
title="Memory Usage" title={t("Memory Usage")}
> >
<MemoryOutlined {...iconStyle} color="disabled" /> <MemoryOutlined {...iconStyle} color="disabled" />
<Typography {...valStyle}>{inuse}</Typography> <Typography {...valStyle}>{inuse}</Typography>

View File

@ -1,4 +1,4 @@
import { useEffect, useRef } from "react"; import { useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { import {
Button, Button,

View File

@ -171,10 +171,10 @@ export const EditorViewer = (props: Props) => {
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button onClick={onClose} variant={readOnly ? "contained" : "outlined"}> <Button onClick={onClose} variant="outlined">
{t("Cancel")} {t(readOnly ? "Close" : "Cancel")}
</Button> </Button>
{readOnly ? null : ( {!readOnly && (
<Button onClick={onSave} variant="contained"> <Button onClick={onSave} variant="contained">
{t("Save")} {t("Save")}
</Button> </Button>

View File

@ -61,7 +61,7 @@ export const LogViewer = (props: Props) => {
<DialogActions> <DialogActions>
<Button onClick={onClose} variant="outlined"> <Button onClick={onClose} variant="outlined">
{t("Back")} {t("Close")}
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>

View File

@ -94,7 +94,7 @@ export const ProviderButton = () => {
} }
contentSx={{ width: 400 }} contentSx={{ width: 400 }}
disableOk disableOk
cancelBtn={t("Cancel")} cancelBtn={t("Close")}
onClose={() => setOpen(false)} onClose={() => setOpen(false)}
onCancel={() => setOpen(false)} onCancel={() => setOpen(false)}
> >

View File

@ -14,12 +14,14 @@ import { BaseEmpty } from "../base";
import { useRenderList } from "./use-render-list"; import { useRenderList } from "./use-render-list";
import { ProxyRender } from "./proxy-render"; import { ProxyRender } from "./proxy-render";
import delayManager from "@/services/delay"; import delayManager from "@/services/delay";
import { useTranslation } from "react-i18next";
interface Props { interface Props {
mode: string; mode: string;
} }
export const ProxyGroups = (props: Props) => { export const ProxyGroups = (props: Props) => {
const { t } = useTranslation();
const { mode } = props; const { mode } = props;
const { renderList, onProxies, onHeadState } = useRenderList(mode); const { renderList, onProxies, onHeadState } = useRenderList(mode);
@ -116,7 +118,7 @@ export const ProxyGroups = (props: Props) => {
}; };
if (mode === "direct") { if (mode === "direct") {
return <BaseEmpty text="Direct Mode" />; return <BaseEmpty text={t("clash_mode_direct")} />;
} }
return ( return (

View File

@ -92,7 +92,7 @@ export const ProviderButton = () => {
} }
contentSx={{ width: 400 }} contentSx={{ width: 400 }}
disableOk disableOk
cancelBtn={t("Cancel")} cancelBtn={t("Close")}
onClose={() => setOpen(false)} onClose={() => setOpen(false)}
onCancel={() => setOpen(false)} onCancel={() => setOpen(false)}
> >

View File

@ -6,18 +6,22 @@ import { useVerge } from "@/hooks/use-verge";
import { useLockFn } from "ahooks"; import { useLockFn } from "ahooks";
import { LoadingButton } from "@mui/lab"; import { LoadingButton } from "@mui/lab";
import { SwitchAccessShortcut, RestartAlt } from "@mui/icons-material"; import { SwitchAccessShortcut, RestartAlt } from "@mui/icons-material";
import { Box, Button, List, ListItemButton, ListItemText } from "@mui/material"; import {
Box,
Button,
Chip,
List,
ListItemButton,
ListItemText,
} from "@mui/material";
import { changeClashCore, restartSidecar } from "@/services/cmds"; import { changeClashCore, restartSidecar } from "@/services/cmds";
import { closeAllConnections, upgradeCore } from "@/services/api"; import { closeAllConnections, upgradeCore } from "@/services/api";
import getSystem from "@/utils/get-system";
const VALID_CORE = [ const VALID_CORE = [
{ name: "Mihomo", core: "verge-mihomo" }, { name: "Mihomo", core: "verge-mihomo", chip: "Release Version" },
{ name: "Mihomo Alpha", core: "verge-mihomo-alpha" }, { name: "Mihomo Alpha", core: "verge-mihomo-alpha", chip: "Alpha Version" },
]; ];
const OS = getSystem();
export const ClashCoreViewer = forwardRef<DialogRef>((props, ref) => { export const ClashCoreViewer = forwardRef<DialogRef>((props, ref) => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -109,7 +113,7 @@ export const ClashCoreViewer = forwardRef<DialogRef>((props, ref) => {
marginTop: "-8px", marginTop: "-8px",
}} }}
disableOk disableOk
cancelBtn={t("Back")} cancelBtn={t("Close")}
onClose={() => setOpen(false)} onClose={() => setOpen(false)}
onCancel={() => setOpen(false)} onCancel={() => setOpen(false)}
> >
@ -121,6 +125,7 @@ export const ClashCoreViewer = forwardRef<DialogRef>((props, ref) => {
onClick={() => onCoreChange(each.core)} onClick={() => onCoreChange(each.core)}
> >
<ListItemText primary={each.name} secondary={`/${each.core}`} /> <ListItemText primary={each.name} secondary={`/${each.core}`} />
<Chip label={t(`${each.chip}`)} size="small" />
</ListItemButton> </ListItemButton>
))} ))}
</List> </List>

View File

@ -79,7 +79,7 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
title={t("Layout Setting")} title={t("Layout Setting")}
contentSx={{ width: 450 }} contentSx={{ width: 450 }}
disableOk disableOk
cancelBtn={t("Cancel")} cancelBtn={t("Close")}
onClose={() => setOpen(false)} onClose={() => setOpen(false)}
onCancel={() => setOpen(false)} onCancel={() => setOpen(false)}
> >

View File

@ -166,7 +166,10 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
</ListItem> </ListItem>
<ListItem sx={{ padding: "5px 2px" }}> <ListItem sx={{ padding: "5px 2px" }}>
<ListItemText primary={t("Proxy Guard")} /> <ListItemText
primary={t("Proxy Guard")}
sx={{ maxWidth: "fit-content" }}
/>
<Tooltip title={t("Proxy Guard Info")}> <Tooltip title={t("Proxy Guard Info")}>
<IconButton color="inherit" size="small"> <IconButton color="inherit" size="small">
<InfoRounded <InfoRounded
@ -180,6 +183,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
disabled={!enabled} disabled={!enabled}
checked={value.guard} checked={value.guard}
onChange={(_, e) => setValue((v) => ({ ...v, guard: e }))} onChange={(_, e) => setValue((v) => ({ ...v, guard: e }))}
sx={{ marginLeft: "auto" }}
/> />
</ListItem> </ListItem>

View File

@ -98,14 +98,13 @@ export const WebUIViewer = forwardRef<DialogRef>((props, ref) => {
overflowY: "auto", overflowY: "auto",
userSelect: "text", userSelect: "text",
}} }}
cancelBtn={t("Back")} cancelBtn={t("Close")}
disableOk disableOk
onClose={() => setOpen(false)} onClose={() => setOpen(false)}
onCancel={() => setOpen(false)} onCancel={() => setOpen(false)}
> >
{!editing && webUIList.length === 0 && ( {!editing && webUIList.length === 0 && (
<BaseEmpty <BaseEmpty
text="Empty"
extra={ extra={
<Typography mt={2} sx={{ fontSize: "12px" }}> <Typography mt={2} sx={{ fontSize: "12px" }}>
{t("Replace host, port, secret with %host, %port, %secret")} {t("Replace host, port, secret with %host, %port, %secret")}

View File

@ -9,7 +9,8 @@ import {
IconButton, IconButton,
Tooltip, Tooltip,
} from "@mui/material"; } from "@mui/material";
import { Settings, Shuffle } from "@mui/icons-material";
import { InfoRounded, Settings, Shuffle } from "@mui/icons-material";
import { DialogRef, Notice, Switch } from "@/components/base"; import { DialogRef, Notice, Switch } from "@/components/base";
import { useClash } from "@/hooks/use-clash"; import { useClash } from "@/hooks/use-clash";
import { GuardState } from "./mods/guard-state"; import { GuardState } from "./mods/guard-state";
@ -175,7 +176,22 @@ const SettingClash = ({ onError }: Props) => {
</SettingItem> </SettingItem>
{isWIN && ( {isWIN && (
<SettingItem onClick={invoke_uwp_tool} label={t("Open UWP tool")} /> <SettingItem
onClick={invoke_uwp_tool}
label={t("Open UWP tool")}
extra={
<>
<Tooltip title={t("Open UWP tool Info")} placement="top">
<IconButton color="inherit" size="small">
<InfoRounded
fontSize="inherit"
style={{ cursor: "pointer", opacity: 0.75 }}
/>
</IconButton>
</Tooltip>
</>
}
/>
)} )}
<SettingItem onClick={onUpdateGeo} label={t("Update GeoData")} /> <SettingItem onClick={onUpdateGeo} label={t("Update GeoData")} />

View File

@ -170,7 +170,21 @@ const SettingSystem = ({ onError }: Props) => {
</GuardState> </GuardState>
</SettingItem> </SettingItem>
<SettingItem label={t("Silent Start")}> <SettingItem
label={t("Silent Start")}
extra={
<>
<Tooltip title={t("Silent Start Info")} placement="top">
<IconButton color="inherit" size="small">
<InfoRounded
fontSize="inherit"
style={{ cursor: "pointer", opacity: 0.75 }}
/>
</IconButton>
</Tooltip>
</>
}
>
<GuardState <GuardState
value={enable_silent_start ?? false} value={enable_silent_start ?? false}
valueProps="checked" valueProps="checked"

View File

@ -6,6 +6,7 @@
"Close": "Close", "Close": "Close",
"Cancel": "Cancel", "Cancel": "Cancel",
"Confirm": "Confirm", "Confirm": "Confirm",
"Empty": "Empty",
"New": "New", "New": "New",
"Edit": "Edit", "Edit": "Edit",
@ -150,6 +151,7 @@
"PAC URL": "PAC URL: ", "PAC URL": "PAC URL: ",
"Auto Launch": "Auto Launch", "Auto Launch": "Auto Launch",
"Silent Start": "Silent Start", "Silent Start": "Silent Start",
"Silent Start Info": "Start the program in background mode without displaying the panel",
"Clash Setting": "Clash Setting", "Clash Setting": "Clash Setting",
"Allow Lan": "Allow Lan", "Allow Lan": "Allow Lan",
@ -167,9 +169,12 @@
"Clash Core": "Clash Core", "Clash Core": "Clash Core",
"Upgrade": "Upgrade", "Upgrade": "Upgrade",
"Restart": "Restart", "Restart": "Restart",
"Release Version": "Release Version",
"Alpha Version": "Alpha Version",
"Tun mode requires": "Tun mode requires", "Tun mode requires": "Tun mode requires",
"Grant": "Grant", "Grant": "Grant",
"Open UWP tool": "Open UWP tool", "Open UWP tool": "Open UWP tool",
"Open UWP tool Info": "Since Windows 8, UWP apps (such as Microsoft Store) are restricted from directly accessing local host network services, and this tool can be used to bypass this restriction",
"Update GeoData": "Update GeoData", "Update GeoData": "Update GeoData",
"Verge Setting": "Verge Setting", "Verge Setting": "Verge Setting",

View File

@ -6,6 +6,7 @@
"Close": "بستن", "Close": "بستن",
"Cancel": "لغو", "Cancel": "لغو",
"Confirm": "تأیید", "Confirm": "تأیید",
"Empty": "خالی خالی",
"New": "جدید", "New": "جدید",
"Edit": "ویرایش", "Edit": "ویرایش",
@ -150,6 +151,7 @@
"PAC URL": "PAC URL: ", "PAC URL": "PAC URL: ",
"Auto Launch": "راه‌اندازی خودکار", "Auto Launch": "راه‌اندازی خودکار",
"Silent Start": "شروع بی‌صدا", "Silent Start": "شروع بی‌صدا",
"Silent Start Info": "برنامه را در حالت پس‌زمینه بدون نمایش پانل اجرا کنید",
"Clash Setting": "تنظیمات Clash", "Clash Setting": "تنظیمات Clash",
"Allow Lan": "اجازه LAN", "Allow Lan": "اجازه LAN",
@ -167,9 +169,12 @@
"Clash Core": "هسته Clash", "Clash Core": "هسته Clash",
"Upgrade": "ارتقاء", "Upgrade": "ارتقاء",
"Restart": "راه‌اندازی مجدد", "Restart": "راه‌اندازی مجدد",
"Release Version": "نسخه نهایی",
"Alpha Version": "نسخه آلفا",
"Tun mode requires": "Tun mode نیاز دارد", "Tun mode requires": "Tun mode نیاز دارد",
"Grant": "اعطا", "Grant": "اعطا",
"Open UWP tool": "باز کردن ابزار UWP", "Open UWP tool": "باز کردن ابزار UWP",
"Open UWP tool Info": "از ویندوز 8 به بعد، برنامه‌های UWP (مانند Microsoft Store) از دسترسی مستقیم به خدمات شبکه محلی محدود شده‌اند و این ابزار می‌تواند برای دور زدن این محدودیت استفاده شود",
"Update GeoData": "به‌روزرسانی GeoData", "Update GeoData": "به‌روزرسانی GeoData",
"Verge Setting": "تنظیمات Verge", "Verge Setting": "تنظیمات Verge",

View File

@ -6,6 +6,7 @@
"Close": "Закрыть", "Close": "Закрыть",
"Cancel": "Отмена", "Cancel": "Отмена",
"Confirm": "Подтвердить", "Confirm": "Подтвердить",
"Empty": "Пусто",
"New": "Новый", "New": "Новый",
"Edit": "Редактировать", "Edit": "Редактировать",
@ -150,6 +151,7 @@
"PAC URL": "Адрес PAC: ", "PAC URL": "Адрес PAC: ",
"Auto Launch": "Автозапуск", "Auto Launch": "Автозапуск",
"Silent Start": "Тихий запуск", "Silent Start": "Тихий запуск",
"Silent Start Info": "Запускать программу в фоновом режиме без отображения панели",
"Clash Setting": "Настройки Clash", "Clash Setting": "Настройки Clash",
"Allow Lan": "Разрешить локальную сеть", "Allow Lan": "Разрешить локальную сеть",
@ -167,9 +169,12 @@
"Clash Core": "Ядра Clash", "Clash Core": "Ядра Clash",
"Upgrade": "Обновлять", "Upgrade": "Обновлять",
"Restart": "Перезапуск", "Restart": "Перезапуск",
"Release Version": "Официальная версия",
"Alpha Version": "Альфа-версия",
"Tun mode requires": "Требуется Режим туннеля", "Tun mode requires": "Требуется Режим туннеля",
"Grant": "Предоставить", "Grant": "Предоставить",
"Open UWP tool": "Открыть UWP инструмент", "Open UWP tool": "Открыть UWP инструмент",
"Open UWP tool Info": "С Windows 8 приложения UWP (такие как Microsoft Store) ограничены в прямом доступе к сетевым службам локального хоста, и этот инструмент позволяет обойти это ограничение",
"Update GeoData": "Обновление GeoData", "Update GeoData": "Обновление GeoData",
"Verge Setting": "Настройки Verge", "Verge Setting": "Настройки Verge",

View File

@ -6,6 +6,7 @@
"Close": "关闭", "Close": "关闭",
"Cancel": "取消", "Cancel": "取消",
"Confirm": "确认", "Confirm": "确认",
"Empty": "空空如也",
"New": "新建", "New": "新建",
"Edit": "编辑", "Edit": "编辑",
@ -150,6 +151,7 @@
"PAC URL": "PAC地址", "PAC URL": "PAC地址",
"Auto Launch": "开机自启", "Auto Launch": "开机自启",
"Silent Start": "静默启动", "Silent Start": "静默启动",
"Silent Start Info": "程序启动时以后台模式运行,不显示程序面板",
"Clash Setting": "Clash 设置", "Clash Setting": "Clash 设置",
"Allow Lan": "局域网连接", "Allow Lan": "局域网连接",
@ -167,9 +169,12 @@
"Clash Core": "Clash 内核", "Clash Core": "Clash 内核",
"Upgrade": "升级内核", "Upgrade": "升级内核",
"Restart": "重启内核", "Restart": "重启内核",
"Release Version": "正式版",
"Alpha Version": "内测版",
"Tun mode requires": "如需启用 Tun 模式需要授权", "Tun mode requires": "如需启用 Tun 模式需要授权",
"Grant": "授权", "Grant": "授权",
"Open UWP tool": "UWP 工具", "Open UWP tool": "UWP 工具",
"Open UWP tool Info": "Windows 8开始限制 UWP 应用(如微软商店)直接访问本地主机的网络服务,使用此工具可绕过该限制",
"Update GeoData": "更新 GeoData", "Update GeoData": "更新 GeoData",
"Verge Setting": "Verge 设置", "Verge Setting": "Verge 设置",

View File

@ -208,7 +208,7 @@ const ConnectionsPage = () => {
}} }}
> >
{filterConn.length === 0 ? ( {filterConn.length === 0 ? (
<BaseEmpty text="No Connections" /> <BaseEmpty />
) : isTableLayout ? ( ) : isTableLayout ? (
<ConnectionTable <ConnectionTable
connections={filterConn} connections={filterConn}

View File

@ -102,7 +102,7 @@ const LogPage = () => {
followOutput={"smooth"} followOutput={"smooth"}
/> />
) : ( ) : (
<BaseEmpty text="No Logs" /> <BaseEmpty />
)} )}
</Box> </Box>
</BasePage> </BasePage>

View File

@ -62,7 +62,7 @@ const RulesPage = () => {
followOutput={"smooth"} followOutput={"smooth"}
/> />
) : ( ) : (
<BaseEmpty text="No Rules" /> <BaseEmpty />
)} )}
</Box> </Box>
</BasePage> </BasePage>