update-dialog.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import useSWR from "swr";
  2. import snarkdown from "snarkdown";
  3. import { useMemo } from "react";
  4. import { useRecoilState } from "recoil";
  5. import {
  6. Box,
  7. Button,
  8. Dialog,
  9. DialogActions,
  10. DialogContent,
  11. DialogTitle,
  12. styled,
  13. } from "@mui/material";
  14. import { relaunch } from "@tauri-apps/api/process";
  15. import { checkUpdate, installUpdate } from "@tauri-apps/api/updater";
  16. import { killSidecars, restartSidecar } from "../../services/cmds";
  17. import { atomUpdateState } from "../../services/states";
  18. import Notice from "../base/base-notice";
  19. interface Props {
  20. open: boolean;
  21. onClose: () => void;
  22. }
  23. const UpdateLog = styled(Box)(() => ({
  24. "h1,h2,h3,ul,ol,p": { margin: "0.5em 0", color: "inherit" },
  25. }));
  26. const UpdateDialog = (props: Props) => {
  27. const { open, onClose } = props;
  28. const { data: updateInfo } = useSWR("checkUpdate", checkUpdate, {
  29. errorRetryCount: 2,
  30. revalidateIfStale: false,
  31. focusThrottleInterval: 36e5, // 1 hour
  32. });
  33. const [updateState, setUpdateState] = useRecoilState(atomUpdateState);
  34. const onUpdate = async () => {
  35. if (updateState) return;
  36. setUpdateState(true);
  37. try {
  38. await killSidecars();
  39. await installUpdate();
  40. await relaunch();
  41. } catch (err: any) {
  42. await restartSidecar();
  43. Notice.error(err?.message || err.toString());
  44. } finally {
  45. setUpdateState(false);
  46. }
  47. };
  48. // markdown parser
  49. const parseContent = useMemo(() => {
  50. if (!updateInfo?.manifest?.body) {
  51. return "New Version is available";
  52. }
  53. return snarkdown(updateInfo?.manifest?.body);
  54. }, [updateInfo]);
  55. return (
  56. <Dialog open={open} onClose={onClose}>
  57. <DialogTitle>New Version v{updateInfo?.manifest?.version}</DialogTitle>
  58. <DialogContent sx={{ minWidth: 360, maxWidth: 400, maxHeight: "50vh" }}>
  59. <UpdateLog dangerouslySetInnerHTML={{ __html: parseContent }} />
  60. </DialogContent>
  61. <DialogActions>
  62. <Button onClick={onClose}>Cancel</Button>
  63. <Button
  64. autoFocus
  65. variant="contained"
  66. disabled={updateState}
  67. onClick={onUpdate}
  68. >
  69. Update
  70. </Button>
  71. </DialogActions>
  72. </Dialog>
  73. );
  74. };
  75. export default UpdateDialog;