fix(conflicts): use winner's source name instead of 'manual'
When resolving a conflict, the last_sync_source is now set to the winner's actual source name (koreader, web, etc.) rather than always 'manual'. This prevents subsequent saves from re-triggering conflicts. Also removes the strict oneof validation on the winner field since the source name is dynamic.
This commit is contained in:
@@ -28,7 +28,7 @@ func NewConflictHandler(db *database.Queries, connManager *wsync.ConnectionManag
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ConflictResolutionRequest struct {
|
type ConflictResolutionRequest struct {
|
||||||
Winner string `json:"winner" validate:"required,oneof=koreader kobo web manual"`
|
Winner string `json:"winner" validate:"required"`
|
||||||
ManualData map[string]interface{} `json:"manual_data"`
|
ManualData map[string]interface{} `json:"manual_data"`
|
||||||
ApplyToAll bool `json:"apply_to_all_future_conflicts"`
|
ApplyToAll bool `json:"apply_to_all_future_conflicts"`
|
||||||
Reason string `json:"reason"`
|
Reason string `json:"reason"`
|
||||||
@@ -235,8 +235,10 @@ func (h *ConflictHandler) ResolveConflict(c *echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
winnerData := map[string]interface{}{}
|
winnerData := map[string]interface{}{}
|
||||||
|
winnerSource := req.Winner
|
||||||
if req.Winner == "manual" {
|
if req.Winner == "manual" {
|
||||||
winnerData = req.ManualData
|
winnerData = req.ManualData
|
||||||
|
winnerSource = "manual"
|
||||||
} else {
|
} else {
|
||||||
source, ok := conflictData[req.Winner]
|
source, ok := conflictData[req.Winner]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -251,7 +253,7 @@ func (h *ConflictHandler) ResolveConflict(c *echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if conflict.ConflictType == "progress" {
|
if conflict.ConflictType == "progress" {
|
||||||
if err := h.applyProgressResolution(conflict.MediaItemID, conflict.UserID, winnerData); err == nil {
|
if err := h.applyProgressResolution(conflict.MediaItemID, conflict.UserID, winnerSource, winnerData); err == nil {
|
||||||
appliedTo["progress"] = true
|
appliedTo["progress"] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -286,7 +288,7 @@ func (h *ConflictHandler) ResolveConflict(c *echo.Context) error {
|
|||||||
return c.JSON(http.StatusOK, response)
|
return c.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ConflictHandler) applyProgressResolution(mediaItemID pgtype.UUID, userID pgtype.UUID, data map[string]interface{}) error {
|
func (h *ConflictHandler) applyProgressResolution(mediaItemID pgtype.UUID, userID pgtype.UUID, winnerSource string, data map[string]interface{}) error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
existingProgress, err := h.db.GetReadingProgress(ctx, database.GetReadingProgressParams{
|
existingProgress, err := h.db.GetReadingProgress(ctx, database.GetReadingProgressParams{
|
||||||
@@ -342,7 +344,7 @@ func (h *ConflictHandler) applyProgressResolution(mediaItemID pgtype.UUID, userI
|
|||||||
CurrentPage: currentPage,
|
CurrentPage: currentPage,
|
||||||
TotalPages: totalPages,
|
TotalPages: totalPages,
|
||||||
LastSyncDevice: pgtype.Text{String: "conflict_resolution", Valid: true},
|
LastSyncDevice: pgtype.Text{String: "conflict_resolution", Valid: true},
|
||||||
LastSyncSource: pgtype.Text{String: "manual", Valid: true},
|
LastSyncSource: pgtype.Text{String: winnerSource, Valid: true},
|
||||||
ViewportY: pgtype.Float8{},
|
ViewportY: pgtype.Float8{},
|
||||||
ScrollPositionX: pgtype.Float8{},
|
ScrollPositionX: pgtype.Float8{},
|
||||||
ScrollPositionY: pgtype.Float8{},
|
ScrollPositionY: pgtype.Float8{},
|
||||||
@@ -551,7 +553,7 @@ func (h *ConflictHandler) BulkResolveConflicts(c *echo.Context) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.applyResolution(conflict.MediaItemID, conflict.UserID, winnerData); err != nil {
|
if err := h.applyResolution(conflict.MediaItemID, conflict.UserID, winningSource, winnerData); err != nil {
|
||||||
results = append(results, ConflictResult{
|
results = append(results, ConflictResult{
|
||||||
ConflictID: conflictIDStr,
|
ConflictID: conflictIDStr,
|
||||||
Status: "error",
|
Status: "error",
|
||||||
@@ -635,7 +637,7 @@ func (h *ConflictHandler) getHighestProgressSource(conflictData map[string]Confl
|
|||||||
return highestSource, highestData
|
return highestSource, highestData
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ConflictHandler) applyResolution(mediaItemID pgtype.UUID, userID pgtype.UUID, data map[string]interface{}) error {
|
func (h *ConflictHandler) applyResolution(mediaItemID pgtype.UUID, userID pgtype.UUID, winnerSource string, data map[string]interface{}) error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
existingProgress, err := h.db.GetReadingProgress(ctx, database.GetReadingProgressParams{
|
existingProgress, err := h.db.GetReadingProgress(ctx, database.GetReadingProgressParams{
|
||||||
@@ -690,8 +692,8 @@ func (h *ConflictHandler) applyResolution(mediaItemID pgtype.UUID, userID pgtype
|
|||||||
CharacterOffset: characterOffset,
|
CharacterOffset: characterOffset,
|
||||||
CurrentPage: currentPage,
|
CurrentPage: currentPage,
|
||||||
TotalPages: totalPages,
|
TotalPages: totalPages,
|
||||||
LastSyncDevice: pgtype.Text{String: "bulk_resolution", Valid: true},
|
LastSyncDevice: pgtype.Text{String: "conflict_resolution", Valid: true},
|
||||||
LastSyncSource: pgtype.Text{String: "bulk", Valid: true},
|
LastSyncSource: pgtype.Text{String: winnerSource, Valid: true},
|
||||||
ViewportY: pgtype.Float8{},
|
ViewportY: pgtype.Float8{},
|
||||||
ScrollPositionX: pgtype.Float8{},
|
ScrollPositionX: pgtype.Float8{},
|
||||||
ScrollPositionY: pgtype.Float8{},
|
ScrollPositionY: pgtype.Float8{},
|
||||||
|
|||||||
Reference in New Issue
Block a user