Skip to content

Instantly share code, notes, and snippets.

@AhmedMourad0
Last active March 1, 2024 18:05
Show Gist options
  • Save AhmedMourad0/1f4430bae5f620ab68ee4f84c7505705 to your computer and use it in GitHub Desktop.
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.
@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