mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-15 05:45:20 +00:00
103 lines
3.3 KiB
TypeScript
103 lines
3.3 KiB
TypeScript
'use client';
|
|
|
|
import { useToast } from "@/components/hooks/use-toast";
|
|
import { ToastAction } from "@/components/ui/toast";
|
|
import { NEXT_PUBLIC_SOURCEBOT_VERSION } from "@/lib/environment.client";
|
|
import { useEffect } from "react";
|
|
import { useLocalStorage } from "usehooks-ts";
|
|
|
|
const GITHUB_TAGS_URL = "https://api.github.com/repos/sourcebot-dev/sourcebot/tags";
|
|
const SEMVER_REGEX = /^v(\d+)\.(\d+)\.(\d+)$/;
|
|
const TOAST_TIMEOUT_MS = 1000 * 60 * 60 * 24;
|
|
|
|
type Version = {
|
|
major: number;
|
|
minor: number;
|
|
patch: number;
|
|
};
|
|
|
|
export const UpgradeToast = () => {
|
|
const { toast } = useToast();
|
|
const [ upgradeToastLastShownDate, setUpgradeToastLastShownDate ] = useLocalStorage<string>(
|
|
"upgradeToastLastShownDate",
|
|
new Date(0).toUTCString()
|
|
);
|
|
|
|
useEffect(() => {
|
|
const currentVersion = getVersionFromString(NEXT_PUBLIC_SOURCEBOT_VERSION);
|
|
if (!currentVersion) {
|
|
return;
|
|
}
|
|
|
|
if (Date.now() - new Date(upgradeToastLastShownDate).getTime() < TOAST_TIMEOUT_MS) {
|
|
return;
|
|
}
|
|
|
|
fetch(GITHUB_TAGS_URL)
|
|
.then((response) => response.json())
|
|
.then((data: { name: string }[]) => {
|
|
const versions = data
|
|
.map(({ name }) => getVersionFromString(name))
|
|
.filter((version) => version !== null)
|
|
.sort((a, b) => compareVersions(a, b))
|
|
.reverse();
|
|
|
|
if (versions.length === 0) {
|
|
return;
|
|
}
|
|
|
|
const latestVersion = versions[0];
|
|
if (compareVersions(currentVersion, latestVersion) >= 0) {
|
|
return;
|
|
}
|
|
|
|
toast({
|
|
title: "New version available 📣 ",
|
|
description: `Upgrade from ${getVersionString(currentVersion)} to ${getVersionString(latestVersion)}`,
|
|
duration: 10 * 1000,
|
|
action: (
|
|
<div className="flex flex-col gap-1">
|
|
<ToastAction
|
|
altText="Upgrade"
|
|
onClick={() => {
|
|
window.open("https://github.com/sourcebot-dev/sourcebot/releases/latest", "_blank");
|
|
}}
|
|
>
|
|
Upgrade
|
|
</ToastAction>
|
|
</div>
|
|
)
|
|
});
|
|
|
|
setUpgradeToastLastShownDate(new Date().toUTCString());
|
|
});
|
|
}, [setUpgradeToastLastShownDate, toast, upgradeToastLastShownDate]);
|
|
|
|
return null;
|
|
}
|
|
|
|
const getVersionFromString = (version: string): Version | null => {
|
|
const match = version.match(SEMVER_REGEX);
|
|
if (!match) {
|
|
return null;
|
|
}
|
|
return {
|
|
major: parseInt(match[1]),
|
|
minor: parseInt(match[2]),
|
|
patch: parseInt(match[3]),
|
|
} satisfies Version;
|
|
}
|
|
|
|
const getVersionString = (version: Version) => {
|
|
return `v${version.major}.${version.minor}.${version.patch}`;
|
|
}
|
|
|
|
const compareVersions = (a: Version, b: Version) => {
|
|
if (a.major !== b.major) {
|
|
return a.major - b.major;
|
|
}
|
|
if (a.minor !== b.minor) {
|
|
return a.minor - b.minor;
|
|
}
|
|
return a.patch - b.patch;
|
|
}
|