Pinned messages list : add loading for pinned messages count and add tests
This commit is contained in:
parent
faae2d1004
commit
80f750ae34
6 changed files with 41 additions and 9 deletions
|
|
@ -86,7 +86,7 @@ class RoomDetailsPresenter @Inject constructor(
|
||||||
val isPublic by remember { derivedStateOf { roomInfo?.isPublic.orFalse() } }
|
val isPublic by remember { derivedStateOf { roomInfo?.isPublic.orFalse() } }
|
||||||
|
|
||||||
val canShowPinnedMessages = isPinnedMessagesFeatureEnabled()
|
val canShowPinnedMessages = isPinnedMessagesFeatureEnabled()
|
||||||
val pinnedMessagesCount by remember { derivedStateOf { roomInfo?.pinnedEventIds?.size ?: 0 } }
|
val pinnedMessagesCount by remember { derivedStateOf { roomInfo?.pinnedEventIds?.size } }
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
canShowNotificationSettings.value = featureFlagService.isFeatureEnabled(FeatureFlags.NotificationSettings)
|
canShowNotificationSettings.value = featureFlagService.isFeatureEnabled(FeatureFlags.NotificationSettings)
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ data class RoomDetailsState(
|
||||||
val isPublic: Boolean,
|
val isPublic: Boolean,
|
||||||
val heroes: ImmutableList<MatrixUser>,
|
val heroes: ImmutableList<MatrixUser>,
|
||||||
val canShowPinnedMessages: Boolean,
|
val canShowPinnedMessages: Boolean,
|
||||||
val pinnedMessagesCount: Int,
|
val pinnedMessagesCount: Int?,
|
||||||
val eventSink: (RoomDetailsEvent) -> Unit
|
val eventSink: (RoomDetailsEvent) -> Unit
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ open class RoomDetailsStateProvider : PreviewParameterProvider<RoomDetailsState>
|
||||||
aRoomDetailsState(canCall = false, canInvite = false),
|
aRoomDetailsState(canCall = false, canInvite = false),
|
||||||
aRoomDetailsState(isPublic = false),
|
aRoomDetailsState(isPublic = false),
|
||||||
aRoomDetailsState(heroes = aMatrixUserList()),
|
aRoomDetailsState(heroes = aMatrixUserList()),
|
||||||
|
aRoomDetailsState(pinnedMessagesCount = 3),
|
||||||
// Add other state here
|
// Add other state here
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +107,7 @@ fun aRoomDetailsState(
|
||||||
isPublic: Boolean = true,
|
isPublic: Boolean = true,
|
||||||
heroes: List<MatrixUser> = emptyList(),
|
heroes: List<MatrixUser> = emptyList(),
|
||||||
canShowPinnedMessages: Boolean = true,
|
canShowPinnedMessages: Boolean = true,
|
||||||
pinnedMessagesCount: Int = 3,
|
pinnedMessagesCount: Int? = null,
|
||||||
eventSink: (RoomDetailsEvent) -> Unit = {},
|
eventSink: (RoomDetailsEvent) -> Unit = {},
|
||||||
) = RoomDetailsState(
|
) = RoomDetailsState(
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.consumeWindowInsets
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
|
@ -66,6 +67,7 @@ import io.element.android.libraries.designsystem.components.preferences.Preferen
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight
|
import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenu
|
import io.element.android.libraries.designsystem.theme.components.DropdownMenu
|
||||||
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
|
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
|
||||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||||
|
|
@ -184,7 +186,7 @@ fun RoomDetailsView(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(state.canShowPinnedMessages) {
|
if (state.canShowPinnedMessages) {
|
||||||
PinnedMessagesItem(
|
PinnedMessagesItem(
|
||||||
pinnedMessagesCount = state.pinnedMessagesCount,
|
pinnedMessagesCount = state.pinnedMessagesCount,
|
||||||
onPinnedMessagesClick = onPinnedMessagesClick
|
onPinnedMessagesClick = onPinnedMessagesClick
|
||||||
|
|
@ -513,13 +515,20 @@ private fun MembersItem(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun PinnedMessagesItem(
|
private fun PinnedMessagesItem(
|
||||||
pinnedMessagesCount: Int,
|
pinnedMessagesCount: Int?,
|
||||||
onPinnedMessagesClick: () -> Unit,
|
onPinnedMessagesClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = { Text(stringResource(CommonStrings.screen_room_details_pinned_events_row_title)) },
|
headlineContent = { Text(stringResource(CommonStrings.screen_room_details_pinned_events_row_title)) },
|
||||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Pin())),
|
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Pin())),
|
||||||
trailingContent = ListItemContent.Text(pinnedMessagesCount.toString()),
|
trailingContent =
|
||||||
|
if (pinnedMessagesCount == null) {
|
||||||
|
ListItemContent.Custom {
|
||||||
|
CircularProgressIndicator(strokeWidth = 2.dp, modifier = Modifier.size(24.dp))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ListItemContent.Text(pinnedMessagesCount.toString())
|
||||||
|
},
|
||||||
onClick = onPinnedMessagesClick,
|
onClick = onPinnedMessagesClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
|
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
|
||||||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||||
import io.element.android.libraries.matrix.api.room.StateEventType
|
import io.element.android.libraries.matrix.api.room.StateEventType
|
||||||
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||||
import io.element.android.libraries.matrix.test.A_USER_ID_2
|
import io.element.android.libraries.matrix.test.A_USER_ID_2
|
||||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
|
|
@ -81,6 +82,7 @@ class RoomDetailsPresenterTest {
|
||||||
dispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
|
dispatchers: CoroutineDispatchers = testCoroutineDispatchers(),
|
||||||
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
|
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
|
||||||
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
||||||
|
isPinnedMessagesFeatureEnabled: Boolean = true,
|
||||||
): RoomDetailsPresenter {
|
): RoomDetailsPresenter {
|
||||||
val matrixClient = FakeMatrixClient(notificationSettingsService = notificationSettingsService)
|
val matrixClient = FakeMatrixClient(notificationSettingsService = notificationSettingsService)
|
||||||
val roomMemberDetailsPresenterFactory = object : RoomMemberDetailsPresenter.Factory {
|
val roomMemberDetailsPresenterFactory = object : RoomMemberDetailsPresenter.Factory {
|
||||||
|
|
@ -99,6 +101,7 @@ class RoomDetailsPresenterTest {
|
||||||
roomMembersDetailsPresenterFactory = roomMemberDetailsPresenterFactory,
|
roomMembersDetailsPresenterFactory = roomMemberDetailsPresenterFactory,
|
||||||
leaveRoomPresenter = leaveRoomPresenter,
|
leaveRoomPresenter = leaveRoomPresenter,
|
||||||
dispatchers = dispatchers,
|
dispatchers = dispatchers,
|
||||||
|
isPinnedMessagesFeatureEnabled = { isPinnedMessagesFeatureEnabled },
|
||||||
analyticsService = analyticsService,
|
analyticsService = analyticsService,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -127,14 +130,15 @@ class RoomDetailsPresenterTest {
|
||||||
assertThat(initialState.roomTopic).isEqualTo(RoomTopicState.ExistingTopic(room.topic!!))
|
assertThat(initialState.roomTopic).isEqualTo(RoomTopicState.ExistingTopic(room.topic!!))
|
||||||
assertThat(initialState.memberCount).isEqualTo(room.joinedMemberCount)
|
assertThat(initialState.memberCount).isEqualTo(room.joinedMemberCount)
|
||||||
assertThat(initialState.isEncrypted).isEqualTo(room.isEncrypted)
|
assertThat(initialState.isEncrypted).isEqualTo(room.isEncrypted)
|
||||||
|
assertThat(initialState.canShowPinnedMessages).isTrue()
|
||||||
|
assertThat(initialState.pinnedMessagesCount).isNull()
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - initial state is updated with roomInfo if it exists`() = runTest {
|
fun `present - initial state is updated with roomInfo if it exists`() = runTest {
|
||||||
val roomInfo = aRoomInfo(name = "A room name", topic = "A topic", avatarUrl = "https://matrix.org/avatar.jpg")
|
val roomInfo = aRoomInfo(name = "A room name", topic = "A topic", avatarUrl = "https://matrix.org/avatar.jpg", pinnedEventIds = listOf(AN_EVENT_ID))
|
||||||
val room = aMatrixRoom(
|
val room = aMatrixRoom(
|
||||||
canInviteResult = { Result.success(true) },
|
canInviteResult = { Result.success(true) },
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
|
|
@ -149,7 +153,7 @@ class RoomDetailsPresenterTest {
|
||||||
assertThat(updatedState.roomName).isEqualTo(roomInfo.name)
|
assertThat(updatedState.roomName).isEqualTo(roomInfo.name)
|
||||||
assertThat(updatedState.roomAvatarUrl).isEqualTo(roomInfo.avatarUrl)
|
assertThat(updatedState.roomAvatarUrl).isEqualTo(roomInfo.avatarUrl)
|
||||||
assertThat(updatedState.roomTopic).isEqualTo(RoomTopicState.ExistingTopic(roomInfo.topic!!))
|
assertThat(updatedState.roomTopic).isEqualTo(RoomTopicState.ExistingTopic(roomInfo.topic!!))
|
||||||
|
assertThat(updatedState.pinnedMessagesCount).isEqualTo(roomInfo.pinnedEventIds.size)
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,22 @@ class RoomDetailsViewTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Config(qualifiers = "h1024dp")
|
||||||
|
@Test
|
||||||
|
fun `click on pinned messages invokes expected callback`() {
|
||||||
|
ensureCalledOnce { callback ->
|
||||||
|
rule.setRoomDetailView(
|
||||||
|
state = aRoomDetailsState(
|
||||||
|
eventSink = EventsRecorder(expectEvents = false),
|
||||||
|
canInvite = true,
|
||||||
|
),
|
||||||
|
onPinnedMessagesClick = callback,
|
||||||
|
)
|
||||||
|
rule.clickOn(CommonStrings.screen_room_details_pinned_events_row_title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Config(qualifiers = "h1024dp")
|
@Config(qualifiers = "h1024dp")
|
||||||
@Test
|
@Test
|
||||||
fun `click on add topic emit expected event`() {
|
fun `click on add topic emit expected event`() {
|
||||||
|
|
@ -263,6 +279,7 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomD
|
||||||
openPollHistory: () -> Unit = EnsureNeverCalled(),
|
openPollHistory: () -> Unit = EnsureNeverCalled(),
|
||||||
openAdminSettings: () -> Unit = EnsureNeverCalled(),
|
openAdminSettings: () -> Unit = EnsureNeverCalled(),
|
||||||
onJoinCallClick: () -> Unit = EnsureNeverCalled(),
|
onJoinCallClick: () -> Unit = EnsureNeverCalled(),
|
||||||
|
onPinnedMessagesClick: () -> Unit = EnsureNeverCalled(),
|
||||||
) {
|
) {
|
||||||
setContent {
|
setContent {
|
||||||
RoomDetailsView(
|
RoomDetailsView(
|
||||||
|
|
@ -277,6 +294,7 @@ private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setRoomD
|
||||||
openPollHistory = openPollHistory,
|
openPollHistory = openPollHistory,
|
||||||
openAdminSettings = openAdminSettings,
|
openAdminSettings = openAdminSettings,
|
||||||
onJoinCallClick = onJoinCallClick,
|
onJoinCallClick = onJoinCallClick,
|
||||||
|
onPinnedMessagesClick = onPinnedMessagesClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue