fix about

This commit is contained in:
Eduard Gert
2026-05-11 09:37:14 +02:00
parent f3f9704c6f
commit 18e3b5dd32
2 changed files with 124 additions and 2 deletions

View File

@@ -4,6 +4,7 @@ import netbirdFull from "@/assets/logos/netbird-full.svg";
import pkg from "../../../package.json";
import { useStatus } from "@/hooks/useStatus";
import { Button } from "@/components/Button";
import { useAccentTrigger } from "@/modules/settings/SettingsAccent";
const LEGAL_LINKS: { label: string; url: string }[] = [
{ label: "Imprint", url: "https://netbird.io/imprint" },
@@ -39,6 +40,8 @@ export function SettingsAbout() {
UpdateSvc.Trigger().catch(() => {});
};
const handleVersionClick = useAccentTrigger();
return (
<div
className={
@@ -47,7 +50,10 @@ export function SettingsAbout() {
>
<img src={netbirdFull} alt={"NetBird"} className={"h-7 w-auto"} />
<div className={"flex flex-col items-center gap-0.5 text-center"}>
<p className={"text-sm font-semibold text-nb-gray-100"}>
<p
className={"text-sm font-semibold text-nb-gray-100 cursor-default select-none"}
onClick={handleVersionClick}
>
NetBird Client v{daemonVersion}
</p>
<p className={"text-sm text-nb-gray-300"}>GUI v{guiVersion}</p>
@@ -60,7 +66,7 @@ export function SettingsAbout() {
}
>
<div>
<p className={"text-sm font-medium"}>
<p className={"text-sm font-semibold"}>
Version {updateVersion} is available.
</p>
<button

View File

@@ -0,0 +1,116 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { createRoot } from "react-dom/client";
export function useAccentTrigger() {
const clicksRef = useRef(0);
const lastClickRef = useRef(0);
return useCallback(() => {
const now = performance.now();
if (now - lastClickRef.current > 400) {
clicksRef.current = 0;
}
lastClickRef.current = now;
clicksRef.current += 1;
if (clicksRef.current >= 10) {
clicksRef.current = 0;
triggerAccent();
}
}, []);
}
function triggerAccent() {
if (document.getElementById("nb-accent-root")) return;
const container = document.createElement("div");
container.id = "nb-accent-root";
document.body.appendChild(container);
const root = createRoot(container);
const cleanup = () => {
root.unmount();
container.remove();
};
root.render(<Accent onDone={cleanup} />);
}
function Accent({ onDone }: { onDone: () => void }) {
const canvasRef = useRef<HTMLCanvasElement>(null);
const [visible, setVisible] = useState(false);
useEffect(() => {
const raf = requestAnimationFrame(() => setVisible(true));
return () => cancelAnimationFrame(raf);
}, []);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
const dpr = window.devicePixelRatio || 1;
const resize = () => {
canvas.width = window.innerWidth * dpr;
canvas.height = window.innerHeight * dpr;
canvas.style.width = `${window.innerWidth}px`;
canvas.style.height = `${window.innerHeight}px`;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
};
resize();
window.addEventListener("resize", resize);
const chars = "TEAMNETBIRD";
const fontSize = 16;
const columns = Math.floor(window.innerWidth / fontSize);
const drops = Array.from({ length: columns }, () => Math.random() * -50);
let raf = 0;
let last = 0;
const draw = (t: number) => {
if (t - last > 50) {
last = t;
ctx.globalCompositeOperation = "destination-out";
ctx.fillStyle = "rgba(0, 0, 0, 0.12)";
ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);
ctx.globalCompositeOperation = "source-over";
ctx.font = `${fontSize}px ui-monospace, monospace`;
ctx.fillStyle = "#f68330";
for (let i = 0; i < drops.length; i++) {
const ch = chars[Math.floor(Math.random() * chars.length)];
const y = drops[i] * fontSize;
ctx.fillText(ch, i * fontSize, y);
if (y > window.innerHeight && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
}
}
raf = requestAnimationFrame(draw);
};
raf = requestAnimationFrame(draw);
const timeout = window.setTimeout(() => {
setVisible(false);
window.setTimeout(onDone, 500);
}, 9000);
return () => {
cancelAnimationFrame(raf);
window.clearTimeout(timeout);
window.removeEventListener("resize", resize);
};
}, [onDone]);
return (
<div
className={`fixed inset-0 z-50 bg-black/5 transition-opacity duration-500 pointer-events-none ${visible ? "opacity-100" : "opacity-0"}`}
>
<canvas ref={canvasRef} className={"block"} />
</div>
);
}