Files
erika/components/version-check.tsx

72 lines
2.0 KiB
TypeScript

"use client";
import { useEffect, useRef } from "react";
import { toast } from "sonner";
import {
checkDeploymentVersion,
shouldReloadPath,
UPDATE_HASH,
} from "@/lib/realtime/deployment-refresh";
import { sse } from "@/lib/realtime/sse";
const UPDATE_TOAST_ID = "deployment-update";
function reloadWithUpdateMarker() {
window.location.hash = UPDATE_HASH;
queueMicrotask(() => window.location.reload());
}
export function VersionCheck() {
const versionRef = useRef<string | null>(null);
useEffect(() => {
let successTimer: ReturnType<typeof setTimeout> | undefined;
if (window.location.hash === UPDATE_HASH) {
const url = new URL(window.location.href);
url.hash = "";
window.history.replaceState(null, "", url);
successTimer = setTimeout(
() => toast.success("คุณอยู่ในเวอร์ชั่นล่าสุดแล้ว"),
1_000,
);
}
const { clean } = sse.active.subMany(
{
version(incomingVersion) {
const result = checkDeploymentVersion(
versionRef.current,
incomingVersion,
);
versionRef.current = result.version;
if (!result.hasUpdate) return;
window.location.hash = UPDATE_HASH;
toast("มีอัปเดตใหม่พร้อมใช้งาน", {
id: UPDATE_TOAST_ID,
description: "รีโหลดเพื่ออัปเดตเป็นเวอร์ชันล่าสุด",
action: {
label: "รีโหลด",
onClick: () => window.location.reload(),
},
duration: Infinity,
});
},
refresh(prefix) {
if (!shouldReloadPath(prefix, window.location.pathname)) return;
reloadWithUpdateMarker();
},
},
{ endpoint: "/api/active" },
);
return () => {
if (successTimer) clearTimeout(successTimer);
clean();
};
}, []);
return null;
}