Show message counts on room list notification badges

This commit is contained in:
Stefan Ceriu
2026-09-03 20:46:48 +03:00
parent 327ca090c5
commit ac183daff8
13 changed files with 55 additions and 14 deletions
@@ -347,6 +347,9 @@ final nonisolated class AppSettings: @unchecked Sendable {
@UserPreference(defaultValue: RoomListActivityVisibility.current)
var roomListActivityVisibility: RoomListActivityVisibility
@UserPreference(defaultValue: false)
var roomListNotificationCountEnabled: Bool
// MARK: - Room Screen
@UserPreference(defaultValue: AppBuildType.current == .debug)
@@ -106,6 +106,8 @@ struct HomeScreenViewState: BindableState {
var roomListActivityVisibility: RoomListActivityVisibility = .current
var roomListNotificationCountEnabled = false
var reportRoomEnabled = false
var shouldShowSpaceFilters = false
@@ -193,6 +195,7 @@ struct HomeScreenRoom: Identifiable, Equatable {
let badges: Badges
struct Badges: Equatable {
let isDotShown: Bool
let notificationCount: UInt
let isMentionShown: Bool
let isMuteShown: Bool
let callBadgeType: CallBadgeType
@@ -237,7 +240,7 @@ struct HomeScreenRoom: Identifiable, Equatable {
HomeScreenRoom(id: UUID().uuidString,
roomID: nil,
type: .placeholder,
badges: .init(isDotShown: false, isMentionShown: false, isMuteShown: false, callBadgeType: .none),
badges: .init(isDotShown: false, notificationCount: 0, isMentionShown: false, isMuteShown: false, callBadgeType: .none),
name: "Placeholder room name",
isDirect: false,
isHighlighted: false,
@@ -287,6 +290,7 @@ extension HomeScreenRoom {
roomID: summary.id,
type: type,
badges: .init(isDotShown: isDotShown,
notificationCount: summary.unreadNotificationsCount,
isMentionShown: isMentionShown,
isMuteShown: isMuteShown,
callBadgeType: callBadge),
@@ -120,6 +120,10 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
}
.store(in: &cancellables)
appSettings.roomListNotificationCountEnabledPublisher
.weakAssign(to: \.state.roomListNotificationCountEnabled, on: self)
.store(in: &cancellables)
appSettings.seenInvitesPublisher
.removeDuplicates()
.sink { [weak self] _ in
@@ -16,6 +16,7 @@ struct HomeScreenRoomCell: View {
let room: HomeScreenRoom
var roomListActivityVisibility: RoomListActivityVisibility = .current
var roomListNotificationCountEnabled = false
let isSelected: Bool
let mediaProvider: MediaProviderProtocol!
let action: (HomeScreenViewAction) -> Void
@@ -157,9 +158,20 @@ struct HomeScreenRoomCell: View {
}
if room.badges.isDotShown {
Circle()
.frame(width: 12, height: 12)
.accessibilityLabel(L10n.a11yNotificationsNewMessages)
if roomListNotificationCountEnabled, room.isHighlighted, room.badges.notificationCount > 0 {
Text(formattedNotificationCount)
.font(.compound.bodySMSemibold)
.foregroundColor(.compound.textOnSolidPrimary)
.lineLimit(1)
.padding(.horizontal, 6)
.frame(minWidth: 20, minHeight: 20)
.background(.compound.iconAccentTertiary, in: .capsule)
.accessibilityLabel(L10n.a11yNotificationsNewMessages)
} else {
Circle()
.frame(width: 12, height: 12)
.accessibilityLabel(L10n.a11yNotificationsNewMessages)
}
}
}
.foregroundColor(room.isHighlighted ? .compound.iconAccentTertiary : .compound.iconQuaternary)
@@ -171,6 +183,10 @@ struct HomeScreenRoomCell: View {
.accessibilityLabel(L10n.a11yNotificationsNewMentions)
}
private var formattedNotificationCount: String {
room.badges.notificationCount > 99 ? "99+" : "\(room.badges.notificationCount)"
}
@ViewBuilder
private var lastMessage: some View {
if let displayedLastMessage = room.displayedLastMessage {
@@ -239,7 +255,7 @@ struct HomeScreenRoomCell_Previews: PreviewProvider, TestablePreview {
VStack(spacing: 0) {
ForEach(notificationsStateRooms) { room in
HomeScreenRoomCell(room: room, isSelected: false, mediaProvider: MediaProviderMock(.init())) { _ in }
HomeScreenRoomCell(room: room, roomListNotificationCountEnabled: true, isSelected: false, mediaProvider: MediaProviderMock(.init())) { _ in }
}
}
.previewLayout(.sizeThatFits)
@@ -37,6 +37,7 @@ struct HomeScreenRoomList: View {
HomeScreenRoomCell(room: room,
roomListActivityVisibility: context.viewState.roomListActivityVisibility,
roomListNotificationCountEnabled: context.viewState.roomListNotificationCountEnabled,
isSelected: isSelected,
mediaProvider: context.mediaProvider,
action: context.send)
@@ -59,6 +59,7 @@ protocol DeveloperOptionsProtocol: AnyObject {
var automaticBackPaginationEnabled: Bool { get set }
var roomListActivityVisibility: RoomListActivityVisibility { get set }
var roomListNotificationCountEnabled: Bool { get set }
var elementCallBaseURLOverride: URL? { get set }
var fuzzyRoomListSearchEnabled: Bool { get set }
@@ -67,6 +67,10 @@ struct DeveloperOptionsScreen: View {
}
}
Toggle(isOn: $context.roomListNotificationCountEnabled) {
Text("Show unread notification count")
}
Toggle(isOn: $context.fuzzyRoomListSearchEnabled) {
Text("Fuzzy searching")
}