feat(ui): version checker

This commit is contained in:
Fu Diwei 2025-02-18 21:21:29 +08:00
parent ff53866e9e
commit 688a013d73
3 changed files with 85 additions and 6 deletions

View File

@ -1,8 +1,10 @@
import { memo, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
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 { useVersionChecker } from "@/hooks";
export type VersionProps = {
className?: string;
@ -12,6 +14,8 @@ export type VersionProps = {
const Version = ({ className, style }: VersionProps) => {
const { t } = useTranslation();
const { data: hasNewVersions } = useVersionChecker();
return (
<Space className={className} style={style} size={4}>
<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>
</div>
</Typography.Link>
<Divider type="vertical" />
<Typography.Link type="secondary" href="https://github.com/usual2970/certimate/releases" target="_blank">
{version}
</Typography.Link>
<Badge styles={{ indicator: { transform: "scale(0.75) translate(50%, -50%)" } }} count={hasNewVersions ? "NEW" : 0}>
<Typography.Link type="secondary" href="https://github.com/usual2970/certimate/releases" target="_blank">
{version}
</Typography.Link>
</Badge>
</Space>
);
};
export default Version;
export default memo(Version);

View File

@ -2,6 +2,7 @@
import useAntdFormName from "./useAntdFormName";
import useBrowserTheme from "./useBrowserTheme";
import useTriggerElement from "./useTriggerElement";
import useVersionChecker from "./useVersionChecker";
import useZustandShallowSelector from "./useZustandShallowSelector";
export { useAntdForm, useAntdFormName, useBrowserTheme, useTriggerElement, useZustandShallowSelector };
export { useAntdForm, useAntdFormName, useBrowserTheme, useTriggerElement, useVersionChecker, useZustandShallowSelector };

View 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;