Room selection: add a limitation of 10 rooms for Share and Forward actions.
This commit is contained in:
+4
-1
@@ -74,7 +74,10 @@ class ForwardMessagesNode(
|
||||
return roomSelectEntryPoint.createNode(
|
||||
parentNode = this,
|
||||
buildContext = buildContext,
|
||||
params = RoomSelectEntryPoint.Params(mode = RoomSelectMode.Forward),
|
||||
params = RoomSelectEntryPoint.Params(
|
||||
mode = RoomSelectMode.Forward,
|
||||
maxNumberOfRooms = RoomSelectEntryPoint.DEFAULT_MAX_NUMBER_OF_ROOMS,
|
||||
),
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
|
||||
+4
-1
@@ -70,7 +70,10 @@ class ShareNode(
|
||||
return roomSelectEntryPoint.createNode(
|
||||
parentNode = this,
|
||||
buildContext = buildContext,
|
||||
params = RoomSelectEntryPoint.Params(mode = RoomSelectMode.Share),
|
||||
params = RoomSelectEntryPoint.Params(
|
||||
mode = RoomSelectMode.Share,
|
||||
maxNumberOfRooms = RoomSelectEntryPoint.DEFAULT_MAX_NUMBER_OF_ROOMS,
|
||||
),
|
||||
callback = callback,
|
||||
)
|
||||
}
|
||||
|
||||
+5
@@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
||||
interface RoomSelectEntryPoint : FeatureEntryPoint {
|
||||
data class Params(
|
||||
val mode: RoomSelectMode,
|
||||
val maxNumberOfRooms: Int,
|
||||
)
|
||||
|
||||
fun createNode(
|
||||
@@ -30,4 +31,8 @@ interface RoomSelectEntryPoint : FeatureEntryPoint {
|
||||
fun onRoomSelected(roomIds: List<RoomId>)
|
||||
fun onCancel()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_MAX_NUMBER_OF_ROOMS = 10
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -26,7 +26,10 @@ class DefaultRoomSelectEntryPoint : RoomSelectEntryPoint {
|
||||
return parentNode.createNode<RoomSelectNode>(
|
||||
buildContext = buildContext,
|
||||
plugins = listOf(
|
||||
RoomSelectNode.Inputs(mode = params.mode),
|
||||
RoomSelectNode.Inputs(
|
||||
mode = params.mode,
|
||||
maxNumberOfRooms = params.maxNumberOfRooms,
|
||||
),
|
||||
callback,
|
||||
)
|
||||
)
|
||||
|
||||
+5
-1
@@ -35,10 +35,14 @@ class RoomSelectNode(
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
data class Inputs(
|
||||
val mode: RoomSelectMode,
|
||||
val maxNumberOfRooms: Int,
|
||||
) : NodeInputs
|
||||
|
||||
private val inputs: Inputs = inputs()
|
||||
private val presenter = presenterFactory.create(inputs.mode)
|
||||
private val presenter = presenterFactory.create(
|
||||
mode = inputs.mode,
|
||||
maxNumberOfRooms = inputs.maxNumberOfRooms,
|
||||
)
|
||||
private val stateFlow = launchMolecule { presenter.present() }
|
||||
private val callback: RoomSelectEntryPoint.Callback = callback()
|
||||
|
||||
|
||||
+6
-1
@@ -34,11 +34,15 @@ import kotlinx.coroutines.launch
|
||||
@AssistedInject
|
||||
class RoomSelectPresenter(
|
||||
@Assisted private val mode: RoomSelectMode,
|
||||
@Assisted private val maxNumberOfRooms: Int,
|
||||
private val dataSourceFactory: RoomSelectSearchDataSource.Factory,
|
||||
) : Presenter<RoomSelectState> {
|
||||
@AssistedFactory
|
||||
fun interface Factory {
|
||||
fun create(mode: RoomSelectMode): RoomSelectPresenter
|
||||
fun create(
|
||||
mode: RoomSelectMode,
|
||||
maxNumberOfRooms: Int,
|
||||
): RoomSelectPresenter
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -86,6 +90,7 @@ class RoomSelectPresenter(
|
||||
|
||||
return RoomSelectState(
|
||||
mode = mode,
|
||||
maxNumberOfRooms = maxNumberOfRooms,
|
||||
resultState = searchResults,
|
||||
searchQuery = queryState,
|
||||
isSearchActive = isSearchActive,
|
||||
|
||||
+5
-2
@@ -16,9 +16,12 @@ import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
data class RoomSelectState(
|
||||
val mode: RoomSelectMode,
|
||||
val maxNumberOfRooms: Int,
|
||||
val resultState: SearchBarResultState<ImmutableList<SelectRoomInfo>>,
|
||||
val searchQuery: TextFieldState,
|
||||
val isSearchActive: Boolean,
|
||||
val selectedRooms: ImmutableList<SelectRoomInfo>,
|
||||
val eventSink: (RoomSelectEvent) -> Unit
|
||||
)
|
||||
val eventSink: (RoomSelectEvent) -> Unit,
|
||||
) {
|
||||
val canSelectMoreRooms = selectedRooms.size < maxNumberOfRooms
|
||||
}
|
||||
|
||||
+8
@@ -40,11 +40,18 @@ open class RoomSelectStateProvider : PreviewParameterProvider<RoomSelectState> {
|
||||
mode = RoomSelectMode.Share,
|
||||
resultState = SearchBarResultState.Results(aRoomSelectRoomList()),
|
||||
),
|
||||
aRoomSelectState(
|
||||
mode = RoomSelectMode.Share,
|
||||
resultState = SearchBarResultState.Results(aRoomSelectRoomList()),
|
||||
selectedRooms = aRoomSelectRoomList().subList(0, 1),
|
||||
maxNumberOfRooms = 1,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
internal fun aRoomSelectState(
|
||||
mode: RoomSelectMode = RoomSelectMode.Forward,
|
||||
maxNumberOfRooms: Int = 10,
|
||||
resultState: SearchBarResultState<ImmutableList<SelectRoomInfo>> = SearchBarResultState.Initial(),
|
||||
searchQuery: String = "",
|
||||
isSearchActive: Boolean = false,
|
||||
@@ -52,6 +59,7 @@ internal fun aRoomSelectState(
|
||||
eventSink: (RoomSelectEvent) -> Unit = {},
|
||||
) = RoomSelectState(
|
||||
mode = mode,
|
||||
maxNumberOfRooms = maxNumberOfRooms,
|
||||
resultState = resultState,
|
||||
searchQuery = TextFieldState(initialText = searchQuery),
|
||||
isSearchActive = isSearchActive,
|
||||
|
||||
+10
-3
@@ -155,7 +155,8 @@ fun RoomSelectView(
|
||||
isSelected = state.selectedRooms.any { it.roomId == roomSummary.roomId },
|
||||
onSelection = { roomSummary ->
|
||||
state.eventSink(RoomSelectEvent.ToggleSelectedRoom(roomSummary))
|
||||
}
|
||||
},
|
||||
canBeSelected = state.canSelectMoreRooms,
|
||||
)
|
||||
HorizontalDivider(modifier = Modifier.fillMaxWidth())
|
||||
}
|
||||
@@ -178,7 +179,8 @@ fun RoomSelectView(
|
||||
isSelected = state.selectedRooms.any { it.roomId == roomSummary.roomId },
|
||||
onSelection = { roomSummary ->
|
||||
state.eventSink(RoomSelectEvent.ToggleSelectedRoom(roomSummary))
|
||||
}
|
||||
},
|
||||
canBeSelected = state.canSelectMoreRooms,
|
||||
)
|
||||
HorizontalDivider(modifier = Modifier.fillMaxWidth())
|
||||
}
|
||||
@@ -211,6 +213,7 @@ private fun SelectedRooms(
|
||||
private fun RoomSummaryView(
|
||||
roomInfo: SelectRoomInfo,
|
||||
isSelected: Boolean,
|
||||
canBeSelected: Boolean,
|
||||
onSelection: (SelectRoomInfo) -> Unit,
|
||||
) {
|
||||
Row(
|
||||
@@ -255,7 +258,11 @@ private fun RoomSummaryView(
|
||||
)
|
||||
}
|
||||
}
|
||||
RadioButton(selected = isSelected, onClick = { onSelection(roomInfo) })
|
||||
RadioButton(
|
||||
selected = isSelected,
|
||||
enabled = isSelected || canBeSelected,
|
||||
onClick = { onSelection(roomInfo) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-4
@@ -33,13 +33,15 @@ class DefaultRoomSelectEntryPointTest {
|
||||
fun `test node builder`() = runTest {
|
||||
val entryPoint = DefaultRoomSelectEntryPoint()
|
||||
val testMode = RoomSelectMode.Share
|
||||
val testMaxNumberOfRooms = 12
|
||||
val parentNode = TestParentNode.create { buildContext, plugins ->
|
||||
RoomSelectNode(
|
||||
buildContext = buildContext,
|
||||
plugins = plugins,
|
||||
presenterFactory = { mode ->
|
||||
presenterFactory = { mode, maxNumberOfRooms ->
|
||||
assertThat(mode).isEqualTo(testMode)
|
||||
createRoomSelectPresenter(mode)
|
||||
assertThat(maxNumberOfRooms).isEqualTo(testMaxNumberOfRooms)
|
||||
createRoomSelectPresenter(mode, maxNumberOfRooms)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -47,7 +49,10 @@ class DefaultRoomSelectEntryPointTest {
|
||||
override fun onRoomSelected(roomIds: List<RoomId>) = lambdaError()
|
||||
override fun onCancel() = lambdaError()
|
||||
}
|
||||
val params = RoomSelectEntryPoint.Params(testMode)
|
||||
val params = RoomSelectEntryPoint.Params(
|
||||
mode = testMode,
|
||||
maxNumberOfRooms = testMaxNumberOfRooms,
|
||||
)
|
||||
val result = entryPoint.createNode(
|
||||
parentNode = parentNode,
|
||||
buildContext = BuildContext.root(null),
|
||||
@@ -55,7 +60,7 @@ class DefaultRoomSelectEntryPointTest {
|
||||
callback = callback,
|
||||
)
|
||||
assertThat(result).isInstanceOf(RoomSelectNode::class.java)
|
||||
assertThat(result.plugins).contains(RoomSelectNode.Inputs(params.mode))
|
||||
assertThat(result.plugins).contains(RoomSelectNode.Inputs(params.mode, params.maxNumberOfRooms))
|
||||
assertThat(result.plugins).contains(callback)
|
||||
}
|
||||
}
|
||||
|
||||
+15
-3
@@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.test.room.aRoomSummary
|
||||
import io.element.android.libraries.matrix.test.roomlist.FakeDynamicRoomList
|
||||
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
|
||||
import io.element.android.libraries.matrix.ui.model.toSelectRoomInfo
|
||||
import io.element.android.libraries.roomselect.api.RoomSelectEntryPoint
|
||||
import io.element.android.libraries.roomselect.api.RoomSelectMode
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.lambda.assert
|
||||
@@ -43,6 +44,8 @@ class RoomSelectPresenterTest {
|
||||
assertThat(initialState.selectedRooms).isEmpty()
|
||||
assertThat(initialState.resultState).isInstanceOf(SearchBarResultState.Initial::class.java)
|
||||
assertThat(initialState.isSearchActive).isFalse()
|
||||
assertThat(initialState.maxNumberOfRooms).isEqualTo(10)
|
||||
assertThat(initialState.canSelectMoreRooms).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,15 +105,22 @@ class RoomSelectPresenterTest {
|
||||
createRoomListLambda = { roomList }
|
||||
)
|
||||
val presenter = createRoomSelectPresenter(
|
||||
maxNumberOfRooms = 1,
|
||||
roomListService = roomListService,
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
val roomInfo = roomSummary.toSelectRoomInfo()
|
||||
initialState.eventSink(RoomSelectEvent.ToggleSelectedRoom(roomInfo))
|
||||
assertThat(awaitItem().selectedRooms).isEqualTo(persistentListOf(roomInfo))
|
||||
initialState.eventSink(RoomSelectEvent.ToggleSelectedRoom(roomInfo))
|
||||
assertThat(awaitItem().selectedRooms).isEmpty()
|
||||
awaitItem().let {
|
||||
assertThat(it.selectedRooms).isEqualTo(persistentListOf(roomInfo))
|
||||
assertThat(it.canSelectMoreRooms).isFalse()
|
||||
it.eventSink(RoomSelectEvent.ToggleSelectedRoom(roomInfo))
|
||||
}
|
||||
awaitItem().let {
|
||||
assertThat(it.selectedRooms).isEmpty()
|
||||
assertThat(it.canSelectMoreRooms).isTrue()
|
||||
}
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
@@ -145,9 +155,11 @@ class RoomSelectPresenterTest {
|
||||
|
||||
internal fun TestScope.createRoomSelectPresenter(
|
||||
mode: RoomSelectMode = RoomSelectMode.Forward,
|
||||
maxNumberOfRooms: Int = RoomSelectEntryPoint.DEFAULT_MAX_NUMBER_OF_ROOMS,
|
||||
roomListService: RoomListService = FakeRoomListService(),
|
||||
) = RoomSelectPresenter(
|
||||
mode = mode,
|
||||
maxNumberOfRooms = maxNumberOfRooms,
|
||||
dataSourceFactory = object : RoomSelectSearchDataSource.Factory {
|
||||
override fun create(coroutineScope: CoroutineScope): RoomSelectSearchDataSource {
|
||||
return RoomSelectSearchDataSource(
|
||||
|
||||
Reference in New Issue
Block a user