Merge pull request #2293 from element-hq/feature/bma/notificationCount

Iterate on notification badges
This commit is contained in:
Benoit Marty
2024-01-30 10:33:17 +01:00
committed by GitHub
48 changed files with 138 additions and 150 deletions

1
changelog.d/2282.bugfix Normal file
View File

@@ -0,0 +1 @@
Room list Ensure the indicators stay grey if the global setting is set to mention only and a regular message is received.

View File

@@ -35,6 +35,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewParameter
@@ -141,7 +142,7 @@ private fun RowScope.NameAndTimestampRow(room: RoomListRoomSummary) {
Text(
text = room.timestamp ?: "",
style = ElementTheme.typography.fontBodySmMedium,
color = if (room.isTimestampHighlighted) {
color = if (room.isHighlighted) {
ElementTheme.colors.unreadIndicator
} else {
MaterialTheme.roomListRoomMessageDate()
@@ -165,86 +166,61 @@ private fun RowScope.LastMessageAndIndicatorRow(room: RoomListRoomSummary) {
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
// Unread
// Call and unread
Row(
modifier = Modifier.height(16.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
// Video call
OnGoingCallIcon(
room.hasRoomCall,
)
// Other indicators
NotificationIcons(
room.userDefinedNotificationMode,
room.numberOfUnreadMessages,
room.numberOfUnreadMentions,
)
val tint = if (room.isHighlighted) ElementTheme.colors.unreadIndicator else ElementTheme.colors.iconQuaternary
if (room.hasRoomCall) {
OnGoingCallIcon(
color = tint,
)
}
if (room.userDefinedNotificationMode == RoomNotificationMode.MUTE) {
NotificationOffIndicatorAtom()
} else if (room.numberOfUnreadMentions > 0) {
MentionIndicatorAtom()
}
if (room.hasNewContent) {
UnreadIndicatorAtom(
color = tint
)
}
}
}
@Composable
private fun OnGoingCallIcon(
hasRoomCall: Boolean,
color: Color,
) {
if (hasRoomCall) {
Icon(
modifier = Modifier.size(16.dp),
imageVector = CompoundIcons.VideoCallSolid,
contentDescription = null,
tint = ElementTheme.colors.unreadIndicator,
)
}
Icon(
modifier = Modifier.size(16.dp),
imageVector = CompoundIcons.VideoCallSolid,
contentDescription = null,
tint = color,
)
}
@Composable
private fun RowScope.NotificationIcons(
userDefinedNotificationMode: RoomNotificationMode?,
numberOfUnreadMessages: Int,
numberOfUnreadMentions: Int,
) {
when (userDefinedNotificationMode) {
null,
RoomNotificationMode.ALL_MESSAGES -> {
if (numberOfUnreadMentions > 0) {
Icon(
modifier = Modifier.size(16.dp),
contentDescription = null,
imageVector = CompoundIcons.Mention,
tint = ElementTheme.colors.unreadIndicator,
)
UnreadIndicatorAtom()
} else if (numberOfUnreadMessages > 0) {
UnreadIndicatorAtom()
}
}
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> {
if (numberOfUnreadMentions > 0) {
Icon(
modifier = Modifier.size(16.dp),
contentDescription = null,
imageVector = CompoundIcons.Mention,
tint = ElementTheme.colors.unreadIndicator,
)
UnreadIndicatorAtom()
} else if (numberOfUnreadMessages > 0) {
UnreadIndicatorAtom(color = ElementTheme.colors.iconQuaternary)
}
}
RoomNotificationMode.MUTE -> {
Icon(
modifier = Modifier.size(16.dp),
contentDescription = null,
imageVector = CompoundIcons.NotificationsSolidOff,
tint = ElementTheme.colors.iconQuaternary,
)
if (numberOfUnreadMessages > 0 || numberOfUnreadMentions > 0) {
UnreadIndicatorAtom(color = ElementTheme.colors.iconQuaternary)
}
}
}
private fun NotificationOffIndicatorAtom() {
Icon(
modifier = Modifier.size(16.dp),
contentDescription = null,
imageVector = CompoundIcons.NotificationsSolidOff,
tint = ElementTheme.colors.iconQuaternary,
)
}
@Composable
private fun MentionIndicatorAtom() {
Icon(
modifier = Modifier.size(16.dp),
contentDescription = null,
imageVector = CompoundIcons.Mention,
tint = ElementTheme.colors.unreadIndicator,
)
}
@PreviewsDayNight

View File

@@ -43,6 +43,7 @@ class RoomListRoomSummaryFactory @Inject constructor(
avatarData = AvatarData(id, "S", size = AvatarSize.RoomListItem),
numberOfUnreadMessages = 0,
numberOfUnreadMentions = 0,
numberOfUnreadNotifications = 0,
userDefinedNotificationMode = null,
hasRoomCall = false,
isDm = false,
@@ -69,6 +70,7 @@ class RoomListRoomSummaryFactory @Inject constructor(
name = roomSummary.details.name,
numberOfUnreadMessages = roomSummary.details.numUnreadMessages,
numberOfUnreadMentions = roomSummary.details.numUnreadMentions,
numberOfUnreadNotifications = roomSummary.details.numUnreadNotifications,
timestamp = lastMessageTimestampFormatter.format(roomSummary.details.lastMessageTimestamp),
lastMessage = roomSummary.details.lastMessage?.let { message ->
roomLastMessageFormatter.format(message.event, roomSummary.details.isDirect)

View File

@@ -28,6 +28,7 @@ data class RoomListRoomSummary(
val name: String,
val numberOfUnreadMessages: Int,
val numberOfUnreadMentions: Int,
val numberOfUnreadNotifications: Int,
val timestamp: String?,
val lastMessage: CharSequence?,
val avatarData: AvatarData,
@@ -36,11 +37,10 @@ data class RoomListRoomSummary(
val hasRoomCall: Boolean,
val isDm: Boolean,
) {
val isTimestampHighlighted = hasRoomCall ||
when (userDefinedNotificationMode) {
null,
RoomNotificationMode.ALL_MESSAGES -> numberOfUnreadMessages > 0 || numberOfUnreadMentions > 0
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> numberOfUnreadMentions > 0
RoomNotificationMode.MUTE -> false
}
val isHighlighted = userDefinedNotificationMode != RoomNotificationMode.MUTE &&
(numberOfUnreadNotifications > 0 || numberOfUnreadMentions > 0)
val hasNewContent = numberOfUnreadMessages > 0 ||
numberOfUnreadMentions > 0 ||
numberOfUnreadNotifications > 0
}

View File

@@ -88,6 +88,7 @@ internal fun aRoomListRoomSummary(
name: String = "Room name",
numberOfUnreadMessages: Int = 0,
numberOfUnreadMentions: Int = 0,
numberOfUnreadNotifications: Int = 0,
lastMessage: String? = "Last message",
timestamp: String? = lastMessage?.let { "88:88" },
isPlaceholder: Boolean = false,
@@ -101,6 +102,7 @@ internal fun aRoomListRoomSummary(
name = name,
numberOfUnreadMessages = numberOfUnreadMessages,
numberOfUnreadMentions = numberOfUnreadMentions,
numberOfUnreadNotifications = numberOfUnreadNotifications,
timestamp = timestamp,
lastMessage = lastMessage,
avatarData = avatarData,

View File

@@ -442,6 +442,7 @@ private val aRoomListRoomSummary = RoomListRoomSummary(
name = A_ROOM_NAME,
numberOfUnreadMentions = 1,
numberOfUnreadMessages = 2,
numberOfUnreadNotifications = 0,
timestamp = A_FORMATTED_DATE,
lastMessage = "",
avatarData = AvatarData(id = A_ROOM_ID.value, name = A_ROOM_NAME, size = AvatarSize.RoomListItem),

View File

@@ -42,6 +42,7 @@ data class RoomSummaryDetails(
val lastMessage: RoomMessage?,
val numUnreadMessages: Int,
val numUnreadMentions: Int,
val numUnreadNotifications: Int,
val inviter: RoomMember?,
val userDefinedNotificationMode: RoomNotificationMode?,
val hasRoomCall: Boolean,

View File

@@ -37,6 +37,7 @@ class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFacto
avatarUrl = roomInfo.avatarUrl,
numUnreadMentions = roomInfo.numUnreadMentions.toInt(),
numUnreadMessages = roomInfo.numUnreadMessages.toInt(),
numUnreadNotifications = roomInfo.numUnreadNotifications.toInt(),
lastMessage = latestRoomMessage,
inviter = roomInfo.inviter?.let(RoomMemberMapper::map),
userDefinedNotificationMode = roomInfo.userDefinedNotificationMode?.let(RoomNotificationSettingsMapper::mapMode),

View File

@@ -61,6 +61,7 @@ fun aRoomSummaryDetails(
lastMessage: RoomMessage? = aRoomMessage(),
numUnreadMentions: Int = 0,
numUnreadMessages: Int = 0,
numUnreadNotifications: Int = 0,
notificationMode: RoomNotificationMode? = null,
inviter: RoomMember? = null,
canonicalAlias: String? = null,
@@ -74,6 +75,7 @@ fun aRoomSummaryDetails(
lastMessage = lastMessage,
numUnreadMentions = numUnreadMentions,
numUnreadMessages = numUnreadMessages,
numUnreadNotifications = numUnreadNotifications,
userDefinedNotificationMode = notificationMode,
inviter = inviter,
canonicalAlias = canonicalAlias,

View File

@@ -115,6 +115,7 @@ fun aRoomSummaryDetails(
isDm: Boolean = false,
numUnreadMentions: Int = 0,
numUnreadMessages: Int = 0,
numUnreadNotifications: Int = 0,
) = RoomSummaryDetails(
roomId = roomId,
name = name,
@@ -128,4 +129,5 @@ fun aRoomSummaryDetails(
isDm = isDm,
numUnreadMentions = numUnreadMentions,
numUnreadMessages = numUnreadMessages,
numUnreadNotifications = numUnreadNotifications,
)