misc : remove direct usage of RoomSummary in UI and let RoomSummary use RoomInfo.

This commit is contained in:
ganfra 2024-10-08 21:34:34 +02:00
parent 5a4e5d0575
commit eeb6b6f4bf
47 changed files with 628 additions and 467 deletions

View file

@ -21,11 +21,12 @@ import dagger.assisted.AssistedInject
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.runUpdatingStateNoSuccess
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.ui.model.getAvatarData
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.FlowPreview
@ -40,7 +41,6 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
private val notificationSettingsService: NotificationSettingsService,
@Assisted private val isOneToOne: Boolean,
private val roomListService: RoomListService,
private val matrixClient: MatrixClient,
) : Presenter<EditDefaultNotificationSettingState> {
@AssistedFactory
interface Factory {
@ -57,8 +57,8 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
val changeNotificationSettingAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
val roomsWithUserDefinedMode: MutableState<List<RoomSummary>> = remember {
mutableStateOf(listOf())
val roomsWithUserDefinedMode: MutableState<List<EditNotificationSettingRoomInfo>> = remember {
mutableStateOf(emptyList())
}
val localCoroutineScope = rememberCoroutineScope()
@ -106,31 +106,37 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
.launchIn(this)
}
private fun CoroutineScope.observeRoomSummaries(roomsWithUserDefinedMode: MutableState<List<RoomSummary>>) {
private fun CoroutineScope.observeRoomSummaries(roomsWithUserDefinedMode: MutableState<List<EditNotificationSettingRoomInfo>>) {
roomListService.allRooms
.summaries
.onEach {
updateRoomsWithUserDefinedMode(it, roomsWithUserDefinedMode)
.onEach { roomSummaries ->
updateRoomsWithUserDefinedMode(roomSummaries, roomsWithUserDefinedMode)
}
.launchIn(this)
}
private fun CoroutineScope.updateRoomsWithUserDefinedMode(
private suspend fun updateRoomsWithUserDefinedMode(
summaries: List<RoomSummary>,
roomsWithUserDefinedMode: MutableState<List<RoomSummary>>
) = launch {
val roomWithUserDefinedRules: Set<String> = notificationSettingsService.getRoomsWithUserDefinedRules().getOrThrow().toSet()
val sortedSummaries = summaries
.filterIsInstance<RoomSummary>()
.filter {
val room = matrixClient.getRoom(it.roomId) ?: return@filter false
roomWithUserDefinedRules.contains(it.roomId.value) && isOneToOne == room.isOneToOne
roomsWithUserDefinedMode: MutableState<List<EditNotificationSettingRoomInfo>>
) {
val roomWithUserDefinedRules: Set<String> = notificationSettingsService.getRoomsWithUserDefinedRules().getOrDefault(emptyList()).toSet()
roomsWithUserDefinedMode.value = summaries
.filter { roomSummary ->
roomWithUserDefinedRules.contains(roomSummary.roomId.value) && roomSummary.isOneToOne == isOneToOne
}
.map { roomSummary ->
EditNotificationSettingRoomInfo(
roomId = roomSummary.roomId,
name = roomSummary.info.name,
heroesAvatar = roomSummary.info.heroes.map { hero ->
hero.getAvatarData(AvatarSize.CustomRoomNotificationSetting)
}.toImmutableList(),
avatarData = roomSummary.info.getAvatarData(AvatarSize.CustomRoomNotificationSetting),
notificationMode = roomSummary.info.userDefinedNotificationMode,
)
}
// locale sensitive sorting
.sortedWith(compareBy(Collator.getInstance()) { it.name })
roomsWithUserDefinedMode.value = sortedSummaries
.sortedWith(compareBy(Collator.getInstance()) { roomSummary -> roomSummary.name })
}
private fun CoroutineScope.setDefaultNotificationMode(mode: RoomNotificationMode, action: MutableState<AsyncAction<Unit>>) = launch {

View file

@ -9,13 +9,12 @@ package io.element.android.features.preferences.impl.notifications.edit
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import kotlinx.collections.immutable.ImmutableList
data class EditDefaultNotificationSettingState(
val isOneToOne: Boolean,
val mode: RoomNotificationMode?,
val roomsWithUserDefinedMode: ImmutableList<RoomSummary>,
val roomsWithUserDefinedMode: ImmutableList<EditNotificationSettingRoomInfo>,
val changeNotificationSettingAction: AsyncAction<Unit>,
val displayMentionsOnlyDisclaimer: Boolean,
val eventSink: (EditDefaultNotificationSettingStateEvents) -> Unit,

View file

@ -9,9 +9,10 @@ package io.element.android.features.preferences.impl.notifications.edit
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.ui.components.aRoomSummaryDetails
import kotlinx.collections.immutable.persistentListOf
open class EditDefaultNotificationSettingStateProvider : PreviewParameterProvider<EditDefaultNotificationSettingState> {
@ -33,21 +34,25 @@ private fun anEditDefaultNotificationSettingsState(
isOneToOne = isOneToOne,
mode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
roomsWithUserDefinedMode = persistentListOf(
aRoomSummary("Room"),
aRoomSummary(null),
anEditNotificationSettingRoomInfo("Room"),
anEditNotificationSettingRoomInfo(null),
),
changeNotificationSettingAction = changeNotificationSettingAction,
displayMentionsOnlyDisclaimer = displayMentionsOnlyDisclaimer,
eventSink = {}
)
private fun aRoomSummary(
private fun anEditNotificationSettingRoomInfo(
name: String?,
) = aRoomSummaryDetails(
) = EditNotificationSettingRoomInfo(
roomId = RoomId("!roomId:domain"),
name = name,
avatarUrl = null,
isDirect = false,
lastMessage = null,
avatarData = AvatarData(
id = "!roomId:domain",
name = name,
url = null,
size = AvatarSize.CustomRoomNotificationSetting,
),
heroesAvatar = persistentListOf(),
notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
)

View file

@ -16,7 +16,6 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.tooling.preview.PreviewParameter
import io.element.android.features.preferences.impl.R
import io.element.android.libraries.designsystem.components.async.AsyncActionView
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.avatar.CompositeAvatar
import io.element.android.libraries.designsystem.components.list.ListItemContent
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
@ -27,9 +26,7 @@ import io.element.android.libraries.designsystem.theme.components.ListItem
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.ui.model.getAvatarData
import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.collections.immutable.toPersistentList
/**
* A view that allows a user to edit the default notification setting for rooms. This can be set separately
@ -80,7 +77,7 @@ fun EditDefaultNotificationSettingView(
if (state.roomsWithUserDefinedMode.isNotEmpty()) {
PreferenceCategory(title = stringResource(id = R.string.screen_notification_settings_edit_custom_settings_section_title)) {
state.roomsWithUserDefinedMode.forEach { summary ->
val subtitle = when (summary.userDefinedNotificationMode) {
val subtitle = when (summary.notificationMode) {
RoomNotificationMode.ALL_MESSAGES -> stringResource(id = R.string.screen_notification_settings_edit_mode_all_messages)
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> {
stringResource(id = R.string.screen_notification_settings_edit_mode_mentions_and_keywords)
@ -101,10 +98,8 @@ fun EditDefaultNotificationSettingView(
},
leadingContent = ListItemContent.Custom {
CompositeAvatar(
avatarData = summary.getAvatarData(size = AvatarSize.CustomRoomNotificationSetting),
heroes = summary.heroes.map { user ->
user.getAvatarData(size = AvatarSize.CustomRoomNotificationSetting)
}.toPersistentList()
avatarData = summary.avatarData,
heroes = summary.heroesAvatar,
)
},
onClick = {

View file

@ -0,0 +1,21 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only
* Please see LICENSE in the repository root for full details.
*/
package io.element.android.features.preferences.impl.notifications.edit
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import kotlinx.collections.immutable.ImmutableList
data class EditNotificationSettingRoomInfo(
val roomId: RoomId,
val name: String?,
val heroesAvatar: ImmutableList<AvatarData>,
val avatarData: AvatarData,
val notificationMode: RoomNotificationMode?
)

View file

@ -14,11 +14,8 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.features.preferences.impl.notifications.edit.EditDefaultNotificationSettingPresenter
import io.element.android.features.preferences.impl.notifications.edit.EditDefaultNotificationSettingStateEvents
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.aRoomSummary
import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService
import io.element.android.tests.testutils.awaitLastSequentialItem
@ -49,24 +46,20 @@ class EditDefaultNotificationSettingsPresenterTest {
@Test
fun `present - ensure list of rooms with user defined mode`() = runTest {
val room = FakeMatrixRoom()
val notificationSettingsService = FakeNotificationSettingsService(
initialRoomMode = RoomNotificationMode.ALL_MESSAGES,
initialRoomModeIsDefault = false
)
val matrixClient = FakeMatrixClient(notificationSettingsService = notificationSettingsService).apply {
givenGetRoomResult(A_ROOM_ID, room)
}
val roomListService = FakeRoomListService()
val presenter = createEditDefaultNotificationSettingPresenter(notificationSettingsService, roomListService, matrixClient)
val presenter = createEditDefaultNotificationSettingPresenter(notificationSettingsService, roomListService)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
roomListService.postAllRooms(listOf(aRoomSummary(notificationMode = RoomNotificationMode.ALL_MESSAGES)))
roomListService.postAllRooms(listOf(aRoomSummary(userDefinedNotificationMode = RoomNotificationMode.ALL_MESSAGES)))
val loadedState = consumeItemsUntilPredicate { state ->
state.roomsWithUserDefinedMode.any { it.userDefinedNotificationMode == RoomNotificationMode.ALL_MESSAGES }
state.roomsWithUserDefinedMode.any { it.notificationMode == RoomNotificationMode.ALL_MESSAGES }
}.last()
assertThat(loadedState.roomsWithUserDefinedMode.any { it.userDefinedNotificationMode == RoomNotificationMode.ALL_MESSAGES }).isTrue()
assertThat(loadedState.roomsWithUserDefinedMode.any { it.notificationMode == RoomNotificationMode.ALL_MESSAGES }).isTrue()
}
}
@ -121,13 +114,11 @@ class EditDefaultNotificationSettingsPresenterTest {
private fun createEditDefaultNotificationSettingPresenter(
notificationSettingsService: FakeNotificationSettingsService = FakeNotificationSettingsService(),
roomListService: FakeRoomListService = FakeRoomListService(),
matrixClient: FakeMatrixClient = FakeMatrixClient(notificationSettingsService = notificationSettingsService)
): EditDefaultNotificationSettingPresenter {
return EditDefaultNotificationSettingPresenter(
notificationSettingsService = notificationSettingsService,
isOneToOne = false,
roomListService = roomListService,
matrixClient = matrixClient
)
}
}