Skip to content

Commit 5d385ce

Browse files
committed
Friendlier construction API for BackStackScreen
* Deprecates the confusing `bottom: T, rest: List` constructor * Adds `fromList` and `fromListOrNull` factory functions to `BackStackScreen.Companion`, since no one ever finds the `List` extensions
1 parent 10e9c88 commit 5d385ce

File tree

5 files changed

+60
-22
lines changed

5 files changed

+60
-22
lines changed

Diff for: workflow-ui/compose/src/androidTest/java/com/squareup/workflow1/ui/compose/ComposeViewTreeIntegrationTest.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,9 @@ internal class ComposeViewTreeIntegrationTest {
582582
}
583583

584584
private fun WorkflowUiTestActivity.setBackstack(vararg backstack: TestComposeRendering) {
585-
setRendering(BackStackScreen(EmptyRendering, backstack.asList()))
585+
setRendering(
586+
BackStackScreen.fromList(listOf<AndroidScreen<*>>(EmptyRendering) + backstack.asList())
587+
)
586588
}
587589

588590
data class TestOverlay(

Diff for: workflow-ui/core-android/src/androidTest/java/com/squareup/workflow1/ui/container/fixtures/BackStackContainerLifecycleActivity.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ internal class BackStackContainerLifecycleActivity : AbstractLifecycleTestActivi
145145
setRendering(backstack.asList().toBackstackWithBase())
146146

147147
private fun List<TestRendering>.toBackstackWithBase() =
148-
BackStackScreen(BaseRendering, this)
148+
BackStackScreen.fromList(listOf<Screen>(BaseRendering) + this)
149149
}
150150

151151
internal fun ActivityScenario<BackStackContainerLifecycleActivity>.viewForScreen(

Diff for: workflow-ui/core-common/api/core-common.api

+7
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,10 @@ public final class com/squareup/workflow1/ui/container/BackStackConfigKt {
213213
}
214214

215215
public final class com/squareup/workflow1/ui/container/BackStackScreen : com/squareup/workflow1/ui/Container, com/squareup/workflow1/ui/Screen {
216+
public static final field Companion Lcom/squareup/workflow1/ui/container/BackStackScreen$Companion;
216217
public fun <init> (Lcom/squareup/workflow1/ui/Screen;Ljava/util/List;)V
217218
public fun <init> (Lcom/squareup/workflow1/ui/Screen;[Lcom/squareup/workflow1/ui/Screen;)V
219+
public synthetic fun <init> (Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
218220
public fun asSequence ()Lkotlin/sequences/Sequence;
219221
public fun equals (Ljava/lang/Object;)Z
220222
public final fun get (I)Lcom/squareup/workflow1/ui/Screen;
@@ -229,6 +231,11 @@ public final class com/squareup/workflow1/ui/container/BackStackScreen : com/squ
229231
public fun toString ()Ljava/lang/String;
230232
}
231233

234+
public final class com/squareup/workflow1/ui/container/BackStackScreen$Companion {
235+
public final fun fromList (Ljava/util/List;)Lcom/squareup/workflow1/ui/container/BackStackScreen;
236+
public final fun fromListOrNull (Ljava/util/List;)Lcom/squareup/workflow1/ui/container/BackStackScreen;
237+
}
238+
232239
public final class com/squareup/workflow1/ui/container/BackStackScreenKt {
233240
public static final fun toBackStackScreen (Ljava/util/List;)Lcom/squareup/workflow1/ui/container/BackStackScreen;
234241
public static final fun toBackStackScreenOrNull (Ljava/util/List;)Lcom/squareup/workflow1/ui/container/BackStackScreen;

Diff for: workflow-ui/core-common/src/main/java/com/squareup/workflow1/ui/container/BackStackScreen.kt

+47-17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package com.squareup.workflow1.ui.container
33
import com.squareup.workflow1.ui.Container
44
import com.squareup.workflow1.ui.Screen
55
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
6+
import com.squareup.workflow1.ui.container.BackStackScreen.Companion
7+
import com.squareup.workflow1.ui.container.BackStackScreen.Companion.fromList
8+
import com.squareup.workflow1.ui.container.BackStackScreen.Companion.fromListOrNull
69

710
/**
811
* Represents an active screen ([top]), and a set of previously visited screens to which we may
@@ -13,25 +16,31 @@ import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
1316
*
1417
* UI kits are expected to provide handling for this class by default.
1518
*
16-
* @param bottom the bottom-most entry in the stack
17-
* @param rest the rest of the stack, empty by default
19+
* @see fromList
20+
* @see fromListOrNull
1821
*/
1922
@WorkflowUiExperimentalApi
20-
public class BackStackScreen<StackedT : Screen>(
21-
bottom: StackedT,
22-
rest: List<StackedT>
23+
public class BackStackScreen<StackedT : Screen> private constructor(
24+
public val frames: List<StackedT>
2325
) : Screen, Container<Screen, StackedT> {
2426
/**
2527
* Creates a screen with elements listed from the [bottom] to the top.
2628
*/
2729
public constructor(
2830
bottom: StackedT,
2931
vararg rest: StackedT
30-
) : this(bottom, rest.toList())
32+
) : this(listOf(bottom) + rest)
3133

32-
override fun asSequence(): Sequence<StackedT> = frames.asSequence()
34+
@Deprecated(
35+
"Use fromList",
36+
ReplaceWith("BackStackScreen.fromList(listOf(bottom) + rest)")
37+
)
38+
public constructor(
39+
bottom: StackedT,
40+
rest: List<StackedT>
41+
) : this(listOf(bottom) + rest)
3342

34-
public val frames: List<StackedT> = listOf(bottom) + rest
43+
override fun asSequence(): Sequence<StackedT> = frames.asSequence()
3544

3645
/**
3746
* The active screen.
@@ -49,7 +58,7 @@ public class BackStackScreen<StackedT : Screen>(
4958
return if (other == null) {
5059
this
5160
} else {
52-
BackStackScreen(frames[0], frames.subList(1, frames.size) + other.frames)
61+
BackStackScreen(frames + other.frames)
5362
}
5463
}
5564

@@ -75,16 +84,37 @@ public class BackStackScreen<StackedT : Screen>(
7584
override fun toString(): String {
7685
return "${this::class.java.simpleName}($frames)"
7786
}
87+
88+
public companion object {
89+
/**
90+
* Builds a [BackStackScreen] from a non-empty list of [frames].
91+
*
92+
* @throws IllegalArgumentException is [frames] is empty
93+
*/
94+
public fun <T : Screen> fromList(frames: List<T>): BackStackScreen<T> {
95+
require(frames.isNotEmpty()) {
96+
"A BackStackScreen must have at least one frame."
97+
}
98+
return BackStackScreen(frames)
99+
}
100+
101+
/**
102+
* Builds a [BackStackScreen] from a list of [frames], or returns `null`
103+
* if [frames] is empty.
104+
*/
105+
public fun <T : Screen> fromListOrNull(frames: List<T>): BackStackScreen<T>? {
106+
return when {
107+
frames.isEmpty() -> null
108+
else -> BackStackScreen(frames)
109+
}
110+
}
111+
}
78112
}
79113

80114
@WorkflowUiExperimentalApi
81-
public fun <T : Screen> List<T>.toBackStackScreenOrNull(): BackStackScreen<T>? = when {
82-
isEmpty() -> null
83-
else -> toBackStackScreen()
84-
}
115+
public fun <T : Screen> List<T>.toBackStackScreenOrNull(): BackStackScreen<T>? =
116+
fromListOrNull(this)
85117

86118
@WorkflowUiExperimentalApi
87-
public fun <T : Screen> List<T>.toBackStackScreen(): BackStackScreen<T> {
88-
require(isNotEmpty())
89-
return BackStackScreen(first(), subList(1, size))
90-
}
119+
public fun <T : Screen> List<T>.toBackStackScreen(): BackStackScreen<T> =
120+
Companion.fromList(this)

Diff for: workflow-ui/core-common/src/test/java/com/squareup/workflow1/ui/container/BackStackScreenTest.kt

+2-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,8 @@ internal class BackStackScreenTest {
4545

4646
@Test fun `bottom and rest`() {
4747
assertThat(
48-
BackStackScreen(
49-
bottom = S(1),
50-
rest = listOf(S(2), S(3), S(4))
48+
BackStackScreen.fromList(
49+
listOf(element = S(1)) + listOf(S(2), S(3), S(4))
5150
)
5251
).isEqualTo(BackStackScreen(S(1), S(2), S(3), S(4)))
5352
}

0 commit comments

Comments
 (0)