Skip to content

Commit

Permalink
Propagate BackHandler#enabled changing in Treehouse
Browse files Browse the repository at this point in the history
  • Loading branch information
veyndan committed Nov 13, 2023
1 parent ea3fc40 commit 34941f6
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import app.cash.redwood.ui.OnBackPressedDispatcher
import app.cash.redwood.ui.UiConfiguration
import app.cash.zipline.ZiplineScope
import app.cash.zipline.ZiplineScoped
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.plus

Expand Down Expand Up @@ -135,15 +136,21 @@ private fun ZiplineTreehouseUi.Host.asOnBackPressedDispatcher() = object : OnBac
}

private fun OnBackPressedCallback.asService() = object : OnBackPressedCallbackService {
override var isEnabled: Boolean
get() = this@asService.isEnabled
set(value) {
this@asService.isEnabled = value
override val isEnabled = MutableStateFlow(this@asService.isEnabled)

init {
enabledChangedCallback = {
isEnabled.value = this@asService.isEnabled
}
}

override fun handleOnBackPressed() {
this@asService.handleOnBackPressed()
}

override fun close() {
enabledChangedCallback = null
}
}

private object NullOnBackPressedDispatcherService : OnBackPressedDispatcherService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ internal actual fun platformOnBackPressedDispatcher(): RedwoodOnBackPressedDispa
object : RedwoodOnBackPressedDispatcher {
override fun addCallback(onBackPressedCallback: RedwoodOnBackPressedCallback): Cancellable {
val androidOnBackPressedCallback = onBackPressedCallback.toAndroid()
onBackPressedCallback.enabledChangedCallback = {
androidOnBackPressedCallback.isEnabled = onBackPressedCallback.isEnabled
}
delegate.addCallback(androidOnBackPressedCallback)
return object : Cancellable {
override fun cancel() {
onBackPressedCallback.enabledChangedCallback = null
androidOnBackPressedCallback.remove()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.job
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine

private class State<A : AppService>(
val viewState: ViewState,
Expand Down Expand Up @@ -457,20 +458,29 @@ private class ViewContentCodeBinding<A : AppService>(
onBackPressedCallbackService: OnBackPressedCallbackService,
): CancellableService {
dispatchers.checkZipline()
val cancellable = onBackPressedDispatcher.addCallback(
object : OnBackPressedCallback(onBackPressedCallbackService.isEnabled) {
val cancellableJob = bindingScope.launch(dispatchers.zipline) {
val onBackPressedCallback = object : OnBackPressedCallback(onBackPressedCallbackService.isEnabled.value) {
override fun handleOnBackPressed() {
bindingScope.launch(dispatchers.zipline) {
onBackPressedCallbackService.handleOnBackPressed()
}
}
},
)
}
val cancellable = onBackPressedDispatcher.addCallback(onBackPressedCallback)
launch {
onBackPressedCallbackService.isEnabled.collect {
onBackPressedCallback.isEnabled = it
}
}
suspendCancellableCoroutine { continuation ->
continuation.invokeOnCancellation { cancellable.cancel() }
}
}

return object : CancellableService {
override fun cancel() {
dispatchers.checkZipline()
cancellable.cancel()
cancellableJob.cancel()
}

override fun close() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import app.cash.redwood.protocol.PropertyChange
import app.cash.redwood.protocol.PropertyTag
import app.cash.redwood.protocol.WidgetTag
import app.cash.redwood.ui.UiConfiguration
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.serialization.json.JsonPrimitive

Expand Down Expand Up @@ -62,7 +63,7 @@ class FakeZiplineTreehouseUi(

fun addBackHandler(isEnabled: Boolean): CancellableService {
val result = host.addOnBackPressedCallback(object : OnBackPressedCallbackService {
override var isEnabled = isEnabled
override var isEnabled = MutableStateFlow(isEnabled)

override fun handleOnBackPressed() {
eventLog += "$name.onBackPressed()"
Expand Down
4 changes: 2 additions & 2 deletions redwood-treehouse/api/zipline-api.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ functions = [
# fun handleOnBackPressed(): kotlin.Unit
"NjIN59uX",

# var isEnabled: kotlin.Boolean
"yKh+yo1c",
# val isEnabled: kotlinx.coroutines.flow.StateFlow<kotlin.Boolean>
"TAJYS/cz",
]

[app.cash.redwood.treehouse.OnBackPressedDispatcherService]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ package app.cash.redwood.treehouse
import app.cash.redwood.ui.OnBackPressedCallback
import app.cash.zipline.ZiplineService
import kotlin.native.ObjCName
import kotlinx.coroutines.flow.StateFlow

/** Redwood's [OnBackPressedCallback] but implementing [ZiplineService]. */
@ObjCName("OnBackPressedCallbackService", exact = true)
public interface OnBackPressedCallbackService : ZiplineService {
public var isEnabled: Boolean
public val isEnabled: StateFlow<Boolean>

public fun handleOnBackPressed()
}

0 comments on commit 34941f6

Please sign in to comment.