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.
This commit is contained in:
J1coding
2026-07-30 16:38:07 +02:00
committed by Jeen
parent 8b3f141639
commit 93c012129a
@@ -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()
}