Merge remote-tracking branch 'nyanpasu/main'

This commit is contained in:
wonfen
2023-11-22 06:48:30 +08:00
78 changed files with 4361 additions and 2559 deletions

View File

@@ -4,14 +4,15 @@ import relativeTime from "dayjs/plugin/relativeTime";
import { SWRConfig, mutate } from "swr";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { Route, Routes } from "react-router-dom";
import { Route, Routes, useLocation } from "react-router-dom";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import { alpha, List, Paper, ThemeProvider } from "@mui/material";
import { listen } from "@tauri-apps/api/event";
import { appWindow } from "@tauri-apps/api/window";
import { routers } from "./_routers";
import { getAxios } from "@/services/api";
import { useVerge } from "@/hooks/use-verge";
import { ReactComponent as LogoSvg } from "@/assets/image/logo.svg";
import LogoSvg from "@/assets/image/logo.svg?react";
import { BaseErrorBoundary, Notice } from "@/components/base";
import { LayoutItem } from "@/components/layout/layout-item";
import { LayoutControl } from "@/components/layout/layout-control";
@@ -34,6 +35,8 @@ const Layout = () => {
const { verge } = useVerge();
const { theme_blur, language } = verge || {};
const location = useLocation();
useEffect(() => {
window.addEventListener("keydown", (e) => {
// macOS有cmd+w
@@ -136,21 +139,27 @@ const Layout = () => {
</div>
)}
<div className="the-content">
<Routes>
{routers.map(({ label, link, ele: Ele }) => (
<Route
key={label}
path={link}
element={
<BaseErrorBoundary key={label}>
<Ele />
</BaseErrorBoundary>
}
/>
))}
</Routes>
</div>
<TransitionGroup className="the-content">
<CSSTransition
key={location.pathname}
timeout={300}
classNames="page"
>
<Routes>
{routers.map(({ label, link, ele: Ele }) => (
<Route
key={label}
path={link}
element={
<BaseErrorBoundary key={label}>
<Ele />
</BaseErrorBoundary>
}
/>
))}
</Routes>
</CSSTransition>
</TransitionGroup>
</div>
</Paper>
</ThemeProvider>

View File

@@ -1,9 +1,9 @@
// default theme setting
export const defaultTheme = {
primary_color: "#5b5c9d",
secondary_color: "#9c27b0",
primary_text: "#637381",
secondary_text: "#909399",
primary_color: "#1867c0",
secondary_color: "#3a88bb",
primary_text: "#1d1d1f",
secondary_text: "#424245",
info_color: "#0288d1",
error_color: "#d32f2f",
warning_color: "#ed6c02",
@@ -14,6 +14,6 @@ export const defaultTheme = {
// dark mode
export const defaultDarkTheme = {
...defaultTheme,
primary_text: "#757575",
secondary_text: "#637381",
primary_text: "#E8E8ED",
secondary_text: "#bbbbbb",
};

View File

@@ -3,16 +3,24 @@ import { useLockFn } from "ahooks";
import {
Box,
Button,
Grid,
IconButton,
MenuItem,
Paper,
Select,
TextField,
Typography,
} from "@mui/material";
import { useRecoilState } from "recoil";
import { Virtuoso } from "react-virtuoso";
import { useTranslation } from "react-i18next";
import { TableChartRounded, TableRowsRounded } from "@mui/icons-material";
import {
ArrowDownward,
ArrowUpward,
Link,
TableChartRounded,
TableRowsRounded,
} from "@mui/icons-material";
import { closeAllConnections } from "@/services/api";
import { atomConnectionSetting } from "@/services/states";
import { useClashInfo } from "@/hooks/use-clash";
@@ -24,6 +32,7 @@ import {
ConnectionDetail,
ConnectionDetailRef,
} from "@/components/connection/connection-detail";
import parseTraffic from "@/utils/parse-traffic";
const initConn = { uploadTotal: 0, downloadTotal: 0, connections: [] };
@@ -48,6 +57,10 @@ const ConnectionsPage = () => {
list.sort((a, b) => b.curDownload! - a.curDownload!),
};
const uploadTotal = connData.uploadTotal;
const downloadTotal = connData.downloadTotal;
const filterConn = useMemo(() => {
const orderFunc = orderOpts[curOrderOpt];
const connections = connData.connections.filter((conn) =>
@@ -112,6 +125,24 @@ const ConnectionsPage = () => {
const detailRef = useRef<ConnectionDetailRef>(null!);
const connectionItems = [
{
icon: <ArrowUpward />,
label: t("Upload Total"),
value: parseTraffic(uploadTotal).join(" "),
},
{
icon: <ArrowDownward />,
label: t("Download Total"),
value: parseTraffic(downloadTotal).join(" "),
},
{
icon: <Link />,
label: t("Active Connections"),
value: filterConn.length,
},
];
return (
<BasePage
title={t("Connections")}
@@ -142,7 +173,21 @@ const ConnectionsPage = () => {
</Box>
}
>
<Paper sx={{ boxShadow: 2, height: "100%" }}>
<Paper sx={{ padding: 2, mb: 2 }}>
<Grid container>
{connectionItems.map((item, index) => (
<Grid item xs={4} key={index}>
<Box display="flex" alignItems="center" whiteSpace="nowrap">
{item.icon}
<Typography sx={{ ml: 1, mr: 1 }}>{item.label}</Typography>
<Typography>{item.value}</Typography>
</Box>
</Grid>
))}
</Grid>
</Paper>
<Paper sx={{ boxShadow: 2, height: "calc(100% - 56px - 16px)" }}>
<Box
sx={{
pt: 1,

View File

@@ -3,6 +3,7 @@ import { useMemo, useRef, useState } from "react";
import { useLockFn } from "ahooks";
import { useSetRecoilState } from "recoil";
import { Box, Button, Grid, IconButton, Stack, TextField } from "@mui/material";
import { LoadingButton } from "@mui/lab";
import {
ClearRounded,
ContentCopyRounded,
@@ -38,6 +39,7 @@ const ProfilePage = () => {
const [url, setUrl] = useState("");
const [disabled, setDisabled] = useState(false);
const [activating, setActivating] = useState("");
const [loading, setLoading] = useState(false);
const {
profiles = {},
@@ -76,12 +78,13 @@ const ProfilePage = () => {
const onImport = async () => {
if (!url) return;
setUrl("");
setDisabled(true);
setLoading(true);
try {
await importProfile(url);
Notice.success("Successfully import profile.");
setUrl("");
setLoading(false);
getProfiles().then((newProfiles) => {
mutate("getProfiles", newProfiles);
@@ -96,8 +99,10 @@ const ProfilePage = () => {
});
} catch (err: any) {
Notice.error(err.message || err.toString());
setLoading(false);
} finally {
setDisabled(false);
setLoading(false);
}
};
@@ -271,14 +276,15 @@ const ProfilePage = () => {
),
}}
/>
<Button
<LoadingButton
disabled={!url || disabled}
loading={loading}
variant="contained"
size="small"
onClick={onImport}
>
{t("Import")}
</Button>
</LoadingButton>
<Button
variant="contained"
size="small"

View File

@@ -1,4 +1,4 @@
import { IconButton, Paper } from "@mui/material";
import { Grid, IconButton, Paper } from "@mui/material";
import { useLockFn } from "ahooks";
import { useTranslation } from "react-i18next";
import { BasePage, Notice } from "@/components/base";
@@ -33,17 +33,25 @@ const SettingPage = () => {
</IconButton>
}
>
<Paper sx={{ borderRadius: 1, boxShadow: 2, mb: 3 }}>
<SettingClash onError={onError} />
</Paper>
<Grid container spacing={{ xs: 2, lg: 3 }}>
<Grid item xs={12} md={6}>
<Paper sx={{ borderRadius: 1, boxShadow: 2 }}>
<SettingClash onError={onError} />
</Paper>
</Grid>
<Paper sx={{ borderRadius: 1, boxShadow: 2, mb: 3 }}>
<SettingSystem onError={onError} />
</Paper>
<Grid item xs={12} md={6}>
<Paper sx={{ borderRadius: 1, boxShadow: 2 }}>
<SettingSystem onError={onError} />
</Paper>
</Grid>
<Paper sx={{ borderRadius: 1, boxShadow: 2 }}>
<SettingVerge onError={onError} />
</Paper>
<Grid item xs={12} md={6}>
<Paper sx={{ borderRadius: 1, boxShadow: 2 }}>
<SettingVerge onError={onError} />
</Paper>
</Grid>
</Grid>
</BasePage>
);
};