Merge branch 'develop' into feature/fga/mark_room_as_favorite

This commit is contained in:
ganfra 2024-02-15 10:16:43 +01:00
commit e00311a739
282 changed files with 718 additions and 300 deletions

View file

@ -135,19 +135,18 @@ private fun RoomListModalBottomSheetContent(
},
leadingContent = ListItemContent.Icon(
iconSource = IconSource.Vector(
CompoundIcons.FavouriteOff,
CompoundIcons.Favourite(),
contentDescription = stringResource(id = CommonStrings.common_favourite),
)
),
trailingContent = ListItemContent.Switch(
checked = contextMenu.isFavorite.dataOrNull().orFalse(),
enabled = contextMenu.isFavorite is AsyncData.Success,
checked = contextMenu.isFavorite,
onChange = { isFavorite ->
onFavoriteChanged(isFavorite)
},
),
onClick = {
onFavoriteChanged(!contextMenu.isFavorite.dataOrNull().orFalse())
onFavoriteChanged(!contextMenu.isFavorite)
},
style = ListItemStyle.Primary,
)

View file

@ -54,10 +54,7 @@ import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.api.user.getCurrentUser
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import javax.inject.Inject
@ -74,7 +71,6 @@ class RoomListPresenter @Inject constructor(
private val encryptionService: EncryptionService,
private val featureFlagService: FeatureFlagService,
private val indicatorService: IndicatorService,
private val setRoomIsFavorite: SetRoomIsFavoriteAction,
private val migrationScreenPresenter: MigrationScreenPresenter,
private val sessionPreferencesStore: SessionPreferencesStore,
) : Presenter<RoomListState> {
@ -146,17 +142,26 @@ class RoomListPresenter @Inject constructor(
}
is RoomListEvents.LeaveRoom -> leaveRoomState.eventSink(LeaveRoomEvent.ShowConfirmation(event.roomId))
is RoomListEvents.SetRoomIsFavorite -> coroutineScope.setRoomIsFavorite(event)
is RoomListEvents.MarkAsRead -> coroutineScope.launch {
val receiptType = if (sessionPreferencesStore.isSendPublicReadReceiptsEnabled().first()) {
ReceiptType.READ
} else {
ReceiptType.READ_PRIVATE
is RoomListEvents.SetRoomIsFavorite -> coroutineScope.launch {
client.getRoom(event.roomId)?.use { room ->
room.setIsFavorite(event.isFavorite)
}
}
is RoomListEvents.MarkAsRead -> coroutineScope.launch {
client.getRoom(event.roomId)?.use { room ->
room.setUnreadFlag(isUnread = false)
val receiptType = if (sessionPreferencesStore.isSendPublicReadReceiptsEnabled().first()) {
ReceiptType.READ
} else {
ReceiptType.READ_PRIVATE
}
room.markAsRead(receiptType)
}
client.getRoom(event.roomId)?.markAsRead(receiptType)
}
is RoomListEvents.MarkAsUnread -> coroutineScope.launch {
client.getRoom(event.roomId)?.markAsUnread()
client.getRoom(event.roomId)?.use { room ->
room.setUnreadFlag(isUnread = true)
}
}
}
}
@ -191,28 +196,11 @@ class RoomListPresenter @Inject constructor(
roomId = event.roomListRoomSummary.roomId,
roomName = event.roomListRoomSummary.name,
isDm = event.roomListRoomSummary.isDm,
isFavorite = AsyncData.Loading(),
isFavorite = event.roomListRoomSummary.isFavorite,
markAsUnreadFeatureFlagEnabled = featureFlagService.isFeatureEnabled(FeatureFlags.MarkAsUnread),
hasNewContent = event.roomListRoomSummary.hasNewContent
)
contextMenuState.value = initialState
client.getRoom(event.roomListRoomSummary.roomId).use { room ->
if (room != null) {
room.notableTagsFlow
.distinctUntilChanged()
.onEach { tags ->
val newState = initialState.copy(isFavorite = AsyncData.Success(tags.isFavorite))
contextMenuState.value = newState
}
.collect()
} else {
contextMenuState.value = initialState.copy(isFavorite = AsyncData.Failure(IllegalStateException("Room not found")))
}
}
}
private fun CoroutineScope.setRoomIsFavorite(event: RoomListEvents.SetRoomIsFavorite) = launch {
setRoomIsFavorite(event.roomId, event.isFavorite)
}
private fun updateVisibleRange(range: IntRange) {

View file

@ -49,7 +49,7 @@ data class RoomListState(
val roomId: RoomId,
val roomName: String,
val isDm: Boolean,
val isFavorite: AsyncData<Boolean>,
val isFavorite: Boolean,
val markAsUnreadFeatureFlagEnabled: Boolean,
val hasNewContent: Boolean,
) : ContextMenu

View file

@ -44,7 +44,7 @@ open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
aRoomListState().copy(displaySearchResults = true, filter = "", filteredRoomList = persistentListOf()),
aRoomListState().copy(displaySearchResults = true),
aRoomListState().copy(contextMenu = aContextMenuShown(roomName = "A nice room name")),
aRoomListState().copy(contextMenu = aContextMenuShown(isFavorite = AsyncData.Success(true))),
aRoomListState().copy(contextMenu = aContextMenuShown(isFavorite = true)),
aRoomListState().copy(displayRecoveryKeyPrompt = true),
aRoomListState().copy(roomList = AsyncData.Success(persistentListOf())),
aRoomListState().copy(roomList = AsyncData.Loading(prevData = RoomListRoomSummaryFactory.createFakeList())),
@ -103,7 +103,7 @@ internal fun aContextMenuShown(
roomName: String = "aRoom",
isDm: Boolean = false,
hasNewContent: Boolean = false,
isFavorite: AsyncData<Boolean> = AsyncData.Success(false),
isFavorite: Boolean = false,
) = RoomListState.ContextMenu.Shown(
roomId = RoomId("!aRoom:aDomain"),
roomName = roomName,

View file

@ -49,6 +49,7 @@ class RoomListRoomSummaryFactory @Inject constructor(
userDefinedNotificationMode = null,
hasRoomCall = false,
isDm = false,
isFavorite = false,
)
}
@ -84,6 +85,7 @@ class RoomListRoomSummaryFactory @Inject constructor(
userDefinedNotificationMode = roomSummary.details.userDefinedNotificationMode,
hasRoomCall = roomSummary.details.hasRoomCall,
isDm = roomSummary.details.isDm,
isFavorite = roomSummary.details.isFavorite,
)
}
}

View file

@ -16,12 +16,11 @@
package io.element.android.features.roomlist.impl.migration
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.stringResource
import io.element.android.features.roomlist.impl.R
import io.element.android.libraries.designsystem.atomic.pages.SunsetPage
@ -33,14 +32,14 @@ fun MigrationScreenView(
isMigrating: Boolean,
modifier: Modifier = Modifier,
) {
val displayMigrationStatusFadeProgress by animateFloatAsState(
targetValue = if (isMigrating) 1f else 0f,
animationSpec = tween(durationMillis = 200),
label = "Migration view fade"
)
if (displayMigrationStatusFadeProgress > 0f) {
AnimatedVisibility(
visible = isMigrating,
enter = fadeIn(),
exit = fadeOut(),
label = "Migration view fade",
) {
SunsetPage(
modifier = modifier.alpha(displayMigrationStatusFadeProgress),
modifier = modifier,
isLoading = true,
title = stringResource(id = R.string.screen_migration_title),
subtitle = stringResource(id = R.string.screen_migration_message),

View file

@ -37,6 +37,7 @@ data class RoomListRoomSummary(
val userDefinedNotificationMode: RoomNotificationMode?,
val hasRoomCall: Boolean,
val isDm: Boolean,
val isFavorite: Boolean,
) {
val isHighlighted = userDefinedNotificationMode != RoomNotificationMode.MUTE &&
(numberOfUnreadNotifications > 0 || numberOfUnreadMentions > 0) ||

View file

@ -97,6 +97,7 @@ internal fun aRoomListRoomSummary(
hasRoomCall: Boolean = false,
avatarData: AvatarData = AvatarData(id, name, size = AvatarSize.RoomListItem),
isDm: Boolean = false,
isFavorite: Boolean = false,
) = RoomListRoomSummary(
id = id,
roomId = RoomId(id),
@ -112,4 +113,5 @@ internal fun aRoomListRoomSummary(
userDefinedNotificationMode = notificationMode,
hasRoomCall = hasRoomCall,
isDm = isDm,
isFavorite = isFavorite,
)

View file

@ -529,19 +529,18 @@ class RoomListPresenterTests {
}.test {
val initialState = awaitItem()
assertThat(room.markAsReadCalls).isEmpty()
assertThat(room.markAsUnreadReadCallCount).isEqualTo(0)
assertThat(room.setUnreadFlagCalls).isEmpty()
initialState.eventSink.invoke(RoomListEvents.MarkAsRead(A_ROOM_ID))
assertThat(room.markAsReadCalls).isEqualTo(listOf(ReceiptType.READ))
assertThat(room.markAsUnreadReadCallCount).isEqualTo(0)
assertThat(room.setUnreadFlagCalls).isEqualTo(listOf(false))
initialState.eventSink.invoke(RoomListEvents.MarkAsUnread(A_ROOM_ID))
assertThat(room.markAsReadCalls).isEqualTo(listOf(ReceiptType.READ))
assertThat(room.markAsUnreadReadCallCount).isEqualTo(1)
assertThat(room.setUnreadFlagCalls).isEqualTo(listOf(false, true))
// Test again with private read receipts
sessionPreferencesStore.setSendPublicReadReceipts(false)
initialState.eventSink.invoke(RoomListEvents.MarkAsRead(A_ROOM_ID))
assertThat(room.markAsReadCalls).isEqualTo(listOf(ReceiptType.READ, ReceiptType.READ_PRIVATE))
assertThat(room.markAsUnreadReadCallCount).isEqualTo(1)
assertThat(room.setUnreadFlagCalls).isEqualTo(listOf(false, true, false))
cancelAndIgnoreRemainingEvents()
scope.cancel()
}

View file

@ -80,6 +80,7 @@ internal fun createRoomListRoomSummary(
numberOfUnreadNotifications: Int = 0,
isMarkedUnread: Boolean = false,
userDefinedNotificationMode: RoomNotificationMode? = null,
isFavorite: Boolean = false,
) = RoomListRoomSummary(
id = A_ROOM_ID.value,
roomId = A_ROOM_ID,
@ -95,4 +96,5 @@ internal fun createRoomListRoomSummary(
userDefinedNotificationMode = userDefinedNotificationMode,
hasRoomCall = false,
isDm = false,
isFavorite = isFavorite,
)