108 lines
2.2 KiB
Go
108 lines
2.2 KiB
Go
package tray
|
|
|
|
import (
|
|
"log"
|
|
"sync"
|
|
|
|
"github.com/energye/systray"
|
|
|
|
"git.davoryn.de/calic/syncwarden/internal/config"
|
|
"git.davoryn.de/calic/syncwarden/internal/icons"
|
|
stClient "git.davoryn.de/calic/syncwarden/internal/syncthing"
|
|
)
|
|
|
|
// App manages the tray icon and Syncthing monitoring.
|
|
type App struct {
|
|
mu sync.Mutex
|
|
cfg config.Config
|
|
client *stClient.Client
|
|
state icons.State
|
|
statusItem *systray.MenuItem
|
|
}
|
|
|
|
// Run starts the tray application (blocking).
|
|
func Run() {
|
|
app := &App{}
|
|
systray.Run(app.onReady, app.onExit)
|
|
}
|
|
|
|
func (a *App) onReady() {
|
|
a.cfg = config.Load()
|
|
|
|
// Auto-discover API key if not configured
|
|
if a.cfg.SyncthingAPIKey == "" {
|
|
if key, err := stClient.DiscoverAPIKey(); err == nil && key != "" {
|
|
a.cfg.SyncthingAPIKey = key
|
|
_ = config.Save(a.cfg)
|
|
log.Printf("auto-discovered Syncthing API key")
|
|
}
|
|
}
|
|
|
|
a.client = stClient.NewClient(a.cfg.BaseURL(), a.cfg.SyncthingAPIKey)
|
|
|
|
// Set initial icon
|
|
a.setState(icons.StateDisconnected)
|
|
systray.SetTitle("SyncWarden")
|
|
systray.SetTooltip("SyncWarden: connecting...")
|
|
|
|
// Right-click shows menu
|
|
systray.SetOnRClick(func(menu systray.IMenu) {
|
|
menu.ShowMenu()
|
|
})
|
|
|
|
// Double-click opens admin panel
|
|
systray.SetOnDClick(func(menu systray.IMenu) {
|
|
a.openPanel()
|
|
})
|
|
|
|
// Build menu
|
|
a.buildMenu()
|
|
|
|
// Check connection
|
|
go a.initialCheck()
|
|
}
|
|
|
|
func (a *App) onExit() {
|
|
log.Println("SyncWarden exiting")
|
|
}
|
|
|
|
func (a *App) setState(s icons.State) {
|
|
a.mu.Lock()
|
|
a.state = s
|
|
a.mu.Unlock()
|
|
|
|
iconData, err := icons.Render(s)
|
|
if err != nil {
|
|
log.Printf("icon render error: %v", err)
|
|
return
|
|
}
|
|
systray.SetIcon(iconData)
|
|
}
|
|
|
|
func (a *App) initialCheck() {
|
|
_, err := a.client.Health()
|
|
if err != nil {
|
|
log.Printf("Syncthing not reachable: %v", err)
|
|
a.setState(icons.StateDisconnected)
|
|
systray.SetTooltip("SyncWarden: Syncthing not reachable")
|
|
a.mu.Lock()
|
|
if a.statusItem != nil {
|
|
a.statusItem.SetTitle("Status: Disconnected")
|
|
}
|
|
a.mu.Unlock()
|
|
return
|
|
}
|
|
log.Println("Syncthing is reachable")
|
|
a.setState(icons.StateIdle)
|
|
systray.SetTooltip("SyncWarden: Idle")
|
|
a.mu.Lock()
|
|
if a.statusItem != nil {
|
|
a.statusItem.SetTitle("Status: Idle")
|
|
}
|
|
a.mu.Unlock()
|
|
}
|
|
|
|
func (a *App) openPanel() {
|
|
launchPanel(a.cfg.BaseURL())
|
|
}
|