Disable mutliple click (parallel or serial) on a room (#4683)
* Disable mutliple click (parallel or serial) on a room (Fixes #4619) * Rename method from FirstThrottler * Move check to the Compose and add unit test on it.
This commit is contained in:
parent
c9ec26f87c
commit
f6cbca4a82
4 changed files with 84 additions and 27 deletions
|
|
@ -17,6 +17,8 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
|||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
|
@ -30,6 +32,7 @@ import io.element.android.features.roomlist.impl.components.RoomListMenuAction
|
|||
import io.element.android.features.roomlist.impl.components.RoomListTopBar
|
||||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
|
||||
import io.element.android.features.roomlist.impl.search.RoomListSearchView
|
||||
import io.element.android.libraries.androidutils.throttler.FirstThrottler
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.FloatingActionButton
|
||||
|
|
@ -54,6 +57,9 @@ fun RoomListView(
|
|||
modifier: Modifier = Modifier,
|
||||
acceptDeclineInviteView: @Composable () -> Unit,
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val firstThrottler = remember { FirstThrottler(300, coroutineScope) }
|
||||
|
||||
ConnectivityIndicatorContainer(
|
||||
modifier = modifier,
|
||||
isOnline = state.hasNetworkConnection,
|
||||
|
|
@ -83,9 +89,9 @@ fun RoomListView(
|
|||
state = state,
|
||||
onSetUpRecoveryClick = onSetUpRecoveryClick,
|
||||
onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick,
|
||||
onRoomClick = onRoomClick,
|
||||
onOpenSettings = onSettingsClick,
|
||||
onCreateRoomClick = onCreateRoomClick,
|
||||
onRoomClick = { if (firstThrottler.canHandle()) onRoomClick(it) },
|
||||
onOpenSettings = { if (firstThrottler.canHandle()) onSettingsClick() },
|
||||
onCreateRoomClick = { if (firstThrottler.canHandle()) onCreateRoomClick() },
|
||||
onMenuActionClick = onMenuActionClick,
|
||||
modifier = Modifier.padding(top = topPadding),
|
||||
)
|
||||
|
|
@ -94,7 +100,7 @@ fun RoomListView(
|
|||
state = state.searchState,
|
||||
eventSink = state.eventSink,
|
||||
hideInvitesAvatars = state.hideInvitesAvatars,
|
||||
onRoomClick = onRoomClick,
|
||||
onRoomClick = { if (firstThrottler.canHandle()) onRoomClick(it) },
|
||||
modifier = Modifier
|
||||
.statusBarsPadding()
|
||||
.padding(top = topPadding)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
||||
package io.element.android.features.roomlist.impl
|
||||
|
||||
import androidx.activity.ComponentActivity
|
||||
|
|
@ -27,6 +29,7 @@ import io.element.android.tests.testutils.EventsRecorder
|
|||
import io.element.android.tests.testutils.clickOn
|
||||
import io.element.android.tests.testutils.ensureCalledOnce
|
||||
import io.element.android.tests.testutils.ensureCalledOnceWithParam
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TestRule
|
||||
|
|
@ -168,6 +171,29 @@ class RoomListViewTest {
|
|||
eventsRecorder.assertEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on a room twice invokes the expected callback only once`() {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvents>()
|
||||
val state = aRoomListState(
|
||||
eventSink = eventsRecorder,
|
||||
)
|
||||
val room0 = state.contentAsRooms().summaries.first {
|
||||
it.displayType == RoomSummaryDisplayType.ROOM
|
||||
}
|
||||
ensureCalledOnceWithParam(room0.roomId) { callback ->
|
||||
rule.setRoomListView(
|
||||
state = state,
|
||||
onRoomClick = callback,
|
||||
)
|
||||
// Remove automatic initial events
|
||||
eventsRecorder.clear()
|
||||
rule.onNodeWithText(room0.lastMessage!!.toString())
|
||||
.performClick()
|
||||
.performClick()
|
||||
}
|
||||
eventsRecorder.assertEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `long clicking on a room emits the expected Event`() {
|
||||
val eventsRecorder = EventsRecorder<RoomListEvents>()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue