mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-25 09:01:29 +02:00
- **Wails v3 application** (`client/ui`) with a React + TypeScript + Tailwind frontend replacing the Fyne UI: main connection view, exit-node switcher, networks/peers browser with detail panels, profile management, settings (general, network, SSH, security, troubleshooting, appearance), debug-bundle creation, and a first-run welcome flow. - **Internationalization**: go-i18n bundle with 9 locales (en, de, es, fr, hu, it, pt, ru, zh-CN) shared between the tray and the frontend. - **New system tray** implementation with per-platform theme-aware icons, including a native XEmbed host for Linux (`xembed_tray_linux.c`) and a Linux theme watcher. - **Session handling**: auth session watcher (`client/internal/auth/sessionwatch`), pending login flow, session-expiration dialog and tray notifications, and `netbird login` improvements. - **Daemon API extensions** (`daemon.proto`): status stream subscription, event stream, networks/exit-node selection endpoints, and richer full status — with probe throttling on the daemon side to protect against UI-driven request storms. - **UI preferences store** persisted per profile, autostart management via the daemon (single source of truth in HKCU on Windows). - **Build system**: Taskfile-based builds per platform (macOS, Linux, Windows), Docker cross-compilation images, MSIX/NSIS/nfpm/AppImage packaging, and a new `frontend-ui` CI workflow. Co-authored-by: Zoltan Papp <zoltan.pmail@gmail.com> Co-authored-by: Eduard Gert <kontakt@eduardgert.de> Co-authored-by: braginini <bangvalo@gmail.com> Co-authored-by: Pascal Fischer <32096965+pascal-fischer@users.noreply.github.com> Co-authored-by: riccardom <riccardomanfrin@gmail.com>
61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
import { useLayoutEffect, useRef } from "react";
|
|
import { Window } from "@wailsio/runtime";
|
|
import i18next from "@/lib/i18n";
|
|
import { isLinux } from "@/lib/platform";
|
|
|
|
// Sizes the current Wails window to the measured content height (keeping `width`),
|
|
// then shows it. Re-applies on content resize and language change.
|
|
export function useAutoSizeWindow<T extends HTMLElement>(width: number, ready: boolean = true) {
|
|
const ref = useRef<T | null>(null);
|
|
useLayoutEffect(() => {
|
|
const el = ref.current;
|
|
if (!el) return;
|
|
let shown = false;
|
|
let raf1 = 0;
|
|
let raf2 = 0;
|
|
const showOnce = () => {
|
|
if (shown) return;
|
|
shown = true;
|
|
Window.Show().catch(() => {});
|
|
Window.Focus().catch(() => {});
|
|
};
|
|
const apply = async () => {
|
|
if (!ready) return;
|
|
const h = Math.ceil(el.getBoundingClientRect().height);
|
|
if (h <= 0) return;
|
|
try {
|
|
// Window.SetSize takes the frame size, so add the OS title-bar height or content clips.
|
|
const frame = await Window.Size();
|
|
const targetH = h + Math.max(0, frame.height - window.innerHeight);
|
|
// Linux: SetSize no-ops on a mapped non-resizable window (X11), so pin via min/max instead.
|
|
if (isLinux()) {
|
|
await Window.SetMinSize(width, targetH);
|
|
await Window.SetMaxSize(width, targetH);
|
|
}
|
|
await Window.SetSize(width, targetH);
|
|
showOnce();
|
|
} catch {
|
|
// window gone / not ready — ignore
|
|
}
|
|
};
|
|
const scheduleApply = () => {
|
|
cancelAnimationFrame(raf1);
|
|
cancelAnimationFrame(raf2);
|
|
raf1 = requestAnimationFrame(() => {
|
|
raf2 = requestAnimationFrame(apply);
|
|
});
|
|
};
|
|
apply();
|
|
const ro = new ResizeObserver(apply);
|
|
ro.observe(el);
|
|
i18next.on("languageChanged", scheduleApply);
|
|
return () => {
|
|
ro.disconnect();
|
|
cancelAnimationFrame(raf1);
|
|
cancelAnimationFrame(raf2);
|
|
i18next.off("languageChanged", scheduleApply);
|
|
};
|
|
}, [width, ready]);
|
|
return ref;
|
|
}
|