mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Display the list of rooms with user-defined notification settings (#1535)
This commit is contained in:
+43
-20
@@ -14,16 +14,22 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct NotificationSettingsEditScreen: View {
|
||||
@ObservedObject var context: NotificationSettingsEditScreenViewModel.Context
|
||||
@State var isSearching = false
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
notificationModeSection
|
||||
|
||||
if context.viewState.displayRoomsWithCustomSettings {
|
||||
roomsWithCustomSettingsSection
|
||||
}
|
||||
}
|
||||
.compoundForm()
|
||||
.compoundList()
|
||||
.navigationTitle(context.viewState.strings.navigationTitle)
|
||||
.alert(item: $context.alertInfo)
|
||||
.track(screen: .settingsDefaultNotifications)
|
||||
@@ -34,25 +40,27 @@ struct NotificationSettingsEditScreen: View {
|
||||
private var notificationModeSection: some View {
|
||||
Section {
|
||||
ForEach(context.viewState.availableDefaultModes, id: \.self) { mode in
|
||||
Button {
|
||||
context.send(viewAction: .setMode(mode))
|
||||
} label: {
|
||||
LabeledContent {
|
||||
if context.viewState.pendingMode == mode {
|
||||
ProgressView()
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
} label: {
|
||||
Text(context.viewState.strings.string(for: mode))
|
||||
}
|
||||
}
|
||||
.buttonStyle(.compoundForm(accessory: .selected(context.viewState.isSelected(mode: mode))))
|
||||
.disabled(context.viewState.pendingMode != nil)
|
||||
ListRow(label: .plain(title: context.viewState.strings.string(for: mode)),
|
||||
details: (context.viewState.pendingMode == mode) ? .isWaiting(true) : nil,
|
||||
kind: .selection(isSelected: context.viewState.isSelected(mode: mode)) {
|
||||
context.send(viewAction: .setMode(mode))
|
||||
})
|
||||
.disabled(context.viewState.pendingMode != nil)
|
||||
}
|
||||
} header: {
|
||||
Text(context.viewState.strings.modeSectionTitle)
|
||||
.compoundFormSectionHeader()
|
||||
.compoundListSectionHeader()
|
||||
}
|
||||
}
|
||||
|
||||
private var roomsWithCustomSettingsSection: some View {
|
||||
Section {
|
||||
ForEach(context.viewState.roomsWithUserDefinedMode, id: \.id) { room in
|
||||
NotificationSettingsEditScreenRoomCell(room: room, context: context)
|
||||
}
|
||||
} header: {
|
||||
Text(L10n.screenNotificationSettingsEditCustomSettingsSectionTitle)
|
||||
.compoundListSectionHeader()
|
||||
}
|
||||
.compoundFormSection()
|
||||
}
|
||||
@@ -64,7 +72,13 @@ struct NotificationSettingsEditScreen_Previews: PreviewProvider {
|
||||
static let viewModelGroupChats: NotificationSettingsEditScreenViewModel = {
|
||||
let notificationSettingsProxy = NotificationSettingsProxyMock(with: .init())
|
||||
notificationSettingsProxy.getDefaultRoomNotificationModeIsEncryptedIsOneToOneReturnValue = .allMessages
|
||||
var viewModel = NotificationSettingsEditScreenViewModel(isDirect: false,
|
||||
|
||||
notificationSettingsProxy.getRoomsWithUserDefinedRulesReturnValue = [RoomSummary].mockRooms.compactMap(\.id)
|
||||
let userSession = MockUserSession(clientProxy: MockClientProxy(userID: "@alice:example.com",
|
||||
roomSummaryProvider: MockRoomSummaryProvider(state: .loaded(.mockRooms))),
|
||||
mediaProvider: MockMediaProvider())
|
||||
var viewModel = NotificationSettingsEditScreenViewModel(chatType: .groupChat,
|
||||
userSession: userSession,
|
||||
notificationSettingsProxy: notificationSettingsProxy)
|
||||
viewModel.fetchInitialContent()
|
||||
return viewModel
|
||||
@@ -73,7 +87,12 @@ struct NotificationSettingsEditScreen_Previews: PreviewProvider {
|
||||
static let viewModelDirectChats: NotificationSettingsEditScreenViewModel = {
|
||||
let notificationSettingsProxy = NotificationSettingsProxyMock(with: .init())
|
||||
notificationSettingsProxy.getDefaultRoomNotificationModeIsEncryptedIsOneToOneReturnValue = .mentionsAndKeywordsOnly
|
||||
var viewModel = NotificationSettingsEditScreenViewModel(isDirect: true,
|
||||
notificationSettingsProxy.getRoomsWithUserDefinedRulesReturnValue = []
|
||||
let userSession = MockUserSession(clientProxy: MockClientProxy(userID: "@alice:example.com",
|
||||
roomSummaryProvider: MockRoomSummaryProvider(state: .loaded(.mockRooms))),
|
||||
mediaProvider: MockMediaProvider())
|
||||
var viewModel = NotificationSettingsEditScreenViewModel(chatType: .oneToOneChat,
|
||||
userSession: userSession,
|
||||
notificationSettingsProxy: notificationSettingsProxy)
|
||||
viewModel.fetchInitialContent()
|
||||
return viewModel
|
||||
@@ -82,7 +101,11 @@ struct NotificationSettingsEditScreen_Previews: PreviewProvider {
|
||||
static let viewModelDirectApplyingChange: NotificationSettingsEditScreenViewModel = {
|
||||
let notificationSettingsProxy = NotificationSettingsProxyMock(with: .init())
|
||||
notificationSettingsProxy.getDefaultRoomNotificationModeIsEncryptedIsOneToOneReturnValue = .mentionsAndKeywordsOnly
|
||||
var viewModel = NotificationSettingsEditScreenViewModel(isDirect: true,
|
||||
notificationSettingsProxy.getRoomsWithUserDefinedRulesReturnValue = []
|
||||
let userSession = MockUserSession(clientProxy: MockClientProxy(userID: "John Doe"), mediaProvider: MockMediaProvider())
|
||||
|
||||
var viewModel = NotificationSettingsEditScreenViewModel(chatType: .oneToOneChat,
|
||||
userSession: userSession,
|
||||
notificationSettingsProxy: notificationSettingsProxy)
|
||||
viewModel.state.pendingMode = .mentionsAndKeywordsOnly
|
||||
viewModel.fetchInitialContent()
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// Copyright 2023 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct NotificationSettingsEditScreenRoomCell: View {
|
||||
@Environment(\.dynamicTypeSize) var dynamicTypeSize
|
||||
|
||||
let room: NotificationSettingsEditScreenRoom
|
||||
let context: NotificationSettingsEditScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
ListRow(label: .action(title: room.name,
|
||||
icon: avatar),
|
||||
details: roomDetailsLabel,
|
||||
kind: .navigationLink {
|
||||
if let roomId = room.roomId {
|
||||
context.send(viewAction: .selectRoom(roomIdentifier: roomId))
|
||||
}
|
||||
})
|
||||
.lineLimit(1)
|
||||
.accessibilityIdentifier(A11yIdentifiers.notificationSettingsEditScreen.roomName(room.name))
|
||||
}
|
||||
|
||||
@ViewBuilder @MainActor
|
||||
var avatar: some View {
|
||||
if dynamicTypeSize < .accessibility3 {
|
||||
LoadableAvatarImage(url: room.avatarURL,
|
||||
name: room.name,
|
||||
contentID: room.roomId,
|
||||
avatarSize: .room(on: .notificationSettings),
|
||||
imageProvider: context.imageProvider)
|
||||
.dynamicTypeSize(dynamicTypeSize < .accessibility1 ? dynamicTypeSize : .accessibility1)
|
||||
.accessibilityHidden(true)
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
var roomDetailsLabel: ListDetailsLabel<EmptyView>? {
|
||||
guard let mode = room.notificationMode else { return nil }
|
||||
return .label(title: context.viewState.strings.string(for: mode),
|
||||
icon: EmptyView())
|
||||
}
|
||||
}
|
||||
|
||||
struct NotificationSettingsEditScreenRoomCell_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let summaryProvider = MockRoomSummaryProvider(state: .loaded(.mockRooms))
|
||||
|
||||
let userSession = MockUserSession(clientProxy: MockClientProxy(userID: "John Doe", roomSummaryProvider: summaryProvider),
|
||||
mediaProvider: MockMediaProvider())
|
||||
|
||||
let notificationSettingsProxy = NotificationSettingsProxyMock(with: .init())
|
||||
notificationSettingsProxy.getRoomsWithUserDefinedRulesReturnValue = []
|
||||
let viewModel = NotificationSettingsEditScreenViewModel(chatType: .groupChat,
|
||||
userSession: userSession,
|
||||
notificationSettingsProxy: notificationSettingsProxy)
|
||||
|
||||
let rooms: [NotificationSettingsEditScreenRoom] = summaryProvider.roomListPublisher.value.compactMap { summary -> NotificationSettingsEditScreenRoom? in
|
||||
switch summary {
|
||||
case .empty, .invalidated:
|
||||
return nil
|
||||
case .filled(let details):
|
||||
return NotificationSettingsEditScreenRoom(id: UUID().uuidString,
|
||||
roomId: details.id,
|
||||
name: details.name)
|
||||
}
|
||||
}
|
||||
|
||||
return VStack(spacing: 0) {
|
||||
ForEach(rooms) { room in
|
||||
NotificationSettingsEditScreenRoomCell(room: room, context: viewModel.context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user