sync: fix SyncStatus binding — remove invalid type assertion, use config for device ID

This commit is contained in:
mirivlad 2026-06-01 22:55:50 +08:00
parent 1a20edac44
commit 5b2cec5bcc
1 changed files with 88 additions and 0 deletions

View File

@ -14,6 +14,7 @@ import (
"verstak/internal/core/actions" "verstak/internal/core/actions"
"verstak/internal/core/activity" "verstak/internal/core/activity"
"verstak/internal/core/config"
"verstak/internal/core/files" "verstak/internal/core/files"
"verstak/internal/core/notes" "verstak/internal/core/notes"
"verstak/internal/core/nodes" "verstak/internal/core/nodes"
@ -835,6 +836,93 @@ func (a *App) Search(query string) ([]SearchResultDTO, error) {
return out, nil return out, nil
} }
// ============================================================
// Sync
// ============================================================
type SyncStatusDTO struct {
Configured bool `json:"configured"`
ServerURL string `json:"serverUrl"`
DeviceID string `json:"deviceId"`
UnpushedOps int `json:"unpushedOps"`
LastSyncAt string `json:"lastSyncAt"`
}
func (a *App) SyncStatus() (*SyncStatusDTO, error) {
serverURL, apiKey, _, lastSyncAt, err := a.sync.GetState()
if err != nil {
return &SyncStatusDTO{}, nil
}
unpushed, _ := a.sync.GetUnpushedOps()
cfg, _ := config.Load(a.vault)
dto := &SyncStatusDTO{
Configured: serverURL != "" && apiKey != "",
ServerURL: serverURL,
UnpushedOps: len(unpushed),
LastSyncAt: lastSyncAt,
}
if cfg != nil {
dto.DeviceID = cfg.Sync.DeviceID
}
return dto, nil
}
func (a *App) SyncConfigure(serverURL, apiKey string) error {
if err := a.sync.SetState(serverURL, apiKey); err != nil {
return err
}
// Persist to vault config.
cfg, err := config.Load(a.vault)
if err != nil {
return err
}
cfg.Sync.ServerURL = serverURL
cfg.Sync.APIKey = apiKey
return config.Save(a.vault, cfg)
}
func (a *App) SyncNow() (map[string]interface{}, error) {
serverURL, apiKey, lastRev, _, err := a.sync.GetState()
if err != nil || serverURL == "" || apiKey == "" {
return nil, fmt.Errorf("sync not configured")
}
deviceID := ""
if cfg, err := config.Load(a.vault); err == nil {
deviceID = cfg.Sync.DeviceID
}
client := syncsvc.NewClient(serverURL, apiKey, deviceID, a.vault)
// Push unpushed ops.
unpushed, err := a.sync.GetUnpushedOps()
if err != nil {
return nil, fmt.Errorf("get ops: %w", err)
}
pushResult := &syncsvc.PushResponse{}
if len(unpushed) > 0 {
pushResult, err = client.Push(unpushed)
if err != nil {
return nil, fmt.Errorf("push: %w", err)
}
if err := a.sync.MarkPushed(pushResult.Accepted); err != nil {
return nil, fmt.Errorf("mark pushed: %w", err)
}
}
// Pull remote ops.
pullResult, err := client.Pull(lastRev)
if err != nil {
return nil, fmt.Errorf("pull: %w", err)
}
return map[string]interface{}{
"pushed": len(pushResult.Accepted),
"pulled": len(pullResult.Ops),
"serverRevision": pullResult.ServerRevision,
}, nil
}
// ============================================================ // ============================================================
// File Dialogs (Wails v2 Runtime) // File Dialogs (Wails v2 Runtime)
// ============================================================ // ============================================================