Implement SyncWarden v0.1.0
Some checks failed
Release / build (push) Failing after 19s

Full Syncthing tray wrapper with:
- System tray with 5 icon states (idle/syncing/paused/error/disconnected)
- Syncthing REST API client with auto-discovered API key
- Long-polling event listener for real-time status
- Transfer rate monitoring, folder tracking, recent files, conflict counting
- Full context menu with folders, recent files, settings toggles
- Embedded admin panel binary (webview, requires CGO)
- OS notifications via beeep (per-event configurable)
- Syncthing process management with auto-restart
- Cross-platform installer with autostart
- CI pipeline for Linux (.deb + .tar.gz) and Windows (.zip)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Axel Meyer
2026-03-03 21:16:28 +01:00
parent 2256df9dd7
commit 34a1a94502
30 changed files with 2156 additions and 38 deletions

View File

@@ -0,0 +1,60 @@
package monitor
import (
"sync"
st "git.davoryn.de/calic/syncwarden/internal/syncthing"
)
// FolderTracker tracks per-folder status.
type FolderTracker struct {
mu sync.Mutex
folders []FolderInfo
}
// NewFolderTracker creates a new folder tracker.
func NewFolderTracker() *FolderTracker {
return &FolderTracker{}
}
// UpdateFromConfig sets the folder list from Syncthing config.
func (ft *FolderTracker) UpdateFromConfig(folders []st.FolderConfig) {
ft.mu.Lock()
defer ft.mu.Unlock()
ft.folders = make([]FolderInfo, len(folders))
for i, f := range folders {
ft.folders[i] = FolderInfo{
ID: f.ID,
Label: f.Label,
Path: f.Path,
State: "unknown",
}
if f.Label == "" {
ft.folders[i].Label = f.ID
}
}
}
// UpdateStatus updates the state for a specific folder.
func (ft *FolderTracker) UpdateStatus(folderID, state string) {
ft.mu.Lock()
defer ft.mu.Unlock()
for i := range ft.folders {
if ft.folders[i].ID == folderID {
ft.folders[i].State = state
return
}
}
}
// Folders returns a snapshot of all folder info.
func (ft *FolderTracker) Folders() []FolderInfo {
ft.mu.Lock()
defer ft.mu.Unlock()
out := make([]FolderInfo, len(ft.folders))
copy(out, ft.folders)
return out
}