Add ability mark as unread / mark as read a room.
This commit is contained in:
parent
6f082232d3
commit
ca91b23512
21 changed files with 229 additions and 13 deletions
|
|
@ -49,6 +49,14 @@ fun RoomListContextMenu(
|
|||
) {
|
||||
RoomListModalBottomSheetContent(
|
||||
contextMenu = contextMenu,
|
||||
onRoomMarkReadClicked = {
|
||||
eventSink(RoomListEvents.HideContextMenu)
|
||||
eventSink(RoomListEvents.MarkAsRead(it))
|
||||
},
|
||||
onRoomMarkUnreadClicked = {
|
||||
eventSink(RoomListEvents.HideContextMenu)
|
||||
eventSink(RoomListEvents.MarkAsUnread(it))
|
||||
},
|
||||
onRoomSettingsClicked = {
|
||||
eventSink(RoomListEvents.HideContextMenu)
|
||||
onRoomSettingsClicked(it)
|
||||
|
|
@ -64,6 +72,8 @@ fun RoomListContextMenu(
|
|||
@Composable
|
||||
private fun RoomListModalBottomSheetContent(
|
||||
contextMenu: RoomListState.ContextMenu.Shown,
|
||||
onRoomMarkReadClicked: (roomId: RoomId) -> Unit,
|
||||
onRoomMarkUnreadClicked: (roomId: RoomId) -> Unit,
|
||||
onRoomSettingsClicked: (roomId: RoomId) -> Unit,
|
||||
onLeaveRoomClicked: (roomId: RoomId) -> Unit,
|
||||
) {
|
||||
|
|
@ -78,6 +88,36 @@ private fun RoomListModalBottomSheetContent(
|
|||
)
|
||||
}
|
||||
)
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
Text(
|
||||
text = stringResource(
|
||||
id = if (contextMenu.hasNewContent) {
|
||||
R.string.screen_roomlist_mark_as_read
|
||||
} else {
|
||||
R.string.screen_roomlist_mark_as_unread
|
||||
}
|
||||
),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
)
|
||||
},
|
||||
modifier = Modifier.clickable {
|
||||
if (contextMenu.hasNewContent) {
|
||||
onRoomMarkReadClicked(contextMenu.roomId)
|
||||
} else {
|
||||
onRoomMarkUnreadClicked(contextMenu.roomId)
|
||||
}
|
||||
},
|
||||
/* TODO Design
|
||||
leadingContent = ListItemContent.Icon(
|
||||
iconSource = IconSource.Vector(
|
||||
CompoundIcons.Settings,
|
||||
contentDescription = stringResource(id = CommonStrings.common_settings)
|
||||
)
|
||||
),
|
||||
*/
|
||||
style = ListItemStyle.Primary,
|
||||
)
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
Text(
|
||||
|
|
@ -96,11 +136,13 @@ private fun RoomListModalBottomSheetContent(
|
|||
)
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
val leaveText = stringResource(id = if (contextMenu.isDm) {
|
||||
CommonStrings.action_leave_conversation
|
||||
} else {
|
||||
CommonStrings.action_leave_room
|
||||
})
|
||||
val leaveText = stringResource(
|
||||
id = if (contextMenu.isDm) {
|
||||
CommonStrings.action_leave_conversation
|
||||
} else {
|
||||
CommonStrings.action_leave_room
|
||||
}
|
||||
)
|
||||
Text(text = leaveText)
|
||||
},
|
||||
modifier = Modifier.clickable { onLeaveRoomClicked(contextMenu.roomId) },
|
||||
|
|
@ -126,7 +168,10 @@ internal fun RoomListModalBottomSheetContentPreview() = ElementPreview {
|
|||
roomId = RoomId(value = "!aRoom:aDomain"),
|
||||
roomName = "aRoom",
|
||||
isDm = false,
|
||||
hasNewContent = true,
|
||||
),
|
||||
onRoomMarkReadClicked = {},
|
||||
onRoomMarkUnreadClicked = {},
|
||||
onRoomSettingsClicked = {},
|
||||
onLeaveRoomClicked = {}
|
||||
)
|
||||
|
|
@ -140,7 +185,10 @@ internal fun RoomListModalBottomSheetContentForDmPreview() = ElementPreview {
|
|||
roomId = RoomId(value = "!aRoom:aDomain"),
|
||||
roomName = "aRoom",
|
||||
isDm = true,
|
||||
hasNewContent = false,
|
||||
),
|
||||
onRoomMarkReadClicked = {},
|
||||
onRoomMarkUnreadClicked = {},
|
||||
onRoomSettingsClicked = {},
|
||||
onLeaveRoomClicked = {}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -28,4 +28,6 @@ sealed interface RoomListEvents {
|
|||
data class ShowContextMenu(val roomListRoomSummary: RoomListRoomSummary) : RoomListEvents
|
||||
data object HideContextMenu : RoomListEvents
|
||||
data class LeaveRoom(val roomId: RoomId) : RoomListEvents
|
||||
data class MarkAsRead(val roomId: RoomId) : RoomListEvents
|
||||
data class MarkAsUnread(val roomId: RoomId) : RoomListEvents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,12 +25,14 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomEvent
|
||||
import io.element.android.features.leaveroom.api.LeaveRoomPresenter
|
||||
import io.element.android.features.networkmonitor.api.NetworkMonitor
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.features.preferences.api.store.SessionPreferencesStore
|
||||
import io.element.android.features.roomlist.impl.datasource.InviteStateDataSource
|
||||
import io.element.android.features.roomlist.impl.datasource.RoomListDataSource
|
||||
import io.element.android.features.roomlist.impl.migration.MigrationScreenPresenter
|
||||
|
|
@ -44,10 +46,12 @@ import io.element.android.libraries.indicator.api.IndicatorService
|
|||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
import io.element.android.libraries.matrix.api.encryption.RecoveryState
|
||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||
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.first
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -65,9 +69,11 @@ class RoomListPresenter @Inject constructor(
|
|||
private val featureFlagService: FeatureFlagService,
|
||||
private val indicatorService: IndicatorService,
|
||||
private val migrationScreenPresenter: MigrationScreenPresenter,
|
||||
private val sessionPreferencesStore: SessionPreferencesStore,
|
||||
) : Presenter<RoomListState> {
|
||||
@Composable
|
||||
override fun present(): RoomListState {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val leaveRoomState = leaveRoomPresenter.present()
|
||||
val matrixUser: MutableState<MatrixUser?> = rememberSaveable {
|
||||
mutableStateOf(null)
|
||||
|
|
@ -129,10 +135,22 @@ class RoomListPresenter @Inject constructor(
|
|||
roomId = event.roomListRoomSummary.roomId,
|
||||
roomName = event.roomListRoomSummary.name,
|
||||
isDm = event.roomListRoomSummary.isDm,
|
||||
hasNewContent = event.roomListRoomSummary.hasNewContent
|
||||
)
|
||||
}
|
||||
is RoomListEvents.HideContextMenu -> contextMenu = RoomListState.ContextMenu.Hidden
|
||||
is RoomListEvents.LeaveRoom -> leaveRoomState.eventSink(LeaveRoomEvent.ShowConfirmation(event.roomId))
|
||||
is RoomListEvents.MarkAsRead -> coroutineScope.launch {
|
||||
val receiptType = if (sessionPreferencesStore.isSendPublicReadReceiptsEnabled().first()) {
|
||||
ReceiptType.READ
|
||||
} else {
|
||||
ReceiptType.READ_PRIVATE
|
||||
}
|
||||
client.getRoom(event.roomId)?.markAsRead(receiptType)
|
||||
}
|
||||
is RoomListEvents.MarkAsUnread -> coroutineScope.launch {
|
||||
client.getRoom(event.roomId)?.markAsUnread()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ data class RoomListState(
|
|||
val roomId: RoomId,
|
||||
val roomName: String,
|
||||
val isDm: Boolean,
|
||||
val hasNewContent: Boolean,
|
||||
) : ContextMenu
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
|
|||
roomId = RoomId("!aRoom:aDomain"),
|
||||
roomName = "A nice room name",
|
||||
isDm = false,
|
||||
hasNewContent = false,
|
||||
)
|
||||
),
|
||||
aRoomListState().copy(displayRecoveryKeyPrompt = true),
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ class RoomListRoomSummaryFactory @Inject constructor(
|
|||
numberOfUnreadMessages = 0,
|
||||
numberOfUnreadMentions = 0,
|
||||
numberOfUnreadNotifications = 0,
|
||||
isMarkedUnread = false,
|
||||
userDefinedNotificationMode = null,
|
||||
hasRoomCall = false,
|
||||
isDm = false,
|
||||
|
|
@ -73,6 +74,7 @@ class RoomListRoomSummaryFactory @Inject constructor(
|
|||
numberOfUnreadMessages = roomSummary.details.numUnreadMessages,
|
||||
numberOfUnreadMentions = roomSummary.details.numUnreadMentions,
|
||||
numberOfUnreadNotifications = roomSummary.details.numUnreadNotifications,
|
||||
isMarkedUnread = roomSummary.details.isMarkedUnread,
|
||||
timestamp = lastMessageTimestampFormatter.format(roomSummary.details.lastMessageTimestamp),
|
||||
lastMessage = roomSummary.details.lastMessage?.let { message ->
|
||||
roomLastMessageFormatter.format(message.event, roomSummary.details.isDirect)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ data class RoomListRoomSummary(
|
|||
val numberOfUnreadMessages: Int,
|
||||
val numberOfUnreadMentions: Int,
|
||||
val numberOfUnreadNotifications: Int,
|
||||
val isMarkedUnread: Boolean,
|
||||
val timestamp: String?,
|
||||
val lastMessage: CharSequence?,
|
||||
val avatarData: AvatarData,
|
||||
|
|
@ -37,10 +38,12 @@ data class RoomListRoomSummary(
|
|||
val hasRoomCall: Boolean,
|
||||
val isDm: Boolean,
|
||||
) {
|
||||
val isHighlighted = userDefinedNotificationMode != RoomNotificationMode.MUTE &&
|
||||
(numberOfUnreadNotifications > 0 || numberOfUnreadMentions > 0)
|
||||
val isHighlighted = (userDefinedNotificationMode != RoomNotificationMode.MUTE &&
|
||||
(numberOfUnreadNotifications > 0 || numberOfUnreadMentions > 0)) ||
|
||||
isMarkedUnread
|
||||
|
||||
val hasNewContent = numberOfUnreadMessages > 0 ||
|
||||
numberOfUnreadMentions > 0 ||
|
||||
numberOfUnreadNotifications > 0
|
||||
numberOfUnreadNotifications > 0 ||
|
||||
isMarkedUnread
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ internal fun aRoomListRoomSummary(
|
|||
numberOfUnreadMessages: Int = 0,
|
||||
numberOfUnreadMentions: Int = 0,
|
||||
numberOfUnreadNotifications: Int = 0,
|
||||
isMarkedUnread: Boolean = false,
|
||||
lastMessage: String? = "Last message",
|
||||
timestamp: String? = lastMessage?.let { "88:88" },
|
||||
isPlaceholder: Boolean = false,
|
||||
|
|
@ -103,6 +104,7 @@ internal fun aRoomListRoomSummary(
|
|||
numberOfUnreadMessages = numberOfUnreadMessages,
|
||||
numberOfUnreadMentions = numberOfUnreadMentions,
|
||||
numberOfUnreadNotifications = numberOfUnreadNotifications,
|
||||
isMarkedUnread = isMarkedUnread,
|
||||
timestamp = timestamp,
|
||||
lastMessage = lastMessage,
|
||||
avatarData = avatarData,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue