Spaces:
Running
Running
File size: 2,740 Bytes
c47ec10 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | "use client";
import { useCallback, useMemo, useState } from "react";
import { toast } from "sonner";
import webConfig from "@/constants/common-env";
import { parseChangelog, type ReleaseInfo } from "@/lib/release";
const latestVersionUrl =
"https://raw.githubusercontent.com/basketikun/chatgpt2api/main/VERSION";
const latestChangelogUrl =
"https://raw.githubusercontent.com/basketikun/chatgpt2api/main/CHANGELOG.md";
function readLocalReleases(): ReleaseInfo[] {
return JSON.parse(process.env.NEXT_PUBLIC_APP_RELEASES || "[]");
}
function toVersionParts(version: string) {
const match = version.trim().match(/^v?(\d+)\.(\d+)\.(\d+)/);
return match ? match.slice(1).map(Number) : null;
}
function isNewerVersion(latestVersion: string, currentVersion: string) {
const latest = toVersionParts(latestVersion);
const current = toVersionParts(currentVersion);
if (!latest || !current) return false;
return latest.some(
(value, index) =>
value > current[index] &&
latest.slice(0, index).every((part, prevIndex) => part === current[prevIndex]),
);
}
export function useVersionCheck() {
const currentVersion = webConfig.appVersion;
const localReleases = useMemo(readLocalReleases, []);
const [latestVersion, setLatestVersion] = useState(currentVersion);
const [releases, setReleases] = useState<ReleaseInfo[]>(localReleases);
const [checking, setChecking] = useState(false);
const [open, setOpen] = useState(false);
const hasNewVersion = isNewerVersion(latestVersion, currentVersion);
const checkLatestRelease = useCallback(
async (showMessage = false) => {
setChecking(true);
try {
const [versionResponse, changelogResponse] = await Promise.all([
fetch(latestVersionUrl),
fetch(latestChangelogUrl),
]);
if (!versionResponse.ok || !changelogResponse.ok) throw new Error();
const [version, changelog] = await Promise.all([
versionResponse.text(),
changelogResponse.text(),
]);
setLatestVersion(version.trim() || currentVersion);
if (changelog.trim()) setReleases(parseChangelog(changelog));
if (showMessage) toast.success("已获取最新版本信息");
} catch {
setLatestVersion(currentVersion);
setReleases(localReleases);
if (showMessage) toast.error("获取最新版本信息失败");
} finally {
setChecking(false);
}
},
[currentVersion, localReleases],
);
const openReleaseModal = () => {
setOpen(true);
void checkLatestRelease();
};
return {
open,
setOpen,
openReleaseModal,
latestVersion,
releases,
checking,
hasNewVersion,
checkLatestRelease,
};
}
|