Last active
March 1, 2024 18:05
-
-
Save AhmedMourad0/1f4430bae5f620ab68ee4f84c7505705 to your computer and use it in GitHub Desktop.
Code snippet for the `Leveraging the Power of Snapshots in Jetpack Compose` Medium article.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Stable | |
class UndoManager(private val stickers: () -> List<Sticker>) { | |
private val undoHistory = mutableStateListOf<BoardAction>() | |
private val redoHistory = mutableStateListOf<BoardAction>() | |
fun register(action: BoardAction) { | |
val invertedAction = action.invert(oldSticker = ???) | |
undoHistory.add(invertedAction) | |
redoHistory.clear() | |
} | |
suspend fun undo(): List<Sticker> = applyAndMove( | |
from = undoHistory, | |
to = redoHistory, | |
stickers = stickers() | |
) | |
suspend fun redo(): List<Sticker> = applyAndMove( | |
from = redoHistory, | |
to = undoHistory, | |
stickers = stickers() | |
) | |
} | |
private suspend fun applyAndMove( | |
from: MutableList<BoardAction>, | |
to: MutableList<BoardAction>, | |
stickers: List<Sticker> | |
): List<Sticker> { | |
if (from.isEmpty()) return stickers | |
return when (val action = from.removeLast()) { | |
is BoardAction.Add -> { | |
to.add(action.invert(action.sticker)) | |
stickers + action.sticker | |
} | |
is BoardAction.Remove -> { | |
val sticker = stickers.last() | |
to.add(action.invert(sticker)) | |
stickers - sticker | |
} | |
is BoardAction.Transform -> { | |
stickers.onEach { sticker -> | |
if (sticker.id == action.id) { | |
to.add(action.invert(sticker)) | |
sticker.offset = action.offset | |
sticker.zIndex = action.zIndex | |
sticker.rotationZ = action.rotationZ | |
sticker.scaleX = action.scaleX | |
sticker.scaleY = action.scaleY | |
} | |
} | |
} | |
} | |
} | |
private fun BoardAction.invert(oldSticker: Sticker): BoardAction = when (this) { | |
is BoardAction.Add -> BoardAction.Remove(oldSticker.id) | |
is BoardAction.Remove -> BoardAction.Add(oldSticker) | |
is BoardAction.Transform -> BoardAction.Transform(oldSticker) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment