From 597c1dd8b23f5783d8ab8e5a36fbf32fda1296cc Mon Sep 17 00:00:00 2001 From: Jake Wharton Date: Wed, 13 Sep 2023 07:02:29 -0400 Subject: [PATCH] Move reset() function up to RedwoodView (#1476) --- .../app/cash/redwood/compose/RedwoodComposition.kt | 2 ++ .../app/cash/redwood/composeui/RedwoodContent.kt | 3 +++ .../app/cash/redwood/treehouse/TreehouseLayout.kt | 8 -------- .../app/cash/redwood/treehouse/TreehouseView.kt | 3 --- .../app/cash/redwood/treehouse/TreehouseUIView.kt | 9 --------- .../kotlin/app/cash/redwood/widget/RedwoodLayout.kt | 7 +++++++ .../kotlin/app/cash/redwood/widget/RedwoodView.kt | 7 +++++++ .../kotlin/app/cash/redwood/widget/RedwoodUIView.kt | 8 ++++++++ .../cash/redwood/widget/RedwoodHTMLElementView.kt | 13 +++++++++++-- 9 files changed, 38 insertions(+), 22 deletions(-) diff --git a/redwood-compose/src/commonMain/kotlin/app/cash/redwood/compose/RedwoodComposition.kt b/redwood-compose/src/commonMain/kotlin/app/cash/redwood/compose/RedwoodComposition.kt index 7f58f8977e..fed1de6575 100644 --- a/redwood-compose/src/commonMain/kotlin/app/cash/redwood/compose/RedwoodComposition.kt +++ b/redwood-compose/src/commonMain/kotlin/app/cash/redwood/compose/RedwoodComposition.kt @@ -53,6 +53,8 @@ public fun RedwoodComposition( provider: Widget.Provider, onEndChanges: () -> Unit = {}, ): RedwoodComposition { + view.reset() + return RedwoodComposition(scope, view.children, view.uiConfiguration, provider, onEndChanges) } diff --git a/redwood-composeui/src/commonMain/kotlin/app/cash/redwood/composeui/RedwoodContent.kt b/redwood-composeui/src/commonMain/kotlin/app/cash/redwood/composeui/RedwoodContent.kt index f8709d277c..145892d6f3 100644 --- a/redwood-composeui/src/commonMain/kotlin/app/cash/redwood/composeui/RedwoodContent.kt +++ b/redwood-composeui/src/commonMain/kotlin/app/cash/redwood/composeui/RedwoodContent.kt @@ -58,6 +58,9 @@ public fun RedwoodContent( object : RedwoodView<@Composable () -> Unit> { override val children = ComposeWidgetChildren() override val uiConfiguration = MutableStateFlow(uiConfiguration) + override fun reset() { + children.remove(0, children.widgets.size) + } } } LaunchedEffect(redwoodView, uiConfiguration) { diff --git a/redwood-treehouse-host/src/androidMain/kotlin/app/cash/redwood/treehouse/TreehouseLayout.kt b/redwood-treehouse-host/src/androidMain/kotlin/app/cash/redwood/treehouse/TreehouseLayout.kt index dba7bb4e3d..7f2f79b8ae 100644 --- a/redwood-treehouse-host/src/androidMain/kotlin/app/cash/redwood/treehouse/TreehouseLayout.kt +++ b/redwood-treehouse-host/src/androidMain/kotlin/app/cash/redwood/treehouse/TreehouseLayout.kt @@ -24,7 +24,6 @@ import android.view.ViewGroup.LayoutParams.MATCH_PARENT import app.cash.redwood.treehouse.TreehouseView.ReadyForContentChangeListener import app.cash.redwood.treehouse.TreehouseView.WidgetSystem import app.cash.redwood.widget.RedwoodLayout -import app.cash.redwood.widget.ViewGroupChildren import java.util.UUID @Deprecated( @@ -56,13 +55,6 @@ public class TreehouseLayout( override var saveCallback: TreehouseView.SaveCallback? = null - override fun reset() { - children.remove(0, (children as ViewGroupChildren).widgets.size) - - // Ensure any out-of-band views are also removed. - removeAllViews() - } - override fun onAttachedToWindow() { super.onAttachedToWindow() readyForContent = true diff --git a/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/TreehouseView.kt b/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/TreehouseView.kt index 8b7934727c..e447c16871 100644 --- a/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/TreehouseView.kt +++ b/redwood-treehouse-host/src/commonMain/kotlin/app/cash/redwood/treehouse/TreehouseView.kt @@ -29,9 +29,6 @@ public interface TreehouseView : RedwoodView { public var saveCallback: SaveCallback? public val stateSnapshotId: StateSnapshot.Id - /** Invoked when new code is loaded. This should at minimum clear all [children]. */ - public fun reset() - @ObjCName("TreehouseViewReadyForContentChangeListener", exact = true) public fun interface ReadyForContentChangeListener { /** Called when [TreehouseView.readyForContent] has changed. */ diff --git a/redwood-treehouse-host/src/iosMain/kotlin/app/cash/redwood/treehouse/TreehouseUIView.kt b/redwood-treehouse-host/src/iosMain/kotlin/app/cash/redwood/treehouse/TreehouseUIView.kt index c7dbcb31a2..fe49bf8fdf 100644 --- a/redwood-treehouse-host/src/iosMain/kotlin/app/cash/redwood/treehouse/TreehouseUIView.kt +++ b/redwood-treehouse-host/src/iosMain/kotlin/app/cash/redwood/treehouse/TreehouseUIView.kt @@ -18,7 +18,6 @@ package app.cash.redwood.treehouse import app.cash.redwood.treehouse.TreehouseView.ReadyForContentChangeListener import app.cash.redwood.treehouse.TreehouseView.WidgetSystem import app.cash.redwood.widget.RedwoodUIView -import app.cash.redwood.widget.UIViewChildren import kotlinx.cinterop.cValue import platform.CoreGraphics.CGRectZero import platform.UIKit.UITraitCollection @@ -54,14 +53,6 @@ public class TreehouseUIView private constructor( (view as RootUiView).treehouseView = this } - override fun reset() { - children.remove(0, (children as UIViewChildren).widgets.size) - - // Ensure any out-of-band views are also removed. - @Suppress("UNCHECKED_CAST") // Correct generic lost by cinterop. - (view.subviews as List).forEach(UIView::removeFromSuperview) - } - private fun superviewChanged() { readyForContentChangeListener?.onReadyForContentChanged(this) } diff --git a/redwood-widget/src/androidMain/kotlin/app/cash/redwood/widget/RedwoodLayout.kt b/redwood-widget/src/androidMain/kotlin/app/cash/redwood/widget/RedwoodLayout.kt index d7f8248308..c1c88b972e 100644 --- a/redwood-widget/src/androidMain/kotlin/app/cash/redwood/widget/RedwoodLayout.kt +++ b/redwood-widget/src/androidMain/kotlin/app/cash/redwood/widget/RedwoodLayout.kt @@ -38,6 +38,13 @@ public open class RedwoodLayout( override val uiConfiguration: StateFlow get() = mutableUiConfiguration + override fun reset() { + _children.remove(0, _children.widgets.size) + + // Ensure any out-of-band views are also removed. + removeAllViews() + } + init { setOnWindowInsetsChangeListener { insets -> mutableUiConfiguration.value = computeUiConfiguration(insets = insets.safeDrawing) diff --git a/redwood-widget/src/commonMain/kotlin/app/cash/redwood/widget/RedwoodView.kt b/redwood-widget/src/commonMain/kotlin/app/cash/redwood/widget/RedwoodView.kt index c0d33c3429..fd355305de 100644 --- a/redwood-widget/src/commonMain/kotlin/app/cash/redwood/widget/RedwoodView.kt +++ b/redwood-widget/src/commonMain/kotlin/app/cash/redwood/widget/RedwoodView.kt @@ -23,4 +23,11 @@ import kotlinx.coroutines.flow.StateFlow public interface RedwoodView { public val children: Widget.Children public val uiConfiguration: StateFlow + + /** + * This should at minimum clear all [children]. + * + * Invoke when switching the backing composition to prepare the view for an initial load. + */ + public fun reset() } diff --git a/redwood-widget/src/iosMain/kotlin/app/cash/redwood/widget/RedwoodUIView.kt b/redwood-widget/src/iosMain/kotlin/app/cash/redwood/widget/RedwoodUIView.kt index c88c7acf63..59f323e4dd 100644 --- a/redwood-widget/src/iosMain/kotlin/app/cash/redwood/widget/RedwoodUIView.kt +++ b/redwood-widget/src/iosMain/kotlin/app/cash/redwood/widget/RedwoodUIView.kt @@ -42,6 +42,14 @@ public open class RedwoodUIView( override val uiConfiguration: StateFlow get() = mutableUiConfiguration + override fun reset() { + _children.remove(0, _children.widgets.size) + + // Ensure any out-of-band views are also removed. + @Suppress("UNCHECKED_CAST") // Correct generic lost by cinterop. + (view.subviews as List).forEach(UIView::removeFromSuperview) + } + protected fun updateUiConfiguration() { mutableUiConfiguration.value = computeUiConfiguration( traitCollection = view.traitCollection, diff --git a/redwood-widget/src/jsMain/kotlin/app/cash/redwood/widget/RedwoodHTMLElementView.kt b/redwood-widget/src/jsMain/kotlin/app/cash/redwood/widget/RedwoodHTMLElementView.kt index 8a22289b03..f93bf7c9e6 100644 --- a/redwood-widget/src/jsMain/kotlin/app/cash/redwood/widget/RedwoodHTMLElementView.kt +++ b/redwood-widget/src/jsMain/kotlin/app/cash/redwood/widget/RedwoodHTMLElementView.kt @@ -22,6 +22,7 @@ import app.cash.redwood.widget.Widget.Children import kotlinx.browser.window import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update +import kotlinx.dom.clear import org.w3c.dom.HTMLElement import org.w3c.dom.MediaQueryList @@ -33,9 +34,10 @@ public fun HTMLElement.asRedwoodView(): RedwoodView { } private class RedwoodHTMLElementView( - element: HTMLElement, + private val element: HTMLElement, ) : RedwoodView { - override val children: Children = HTMLElementChildren(element) + private val _children = HTMLElementChildren(element) + override val children: Children get() = _children override val uiConfiguration = MutableStateFlow( UiConfiguration( darkMode = window.matchMedia("(prefers-color-scheme: dark)").matches, @@ -61,4 +63,11 @@ private class RedwoodHTMLElementView( // TODO Watch size change // https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver } + + override fun reset() { + _children.remove(0, _children.widgets.size) + + // Ensure any out-of-band nodes are also removed. + element.clear() + } }