Add green N AppIcon to the .app bundle, keep WKWebView GUI stable, and stamp builds via BaseVersion/BuildNumber. Co-authored-by: Cursor <cursoragent@cursor.com>
104 lines
2.2 KiB
Go
104 lines
2.2 KiB
Go
//go:build darwin
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/crgimenes/glaze"
|
|
|
|
"vpnclient/internal/apphost"
|
|
"vpnclient/internal/config"
|
|
"vpnclient/internal/core"
|
|
"vpnclient/internal/update"
|
|
)
|
|
|
|
func main() {
|
|
if update.MaybeFinishUpdate(os.Args[1:]) {
|
|
return
|
|
}
|
|
update.CleanupStaleDownloads()
|
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
|
|
|
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 := &bytes.Buffer{}
|
|
mgr, err := core.NewManager(cfgPath, cfg, logBuf)
|
|
if err != nil {
|
|
fatalf("%v", err)
|
|
}
|
|
|
|
a := apphost.New(mgr, cfgPath, logBuf)
|
|
a.OpenURL = func(u string) error {
|
|
return exec.Command("open", u).Start()
|
|
}
|
|
a.OnAfterUpdate = func() {
|
|
go func() {
|
|
time.Sleep(300 * time.Millisecond)
|
|
os.Exit(0)
|
|
}()
|
|
}
|
|
|
|
ln, uiURL, err := apphost.ListenLocal()
|
|
if err != nil {
|
|
fatalf("listen: %v", err)
|
|
}
|
|
srv := &http.Server{Handler: a.Handler()}
|
|
go func() {
|
|
_ = srv.Serve(ln)
|
|
}()
|
|
go a.AutoCheckUpdate()
|
|
|
|
w, err := glaze.New(false)
|
|
if err != nil || w == nil {
|
|
log.Printf("webview unavailable (%v); opening default browser", err)
|
|
if err2 := exec.Command("open", uiURL).Run(); err2 != nil {
|
|
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, os.Interrupt, syscall.SIGTERM)
|
|
<-sig
|
|
_ = mgr.Disconnect()
|
|
_ = srv.Close()
|
|
return
|
|
}
|
|
defer func() {
|
|
_ = mgr.Disconnect()
|
|
_ = srv.Close()
|
|
w.Destroy()
|
|
}()
|
|
|
|
w.SetTitle("Navis 2")
|
|
w.SetSize(500, 900, glaze.HintNone)
|
|
w.Navigate(uiURL)
|
|
log.Printf("Navis UI: %s", uiURL)
|
|
w.Run()
|
|
}
|
|
|
|
func fatalf(format string, args ...any) {
|
|
msg := fmt.Sprintf(format, args...)
|
|
log.Println(msg)
|
|
_ = exec.Command("osascript", "-e", fmt.Sprintf(`display alert "Navis" message %q`, msg)).Run()
|
|
os.Exit(1)
|
|
}
|