mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Show message counts on room list notification badges
This commit is contained in:
@@ -347,6 +347,9 @@ final nonisolated class AppSettings: @unchecked Sendable {
|
|||||||
@UserPreference(defaultValue: RoomListActivityVisibility.current)
|
@UserPreference(defaultValue: RoomListActivityVisibility.current)
|
||||||
var roomListActivityVisibility: RoomListActivityVisibility
|
var roomListActivityVisibility: RoomListActivityVisibility
|
||||||
|
|
||||||
|
@UserPreference(defaultValue: false)
|
||||||
|
var roomListNotificationCountEnabled: Bool
|
||||||
|
|
||||||
// MARK: - Room Screen
|
// MARK: - Room Screen
|
||||||
|
|
||||||
@UserPreference(defaultValue: AppBuildType.current == .debug)
|
@UserPreference(defaultValue: AppBuildType.current == .debug)
|
||||||
|
|||||||
@@ -106,6 +106,8 @@ struct HomeScreenViewState: BindableState {
|
|||||||
|
|
||||||
var roomListActivityVisibility: RoomListActivityVisibility = .current
|
var roomListActivityVisibility: RoomListActivityVisibility = .current
|
||||||
|
|
||||||
|
var roomListNotificationCountEnabled = false
|
||||||
|
|
||||||
var reportRoomEnabled = false
|
var reportRoomEnabled = false
|
||||||
|
|
||||||
var shouldShowSpaceFilters = false
|
var shouldShowSpaceFilters = false
|
||||||
@@ -193,6 +195,7 @@ struct HomeScreenRoom: Identifiable, Equatable {
|
|||||||
let badges: Badges
|
let badges: Badges
|
||||||
struct Badges: Equatable {
|
struct Badges: Equatable {
|
||||||
let isDotShown: Bool
|
let isDotShown: Bool
|
||||||
|
let notificationCount: UInt
|
||||||
let isMentionShown: Bool
|
let isMentionShown: Bool
|
||||||
let isMuteShown: Bool
|
let isMuteShown: Bool
|
||||||
let callBadgeType: CallBadgeType
|
let callBadgeType: CallBadgeType
|
||||||
@@ -237,7 +240,7 @@ struct HomeScreenRoom: Identifiable, Equatable {
|
|||||||
HomeScreenRoom(id: UUID().uuidString,
|
HomeScreenRoom(id: UUID().uuidString,
|
||||||
roomID: nil,
|
roomID: nil,
|
||||||
type: .placeholder,
|
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",
|
name: "Placeholder room name",
|
||||||
isDirect: false,
|
isDirect: false,
|
||||||
isHighlighted: false,
|
isHighlighted: false,
|
||||||
@@ -287,6 +290,7 @@ extension HomeScreenRoom {
|
|||||||
roomID: summary.id,
|
roomID: summary.id,
|
||||||
type: type,
|
type: type,
|
||||||
badges: .init(isDotShown: isDotShown,
|
badges: .init(isDotShown: isDotShown,
|
||||||
|
notificationCount: summary.unreadNotificationsCount,
|
||||||
isMentionShown: isMentionShown,
|
isMentionShown: isMentionShown,
|
||||||
isMuteShown: isMuteShown,
|
isMuteShown: isMuteShown,
|
||||||
callBadgeType: callBadge),
|
callBadgeType: callBadge),
|
||||||
|
|||||||
@@ -120,6 +120,10 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
appSettings.roomListNotificationCountEnabledPublisher
|
||||||
|
.weakAssign(to: \.state.roomListNotificationCountEnabled, on: self)
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
appSettings.seenInvitesPublisher
|
appSettings.seenInvitesPublisher
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.sink { [weak self] _ in
|
.sink { [weak self] _ in
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ struct HomeScreenRoomCell: View {
|
|||||||
|
|
||||||
let room: HomeScreenRoom
|
let room: HomeScreenRoom
|
||||||
var roomListActivityVisibility: RoomListActivityVisibility = .current
|
var roomListActivityVisibility: RoomListActivityVisibility = .current
|
||||||
|
var roomListNotificationCountEnabled = false
|
||||||
let isSelected: Bool
|
let isSelected: Bool
|
||||||
let mediaProvider: MediaProviderProtocol!
|
let mediaProvider: MediaProviderProtocol!
|
||||||
let action: (HomeScreenViewAction) -> Void
|
let action: (HomeScreenViewAction) -> Void
|
||||||
@@ -157,9 +158,20 @@ struct HomeScreenRoomCell: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if room.badges.isDotShown {
|
if room.badges.isDotShown {
|
||||||
Circle()
|
if roomListNotificationCountEnabled, room.isHighlighted, room.badges.notificationCount > 0 {
|
||||||
.frame(width: 12, height: 12)
|
Text(formattedNotificationCount)
|
||||||
.accessibilityLabel(L10n.a11yNotificationsNewMessages)
|
.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)
|
.foregroundColor(room.isHighlighted ? .compound.iconAccentTertiary : .compound.iconQuaternary)
|
||||||
@@ -171,6 +183,10 @@ struct HomeScreenRoomCell: View {
|
|||||||
.accessibilityLabel(L10n.a11yNotificationsNewMentions)
|
.accessibilityLabel(L10n.a11yNotificationsNewMentions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var formattedNotificationCount: String {
|
||||||
|
room.badges.notificationCount > 99 ? "99+" : "\(room.badges.notificationCount)"
|
||||||
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var lastMessage: some View {
|
private var lastMessage: some View {
|
||||||
if let displayedLastMessage = room.displayedLastMessage {
|
if let displayedLastMessage = room.displayedLastMessage {
|
||||||
@@ -239,7 +255,7 @@ struct HomeScreenRoomCell_Previews: PreviewProvider, TestablePreview {
|
|||||||
|
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
ForEach(notificationsStateRooms) { room in
|
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)
|
.previewLayout(.sizeThatFits)
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ struct HomeScreenRoomList: View {
|
|||||||
|
|
||||||
HomeScreenRoomCell(room: room,
|
HomeScreenRoomCell(room: room,
|
||||||
roomListActivityVisibility: context.viewState.roomListActivityVisibility,
|
roomListActivityVisibility: context.viewState.roomListActivityVisibility,
|
||||||
|
roomListNotificationCountEnabled: context.viewState.roomListNotificationCountEnabled,
|
||||||
isSelected: isSelected,
|
isSelected: isSelected,
|
||||||
mediaProvider: context.mediaProvider,
|
mediaProvider: context.mediaProvider,
|
||||||
action: context.send)
|
action: context.send)
|
||||||
|
|||||||
+1
@@ -59,6 +59,7 @@ protocol DeveloperOptionsProtocol: AnyObject {
|
|||||||
var automaticBackPaginationEnabled: Bool { get set }
|
var automaticBackPaginationEnabled: Bool { get set }
|
||||||
|
|
||||||
var roomListActivityVisibility: RoomListActivityVisibility { get set }
|
var roomListActivityVisibility: RoomListActivityVisibility { get set }
|
||||||
|
var roomListNotificationCountEnabled: Bool { get set }
|
||||||
var elementCallBaseURLOverride: URL? { get set }
|
var elementCallBaseURLOverride: URL? { get set }
|
||||||
|
|
||||||
var fuzzyRoomListSearchEnabled: Bool { get set }
|
var fuzzyRoomListSearchEnabled: Bool { get set }
|
||||||
|
|||||||
+4
@@ -67,6 +67,10 @@ struct DeveloperOptionsScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Toggle(isOn: $context.roomListNotificationCountEnabled) {
|
||||||
|
Text("Show unread notification count")
|
||||||
|
}
|
||||||
|
|
||||||
Toggle(isOn: $context.fuzzyRoomListSearchEnabled) {
|
Toggle(isOn: $context.fuzzyRoomListSearchEnabled) {
|
||||||
Text("Fuzzy searching")
|
Text("Fuzzy searching")
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
Submodule Enterprise updated: fc45cdfbcf...30d2ad29a8
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:050527f53b7afa77b75c456a54d6e98d15fe422f3f36921f09431fb1255dbcd6
|
oid sha256:7ad7111dc38ca268615888915548c5c85cef835f9b20d2d79b71f9445f9dd918
|
||||||
size 783268
|
size 786479
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:9f8cae65c6e8a501caaf2b3fcd07b48d2714c44cf7b9efa17fabffc108a32b71
|
oid sha256:2f555cef6b6514ac6dda6604cf93bbf73f5b74712324e29d926d94354026fe1b
|
||||||
size 788915
|
size 792039
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5f25670c5b16a8b37845fdc90f471d4586fbbc3eacd732fd71007ed4391f7b5e
|
oid sha256:2c77c9c9db4bc2547567c185aecf3d6378d4f538941ee129ab592b4d749266f8
|
||||||
size 536811
|
size 539834
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:58d40c544df548edd120862e403d2eb61c8af11e213696b22a17e92feaa45c55
|
oid sha256:32d421dbf919a73112b48a5fa876447ecd8842df65c6a4f21e91cbf2c9bb8c58
|
||||||
size 540360
|
size 543432
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ struct HomeScreenRoomTests {
|
|||||||
|
|
||||||
#expect(!room.isHighlighted)
|
#expect(!room.isHighlighted)
|
||||||
#expect(!room.badges.isDotShown)
|
#expect(!room.badges.isDotShown)
|
||||||
|
#expect(room.badges.notificationCount == 0)
|
||||||
#expect(room.badges.callBadgeType == .none)
|
#expect(room.badges.callBadgeType == .none)
|
||||||
#expect(!room.badges.isMuteShown)
|
#expect(!room.badges.isMuteShown)
|
||||||
#expect(!room.badges.isMentionShown)
|
#expect(!room.badges.isMentionShown)
|
||||||
@@ -78,6 +79,7 @@ struct HomeScreenRoomTests {
|
|||||||
|
|
||||||
#expect(room.isHighlighted)
|
#expect(room.isHighlighted)
|
||||||
#expect(room.badges.isDotShown)
|
#expect(room.badges.isDotShown)
|
||||||
|
#expect(room.badges.notificationCount == 5)
|
||||||
#expect(room.badges.callBadgeType == .video)
|
#expect(room.badges.callBadgeType == .video)
|
||||||
#expect(!room.badges.isMuteShown)
|
#expect(!room.badges.isMuteShown)
|
||||||
#expect(room.badges.isMentionShown)
|
#expect(room.badges.isMentionShown)
|
||||||
@@ -111,6 +113,7 @@ struct HomeScreenRoomTests {
|
|||||||
|
|
||||||
#expect(!room.isHighlighted)
|
#expect(!room.isHighlighted)
|
||||||
#expect(room.badges.isDotShown)
|
#expect(room.badges.isDotShown)
|
||||||
|
#expect(room.badges.notificationCount == 0)
|
||||||
#expect(room.badges.callBadgeType == .none)
|
#expect(room.badges.callBadgeType == .none)
|
||||||
#expect(!room.badges.isMuteShown)
|
#expect(!room.badges.isMuteShown)
|
||||||
#expect(!room.badges.isMentionShown)
|
#expect(!room.badges.isMentionShown)
|
||||||
@@ -129,6 +132,7 @@ struct HomeScreenRoomTests {
|
|||||||
|
|
||||||
#expect(room.isHighlighted)
|
#expect(room.isHighlighted)
|
||||||
#expect(room.badges.isDotShown)
|
#expect(room.badges.isDotShown)
|
||||||
|
#expect(room.badges.notificationCount == 5)
|
||||||
#expect(room.badges.callBadgeType == .none)
|
#expect(room.badges.callBadgeType == .none)
|
||||||
#expect(!room.badges.isMuteShown)
|
#expect(!room.badges.isMuteShown)
|
||||||
#expect(!room.badges.isMentionShown)
|
#expect(!room.badges.isMentionShown)
|
||||||
@@ -147,6 +151,7 @@ struct HomeScreenRoomTests {
|
|||||||
|
|
||||||
#expect(room.isHighlighted)
|
#expect(room.isHighlighted)
|
||||||
#expect(room.badges.isDotShown)
|
#expect(room.badges.isDotShown)
|
||||||
|
#expect(room.badges.notificationCount == 0)
|
||||||
#expect(room.badges.callBadgeType == .none)
|
#expect(room.badges.callBadgeType == .none)
|
||||||
#expect(!room.badges.isMuteShown)
|
#expect(!room.badges.isMuteShown)
|
||||||
#expect(room.badges.isMentionShown)
|
#expect(room.badges.isMentionShown)
|
||||||
@@ -221,6 +226,7 @@ struct HomeScreenRoomTests {
|
|||||||
|
|
||||||
#expect(room.isHighlighted)
|
#expect(room.isHighlighted)
|
||||||
#expect(room.badges.isDotShown)
|
#expect(room.badges.isDotShown)
|
||||||
|
#expect(room.badges.notificationCount == 0)
|
||||||
#expect(room.badges.callBadgeType == .none)
|
#expect(room.badges.callBadgeType == .none)
|
||||||
#expect(!room.badges.isMuteShown)
|
#expect(!room.badges.isMuteShown)
|
||||||
#expect(!room.badges.isMentionShown)
|
#expect(!room.badges.isMentionShown)
|
||||||
@@ -239,6 +245,7 @@ struct HomeScreenRoomTests {
|
|||||||
|
|
||||||
#expect(room.isHighlighted)
|
#expect(room.isHighlighted)
|
||||||
#expect(room.badges.isDotShown)
|
#expect(room.badges.isDotShown)
|
||||||
|
#expect(room.badges.notificationCount == 0)
|
||||||
#expect(room.badges.callBadgeType == .none)
|
#expect(room.badges.callBadgeType == .none)
|
||||||
#expect(!room.badges.isMuteShown)
|
#expect(!room.badges.isMuteShown)
|
||||||
#expect(room.badges.isMentionShown)
|
#expect(room.badges.isMentionShown)
|
||||||
@@ -257,6 +264,7 @@ struct HomeScreenRoomTests {
|
|||||||
|
|
||||||
#expect(room.isHighlighted)
|
#expect(room.isHighlighted)
|
||||||
#expect(room.badges.isDotShown)
|
#expect(room.badges.isDotShown)
|
||||||
|
#expect(room.badges.notificationCount == 5)
|
||||||
#expect(room.badges.callBadgeType == .video)
|
#expect(room.badges.callBadgeType == .video)
|
||||||
#expect(room.badges.isMuteShown)
|
#expect(room.badges.isMuteShown)
|
||||||
#expect(!room.badges.isMentionShown)
|
#expect(!room.badges.isMentionShown)
|
||||||
|
|||||||
Reference in New Issue
Block a user