235 lines
4.9 KiB
Go
235 lines
4.9 KiB
Go
//go:build windows
|
|
|
|
// backend\tray.go
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
_ "embed"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/getlantern/systray"
|
|
)
|
|
|
|
//go:embed assets/img/tray.ico
|
|
var trayIcon []byte
|
|
|
|
func runTray(ctx context.Context, onQuit func(), statsFn func() TrayStats) {
|
|
systray.Run(func() {
|
|
if len(trayIcon) > 0 {
|
|
systray.SetIcon(trayIcon)
|
|
}
|
|
|
|
systray.SetTitle("Recorder")
|
|
systray.SetTooltip("Recorder Backend läuft")
|
|
|
|
mStatus := systray.AddMenuItem("Status wird geladen…", "Aktueller Recorder-Status")
|
|
mStatus.Disable()
|
|
|
|
mAutostart := systray.AddMenuItem("Autostart: …", "Autostart-Status")
|
|
mAutostart.Disable()
|
|
|
|
mDownloads := systray.AddMenuItem("Downloads: …", "Download-Status")
|
|
mDownloads.Disable()
|
|
|
|
mPostwork := systray.AddMenuItem("Postwork: …", "Postwork-Status")
|
|
mPostwork.Disable()
|
|
|
|
mEnrich := systray.AddMenuItem("Enrich: …", "Enrich-Status")
|
|
mEnrich.Disable()
|
|
|
|
mDisk := systray.AddMenuItem("Freier Speicher: …", "Speicherplatz")
|
|
mDisk.Disable()
|
|
|
|
mUptime := systray.AddMenuItem("Uptime: …", "Laufzeit")
|
|
mUptime.Disable()
|
|
|
|
systray.AddSeparator()
|
|
|
|
mOpenFrontend := systray.AddMenuItem("Frontend öffnen", "Öffnet das Web-Frontend")
|
|
mOpenRecordDir := systray.AddMenuItem("Record-Ordner öffnen", "Öffnet den Aufnahmeordner")
|
|
mOpenDoneDir := systray.AddMenuItem("Done-Ordner öffnen", "Öffnet den Done-Ordner")
|
|
|
|
systray.AddSeparator()
|
|
|
|
mToggleAutostart := systray.AddMenuItem("Autostart pausieren", "Autostart pausieren oder fortsetzen")
|
|
mStopAll := systray.AddMenuItem(
|
|
"Alle Downloads stoppen + Autostart pausieren",
|
|
"Stoppt alle aktiven Downloads und pausiert den Autostart",
|
|
)
|
|
|
|
systray.AddSeparator()
|
|
|
|
mQuit := systray.AddMenuItem("Beenden", "Backend sauber beenden")
|
|
|
|
updateStatus := func() {
|
|
if statsFn == nil {
|
|
return
|
|
}
|
|
|
|
stats := statsFn()
|
|
|
|
mStatus.SetTitle(stats.MenuTitle())
|
|
mAutostart.SetTitle(stats.AutostartLine())
|
|
mDownloads.SetTitle(stats.DownloadsLine())
|
|
mPostwork.SetTitle(stats.PostworkLine())
|
|
mEnrich.SetTitle(stats.EnrichLine())
|
|
mDisk.SetTitle(stats.DiskLine())
|
|
mUptime.SetTitle(stats.UptimeLine())
|
|
|
|
mToggleAutostart.SetTitle(stats.ToggleAutostartTitle())
|
|
|
|
if stats.AutostartPausedByDisk {
|
|
mToggleAutostart.Disable()
|
|
} else {
|
|
mToggleAutostart.Enable()
|
|
}
|
|
|
|
if stats.ActiveDownloads > 0 || !stats.AutostartPaused {
|
|
mStopAll.Enable()
|
|
} else {
|
|
mStopAll.Disable()
|
|
}
|
|
|
|
systray.SetTooltip(stats.Tooltip())
|
|
}
|
|
|
|
updateStatus()
|
|
|
|
go func() {
|
|
<-ctx.Done()
|
|
systray.Quit()
|
|
}()
|
|
|
|
go func() {
|
|
ticker := time.NewTicker(2 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
updateStatus()
|
|
|
|
case <-mOpenFrontend.ClickedCh:
|
|
_ = openBrowser("https://l14pbbk95100006.tegdssd.de:9999")
|
|
|
|
case <-mOpenRecordDir.ClickedCh:
|
|
_ = openFolder(resolveConfiguredDir(getSettings().RecordDir))
|
|
|
|
case <-mOpenDoneDir.ClickedCh:
|
|
_ = openFolder(resolveConfiguredDir(getSettings().DoneDir))
|
|
|
|
case <-mToggleAutostart.ClickedCh:
|
|
state := getAutostartStatePayload()
|
|
|
|
if state.PausedByDisk {
|
|
updateStatus()
|
|
continue
|
|
}
|
|
|
|
if state.Paused {
|
|
setAutostartPaused(false)
|
|
} else {
|
|
setAutostartPaused(true)
|
|
}
|
|
|
|
updateStatus()
|
|
|
|
case <-mStopAll.ClickedCh:
|
|
_ = stopAllDownloadsAndPauseAutostart()
|
|
updateStatus()
|
|
|
|
case <-mQuit.ClickedCh:
|
|
onQuit()
|
|
systray.Quit()
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
}, func() {
|
|
// optional cleanup
|
|
})
|
|
}
|
|
|
|
func stopAllDownloadsAndPauseAutostart() int {
|
|
// Immer zuerst Autostart pausieren, damit nichts direkt wieder neu startet.
|
|
setAutostartPaused(true)
|
|
|
|
// Danach aktive Downloads stoppen.
|
|
return stopAllActiveDownloads()
|
|
}
|
|
|
|
func stopAllActiveDownloads() int {
|
|
jobsMu.RLock()
|
|
toStop := make([]*RecordJob, 0, len(jobs))
|
|
|
|
for _, job := range jobs {
|
|
if job == nil {
|
|
continue
|
|
}
|
|
if isPostworkJob(job) {
|
|
continue
|
|
}
|
|
if isTerminalJobStatus(job.Status) {
|
|
continue
|
|
}
|
|
if job.EndedAt != nil {
|
|
continue
|
|
}
|
|
|
|
toStop = append(toStop, job)
|
|
}
|
|
jobsMu.RUnlock()
|
|
|
|
if len(toStop) > 0 {
|
|
stopJobsInternal(toStop)
|
|
}
|
|
|
|
return len(toStop)
|
|
}
|
|
|
|
func resolveConfiguredDir(raw string) string {
|
|
raw = strings.TrimSpace(raw)
|
|
if raw == "" {
|
|
return ""
|
|
}
|
|
|
|
if abs, err := resolvePathRelativeToApp(raw); err == nil && strings.TrimSpace(abs) != "" {
|
|
return abs
|
|
}
|
|
|
|
return raw
|
|
}
|
|
|
|
func openFolder(dir string) error {
|
|
dir = filepath.Clean(strings.TrimSpace(dir))
|
|
if dir == "" {
|
|
return nil
|
|
}
|
|
|
|
switch runtime.GOOS {
|
|
case "windows":
|
|
return exec.Command("explorer", dir).Start()
|
|
case "darwin":
|
|
return exec.Command("open", dir).Start()
|
|
default:
|
|
return exec.Command("xdg-open", dir).Start()
|
|
}
|
|
}
|
|
|
|
func openBrowser(url string) error {
|
|
switch runtime.GOOS {
|
|
case "windows":
|
|
return exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
|
|
case "darwin":
|
|
return exec.Command("open", url).Start()
|
|
default:
|
|
return exec.Command("xdg-open", url).Start()
|
|
}
|
|
}
|