60 lines
1.7 KiB
TypeScript
60 lines
1.7 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useEffectEvent, useRef } from "react";
|
|
import { toast } from "sonner";
|
|
import { useTranslation } from "@/components/i18n/locale-provider";
|
|
|
|
import {
|
|
hasDeploymentChanged,
|
|
normalizeDeploymentId,
|
|
} from "@/lib/deployment/version";
|
|
|
|
const UPDATE_TOAST_ID = "deployment-update";
|
|
|
|
export function DeploymentUpdateNotifier({
|
|
deploymentId,
|
|
}: {
|
|
deploymentId: string;
|
|
}) {
|
|
const { t } = useTranslation();
|
|
const showUpdate = useEffectEvent(() => {
|
|
toast(t("มีอัปเดตใหม่พร้อมใช้งาน"), {
|
|
id: UPDATE_TOAST_ID,
|
|
description: t("รีโหลดเพื่ออัปเดตเป็นเวอร์ชันล่าสุด"),
|
|
action: { label: t("รีโหลด"), onClick: () => window.location.reload() },
|
|
duration: Infinity,
|
|
});
|
|
});
|
|
const currentDeployment = useRef(normalizeDeploymentId(deploymentId));
|
|
const updateAvailable = useRef(false);
|
|
|
|
useEffect(() => {
|
|
const source = new EventSource("/api/active");
|
|
const receiveDeployment = (event: Event) => {
|
|
if (
|
|
updateAvailable.current ||
|
|
!(event instanceof MessageEvent) ||
|
|
typeof event.data !== "string"
|
|
) {
|
|
return;
|
|
}
|
|
|
|
const nextDeployment = normalizeDeploymentId(event.data);
|
|
if (!hasDeploymentChanged(currentDeployment.current, nextDeployment)) {
|
|
return;
|
|
}
|
|
|
|
updateAvailable.current = true;
|
|
showUpdate();
|
|
};
|
|
|
|
source.addEventListener("deployment", receiveDeployment);
|
|
return () => {
|
|
source.removeEventListener("deployment", receiveDeployment);
|
|
source.close();
|
|
};
|
|
}, []);
|
|
|
|
return null;
|
|
}
|