mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-18 20:49:56 +00:00
add overlay if daemon not compatible
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { AlertTriangleIcon, DownloadIcon } from "lucide-react";
|
||||
import { Browser } from "@wailsio/runtime";
|
||||
import { Button } from "@/components/buttons/Button";
|
||||
import { useStatus } from "@/contexts/StatusContext.tsx";
|
||||
|
||||
const RELEASES_URL = "https://github.com/netbirdio/netbird/releases/latest";
|
||||
|
||||
function openUrl(url: string) {
|
||||
Browser.OpenURL(url).catch(() => globalThis.open(url, "_blank"));
|
||||
}
|
||||
|
||||
export const DaemonOutdatedOverlay = () => {
|
||||
const { t } = useTranslation();
|
||||
const { isDaemonOutdated } = useStatus();
|
||||
|
||||
if (!isDaemonOutdated) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
"fixed inset-0 z-[100] flex items-center justify-center bg-nb-gray-950 backdrop-blur-sm cursor-default select-none wails-draggable"
|
||||
}
|
||||
>
|
||||
<div className={"flex flex-col items-center gap-5 px-8 max-w-lg text-center"}>
|
||||
<div
|
||||
className={
|
||||
"h-11 w-11 rounded-xl flex items-center justify-center bg-nb-gray-920 border border-nb-gray-900 text-amber-500"
|
||||
}
|
||||
>
|
||||
<AlertTriangleIcon size={20} />
|
||||
</div>
|
||||
|
||||
<div className={"flex flex-col items-center gap-1"}>
|
||||
<p className={"text-base font-medium text-nb-gray-50"}>
|
||||
{t("daemon.outdated.title")}
|
||||
</p>
|
||||
<p className={"text-sm text-nb-gray-300"}>
|
||||
{t("daemon.outdated.description")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={"wails-no-draggable"}>
|
||||
<Button variant={"primary"} size={"xs"} onClick={() => openUrl(RELEASES_URL)}>
|
||||
<DownloadIcon size={14} />
|
||||
{t("update.card.getInstaller")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -10,7 +10,9 @@ import {
|
||||
import { Events } from "@wailsio/runtime";
|
||||
import { DaemonFeed } from "@bindings/services";
|
||||
import { Status } from "@bindings/services/models.js";
|
||||
import { DaemonOutdatedOverlay } from "@/components/empty-state/DaemonOutdatedOverlay.tsx";
|
||||
import { DaemonUnavailableOverlay } from "@/components/empty-state/DaemonUnavailableOverlay.tsx";
|
||||
import { isDaemonCompatible } from "@/lib/compat";
|
||||
|
||||
const EVENT_STATUS = "netbird:status";
|
||||
|
||||
@@ -21,6 +23,7 @@ type StatusContextValue = {
|
||||
isReady: boolean;
|
||||
isDaemonUnavailable: boolean;
|
||||
isDaemonAvailable: boolean;
|
||||
isDaemonOutdated: boolean;
|
||||
};
|
||||
|
||||
const StatusContext = createContext<StatusContextValue | null>(null);
|
||||
@@ -36,6 +39,7 @@ export const useStatus = () => {
|
||||
export const StatusProvider = ({ children }: { children: ReactNode }) => {
|
||||
const [status, setStatus] = useState<Status | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [isDaemonOutdated, setIsDaemonOutdated] = useState(false);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
try {
|
||||
@@ -64,6 +68,21 @@ export const StatusProvider = ({ children }: { children: ReactNode }) => {
|
||||
const isDaemonUnavailable = isReady && status.status === "DaemonUnavailable";
|
||||
const isDaemonAvailable = isReady && !isDaemonUnavailable;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDaemonAvailable) return;
|
||||
let cancelled = false;
|
||||
isDaemonCompatible()
|
||||
.then((ok) => {
|
||||
if (!cancelled) setIsDaemonOutdated(!ok);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("[StatusContext] daemon compatible error", err);
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [isDaemonAvailable]);
|
||||
|
||||
const value = useMemo<StatusContextValue>(
|
||||
() => ({
|
||||
status,
|
||||
@@ -72,14 +91,16 @@ export const StatusProvider = ({ children }: { children: ReactNode }) => {
|
||||
isReady,
|
||||
isDaemonUnavailable,
|
||||
isDaemonAvailable,
|
||||
isDaemonOutdated,
|
||||
}),
|
||||
[status, error, refresh, isReady, isDaemonUnavailable, isDaemonAvailable],
|
||||
[status, error, refresh, isReady, isDaemonUnavailable, isDaemonAvailable, isDaemonOutdated],
|
||||
);
|
||||
|
||||
return (
|
||||
<StatusContext.Provider value={value}>
|
||||
{isDaemonAvailable && children}
|
||||
{isDaemonAvailable && !isDaemonOutdated && children}
|
||||
<DaemonUnavailableOverlay />
|
||||
<DaemonOutdatedOverlay />
|
||||
</StatusContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1250,6 +1250,12 @@
|
||||
"daemon.unavailable.docsLink": {
|
||||
"message": "Dokumentation"
|
||||
},
|
||||
"daemon.outdated.title": {
|
||||
"message": "NetBird-Dienst ist veraltet"
|
||||
},
|
||||
"daemon.outdated.description": {
|
||||
"message": "Aktualisieren Sie den NetBird-Dienst, um diese App zu verwenden."
|
||||
},
|
||||
"error.jwt_clock_skew": {
|
||||
"message": "Anmeldung fehlgeschlagen: Die Uhr dieses Geräts ist nicht mit dem Server synchron. Bitte synchronisieren Sie die Systemuhr und versuchen Sie es erneut."
|
||||
},
|
||||
|
||||
@@ -1667,6 +1667,14 @@
|
||||
"message": "Documentation",
|
||||
"description": "Documentation link on the daemon-unavailable overlay."
|
||||
},
|
||||
"daemon.outdated.title": {
|
||||
"message": "NetBird Service Is Outdated",
|
||||
"description": "Title of the overlay shown when the NetBird background service is too old to drive this UI."
|
||||
},
|
||||
"daemon.outdated.description": {
|
||||
"message": "Update the NetBird service to use this app.",
|
||||
"description": "Body of the daemon-outdated overlay telling the user to upgrade the service."
|
||||
},
|
||||
"error.jwt_clock_skew": {
|
||||
"message": "Sign-in failed: this device's clock is out of sync with the server. Please sync your system clock and try again.",
|
||||
"description": "Sign-in error shown to the user: the device clock is out of sync with the server."
|
||||
|
||||
@@ -1250,6 +1250,12 @@
|
||||
"daemon.unavailable.docsLink": {
|
||||
"message": "Documentación"
|
||||
},
|
||||
"daemon.outdated.title": {
|
||||
"message": "El servicio de NetBird está desactualizado"
|
||||
},
|
||||
"daemon.outdated.description": {
|
||||
"message": "Actualice el servicio de NetBird para usar esta aplicación."
|
||||
},
|
||||
"error.jwt_clock_skew": {
|
||||
"message": "Error al iniciar sesión: el reloj de este dispositivo no está sincronizado con el servidor. Sincronice el reloj del sistema e inténtelo de nuevo."
|
||||
},
|
||||
|
||||
@@ -1250,6 +1250,12 @@
|
||||
"daemon.unavailable.docsLink": {
|
||||
"message": "Documentation"
|
||||
},
|
||||
"daemon.outdated.title": {
|
||||
"message": "Le service NetBird est obsolète"
|
||||
},
|
||||
"daemon.outdated.description": {
|
||||
"message": "Mettez à jour le service NetBird pour utiliser cette application."
|
||||
},
|
||||
"error.jwt_clock_skew": {
|
||||
"message": "Échec de la connexion : l’horloge de cet appareil n’est pas synchronisée avec le serveur. Veuillez synchroniser l’horloge de votre système et réessayer."
|
||||
},
|
||||
|
||||
@@ -1250,6 +1250,12 @@
|
||||
"daemon.unavailable.docsLink": {
|
||||
"message": "Dokumentáció"
|
||||
},
|
||||
"daemon.outdated.title": {
|
||||
"message": "A NetBird szolgáltatás elavult"
|
||||
},
|
||||
"daemon.outdated.description": {
|
||||
"message": "Frissítsd a NetBird szolgáltatást az alkalmazás használatához."
|
||||
},
|
||||
"error.jwt_clock_skew": {
|
||||
"message": "A bejelentkezés sikertelen: az eszköz órája eltér a szerverétől. Kérjük, szinkronizálja a rendszer óráját, majd próbálja újra."
|
||||
},
|
||||
|
||||
@@ -1250,6 +1250,12 @@
|
||||
"daemon.unavailable.docsLink": {
|
||||
"message": "Documentazione"
|
||||
},
|
||||
"daemon.outdated.title": {
|
||||
"message": "Il servizio NetBird è obsoleto"
|
||||
},
|
||||
"daemon.outdated.description": {
|
||||
"message": "Aggiorna il servizio NetBird per usare questa app."
|
||||
},
|
||||
"error.jwt_clock_skew": {
|
||||
"message": "Accesso non riuscito: l'orologio di questo dispositivo non è sincronizzato con il server. Sincronizzi l'orologio di sistema e riprovi."
|
||||
},
|
||||
|
||||
@@ -1250,6 +1250,12 @@
|
||||
"daemon.unavailable.docsLink": {
|
||||
"message": "Documentação"
|
||||
},
|
||||
"daemon.outdated.title": {
|
||||
"message": "O serviço NetBird está desatualizado"
|
||||
},
|
||||
"daemon.outdated.description": {
|
||||
"message": "Atualize o serviço NetBird para usar este aplicativo."
|
||||
},
|
||||
"error.jwt_clock_skew": {
|
||||
"message": "Falha no login: o relógio deste dispositivo está fora de sincronia com o servidor. Sincronize o relógio do sistema e tente novamente."
|
||||
},
|
||||
|
||||
@@ -1250,6 +1250,12 @@
|
||||
"daemon.unavailable.docsLink": {
|
||||
"message": "Документация"
|
||||
},
|
||||
"daemon.outdated.title": {
|
||||
"message": "Служба NetBird устарела"
|
||||
},
|
||||
"daemon.outdated.description": {
|
||||
"message": "Обновите службу NetBird, чтобы использовать это приложение."
|
||||
},
|
||||
"error.jwt_clock_skew": {
|
||||
"message": "Не удалось войти: часы этого устройства рассинхронизированы с сервером. Синхронизируйте системные часы и повторите попытку."
|
||||
},
|
||||
|
||||
@@ -1250,6 +1250,12 @@
|
||||
"daemon.unavailable.docsLink": {
|
||||
"message": "文档"
|
||||
},
|
||||
"daemon.outdated.title": {
|
||||
"message": "NetBird 服务版本过旧"
|
||||
},
|
||||
"daemon.outdated.description": {
|
||||
"message": "请更新 NetBird 服务以使用此应用。"
|
||||
},
|
||||
"error.jwt_clock_skew": {
|
||||
"message": "登录失败:此设备的时钟与服务器不同步。请同步您的系统时钟后重试。"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user