mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-27 23:00:03 +00:00
feat(ui): version checker
This commit is contained in:
parent
ff53866e9e
commit
688a013d73
@ -1,8 +1,10 @@
|
|||||||
|
import { memo, useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { ReadOutlined as ReadOutlinedIcon } from "@ant-design/icons";
|
import { ReadOutlined as ReadOutlinedIcon } from "@ant-design/icons";
|
||||||
import { Divider, Space, Typography } from "antd";
|
import { Badge, Divider, Space, Typography } from "antd";
|
||||||
|
|
||||||
import { version } from "@/domain/version";
|
import { version } from "@/domain/version";
|
||||||
|
import { useVersionChecker } from "@/hooks";
|
||||||
|
|
||||||
export type VersionProps = {
|
export type VersionProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -12,6 +14,8 @@ export type VersionProps = {
|
|||||||
const Version = ({ className, style }: VersionProps) => {
|
const Version = ({ className, style }: VersionProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { data: hasNewVersions } = useVersionChecker();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Space className={className} style={style} size={4}>
|
<Space className={className} style={style} size={4}>
|
||||||
<Typography.Link type="secondary" href="https://docs.certimate.me" target="_blank">
|
<Typography.Link type="secondary" href="https://docs.certimate.me" target="_blank">
|
||||||
@ -20,12 +24,16 @@ const Version = ({ className, style }: VersionProps) => {
|
|||||||
<span>{t("common.menu.document")}</span>
|
<span>{t("common.menu.document")}</span>
|
||||||
</div>
|
</div>
|
||||||
</Typography.Link>
|
</Typography.Link>
|
||||||
|
|
||||||
<Divider type="vertical" />
|
<Divider type="vertical" />
|
||||||
<Typography.Link type="secondary" href="https://github.com/usual2970/certimate/releases" target="_blank">
|
|
||||||
{version}
|
<Badge styles={{ indicator: { transform: "scale(0.75) translate(50%, -50%)" } }} count={hasNewVersions ? "NEW" : 0}>
|
||||||
</Typography.Link>
|
<Typography.Link type="secondary" href="https://github.com/usual2970/certimate/releases" target="_blank">
|
||||||
|
{version}
|
||||||
|
</Typography.Link>
|
||||||
|
</Badge>
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Version;
|
export default memo(Version);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import useAntdFormName from "./useAntdFormName";
|
import useAntdFormName from "./useAntdFormName";
|
||||||
import useBrowserTheme from "./useBrowserTheme";
|
import useBrowserTheme from "./useBrowserTheme";
|
||||||
import useTriggerElement from "./useTriggerElement";
|
import useTriggerElement from "./useTriggerElement";
|
||||||
|
import useVersionChecker from "./useVersionChecker";
|
||||||
import useZustandShallowSelector from "./useZustandShallowSelector";
|
import useZustandShallowSelector from "./useZustandShallowSelector";
|
||||||
|
|
||||||
export { useAntdForm, useAntdFormName, useBrowserTheme, useTriggerElement, useZustandShallowSelector };
|
export { useAntdForm, useAntdFormName, useBrowserTheme, useTriggerElement, useVersionChecker, useZustandShallowSelector };
|
||||||
|
70
ui/src/hooks/useVersionChecker.ts
Normal file
70
ui/src/hooks/useVersionChecker.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { useRequest } from "ahooks";
|
||||||
|
|
||||||
|
import { version } from "@/domain/version";
|
||||||
|
|
||||||
|
export type UseVersionCheckerReturns = {
|
||||||
|
data: boolean;
|
||||||
|
check: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const extractSemver = (vers: string) => {
|
||||||
|
let semver = String(vers ?? "");
|
||||||
|
semver = semver.replace(/^v/i, "");
|
||||||
|
semver = semver.split("-")[0];
|
||||||
|
return semver;
|
||||||
|
};
|
||||||
|
|
||||||
|
const compareVersions = (a: string, b: string) => {
|
||||||
|
const aSemver = extractSemver(a);
|
||||||
|
const bSemver = extractSemver(b);
|
||||||
|
const aSemverParts = aSemver.split(".");
|
||||||
|
const bSemverParts = bSemver.split(".");
|
||||||
|
|
||||||
|
const len = Math.max(aSemverParts.length, bSemverParts.length);
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
const aPart = parseInt(aSemverParts[i] ?? "0");
|
||||||
|
const bPart = parseInt(bSemverParts[i] ?? "0");
|
||||||
|
if (aPart > bPart) return 1;
|
||||||
|
if (bPart > aPart) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取版本检查器。
|
||||||
|
* @returns {UseVersionCheckerReturns}
|
||||||
|
*/
|
||||||
|
const useVersionChecker = () => {
|
||||||
|
const { data, refresh } = useRequest(
|
||||||
|
async () => {
|
||||||
|
const releases = await fetch("https://api.github.com/repos/usual2970/certimate/releases")
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((res) => Array.from(res));
|
||||||
|
|
||||||
|
const cIdx = releases.findIndex((e: any) => e.name === version);
|
||||||
|
if (cIdx === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nIdx = releases.findIndex((e: any) => compareVersions(e.name, version) !== -1);
|
||||||
|
if (cIdx >= nIdx) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!releases[nIdx];
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pollingInterval: 6 * 60 * 60 * 1000,
|
||||||
|
refreshOnWindowFocus: true,
|
||||||
|
focusTimespan: 15 * 60 * 1000,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: !!data,
|
||||||
|
check: refresh,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useVersionChecker;
|
Loading…
x
Reference in New Issue
Block a user