From 93c012129a1db3ab8d31aa694f9dff10cc35faaf Mon Sep 17 00:00:00 2001 From: J1coding Date: Thu, 30 Jul 2026 16:31:10 +0200 Subject: [PATCH] iOS: make Cancel in the colours editor mean cancel Cancel is wrong in both directions at once. It throws away the swatch you just saved and keeps the colour edits you just cancelled. Saving a swatch mid session calls onSaveAppearance, which persists the entire preferences struct rather than just the swatch, so every edit made before that point is already committed. cancelChanges then restores the bindings in memory and never writes them back, so those edits survive. Meanwhile the swatch list is @AppStorage and writes through the moment the snapshot restores it, which deletes the swatch that was explicitly saved. So commit the restored state instead of leaving it in memory, and leave the swatch list out of the restore. Undo and redo still move the swatch list with everything else, which is what you want from undo. Only Cancel treats a saved swatch as something you meant to keep. --- .../Background/Dynamic/DynamicColours.swift | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/platforms/ios/app/src/main/swift/Views/Background/Dynamic/DynamicColours.swift b/platforms/ios/app/src/main/swift/Views/Background/Dynamic/DynamicColours.swift index a70af43617..77c8d4cf88 100644 --- a/platforms/ios/app/src/main/swift/Views/Background/Dynamic/DynamicColours.swift +++ b/platforms/ios/app/src/main/swift/Views/Background/Dynamic/DynamicColours.swift @@ -1746,7 +1746,13 @@ struct ThemePaletteEditor: View { applyEditorSnapshot(snapshot) } - private func applyEditorSnapshot(_ snapshot: ThemePaletteEditorSnapshot) { + // restoringSavedColors is false only for Cancel. Undo and redo do want the swatch list + // to move with everything else; Cancel does not, because saving a swatch is its own + // deliberate act and rolling it back reads as losing work. + private func applyEditorSnapshot( + _ snapshot: ThemePaletteEditorSnapshot, + restoringSavedColors: Bool = true + ) { pendingUndoSnapshot = nil sharedPalette = snapshot.sharedPalette sharedCustomColor = snapshot.sharedCustomColor @@ -1756,7 +1762,9 @@ struct ThemePaletteEditor: View { ribbonMultiColor = snapshot.ribbonMultiColor particleSettings = snapshot.particleSettings isPlayStation3XMBPresetExplicit = snapshot.isPlayStation3XMBPresetExplicit - savedColorsJSON = snapshot.savedColorsJSON + if restoringSavedColors { + savedColorsJSON = snapshot.savedColorsJSON + } lastEditorSnapshot = snapshot } @@ -1776,7 +1784,11 @@ struct ThemePaletteEditor: View { isClosingEditor = true endBackgroundPreview() if let initialEditorSnapshot { - applyEditorSnapshot(initialEditorSnapshot) + applyEditorSnapshot(initialEditorSnapshot, restoringSavedColors: false) + // Restoring the bindings is not enough. Saving a swatch mid session calls + // onSaveAppearance, which persists the whole preferences struct, so everything + // edited before that point is already committed and would outlive Cancel. + onSaveAppearance() } dismiss() }