diff --git a/internal/sync/progress.go b/internal/sync/progress.go index 5631dfa..4e4c1b7 100644 --- a/internal/sync/progress.go +++ b/internal/sync/progress.go @@ -288,6 +288,7 @@ type SaveProgressRequest struct { Percentage *float64 Epubcfi *string + ContextText *string CharacterOffset *int64 Chapter *int ChapterProgress *float64 @@ -334,6 +335,7 @@ func (s *ProgressService) SaveProgress(ctx context.Context, req SaveProgressRequ params.Percentage = existing.Percentage params.CharacterOffset = existing.CharacterOffset params.Epubcfi = existing.Epubcfi + params.ContextText = existing.ContextText params.Chapter = existing.Chapter params.ChapterProgress = existing.ChapterProgress params.ViewportX = existing.ViewportX @@ -355,6 +357,9 @@ func (s *ProgressService) SaveProgress(ctx context.Context, req SaveProgressRequ if req.Epubcfi != nil { params.Epubcfi = pgtype.Text{String: *req.Epubcfi, Valid: *req.Epubcfi != ""} } + if req.ContextText != nil { + params.ContextText = pgtype.Text{String: *req.ContextText, Valid: *req.ContextText != ""} + } if req.CharacterOffset != nil { params.CharacterOffset = pgtype.Int8{Int64: *req.CharacterOffset, Valid: true} } @@ -430,7 +435,13 @@ func (s *ProgressService) SaveProgress(ctx context.Context, req SaveProgressRequ diff = -diff } if diff > 0.01 { - conflictDetected = true + recentlyResolved, _ := s.db.HasRecentConflictResolution(ctx, database.HasRecentConflictResolutionParams{ + MediaItemID: req.MediaItemID, + UserID: req.UserID, + }) + if !recentlyResolved { + conflictDetected = true + } } } } @@ -442,26 +453,24 @@ func (s *ProgressService) SaveProgress(ctx context.Context, req SaveProgressRequ } if conflictDetected { - newData := map[string]interface{}{ - "source": req.Source, - "timestamp": time.Now().Format(time.RFC3339), - "data": buildProgressSnapshot(req), - } - existingData := map[string]interface{}{ - "source": existing.LastSyncSource.String, - "timestamp": existing.LastSyncTimestamp.Time.Format(time.RFC3339), - "data": map[string]interface{}{ - "percentage": float64Ptr(existing.Percentage), - "epubcfi": textPtr(existing.Epubcfi), - "chapter": int32Ptr(existing.Chapter), - "character": int64Ptr(existing.CharacterOffset), - "page": int32Ptr(existing.CurrentPage), - "total_pages": int32Ptr(existing.TotalPages), - }, - } conflictData := map[string]interface{}{ - "new": newData, - "existing": existingData, + req.Source: map[string]interface{}{ + "source": req.Source, + "timestamp": time.Now().Format(time.RFC3339), + "data": buildProgressSnapshot(req), + }, + existing.LastSyncSource.String: map[string]interface{}{ + "source": existing.LastSyncSource.String, + "timestamp": existing.LastSyncTimestamp.Time.Format(time.RFC3339), + "data": map[string]interface{}{ + "percentage": float64Ptr(existing.Percentage), + "epubcfi": textPtr(existing.Epubcfi), + "chapter": int32Ptr(existing.Chapter), + "character": int64Ptr(existing.CharacterOffset), + "page": int32Ptr(existing.CurrentPage), + "total_pages": int32Ptr(existing.TotalPages), + }, + }, } conflictJSON, _ := json.Marshal(conflictData) _, err := s.db.CreateSyncConflict(ctx, database.CreateSyncConflictParams{ @@ -508,6 +517,9 @@ func buildProgressSnapshot(req SaveProgressRequest) map[string]interface{} { if req.Epubcfi != nil { data["epubcfi"] = *req.Epubcfi } + if req.ContextText != nil { + data["context_text"] = *req.ContextText + } if req.Chapter != nil { data["chapter"] = *req.Chapter } diff --git a/internal/sync/queue.go b/internal/sync/queue.go index e2253aa..e4ad5d9 100644 --- a/internal/sync/queue.go +++ b/internal/sync/queue.go @@ -48,6 +48,7 @@ type ProgressUpdate struct { UserID pgtype.UUID Percentage float64 Epubcfi *string + ContextText *string Chapter *int Character *int64 Page *int @@ -122,6 +123,9 @@ func (p *SyncQueueProcessor) enqueueProgressUpdate(ctx context.Context, update * if update.Epubcfi != nil { syncData["epubcfi"] = *update.Epubcfi } + if update.ContextText != nil { + syncData["context_text"] = *update.ContextText + } if update.Chapter != nil { syncData["chapter"] = *update.Chapter } @@ -331,6 +335,9 @@ func (p *SyncQueueProcessor) syncProgress(ctx context.Context, userID pgtype.UUI if v, ok := syncData["epubcfi"].(string); ok { req.Epubcfi = &v } + if v, ok := syncData["context_text"].(string); ok { + req.ContextText = &v + } if v, ok := syncData["chapter"].(float64); ok { ch := int(v) req.Chapter = &ch