chore(wailsv3): migrate Go backend from Wails v2 to v3

Minimal-structure migration to Wails v3.0.0-beta.20 (CLI-matching pin). Single App service preserved; no domain logic touched.

- main.go: wails.Run(options.App) -> application.New + RegisterService + Window.NewWithOptions. Window keeps title-with-version, 1024x768, RGBA background, Linux icon/translucency/GpuPolicyNever, ProgramName. SingleInstanceLock -> SingleInstanceOptions (same UniqueID); callback closes over the service variable set right after New.
- app.go: App holds *application.App instead of a context. startup(ctx) is gone; the version title moves into the window options via appTitle(). onSecondInstanceLaunch takes v3 SecondInstanceData (Args/WorkingDir) and uses Window.Current() Restore+Focus plus Event.Emit for launchArgs. ShowVersion uses Dialog.Info.
- AniList/MAL/Simkl *UserFunctions.go: runtime.BrowserOpenURL -> app.Browser.OpenURL (errors logged), runtime.MessageDialog -> app.Dialog.Info chains. OAuth callback servers, token flows, and key names unchanged.
- Secrets: 99designs/keyring replaced with zalando/go-keyring (what v3 itself depends on) under the same AniTrack service name, so existing stored tokens keep working. Per-file Set helpers kept; Open/Ready boilerplate deleted (zalando needs no handle).
- go.mod: v2 + 99designs dropped (stale v2 replace directive removed), v3 beta.20 + zalando v0.2.8 added.
This commit is contained in:
John O'Keefe
2026-09-13 17:10:09 -04:00
parent 2bf8d3887e
commit 850c1c6aee
13 changed files with 184 additions and 2191 deletions
+23 -32
View File
@@ -1,58 +1,49 @@
package main
import (
"context"
_ "embed"
"log"
"strings"
"github.com/wailsapp/wails/v2/pkg/options"
"github.com/wailsapp/wails/v2/pkg/runtime"
"github.com/tidwall/gjson"
"github.com/wailsapp/wails/v3/pkg/application"
)
//go:embed wails.json
var wailsJSON string
var wailsContext *context.Context
// App struct
type App struct {
ctx context.Context
app *application.App
}
// NewApp creates a new App application struct
func NewApp() *App {
return &App{}
func NewApp(app *application.App) *App {
return &App{app: app}
}
// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
version := gjson.Get(wailsJSON, "info.productVersion")
wailsContext = &ctx
runtime.WindowSetTitle(ctx, "AniTrack "+version.String())
//runtime.WindowMaximise(ctx)
// appVersion reads the product version from wails.json.
func appVersion() string {
return gjson.Get(wailsJSON, "info.productVersion").String()
}
func (a *App) onSecondInstanceLaunch(secondInstanceData options.SecondInstanceData) {
var secondInstanceArgs = secondInstanceData.Args
// appTitle is the window title: "AniTrack <version>".
func appTitle() string {
return "AniTrack " + appVersion()
}
println("user opened second instance", strings.Join(secondInstanceData.Args, ","))
println("user opened second from", secondInstanceData.WorkingDirectory)
runtime.WindowUnminimise(*wailsContext)
runtime.Show(*wailsContext)
go runtime.EventsEmit(*wailsContext, "launchArgs", secondInstanceArgs)
func (a *App) onSecondInstanceLaunch(data application.SecondInstanceData) {
println("user opened second instance", strings.Join(data.Args, ","))
println("user opened second from", data.WorkingDir)
if w := a.app.Window.Current(); w != nil {
w.Restore()
w.Focus()
}
go a.app.Event.Emit("launchArgs", data.Args)
}
func (a *App) ShowVersion() {
version := gjson.Get(wailsJSON, "info.productVersion")
_, err := runtime.MessageDialog(*wailsContext, runtime.MessageDialogOptions{
Title: "Version",
Message: "AniTrack Version: " + version.String(),
})
if err != nil {
log.Println(err)
}
a.app.Dialog.Info().
SetTitle("Version").
SetMessage("AniTrack Version: " + appVersion()).
Show()
}