diff --git a/src/assets/styles/layout.scss b/src/assets/styles/layout.scss index be322bf..509aaba 100644 --- a/src/assets/styles/layout.scss +++ b/src/assets/styles/layout.scss @@ -17,6 +17,7 @@ overflow: hidden; .the-logo { + position: relative; flex: 0 1 180px; width: 100%; max-width: 180px; @@ -25,6 +26,13 @@ padding: 0 8px; text-align: center; box-sizing: border-box; + + .the-newbtn { + position: absolute; + right: 20px; + bottom: 12px; + transform: scale(0.8); + } } .the-menu { diff --git a/src/components/setting-verge.tsx b/src/components/setting-verge.tsx index bc578c7..ea926cd 100644 --- a/src/components/setting-verge.tsx +++ b/src/components/setting-verge.tsx @@ -7,15 +7,15 @@ import { Typography, } from "@mui/material"; import { + setSysProxy, getVergeConfig, patchVergeConfig, - setSysProxy, } from "../services/cmds"; import { CmdType } from "../services/types"; +import { version } from "../../package.json"; import GuardState from "./guard-state"; import SettingItem from "./setting-item"; import PaletteSwitch from "./palette-switch"; -import { version } from "../../package.json"; interface Props { onError?: (err: Error) => void; @@ -32,7 +32,6 @@ const SettingVerge = ({ onError }: Props) => { } = vergeConfig ?? {}; const onSwitchFormat = (_e: any, value: boolean) => value; - const onChangeData = (patch: Partial) => { mutate("getVergeConfig", { ...vergeConfig, ...patch }, false); }; diff --git a/src/components/update-dialog.tsx b/src/components/update-dialog.tsx new file mode 100644 index 0000000..1881148 --- /dev/null +++ b/src/components/update-dialog.tsx @@ -0,0 +1,66 @@ +import useSWR from "swr"; +import { useState } from "react"; +import { checkUpdate, installUpdate } from "@tauri-apps/api/updater"; +import { relaunch } from "@tauri-apps/api/process"; +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, +} from "@mui/material"; + +interface Props { + open: boolean; + onClose: () => void; +} + +let uploadingState = false; + +const UpdateDialog = (props: Props) => { + const { open, onClose } = props; + const { data: updateInfo } = useSWR("checkUpdate", checkUpdate, { + errorRetryCount: 2, + revalidateIfStale: false, + focusThrottleInterval: 36e5, // 1 hour + }); + const [uploading, setUploading] = useState(uploadingState); + + const onUpdate = async () => { + try { + setUploading(true); + uploadingState = true; + await installUpdate(); + await relaunch(); + } catch (error) { + console.log(error); + window.alert("Failed to upload, please try again."); + } finally { + setUploading(true); + uploadingState = true; + } + }; + + return ( + + New Version v{updateInfo?.manifest?.version} + + {updateInfo?.manifest?.body} + + + + + + + ); +}; + +export default UpdateDialog; diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx index adf7159..f5ea019 100644 --- a/src/pages/_layout.tsx +++ b/src/pages/_layout.tsx @@ -1,8 +1,9 @@ -import { useEffect, useMemo } from "react"; +import { useEffect, useMemo, useState } from "react"; import useSWR, { SWRConfig } from "swr"; import { Route, Routes } from "react-router-dom"; import { useRecoilState } from "recoil"; import { + Button, createTheme, IconButton, List, @@ -10,6 +11,7 @@ import { ThemeProvider, } from "@mui/material"; import { HorizontalRuleRounded, CloseRounded } from "@mui/icons-material"; +import { checkUpdate } from "@tauri-apps/api/updater"; import { atomPaletteMode } from "../states/setting"; import { getVergeConfig, windowDrag, windowHide } from "../services/cmds"; import LogoSvg from "../assets/image/logo.svg"; @@ -20,6 +22,7 @@ import SettingPage from "./setting"; import ConnectionsPage from "./connections"; import LayoutItem from "../components/layout-item"; import Traffic from "../components/traffic"; +import UpdateDialog from "../components/update-dialog"; const routers = [ { @@ -52,6 +55,12 @@ const routers = [ const Layout = () => { const [mode, setMode] = useRecoilState(atomPaletteMode); const { data: vergeConfig } = useSWR("getVergeConfig", getVergeConfig); + const { data: updateInfo } = useSWR("checkUpdate", checkUpdate, { + errorRetryCount: 2, + revalidateIfStale: false, + focusThrottleInterval: 36e5, // 1 hour + }); + const [dialogOpen, setDialogOpen] = useState(false); useEffect(() => { setMode(vergeConfig?.theme_mode ?? "light"); @@ -92,6 +101,18 @@ const Layout = () => { e.preventDefault(); }} /> + + {updateInfo?.shouldUpdate && ( + + )} @@ -126,13 +147,14 @@ const Layout = () => {
- {routers.map(({ link, ele: Ele }) => ( - } /> + {routers.map(({ label, link, ele: Ele }) => ( + } /> ))}
+ setDialogOpen(false)} /> );