feat(playlists): two-way (3-way) merge YouTube sync + mandatory preview (S7)
"Sync to YouTube" was a one-directional destructive push (local wins, deletes from YouTube every item not in the local list), so items added on YouTube were lost and a dirty pull was skipped entirely. Replace it with a real 3-way merge: each item is classified against the last-synced baseline as a local-add, a YouTube-add, or a genuine delete, so an add or delete on either side survives. - Persist the ordered baseline id set (new playlists.synced_video_ids, migration 0075); the fingerprint hash alone couldn't drive a merge. NULL baseline (fresh export / pre-S7 link) unions losslessly on the first sync and records one. - Pure merge_plan(baseline, local, youtube) -> add/remove per side + merged order (local order, YouTube-only additions appended). merge_playlist applies the local side directly and the YouTube side through the failure breaker; the baseline only advances on full success so a partial failure re-converges. - plan_merge/push-plan now report what each side gains and loses; the confirm dialog shows the two-way plan before applying (pushPlanMerge, HU+EN). - Tests: 10 new (pure classification incl. delete-vs-stale-copy; DB apply proving a YouTube-add and a Siftlode-add both survive on both sides, a genuine delete propagates without collateral loss, no-baseline never deletes, create path).
This commit is contained in:
@@ -35,8 +35,7 @@
|
||||
"pushTitle": "Sync to YouTube",
|
||||
"pushConfirm": "Sync",
|
||||
"pushPlanCreate": "Create a new YouTube playlist with {{count}} videos? (~{{units}} quota units; {{left}} left today.)",
|
||||
"pushPlanUpdate": "Update on YouTube — add {{insert}}, remove {{del}}, reorder {{reorder}}? (~{{units}} quota units; {{left}} left today.)",
|
||||
"pushDiverged": "{{count}} video(s) currently on YouTube will be removed.",
|
||||
"pushPlanMerge": "Two-way sync — on YouTube: +{{addYt}} / −{{removeYt}}; here: +{{addLocal}} / −{{removeLocal}}. (~{{units}} quota units; {{left}} left today.)",
|
||||
"pushNoQuota": "Not enough YouTube quota left today ({{left}}) for this sync (~{{units}} needed). Try again tomorrow.",
|
||||
"pushUpToDate": "“{{name}}” is already in sync with YouTube.",
|
||||
"pushDone": "“{{name}}” synced to YouTube ✓",
|
||||
|
||||
@@ -35,8 +35,7 @@
|
||||
"pushTitle": "Szinkron YouTube-ra",
|
||||
"pushConfirm": "Szinkron",
|
||||
"pushPlanCreate": "Létrehozol egy új YouTube-listát {{count}} videóval? (~{{units}} kvótaegység; ma még {{left}} maradt.)",
|
||||
"pushPlanUpdate": "Frissítés a YouTube-on — {{insert}} hozzáadása, {{del}} eltávolítása, {{reorder}} átrendezése? (~{{units}} kvótaegység; ma még {{left}} maradt.)",
|
||||
"pushDiverged": "{{count}} videó, amely jelenleg a YouTube-on van, el lesz távolítva.",
|
||||
"pushPlanMerge": "Kétirányú szinkron — YouTube-on: +{{addYt}} / −{{removeYt}}; itt: +{{addLocal}} / −{{removeLocal}}. (~{{units}} kvótaegység; ma még {{left}} maradt.)",
|
||||
"pushNoQuota": "Nincs elég YouTube-kvóta mára ({{left}}) ehhez a szinkronhoz (~{{units}} kell). Próbáld újra holnap.",
|
||||
"pushUpToDate": "A(z) „{{name}}” már szinkronban van a YouTube-bal.",
|
||||
"pushDone": "„{{name}}” szinkronizálva a YouTube-ra ✓",
|
||||
|
||||
Reference in New Issue
Block a user