Release 3.8.2.4: unify Windows/macOS GUI on glaze HTTP host.
ci / test (macos-latest) (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run

Auto-bump build number on each compile; ship versioned Windows artifacts.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
M4
2026-08-01 16:01:25 +03:00
co-authored by Cursor
parent d1570b23d3
commit 464a61aebf
26 changed files with 406 additions and 256 deletions
+112
View File
@@ -0,0 +1,112 @@
//go:build windows || darwin
package main
import (
"log"
"net/http"
"os"
"os/signal"
"runtime"
"time"
"github.com/crgimenes/glaze"
"vpnclient/internal/apphost"
"vpnclient/internal/config"
"vpnclient/internal/core"
"vpnclient/internal/logbuf"
"vpnclient/internal/trayhost"
"vpnclient/internal/update"
)
func main() {
if update.MaybeFinishUpdate(os.Args[1:]) {
return
}
update.CleanupStaleDownloads()
log.SetFlags(log.LstdFlags | log.Lshortfile)
log.Printf("Navis %s · GOMAXPROCS=%d NumCPU=%d", update.DisplayVersion(), runtime.GOMAXPROCS(0), runtime.NumCPU())
cfgPath, err := config.LocateConfig()
if err != nil {
fatalf("Не удалось найти путь конфига: %v", err)
}
if _, err := os.Stat(cfgPath); os.IsNotExist(err) {
if err := config.WriteExample(cfgPath); err != nil {
fatalf("Не удалось создать конфиг: %v", err)
}
}
cfg, err := config.Load(cfgPath)
if err != nil {
fatalf("Ошибка конфига %s: %v", cfgPath, err)
}
logBuf := logbuf.New(0)
mgr, err := core.NewManager(cfgPath, cfg, logBuf)
if err != nil {
fatalf("%v", err)
}
a := apphost.New(mgr, cfgPath, logBuf)
a.OpenURL = openExternal
a.OnAfterUpdate = func() {
// Hard-exit so the OS unlocks the binary for replacement.
go func() {
time.Sleep(300 * time.Millisecond)
_ = a.Disconnect()
os.Exit(0)
}()
}
ln, uiURL, token, err := apphost.ListenLocal()
if err != nil {
fatalf("listen: %v", err)
}
a.APIToken = token
srv := &http.Server{Handler: a.Handler()}
go func() {
_ = srv.Serve(ln)
}()
a.StartBackground()
trayhost.Start("Navis", trayhost.Hooks{
Connect: func() { _ = a.Connect() },
Disconnect: func() { _ = a.Disconnect() },
Quit: func() {
_ = a.Disconnect()
os.Exit(0)
},
IsUp: func() bool { return a.Mgr.Status().Connected },
})
go a.AutoCheckUpdate()
w, err := glaze.New(false)
if err != nil || w == nil {
log.Printf("webview unavailable (%v); opening default browser", err)
if err2 := openExternal(uiURL); err2 != nil {
_ = srv.Close()
fatalf("Не удалось открыть интерфейс:\n%v\n%v\n%s", err, err2, uiURL)
}
log.Printf("Navis UI: %s", uiURL)
sig := make(chan os.Signal, 1)
signal.Notify(sig, shutdownSignals()...)
<-sig
_ = mgr.Disconnect()
_ = srv.Close()
return
}
defer func() {
_ = mgr.Disconnect()
_ = srv.Close()
w.Destroy()
}()
w.SetTitle("Navis")
w.SetSize(500, 900, glaze.HintNone)
decorateWindow(w)
w.Navigate(uiURL)
log.Printf("Navis UI: %s", uiURL)
w.Run()
}