mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 10:33:45 +00:00
Add a link to the global settings in the room notifications settings (#1433)
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
import Combine
|
import Combine
|
||||||
import Foundation
|
import Foundation
|
||||||
import SwiftState
|
import SwiftState
|
||||||
|
import UserNotifications
|
||||||
|
|
||||||
enum RoomFlowCoordinatorAction: Equatable {
|
enum RoomFlowCoordinatorAction: Equatable {
|
||||||
case presentedRoom(String)
|
case presentedRoom(String)
|
||||||
@@ -149,6 +150,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
return .mapNavigator(roomID: roomID)
|
return .mapNavigator(roomID: roomID)
|
||||||
case (.dismissMapNavigator, .mapNavigator(let roomID)):
|
case (.dismissMapNavigator, .mapNavigator(let roomID)):
|
||||||
return .room(roomID: roomID)
|
return .room(roomID: roomID)
|
||||||
|
|
||||||
|
case (.presentNotificationSettingsScreen, .roomDetails(let roomID, _)):
|
||||||
|
return .notificationSettingsScreen(roomID: roomID)
|
||||||
|
case (.dismissNotificationSettingsScreen, .notificationSettingsScreen(let roomID)):
|
||||||
|
return .roomDetails(roomID: roomID, isRoot: false)
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -215,6 +221,12 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
presentMapNavigator(interactionMode: mode)
|
presentMapNavigator(interactionMode: mode)
|
||||||
case (.mapNavigator, .dismissMapNavigator, .room):
|
case (.mapNavigator, .dismissMapNavigator, .room):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case (.roomDetails, .presentNotificationSettingsScreen, .notificationSettingsScreen):
|
||||||
|
asyncPresentNotificationSettingsScreen(animated: animated)
|
||||||
|
case (.notificationSettingsScreen, .dismissNotificationSettingsScreen, .roomDetails):
|
||||||
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fatalError("Unknown transition: \(context)")
|
fatalError("Unknown transition: \(context)")
|
||||||
}
|
}
|
||||||
@@ -372,12 +384,15 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
userIndicatorController: userIndicatorController,
|
userIndicatorController: userIndicatorController,
|
||||||
notificationSettings: userSession.clientProxy.notificationSettings())
|
notificationSettings: userSession.clientProxy.notificationSettings())
|
||||||
let coordinator = RoomDetailsScreenCoordinator(parameters: params)
|
let coordinator = RoomDetailsScreenCoordinator(parameters: params)
|
||||||
coordinator.callback = { [weak self] action in
|
coordinator.actions.sink { [weak self] action in
|
||||||
switch action {
|
switch action {
|
||||||
case .leftRoom:
|
case .leftRoom:
|
||||||
self?.dismissRoom(animated: animated)
|
self?.dismissRoom(animated: animated)
|
||||||
|
case .presentNotificationSettingsScreen:
|
||||||
|
self?.stateMachine.tryEvent(.presentNotificationSettingsScreen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
if isRoot {
|
if isRoot {
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator, animated: animated) { [weak self] in
|
navigationStackCoordinator.setRootCoordinator(coordinator, animated: animated) { [weak self] in
|
||||||
@@ -610,6 +625,32 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
stateMachine.tryEvent(.presentRoom(roomID: roomID), userInfo: EventUserInfo(animated: true, destinationRoomProxy: targetRoomProxy))
|
stateMachine.tryEvent(.presentRoom(roomID: roomID), userInfo: EventUserInfo(animated: true, destinationRoomProxy: targetRoomProxy))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func asyncPresentNotificationSettingsScreen(animated: Bool) {
|
||||||
|
Task {
|
||||||
|
await presentNotificationSettingsScreen(animated: animated)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func presentNotificationSettingsScreen(animated: Bool) async {
|
||||||
|
let navigationCoordinator = NavigationStackCoordinator()
|
||||||
|
let parameters = await NotificationSettingsScreenCoordinatorParameters(userNotificationCenter: UNUserNotificationCenter.current(),
|
||||||
|
notificationSettings: userSession.clientProxy.notificationSettings(),
|
||||||
|
isModallyPresented: true)
|
||||||
|
let coordinator = NotificationSettingsScreenCoordinator(parameters: parameters)
|
||||||
|
coordinator.actions.sink { [weak self] action in
|
||||||
|
switch action {
|
||||||
|
case .close:
|
||||||
|
self?.navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
navigationCoordinator.setRootCoordinator(coordinator)
|
||||||
|
navigationStackCoordinator.setSheetCoordinator(navigationCoordinator) { [weak self] in
|
||||||
|
self?.stateMachine.tryEvent(.dismissNotificationSettingsScreen)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension RoomFlowCoordinator {
|
private extension RoomFlowCoordinator {
|
||||||
@@ -636,6 +677,7 @@ private extension RoomFlowCoordinator {
|
|||||||
case mapNavigator(roomID: String)
|
case mapNavigator(roomID: String)
|
||||||
case roomMemberDetails(roomID: String, member: HashableRoomMemberWrapper)
|
case roomMemberDetails(roomID: String, member: HashableRoomMemberWrapper)
|
||||||
case messageForwarding(roomID: String, itemID: TimelineItemIdentifier)
|
case messageForwarding(roomID: String, itemID: TimelineItemIdentifier)
|
||||||
|
case notificationSettingsScreen(roomID: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EventUserInfo {
|
struct EventUserInfo {
|
||||||
@@ -670,6 +712,9 @@ private extension RoomFlowCoordinator {
|
|||||||
|
|
||||||
case presentMessageForwarding(itemID: TimelineItemIdentifier)
|
case presentMessageForwarding(itemID: TimelineItemIdentifier)
|
||||||
case dismissMessageForwarding
|
case dismissMessageForwarding
|
||||||
|
|
||||||
|
case presentNotificationSettingsScreen
|
||||||
|
case dismissNotificationSettingsScreen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,18 +29,23 @@ struct RoomDetailsScreenCoordinatorParameters {
|
|||||||
|
|
||||||
enum RoomDetailsScreenCoordinatorAction {
|
enum RoomDetailsScreenCoordinatorAction {
|
||||||
case leftRoom
|
case leftRoom
|
||||||
|
case presentNotificationSettingsScreen
|
||||||
}
|
}
|
||||||
|
|
||||||
final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
||||||
private let parameters: RoomDetailsScreenCoordinatorParameters
|
private let parameters: RoomDetailsScreenCoordinatorParameters
|
||||||
private var viewModel: RoomDetailsScreenViewModelProtocol
|
private var viewModel: RoomDetailsScreenViewModelProtocol
|
||||||
private var cancellables: Set<AnyCancellable> = .init()
|
|
||||||
private let selectedUsers: CurrentValueSubject<[UserProfileProxy], Never> = .init([])
|
private let selectedUsers: CurrentValueSubject<[UserProfileProxy], Never> = .init([])
|
||||||
private var navigationStackCoordinator: NavigationStackCoordinator? {
|
private var navigationStackCoordinator: NavigationStackCoordinator? {
|
||||||
parameters.navigationStackCoordinator
|
parameters.navigationStackCoordinator
|
||||||
}
|
}
|
||||||
|
|
||||||
var callback: ((RoomDetailsScreenCoordinatorAction) -> Void)?
|
private let actionsSubject: PassthroughSubject<RoomDetailsScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables: Set<AnyCancellable> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<RoomDetailsScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
init(parameters: RoomDetailsScreenCoordinatorParameters) {
|
init(parameters: RoomDetailsScreenCoordinatorParameters) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
@@ -65,7 +70,7 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
|||||||
case .requestInvitePeoplePresentation:
|
case .requestInvitePeoplePresentation:
|
||||||
self.presentInviteUsersScreen()
|
self.presentInviteUsersScreen()
|
||||||
case .leftRoom:
|
case .leftRoom:
|
||||||
self.callback?(.leftRoom)
|
self.actionsSubject.send(.leftRoom)
|
||||||
case .requestEditDetailsPresentation(let accountOwner):
|
case .requestEditDetailsPresentation(let accountOwner):
|
||||||
self.presentRoomDetailsEditScreen(accountOwner: accountOwner)
|
self.presentRoomDetailsEditScreen(accountOwner: accountOwner)
|
||||||
case .requestNotificationSettingsPresentation:
|
case .requestNotificationSettingsPresentation:
|
||||||
@@ -189,9 +194,17 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func presentNotificationSettings() {
|
private func presentNotificationSettings() {
|
||||||
let roomNotificationSettingsParameters = RoomNotificationSettingsScreenCoordinatorParameters(notificationSettingsProxy: parameters.notificationSettings,
|
let roomNotificationSettingsParameters = RoomNotificationSettingsScreenCoordinatorParameters(navigationStackCoordinator: parameters.navigationStackCoordinator,
|
||||||
|
notificationSettingsProxy: parameters.notificationSettings,
|
||||||
roomProxy: parameters.roomProxy)
|
roomProxy: parameters.roomProxy)
|
||||||
let roomNotificationSettingsCoordinator = RoomNotificationSettingsScreenCoordinator(parameters: roomNotificationSettingsParameters)
|
let roomNotificationSettingsCoordinator = RoomNotificationSettingsScreenCoordinator(parameters: roomNotificationSettingsParameters)
|
||||||
|
roomNotificationSettingsCoordinator.actions.sink { [weak self] actions in
|
||||||
|
switch actions {
|
||||||
|
case .presentNotificationSettingsScreen:
|
||||||
|
self?.actionsSubject.send(.presentNotificationSettingsScreen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
navigationStackCoordinator?.push(roomNotificationSettingsCoordinator)
|
navigationStackCoordinator?.push(roomNotificationSettingsCoordinator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-1
@@ -18,21 +18,44 @@ import Combine
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct RoomNotificationSettingsScreenCoordinatorParameters {
|
struct RoomNotificationSettingsScreenCoordinatorParameters {
|
||||||
|
weak var navigationStackCoordinator: NavigationStackCoordinator?
|
||||||
let notificationSettingsProxy: NotificationSettingsProxyProtocol
|
let notificationSettingsProxy: NotificationSettingsProxyProtocol
|
||||||
let roomProxy: RoomProxyProtocol
|
let roomProxy: RoomProxyProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum RoomNotificationSettingsScreenCoordinatorAction {
|
||||||
|
case presentNotificationSettingsScreen
|
||||||
|
}
|
||||||
|
|
||||||
final class RoomNotificationSettingsScreenCoordinator: CoordinatorProtocol {
|
final class RoomNotificationSettingsScreenCoordinator: CoordinatorProtocol {
|
||||||
private let parameters: RoomNotificationSettingsScreenCoordinatorParameters
|
private let parameters: RoomNotificationSettingsScreenCoordinatorParameters
|
||||||
private var viewModel: RoomNotificationSettingsScreenViewModelProtocol
|
private var viewModel: RoomNotificationSettingsScreenViewModelProtocol
|
||||||
|
|
||||||
|
private let actionsSubject: PassthroughSubject<RoomNotificationSettingsScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables: Set<AnyCancellable> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<RoomNotificationSettingsScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var navigationStackCoordinator: NavigationStackCoordinator? {
|
||||||
|
parameters.navigationStackCoordinator
|
||||||
|
}
|
||||||
|
|
||||||
init(parameters: RoomNotificationSettingsScreenCoordinatorParameters) {
|
init(parameters: RoomNotificationSettingsScreenCoordinatorParameters) {
|
||||||
self.parameters = parameters
|
self.parameters = parameters
|
||||||
viewModel = RoomNotificationSettingsScreenViewModel(notificationSettingsProxy: parameters.notificationSettingsProxy,
|
viewModel = RoomNotificationSettingsScreenViewModel(notificationSettingsProxy: parameters.notificationSettingsProxy,
|
||||||
roomProxy: parameters.roomProxy)
|
roomProxy: parameters.roomProxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() { }
|
func start() {
|
||||||
|
viewModel.actions.sink { [weak self] action in
|
||||||
|
switch action {
|
||||||
|
case .openGlobalSettings:
|
||||||
|
self?.actionsSubject.send(.presentNotificationSettingsScreen)
|
||||||
|
}
|
||||||
|
}.store(in: &cancellables)
|
||||||
|
}
|
||||||
|
|
||||||
func toPresentable() -> AnyView {
|
func toPresentable() -> AnyView {
|
||||||
AnyView(RoomNotificationSettingsScreen(context: viewModel.context))
|
AnyView(RoomNotificationSettingsScreen(context: viewModel.context))
|
||||||
|
|||||||
+8
-1
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum RoomNotificationSettingsScreenViewModelAction { }
|
enum RoomNotificationSettingsScreenViewModelAction {
|
||||||
|
case openGlobalSettings
|
||||||
|
}
|
||||||
|
|
||||||
enum RoomNotificationSettingsState {
|
enum RoomNotificationSettingsState {
|
||||||
case loading
|
case loading
|
||||||
@@ -66,15 +68,20 @@ struct RoomNotificationSettingsScreenViewStateBindings {
|
|||||||
enum RoomNotificationSettingsScreenViewAction {
|
enum RoomNotificationSettingsScreenViewAction {
|
||||||
case changedAllowCustomSettings
|
case changedAllowCustomSettings
|
||||||
case setCustomMode(RoomNotificationModeProxy)
|
case setCustomMode(RoomNotificationModeProxy)
|
||||||
|
case customSettingFootnoteLinkTapped
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RoomNotificationSettingsScreenStrings {
|
struct RoomNotificationSettingsScreenStrings {
|
||||||
let customSettingFootnote: AttributedString
|
let customSettingFootnote: AttributedString
|
||||||
|
let customSettingFootnoteLink: URL?
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
customSettingFootnoteLink = URL(string: "element://openGlobalSettings")
|
||||||
|
|
||||||
let linkPlaceholder = "{link}"
|
let linkPlaceholder = "{link}"
|
||||||
var customSettingFootnote = AttributedString(L10n.screenRoomNotificationSettingsDefaultSettingFootnote(linkPlaceholder))
|
var customSettingFootnote = AttributedString(L10n.screenRoomNotificationSettingsDefaultSettingFootnote(linkPlaceholder))
|
||||||
var linkString = AttributedString(L10n.screenRoomNotificationSettingsDefaultSettingFootnoteContentLink)
|
var linkString = AttributedString(L10n.screenRoomNotificationSettingsDefaultSettingFootnoteContentLink)
|
||||||
|
linkString.link = customSettingFootnoteLink
|
||||||
linkString.bold()
|
linkString.bold()
|
||||||
customSettingFootnote.replace(linkPlaceholder, with: linkString)
|
customSettingFootnote.replace(linkPlaceholder, with: linkString)
|
||||||
|
|
||||||
|
|||||||
+2
@@ -48,6 +48,8 @@ class RoomNotificationSettingsScreenViewModel: RoomNotificationSettingsScreenVie
|
|||||||
toogleCustomSetting()
|
toogleCustomSetting()
|
||||||
case .setCustomMode(let mode):
|
case .setCustomMode(let mode):
|
||||||
setCustomMode(mode)
|
setCustomMode(mode)
|
||||||
|
case .customSettingFootnoteLinkTapped:
|
||||||
|
actionsSubject.send(.openGlobalSettings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
@@ -71,6 +71,11 @@ struct RoomNotificationSettingsScreen: View {
|
|||||||
.compoundFormSectionHeader()
|
.compoundFormSectionHeader()
|
||||||
} footer: {
|
} footer: {
|
||||||
Text(context.viewState.strings.customSettingFootnote)
|
Text(context.viewState.strings.customSettingFootnote)
|
||||||
|
.environment(\.openURL, OpenURLAction { url in
|
||||||
|
guard url == context.viewState.strings.customSettingFootnoteLink else { return .discarded }
|
||||||
|
context.send(viewAction: .customSettingFootnoteLinkTapped)
|
||||||
|
return .handled
|
||||||
|
})
|
||||||
.compoundFormSectionFooter()
|
.compoundFormSectionFooter()
|
||||||
}
|
}
|
||||||
.compoundFormSection()
|
.compoundFormSection()
|
||||||
|
|||||||
+14
-2
@@ -20,9 +20,12 @@ import SwiftUI
|
|||||||
struct NotificationSettingsScreenCoordinatorParameters {
|
struct NotificationSettingsScreenCoordinatorParameters {
|
||||||
let userNotificationCenter: UserNotificationCenterProtocol
|
let userNotificationCenter: UserNotificationCenterProtocol
|
||||||
let notificationSettings: NotificationSettingsProxyProtocol
|
let notificationSettings: NotificationSettingsProxyProtocol
|
||||||
|
let isModallyPresented: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NotificationSettingsScreenCoordinatorAction { }
|
enum NotificationSettingsScreenCoordinatorAction {
|
||||||
|
case close
|
||||||
|
}
|
||||||
|
|
||||||
final class NotificationSettingsScreenCoordinator: CoordinatorProtocol {
|
final class NotificationSettingsScreenCoordinator: CoordinatorProtocol {
|
||||||
private let parameters: NotificationSettingsScreenCoordinatorParameters
|
private let parameters: NotificationSettingsScreenCoordinatorParameters
|
||||||
@@ -39,11 +42,20 @@ final class NotificationSettingsScreenCoordinator: CoordinatorProtocol {
|
|||||||
|
|
||||||
viewModel = NotificationSettingsScreenViewModel(appSettings: ServiceLocator.shared.settings,
|
viewModel = NotificationSettingsScreenViewModel(appSettings: ServiceLocator.shared.settings,
|
||||||
userNotificationCenter: parameters.userNotificationCenter,
|
userNotificationCenter: parameters.userNotificationCenter,
|
||||||
notificationSettingsProxy: parameters.notificationSettings)
|
notificationSettingsProxy: parameters.notificationSettings,
|
||||||
|
isModallyPresented: parameters.isModallyPresented)
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
viewModel.fetchInitialContent()
|
viewModel.fetchInitialContent()
|
||||||
|
|
||||||
|
viewModel.actions.sink { [weak self] action in
|
||||||
|
switch action {
|
||||||
|
case .close:
|
||||||
|
self?.actionsSubject.send(.close)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPresentable() -> AnyView {
|
func toPresentable() -> AnyView {
|
||||||
|
|||||||
+5
-1
@@ -17,11 +17,14 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
enum NotificationSettingsScreenViewModelAction { }
|
enum NotificationSettingsScreenViewModelAction {
|
||||||
|
case close
|
||||||
|
}
|
||||||
|
|
||||||
struct NotificationSettingsScreenViewState: BindableState {
|
struct NotificationSettingsScreenViewState: BindableState {
|
||||||
var bindings: NotificationSettingsScreenViewStateBindings
|
var bindings: NotificationSettingsScreenViewStateBindings
|
||||||
var strings = NotificationSettingsScreenStrings()
|
var strings = NotificationSettingsScreenStrings()
|
||||||
|
let isModallyPresented: Bool
|
||||||
var isUserPermissionGranted: Bool?
|
var isUserPermissionGranted: Bool?
|
||||||
var allowedNotificationModes: [RoomNotificationModeProxy] = [.allMessages, .mentionsAndKeywordsOnly]
|
var allowedNotificationModes: [RoomNotificationModeProxy] = [.allMessages, .mentionsAndKeywordsOnly]
|
||||||
|
|
||||||
@@ -82,6 +85,7 @@ enum NotificationSettingsScreenViewAction {
|
|||||||
case directChatsTapped
|
case directChatsTapped
|
||||||
case roomMentionChanged
|
case roomMentionChanged
|
||||||
case callsChanged
|
case callsChanged
|
||||||
|
case close
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NotificationSettingsScreenErrorType: Hashable {
|
enum NotificationSettingsScreenErrorType: Hashable {
|
||||||
|
|||||||
+4
-2
@@ -30,13 +30,13 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
|
|||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(appSettings: AppSettings, userNotificationCenter: UserNotificationCenterProtocol, notificationSettingsProxy: NotificationSettingsProxyProtocol) {
|
init(appSettings: AppSettings, userNotificationCenter: UserNotificationCenterProtocol, notificationSettingsProxy: NotificationSettingsProxyProtocol, isModallyPresented: Bool) {
|
||||||
self.appSettings = appSettings
|
self.appSettings = appSettings
|
||||||
self.userNotificationCenter = userNotificationCenter
|
self.userNotificationCenter = userNotificationCenter
|
||||||
self.notificationSettingsProxy = notificationSettingsProxy
|
self.notificationSettingsProxy = notificationSettingsProxy
|
||||||
|
|
||||||
let bindings = NotificationSettingsScreenViewStateBindings(enableNotifications: appSettings.enableNotifications)
|
let bindings = NotificationSettingsScreenViewStateBindings(enableNotifications: appSettings.enableNotifications)
|
||||||
super.init(initialViewState: NotificationSettingsScreenViewState(bindings: bindings))
|
super.init(initialViewState: NotificationSettingsScreenViewState(bindings: bindings, isModallyPresented: isModallyPresented))
|
||||||
|
|
||||||
// Listen for changes to AppSettings.enableNotifications
|
// Listen for changes to AppSettings.enableNotifications
|
||||||
appSettings.$enableNotifications
|
appSettings.$enableNotifications
|
||||||
@@ -73,6 +73,8 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
Task { await enableCalls(state.bindings.callsEnabled) }
|
Task { await enableCalls(state.bindings.callsEnabled) }
|
||||||
|
case .close:
|
||||||
|
actionsSubject.send(.close)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-1
@@ -37,12 +37,25 @@ struct NotificationSettingsScreen: View {
|
|||||||
}
|
}
|
||||||
.compoundForm()
|
.compoundForm()
|
||||||
.navigationTitle(L10n.screenNotificationSettingsTitle)
|
.navigationTitle(L10n.screenNotificationSettingsTitle)
|
||||||
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
.toolbar { toolbar }
|
||||||
.alert(item: $context.alertInfo)
|
.alert(item: $context.alertInfo)
|
||||||
.track(screen: .settingsNotifications)
|
.track(screen: .settingsNotifications)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
|
@ToolbarContentBuilder
|
||||||
|
private var toolbar: some ToolbarContent {
|
||||||
|
if context.viewState.isModallyPresented {
|
||||||
|
ToolbarItem(placement: .confirmationAction) {
|
||||||
|
Button(L10n.actionClose) {
|
||||||
|
context.send(viewAction: .close)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var userPermissionSection: some View {
|
private var userPermissionSection: some View {
|
||||||
Section {
|
Section {
|
||||||
HStack(alignment: .firstTextBaseline, spacing: 13) {
|
HStack(alignment: .firstTextBaseline, spacing: 13) {
|
||||||
@@ -183,7 +196,8 @@ struct NotificationSettingsScreen_Previews: PreviewProvider {
|
|||||||
|
|
||||||
var viewModel = NotificationSettingsScreenViewModel(appSettings: appSettings,
|
var viewModel = NotificationSettingsScreenViewModel(appSettings: appSettings,
|
||||||
userNotificationCenter: notificationCenter,
|
userNotificationCenter: notificationCenter,
|
||||||
notificationSettingsProxy: notificationSettingsProxy)
|
notificationSettingsProxy: notificationSettingsProxy,
|
||||||
|
isModallyPresented: true)
|
||||||
viewModel.fetchInitialContent()
|
viewModel.fetchInitialContent()
|
||||||
return viewModel
|
return viewModel
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -142,7 +142,8 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
|||||||
|
|
||||||
private func presentNotificationSettings() {
|
private func presentNotificationSettings() {
|
||||||
let notificationParameters = NotificationSettingsScreenCoordinatorParameters(userNotificationCenter: UNUserNotificationCenter.current(),
|
let notificationParameters = NotificationSettingsScreenCoordinatorParameters(userNotificationCenter: UNUserNotificationCenter.current(),
|
||||||
notificationSettings: parameters.notificationSettings)
|
notificationSettings: parameters.notificationSettings,
|
||||||
|
isModallyPresented: false)
|
||||||
let coordinator = NotificationSettingsScreenCoordinator(parameters: notificationParameters)
|
let coordinator = NotificationSettingsScreenCoordinator(parameters: notificationParameters)
|
||||||
parameters.navigationStackCoordinator?.push(coordinator)
|
parameters.navigationStackCoordinator?.push(coordinator)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,8 @@ class MockScreen: Identifiable {
|
|||||||
let userNotificationCenter = UserNotificationCenterMock()
|
let userNotificationCenter = UserNotificationCenterMock()
|
||||||
userNotificationCenter.authorizationStatusReturnValue = .denied
|
userNotificationCenter.authorizationStatusReturnValue = .denied
|
||||||
let parameters = NotificationSettingsScreenCoordinatorParameters(userNotificationCenter: userNotificationCenter,
|
let parameters = NotificationSettingsScreenCoordinatorParameters(userNotificationCenter: userNotificationCenter,
|
||||||
notificationSettings: NotificationSettingsProxyMock(with: .init()))
|
notificationSettings: NotificationSettingsProxyMock(with: .init()),
|
||||||
|
isModallyPresented: false)
|
||||||
return NotificationSettingsScreenCoordinator(parameters: parameters)
|
return NotificationSettingsScreenCoordinator(parameters: parameters)
|
||||||
case .onboarding:
|
case .onboarding:
|
||||||
return OnboardingCoordinator()
|
return OnboardingCoordinator()
|
||||||
@@ -481,14 +482,16 @@ class MockScreen: Identifiable {
|
|||||||
case .roomNotificationSettingsDefaultSetting:
|
case .roomNotificationSettingsDefaultSetting:
|
||||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
let members: [RoomMemberProxyMock] = [.mockInvitedAlice, .mockBob, .mockCharlie]
|
let members: [RoomMemberProxyMock] = [.mockInvitedAlice, .mockBob, .mockCharlie]
|
||||||
let coordinator = RoomNotificationSettingsScreenCoordinator(parameters: .init(notificationSettingsProxy: NotificationSettingsProxyMock(with: .init(defaultRoomMode: .allMessages, roomMode: .allMessages)),
|
let coordinator = RoomNotificationSettingsScreenCoordinator(parameters: .init(navigationStackCoordinator: navigationStackCoordinator,
|
||||||
|
notificationSettingsProxy: NotificationSettingsProxyMock(with: .init(defaultRoomMode: .allMessages, roomMode: .allMessages)),
|
||||||
roomProxy: RoomProxyMock(with: .init(displayName: "test", members: members))))
|
roomProxy: RoomProxyMock(with: .init(displayName: "test", members: members))))
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
case .roomNotificationSettingsCustomSetting:
|
case .roomNotificationSettingsCustomSetting:
|
||||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
let members: [RoomMemberProxyMock] = [.mockInvitedAlice, .mockBob, .mockCharlie]
|
let members: [RoomMemberProxyMock] = [.mockInvitedAlice, .mockBob, .mockCharlie]
|
||||||
let coordinator = RoomNotificationSettingsScreenCoordinator(parameters: .init(notificationSettingsProxy: NotificationSettingsProxyMock(with: .init(defaultRoomMode: .allMessages, roomMode: .mentionsAndKeywordsOnly)),
|
let coordinator = RoomNotificationSettingsScreenCoordinator(parameters: .init(navigationStackCoordinator: navigationStackCoordinator,
|
||||||
|
notificationSettingsProxy: NotificationSettingsProxyMock(with: .init(defaultRoomMode: .allMessages, roomMode: .mentionsAndKeywordsOnly)),
|
||||||
roomProxy: RoomProxyMock(with: .init(displayName: "test", members: members))))
|
roomProxy: RoomProxyMock(with: .init(displayName: "test", members: members))))
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ class NotificationSettingsScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
viewModel = NotificationSettingsScreenViewModel(appSettings: appSettings,
|
viewModel = NotificationSettingsScreenViewModel(appSettings: appSettings,
|
||||||
userNotificationCenter: userNotificationCenter,
|
userNotificationCenter: userNotificationCenter,
|
||||||
notificationSettingsProxy: notificationSettingsProxy)
|
notificationSettingsProxy: notificationSettingsProxy,
|
||||||
|
isModallyPresented: false)
|
||||||
context = viewModel.context
|
context = viewModel.context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user