feat: support update checker

This commit is contained in:
GyDi 2022-01-10 02:05:35 +08:00
parent 83fe9835b6
commit 66340a27fa
4 changed files with 101 additions and 6 deletions

View File

@ -17,6 +17,7 @@
overflow: hidden; overflow: hidden;
.the-logo { .the-logo {
position: relative;
flex: 0 1 180px; flex: 0 1 180px;
width: 100%; width: 100%;
max-width: 180px; max-width: 180px;
@ -25,6 +26,13 @@
padding: 0 8px; padding: 0 8px;
text-align: center; text-align: center;
box-sizing: border-box; box-sizing: border-box;
.the-newbtn {
position: absolute;
right: 20px;
bottom: 12px;
transform: scale(0.8);
}
} }
.the-menu { .the-menu {

View File

@ -7,15 +7,15 @@ import {
Typography, Typography,
} from "@mui/material"; } from "@mui/material";
import { import {
setSysProxy,
getVergeConfig, getVergeConfig,
patchVergeConfig, patchVergeConfig,
setSysProxy,
} from "../services/cmds"; } from "../services/cmds";
import { CmdType } from "../services/types"; import { CmdType } from "../services/types";
import { version } from "../../package.json";
import GuardState from "./guard-state"; import GuardState from "./guard-state";
import SettingItem from "./setting-item"; import SettingItem from "./setting-item";
import PaletteSwitch from "./palette-switch"; import PaletteSwitch from "./palette-switch";
import { version } from "../../package.json";
interface Props { interface Props {
onError?: (err: Error) => void; onError?: (err: Error) => void;
@ -32,7 +32,6 @@ const SettingVerge = ({ onError }: Props) => {
} = vergeConfig ?? {}; } = vergeConfig ?? {};
const onSwitchFormat = (_e: any, value: boolean) => value; const onSwitchFormat = (_e: any, value: boolean) => value;
const onChangeData = (patch: Partial<CmdType.VergeConfig>) => { const onChangeData = (patch: Partial<CmdType.VergeConfig>) => {
mutate("getVergeConfig", { ...vergeConfig, ...patch }, false); mutate("getVergeConfig", { ...vergeConfig, ...patch }, false);
}; };

View File

@ -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 (
<Dialog open={open} onClose={onClose}>
<DialogTitle>New Version v{updateInfo?.manifest?.version}</DialogTitle>
<DialogContent sx={{ minWidth: 360, maxWidth: 400, maxHeight: "50vh" }}>
<DialogContentText>{updateInfo?.manifest?.body}</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={onClose}>Cancel</Button>
<Button
variant="contained"
autoFocus
onClick={onUpdate}
disabled={uploading}
>
Update
</Button>
</DialogActions>
</Dialog>
);
};
export default UpdateDialog;

View File

@ -1,8 +1,9 @@
import { useEffect, useMemo } from "react"; import { useEffect, useMemo, useState } from "react";
import useSWR, { SWRConfig } from "swr"; import useSWR, { SWRConfig } from "swr";
import { Route, Routes } from "react-router-dom"; import { Route, Routes } from "react-router-dom";
import { useRecoilState } from "recoil"; import { useRecoilState } from "recoil";
import { import {
Button,
createTheme, createTheme,
IconButton, IconButton,
List, List,
@ -10,6 +11,7 @@ import {
ThemeProvider, ThemeProvider,
} from "@mui/material"; } from "@mui/material";
import { HorizontalRuleRounded, CloseRounded } from "@mui/icons-material"; import { HorizontalRuleRounded, CloseRounded } from "@mui/icons-material";
import { checkUpdate } from "@tauri-apps/api/updater";
import { atomPaletteMode } from "../states/setting"; import { atomPaletteMode } from "../states/setting";
import { getVergeConfig, windowDrag, windowHide } from "../services/cmds"; import { getVergeConfig, windowDrag, windowHide } from "../services/cmds";
import LogoSvg from "../assets/image/logo.svg"; import LogoSvg from "../assets/image/logo.svg";
@ -20,6 +22,7 @@ import SettingPage from "./setting";
import ConnectionsPage from "./connections"; import ConnectionsPage from "./connections";
import LayoutItem from "../components/layout-item"; import LayoutItem from "../components/layout-item";
import Traffic from "../components/traffic"; import Traffic from "../components/traffic";
import UpdateDialog from "../components/update-dialog";
const routers = [ const routers = [
{ {
@ -52,6 +55,12 @@ const routers = [
const Layout = () => { const Layout = () => {
const [mode, setMode] = useRecoilState(atomPaletteMode); const [mode, setMode] = useRecoilState(atomPaletteMode);
const { data: vergeConfig } = useSWR("getVergeConfig", getVergeConfig); 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(() => { useEffect(() => {
setMode(vergeConfig?.theme_mode ?? "light"); setMode(vergeConfig?.theme_mode ?? "light");
@ -92,6 +101,18 @@ const Layout = () => {
e.preventDefault(); e.preventDefault();
}} }}
/> />
{updateInfo?.shouldUpdate && (
<Button
color="error"
variant="contained"
size="small"
className="the-newbtn"
onClick={() => setDialogOpen(true)}
>
New
</Button>
)}
</div> </div>
<List className="the-menu"> <List className="the-menu">
@ -126,13 +147,14 @@ const Layout = () => {
<div className="the-content"> <div className="the-content">
<Routes> <Routes>
{routers.map(({ link, ele: Ele }) => ( {routers.map(({ label, link, ele: Ele }) => (
<Route path={link} element={<Ele />} /> <Route key={label} path={link} element={<Ele />} />
))} ))}
</Routes> </Routes>
</div> </div>
</div> </div>
</Paper> </Paper>
<UpdateDialog open={dialogOpen} onClose={() => setDialogOpen(false)} />
</ThemeProvider> </ThemeProvider>
</SWRConfig> </SWRConfig>
); );