Merge pull request #2265 from element-hq/bma/notificationCount

Iterate on notification count
This commit is contained in:
Benoit Marty
2024-01-23 12:13:23 +01:00
committed by GitHub
68 changed files with 307 additions and 99 deletions

View File

@@ -431,7 +431,6 @@ class InviteListPresenterTests {
avatarUrl = null,
isDirect = false,
lastMessage = null,
unreadNotificationCount = 0,
inviter = RoomMember(
userId = A_USER_ID,
displayName = A_USER_NAME,
@@ -459,7 +458,6 @@ class InviteListPresenterTests {
avatarUrl = null,
isDirect = true,
lastMessage = null,
unreadNotificationCount = 0,
inviter = RoomMember(
userId = A_USER_ID,
displayName = A_USER_NAME,
@@ -484,7 +482,6 @@ class InviteListPresenterTests {
avatarUrl = null,
isDirect = false,
lastMessage = null,
unreadNotificationCount = 0,
)
)

View File

@@ -55,7 +55,6 @@ private fun aRoomSummary() = RoomSummary.Filled(
avatarUrl = null,
isDirect = false,
lastMessage = null,
unreadNotificationCount = 0,
notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
)
)

View File

@@ -73,7 +73,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
return persistentListOf(
aRoomListRoomSummary(
name = "Room",
hasUnread = true,
numberOfUnreadMessages = 1,
timestamp = "14:18",
lastMessage = "A very very very very long message which suites on two lines",
avatarData = AvatarData("!id", "R", size = AvatarSize.RoomListItem),
@@ -81,7 +81,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
),
aRoomListRoomSummary(
name = "Room#2",
hasUnread = false,
numberOfUnreadMessages = 0,
timestamp = "14:16",
lastMessage = "A short message",
avatarData = AvatarData("!id", "Z", size = AvatarSize.RoomListItem),

View File

@@ -141,7 +141,7 @@ private fun RowScope.NameAndTimestampRow(room: RoomListRoomSummary) {
Text(
text = room.timestamp ?: "",
style = ElementTheme.typography.fontBodySmMedium,
color = if (room.hasUnread) {
color = if (room.isTimestampHighlighted) {
ElementTheme.colors.unreadIndicator
} else {
MaterialTheme.roomListRoomMessageDate()
@@ -173,40 +173,77 @@ private fun RowScope.LastMessageAndIndicatorRow(room: RoomListRoomSummary) {
verticalAlignment = Alignment.CenterVertically,
) {
// Video call
if (room.hasRoomCall) {
Icon(
modifier = Modifier.size(16.dp),
imageVector = CompoundIcons.VideoCallSolid,
contentDescription = null,
tint = ElementTheme.colors.unreadIndicator,
)
}
NotificationIcon(room)
if (room.hasUnread) {
UnreadIndicatorAtom()
}
OnGoingCallIcon(
room.hasRoomCall,
)
// Other indicators
NotificationIcons(
room.userDefinedNotificationMode,
room.numberOfUnreadMessages,
room.numberOfUnreadMentions,
)
}
}
@Composable
private fun NotificationIcon(room: RoomListRoomSummary) {
val tint = if (room.hasUnread) ElementTheme.colors.unreadIndicator else ElementTheme.colors.iconQuaternary
when (room.userDefinedNotificationMode) {
null, RoomNotificationMode.ALL_MESSAGES -> return
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY ->
Icon(
modifier = Modifier.size(16.dp),
contentDescription = null,
imageVector = CompoundIcons.Mention,
tint = tint,
)
RoomNotificationMode.MUTE ->
private fun OnGoingCallIcon(
hasRoomCall: Boolean,
) {
if (hasRoomCall) {
Icon(
modifier = Modifier.size(16.dp),
imageVector = CompoundIcons.VideoCallSolid,
contentDescription = null,
tint = ElementTheme.colors.unreadIndicator,
)
}
}
@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 = tint,
tint = ElementTheme.colors.iconQuaternary,
)
if (numberOfUnreadMessages > 0 || numberOfUnreadMentions > 0) {
UnreadIndicatorAtom(color = ElementTheme.colors.iconQuaternary)
}
}
}
}

View File

@@ -41,7 +41,8 @@ class RoomListRoomSummaryFactory @Inject constructor(
timestamp = "hh:mm",
lastMessage = "Last message for placeholder",
avatarData = AvatarData(id, "S", size = AvatarSize.RoomListItem),
hasUnread = false,
numberOfUnreadMessages = 0,
numberOfUnreadMentions = 0,
userDefinedNotificationMode = null,
hasRoomCall = false,
isDm = false,
@@ -66,7 +67,8 @@ class RoomListRoomSummaryFactory @Inject constructor(
id = roomIdentifier,
roomId = RoomId(roomIdentifier),
name = roomSummary.details.name,
hasUnread = roomSummary.details.unreadNotificationCount > 0,
numberOfUnreadMessages = roomSummary.details.numUnreadMessages,
numberOfUnreadMentions = roomSummary.details.numUnreadMentions,
timestamp = lastMessageTimestampFormatter.format(roomSummary.details.lastMessageTimestamp),
lastMessage = roomSummary.details.lastMessage?.let { message ->
roomLastMessageFormatter.format(message.event, roomSummary.details.isDirect)

View File

@@ -26,7 +26,8 @@ data class RoomListRoomSummary(
val id: String,
val roomId: RoomId,
val name: String,
val hasUnread: Boolean,
val numberOfUnreadMessages: Int,
val numberOfUnreadMentions: Int,
val timestamp: String?,
val lastMessage: CharSequence?,
val avatarData: AvatarData,
@@ -34,4 +35,12 @@ data class RoomListRoomSummary(
val userDefinedNotificationMode: RoomNotificationMode?,
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
}
}

View File

@@ -25,29 +25,69 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationMode
open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSummary> {
override val values: Sequence<RoomListRoomSummary>
get() = sequenceOf(
aRoomListRoomSummary(),
aRoomListRoomSummary(lastMessage = null),
aRoomListRoomSummary(hasUnread = true, notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY),
aRoomListRoomSummary(notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY),
aRoomListRoomSummary(notificationMode = RoomNotificationMode.MUTE),
aRoomListRoomSummary(hasUnread = true),
aRoomListRoomSummary(isPlaceholder = true),
aRoomListRoomSummary(
name = "A very long room name that should be truncated",
lastMessage = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" +
" ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" +
"modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
timestamp = "yesterday",
hasUnread = true,
listOf(
aRoomListRoomSummary(isPlaceholder = true),
aRoomListRoomSummary(),
aRoomListRoomSummary(lastMessage = null),
aRoomListRoomSummary(
name = "A very long room name that should be truncated",
lastMessage = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" +
" ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" +
"modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
timestamp = "yesterday",
numberOfUnreadMessages = 1,
),
),
aRoomListRoomSummary(hasUnread = true, hasRoomCall = true),
)
listOf(false, true).map { hasCall ->
listOf(
RoomNotificationMode.ALL_MESSAGES,
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
RoomNotificationMode.MUTE,
).map { roomNotificationMode ->
listOf(
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "No activity" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 0,
numberOfUnreadMentions = 0,
hasRoomCall = hasCall,
),
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "New messages" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 1,
numberOfUnreadMentions = 0,
hasRoomCall = hasCall,
),
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "New messages, mentions" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 1,
numberOfUnreadMentions = 1,
hasRoomCall = hasCall,
),
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "New mentions" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 0,
numberOfUnreadMentions = 1,
hasRoomCall = hasCall,
),
)
}.flatten()
}.flatten(),
).flatten()
}
internal fun aRoomListRoomSummary(
id: String = "!roomId:domain",
name: String = "Room name",
hasUnread: Boolean = false,
numberOfUnreadMessages: Int = 0,
numberOfUnreadMentions: Int = 0,
lastMessage: String? = "Last message",
timestamp: String? = lastMessage?.let { "88:88" },
isPlaceholder: Boolean = false,
@@ -59,7 +99,8 @@ internal fun aRoomListRoomSummary(
id = id,
roomId = RoomId(id),
name = name,
hasUnread = hasUnread,
numberOfUnreadMessages = numberOfUnreadMessages,
numberOfUnreadMentions = numberOfUnreadMentions,
timestamp = timestamp,
lastMessage = lastMessage,
avatarData = avatarData,

View File

@@ -440,7 +440,8 @@ private val aRoomListRoomSummary = RoomListRoomSummary(
id = A_ROOM_ID.value,
roomId = A_ROOM_ID,
name = A_ROOM_NAME,
hasUnread = true,
numberOfUnreadMentions = 1,
numberOfUnreadMessages = 2,
timestamp = A_FORMATTED_DATE,
lastMessage = "",
avatarData = AvatarData(id = A_ROOM_ID.value, name = A_ROOM_NAME, size = AvatarSize.RoomListItem),

View File

@@ -40,7 +40,8 @@ data class RoomSummaryDetails(
val isDirect: Boolean,
val avatarUrl: String?,
val lastMessage: RoomMessage?,
val unreadNotificationCount: Int,
val numUnreadMessages: Int,
val numUnreadMentions: Int,
val inviter: RoomMember?,
val userDefinedNotificationMode: RoomNotificationMode?,
val hasRoomCall: Boolean,

View File

@@ -35,7 +35,8 @@ class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFacto
canonicalAlias = roomInfo.canonicalAlias,
isDirect = roomInfo.isDirect,
avatarUrl = roomInfo.avatarUrl,
unreadNotificationCount = roomInfo.notificationCount.toInt(),
numUnreadMentions = roomInfo.numUnreadMentions.toInt(),
numUnreadMessages = roomInfo.numUnreadMessages.toInt(),
lastMessage = latestRoomMessage,
inviter = roomInfo.inviter?.let(RoomMemberMapper::map),
userDefinedNotificationMode = roomInfo.userDefinedNotificationMode?.let(RoomNotificationSettingsMapper::mapMode),

View File

@@ -37,7 +37,8 @@ fun aRoomSummaryFilled(
isDirect: Boolean = false,
avatarUrl: String? = null,
lastMessage: RoomMessage? = aRoomMessage(),
unreadNotificationCount: Int = 2,
numUnreadMentions: Int = 1,
numUnreadMessages: Int = 2,
notificationMode: RoomNotificationMode? = null,
) = RoomSummary.Filled(
aRoomSummaryDetails(
@@ -46,7 +47,8 @@ fun aRoomSummaryFilled(
isDirect = isDirect,
avatarUrl = avatarUrl,
lastMessage = lastMessage,
unreadNotificationCount = unreadNotificationCount,
numUnreadMentions = numUnreadMentions,
numUnreadMessages = numUnreadMessages,
notificationMode = notificationMode,
)
)
@@ -57,7 +59,8 @@ fun aRoomSummaryDetails(
isDirect: Boolean = false,
avatarUrl: String? = null,
lastMessage: RoomMessage? = aRoomMessage(),
unreadNotificationCount: Int = 2,
numUnreadMentions: Int = 0,
numUnreadMessages: Int = 0,
notificationMode: RoomNotificationMode? = null,
inviter: RoomMember? = null,
canonicalAlias: String? = null,
@@ -69,7 +72,8 @@ fun aRoomSummaryDetails(
isDirect = isDirect,
avatarUrl = avatarUrl,
lastMessage = lastMessage,
unreadNotificationCount = unreadNotificationCount,
numUnreadMentions = numUnreadMentions,
numUnreadMessages = numUnreadMessages,
userDefinedNotificationMode = notificationMode,
inviter = inviter,
canonicalAlias = canonicalAlias,

View File

@@ -113,7 +113,8 @@ fun aRoomSummaryDetails(
notificationMode: RoomNotificationMode? = null,
hasRoomCall: Boolean = false,
isDm: Boolean = false,
unreadNotificationCount: Int = 0
numUnreadMentions: Int = 0,
numUnreadMessages: Int = 0,
) = RoomSummaryDetails(
roomId = roomId,
name = name,
@@ -125,5 +126,6 @@ fun aRoomSummaryDetails(
userDefinedNotificationMode = notificationMode,
hasRoomCall = hasRoomCall,
isDm = isDm,
unreadNotificationCount = unreadNotificationCount,
numUnreadMentions = numUnreadMentions,
numUnreadMessages = numUnreadMessages,
)