Add toggle not invite notifications. (#2207)
This commit is contained in:
@@ -1710,6 +1710,47 @@ class NotificationSettingsProxyMock: NotificationSettingsProxyProtocol {
|
||||
setCallEnabledEnabledReceivedInvocations.append(enabled)
|
||||
try await setCallEnabledEnabledClosure?(enabled)
|
||||
}
|
||||
//MARK: - isInviteForMeEnabled
|
||||
|
||||
var isInviteForMeEnabledThrowableError: Error?
|
||||
var isInviteForMeEnabledCallsCount = 0
|
||||
var isInviteForMeEnabledCalled: Bool {
|
||||
return isInviteForMeEnabledCallsCount > 0
|
||||
}
|
||||
var isInviteForMeEnabledReturnValue: Bool!
|
||||
var isInviteForMeEnabledClosure: (() async throws -> Bool)?
|
||||
|
||||
func isInviteForMeEnabled() async throws -> Bool {
|
||||
if let error = isInviteForMeEnabledThrowableError {
|
||||
throw error
|
||||
}
|
||||
isInviteForMeEnabledCallsCount += 1
|
||||
if let isInviteForMeEnabledClosure = isInviteForMeEnabledClosure {
|
||||
return try await isInviteForMeEnabledClosure()
|
||||
} else {
|
||||
return isInviteForMeEnabledReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - setInviteForMeEnabled
|
||||
|
||||
var setInviteForMeEnabledEnabledThrowableError: Error?
|
||||
var setInviteForMeEnabledEnabledCallsCount = 0
|
||||
var setInviteForMeEnabledEnabledCalled: Bool {
|
||||
return setInviteForMeEnabledEnabledCallsCount > 0
|
||||
}
|
||||
var setInviteForMeEnabledEnabledReceivedEnabled: Bool?
|
||||
var setInviteForMeEnabledEnabledReceivedInvocations: [Bool] = []
|
||||
var setInviteForMeEnabledEnabledClosure: ((Bool) async throws -> Void)?
|
||||
|
||||
func setInviteForMeEnabled(enabled: Bool) async throws {
|
||||
if let error = setInviteForMeEnabledEnabledThrowableError {
|
||||
throw error
|
||||
}
|
||||
setInviteForMeEnabledEnabledCallsCount += 1
|
||||
setInviteForMeEnabledEnabledReceivedEnabled = enabled
|
||||
setInviteForMeEnabledEnabledReceivedInvocations.append(enabled)
|
||||
try await setInviteForMeEnabledEnabledClosure?(enabled)
|
||||
}
|
||||
//MARK: - getRoomsWithUserDefinedRules
|
||||
|
||||
var getRoomsWithUserDefinedRulesThrowableError: Error?
|
||||
|
||||
@@ -42,6 +42,7 @@ extension NotificationSettingsProxyMock {
|
||||
getRoomsWithUserDefinedRulesReturnValue = []
|
||||
isRoomMentionEnabledReturnValue = true
|
||||
isCallEnabledReturnValue = true
|
||||
isInviteForMeEnabledReturnValue = true
|
||||
|
||||
setNotificationModeRoomIdModeClosure = { [weak self] _, mode in
|
||||
guard let self else { return }
|
||||
@@ -83,6 +84,14 @@ extension NotificationSettingsProxyMock {
|
||||
}
|
||||
}
|
||||
|
||||
setInviteForMeEnabledEnabledClosure = { [weak self] enabled in
|
||||
guard let self else { return }
|
||||
self.isInviteForMeEnabledReturnValue = enabled
|
||||
Task {
|
||||
self.callbacks.send(.settingsDidChange)
|
||||
}
|
||||
}
|
||||
|
||||
canHomeserverPushEncryptedEventsToDeviceClosure = {
|
||||
configuration.canHomeserverPushEncryptedEvents
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ struct NotificationSettingsScreenViewStateBindings {
|
||||
var enableNotifications = false
|
||||
var roomMentionsEnabled = false
|
||||
var callsEnabled = false
|
||||
var invitationsEnabled = false
|
||||
var alertInfo: AlertInfo<NotificationSettingsScreenErrorType>?
|
||||
}
|
||||
|
||||
@@ -52,6 +53,7 @@ struct NotificationSettingsScreenSettings {
|
||||
let directChatsMode: RoomNotificationModeProxy
|
||||
let roomMentionsEnabled: Bool?
|
||||
let callsEnabled: Bool?
|
||||
let invitationsEnabled: Bool?
|
||||
// Old clients were having specific settings for encrypted and unencrypted rooms,
|
||||
// so it's possible for `group chats` and `direct chats` settings to be inconsistent (e.g. encrypted `direct chats` can have a different mode that unencrypted `direct chats`)
|
||||
let inconsistentSettings: [NotificationSettingsScreenInvalidSetting]
|
||||
@@ -93,6 +95,7 @@ enum NotificationSettingsScreenViewAction {
|
||||
case directChatsTapped
|
||||
case roomMentionChanged
|
||||
case callsChanged
|
||||
case invitationsChanged
|
||||
case close
|
||||
case fixConfigurationMismatchTapped
|
||||
}
|
||||
|
||||
@@ -73,6 +73,11 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
|
||||
return
|
||||
}
|
||||
Task { await enableCalls(state.bindings.callsEnabled) }
|
||||
case .invitationsChanged:
|
||||
guard let settings = state.settings, settings.invitationsEnabled != state.bindings.invitationsEnabled else {
|
||||
return
|
||||
}
|
||||
Task { await enableInvitations(state.bindings.invitationsEnabled) }
|
||||
case .close:
|
||||
actionsSubject.send(.close)
|
||||
case .fixConfigurationMismatchTapped:
|
||||
@@ -146,6 +151,7 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
|
||||
// The following calls may fail if the associated push rule doesn't exist
|
||||
let roomMentionsEnabled = try? await notificationSettingsProxy.isRoomMentionEnabled()
|
||||
let callEnabled = try? await notificationSettingsProxy.isCallEnabled()
|
||||
let invitationsEnabled = try? await notificationSettingsProxy.isInviteForMeEnabled()
|
||||
|
||||
guard !Task.isCancelled else { return }
|
||||
|
||||
@@ -153,11 +159,13 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
|
||||
directChatsMode: directChatsMode,
|
||||
roomMentionsEnabled: roomMentionsEnabled,
|
||||
callsEnabled: callEnabled,
|
||||
invitationsEnabled: invitationsEnabled,
|
||||
inconsistentSettings: inconsistentSettings)
|
||||
|
||||
state.settings = notificationSettings
|
||||
state.bindings.roomMentionsEnabled = notificationSettings.roomMentionsEnabled ?? false
|
||||
state.bindings.callsEnabled = notificationSettings.callsEnabled ?? false
|
||||
state.bindings.invitationsEnabled = notificationSettings.invitationsEnabled ?? false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,7 +195,7 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
|
||||
guard let notificationSettings = state.settings else { return }
|
||||
do {
|
||||
state.applyingChange = true
|
||||
MXLog.info("[NotificationSettingsScreenViewMode] setRoomMentionEnabled(\(enable))")
|
||||
MXLog.info("setRoomMentionEnabled(\(enable))")
|
||||
try await notificationSettingsProxy.setRoomMentionEnabled(enabled: enable)
|
||||
} catch {
|
||||
state.bindings.alertInfo = AlertInfo(id: .alert)
|
||||
@@ -200,7 +208,7 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
|
||||
guard let notificationSettings = state.settings else { return }
|
||||
do {
|
||||
state.applyingChange = true
|
||||
MXLog.info("[NotificationSettingsScreenViewMode] setCallEnabled(\(enable))")
|
||||
MXLog.info("setCallEnabled(\(enable))")
|
||||
try await notificationSettingsProxy.setCallEnabled(enabled: enable)
|
||||
} catch {
|
||||
state.bindings.alertInfo = AlertInfo(id: .alert)
|
||||
@@ -208,6 +216,19 @@ class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelTy
|
||||
}
|
||||
state.applyingChange = false
|
||||
}
|
||||
|
||||
func enableInvitations(_ enable: Bool) async {
|
||||
guard let notificationSettings = state.settings else { return }
|
||||
do {
|
||||
state.applyingChange = true
|
||||
MXLog.info("setInviteForMeEnabled(\(enable))")
|
||||
try await notificationSettingsProxy.setInviteForMeEnabled(enabled: enable)
|
||||
} catch {
|
||||
state.bindings.alertInfo = AlertInfo(id: .alert)
|
||||
state.bindings.callsEnabled = notificationSettings.invitationsEnabled ?? false
|
||||
}
|
||||
state.applyingChange = false
|
||||
}
|
||||
}
|
||||
|
||||
extension UNUserNotificationCenter {
|
||||
|
||||
@@ -37,6 +37,9 @@ struct NotificationSettingsScreen: View {
|
||||
if context.viewState.showCallsSettings, context.viewState.settings?.callsEnabled != nil {
|
||||
callsSection
|
||||
}
|
||||
if context.viewState.settings?.invitationsEnabled != nil {
|
||||
additionalSettingsSection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,6 +156,21 @@ struct NotificationSettingsScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
private var additionalSettingsSection: some View {
|
||||
Section {
|
||||
ListRow(label: .plain(title: L10n.screenNotificationSettingsInviteForMeLabel),
|
||||
kind: .toggle($context.invitationsEnabled))
|
||||
.disabled(context.viewState.settings?.invitationsEnabled == nil)
|
||||
.allowsHitTesting(!context.viewState.applyingChange)
|
||||
.onChange(of: context.invitationsEnabled) { _ in
|
||||
context.send(viewAction: .invitationsChanged)
|
||||
}
|
||||
} header: {
|
||||
Text(L10n.screenNotificationSettingsAdditionalSettingsSectionTitle)
|
||||
.compoundListSectionHeader()
|
||||
}
|
||||
}
|
||||
|
||||
private var configurationMismatchSection: some View {
|
||||
Section {
|
||||
ListRow(kind: .custom {
|
||||
@@ -242,7 +260,9 @@ struct NotificationSettingsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
static var previews: some View {
|
||||
NotificationSettingsScreen(context: viewModel.context)
|
||||
.snapshot(delay: 0.1)
|
||||
NotificationSettingsScreen(context: viewModelConfigurationMismatch.context)
|
||||
.snapshot(delay: 0.1)
|
||||
.previewDisplayName("Configuration mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,18 @@ final class NotificationSettingsProxy: NotificationSettingsProxyProtocol {
|
||||
await updatedSettings()
|
||||
}
|
||||
|
||||
func isInviteForMeEnabled() async throws -> Bool {
|
||||
try await notificationSettings.isInviteForMeEnabled()
|
||||
}
|
||||
|
||||
func setInviteForMeEnabled(enabled: Bool) async throws {
|
||||
let backgroundTask = await backgroundTaskService?.startBackgroundTask(withName: "setInviteForMeEnabled")
|
||||
defer { backgroundTask?.stop() }
|
||||
|
||||
try await notificationSettings.setInviteForMeEnabled(enabled: enabled)
|
||||
await updatedSettings()
|
||||
}
|
||||
|
||||
func getRoomsWithUserDefinedRules() async throws -> [String] {
|
||||
await notificationSettings.getRoomsWithUserDefinedRules(enabled: true)
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ protocol NotificationSettingsProxyProtocol {
|
||||
func setUserMentionEnabled(enabled: Bool) async throws
|
||||
func isCallEnabled() async throws -> Bool
|
||||
func setCallEnabled(enabled: Bool) async throws
|
||||
func isInviteForMeEnabled() async throws -> Bool
|
||||
func setInviteForMeEnabled(enabled: Bool) async throws
|
||||
func getRoomsWithUserDefinedRules() async throws -> [String]
|
||||
func canHomeserverPushEncryptedEventsToDevice() async -> Bool
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9704334caaadde07dcdf78efa200853d9315bf630296adfae54963fc5ec5d989
|
||||
size 103239
|
||||
oid sha256:ef3b3ede5511460271ea3879651efd4424b5d16b4242965c8c068a55e5c7fc4c
|
||||
size 113310
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b3d623d6e0ddd1ec3387a38461a58e1381494ee21c45344e31ad3b708604ca2a
|
||||
size 126931
|
||||
oid sha256:e924d67a0b598ddc9a015f774512fc1460195c8b7292862b44cc353dba36278b
|
||||
size 139993
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d2162569e78dffee8d4095998dc31a3672ff3dbb43f0b1f58a44850a18c4c5f6
|
||||
size 117932
|
||||
oid sha256:af2f6e2f7e5b16d2bd08224e4a1cea85766196e54cead0ea1ed07529caae3da0
|
||||
size 132174
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ba9fd9cbc5f49630dd1853f2d49611f1d4bb47166ae7ddff79319e0c1d0088bf
|
||||
size 165797
|
||||
oid sha256:e61e23b4a91d4510c1386d1c3a39c99a43c394fadc6e3d73949ce74aab34adc6
|
||||
size 182864
|
||||
|
||||
@@ -388,4 +388,84 @@ class NotificationSettingsScreenViewModelTests: XCTestCase {
|
||||
|
||||
XCTAssertNotNil(context.alertInfo)
|
||||
}
|
||||
|
||||
func testToggleInvitationsOff() async throws {
|
||||
notificationSettingsProxy.isInviteForMeEnabledReturnValue = true
|
||||
|
||||
let deferredInitialFetch = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.settings != nil
|
||||
}
|
||||
|
||||
viewModel.fetchInitialContent()
|
||||
|
||||
try await deferredInitialFetch.fulfill()
|
||||
|
||||
context.invitationsEnabled = false
|
||||
let deferred = deferFulfillment(notificationSettingsProxy.callbacks) { callback in
|
||||
callback == .settingsDidChange
|
||||
}
|
||||
|
||||
context.send(viewAction: .invitationsChanged)
|
||||
|
||||
try await deferred.fulfill()
|
||||
|
||||
XCTAssert(notificationSettingsProxy.setInviteForMeEnabledEnabledCalled)
|
||||
XCTAssertEqual(notificationSettingsProxy.setInviteForMeEnabledEnabledReceivedEnabled, false)
|
||||
}
|
||||
|
||||
func testToggleInvitationsOn() async throws {
|
||||
notificationSettingsProxy.isInviteForMeEnabledReturnValue = false
|
||||
|
||||
let deferredInitialFetch = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.settings != nil
|
||||
}
|
||||
|
||||
viewModel.fetchInitialContent()
|
||||
|
||||
try await deferredInitialFetch.fulfill()
|
||||
|
||||
context.invitationsEnabled = true
|
||||
|
||||
let deferred = deferFulfillment(notificationSettingsProxy.callbacks) { callback in
|
||||
callback == .settingsDidChange
|
||||
}
|
||||
|
||||
context.send(viewAction: .invitationsChanged)
|
||||
|
||||
try await deferred.fulfill()
|
||||
|
||||
XCTAssert(notificationSettingsProxy.setInviteForMeEnabledEnabledCalled)
|
||||
XCTAssertEqual(notificationSettingsProxy.setInviteForMeEnabledEnabledReceivedEnabled, true)
|
||||
}
|
||||
|
||||
func testToggleInvitesFailure() async throws {
|
||||
notificationSettingsProxy.setInviteForMeEnabledEnabledThrowableError = NotificationSettingsError.Generic(msg: "error")
|
||||
notificationSettingsProxy.isInviteForMeEnabledReturnValue = false
|
||||
|
||||
let deferredInitialFetch = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.settings != nil
|
||||
}
|
||||
|
||||
viewModel.fetchInitialContent()
|
||||
|
||||
try await deferredInitialFetch.fulfill()
|
||||
|
||||
context.invitationsEnabled = true
|
||||
|
||||
var deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.applyingChange == true
|
||||
}
|
||||
|
||||
context.send(viewAction: .invitationsChanged)
|
||||
|
||||
try await deferred.fulfill()
|
||||
|
||||
deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.applyingChange == false
|
||||
}
|
||||
|
||||
try await deferred.fulfill()
|
||||
|
||||
XCTAssertNotNil(context.alertInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3d858bdd5b55a445ce924c4bba25a8ca420086c033ca5e17b4a73cf571d90c15
|
||||
size 97653
|
||||
oid sha256:6ca120ad1ccae3415ebf22f9db7fc8389e2b21682ae336de2545651c2027cc87
|
||||
size 155222
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3d858bdd5b55a445ce924c4bba25a8ca420086c033ca5e17b4a73cf571d90c15
|
||||
size 97653
|
||||
oid sha256:321892e72a5da150eb1a2db3b81576eac4a9474aec8cee5c68c8c3315b3dbe46
|
||||
size 126720
|
||||
|
||||
1
changelog.d/2205.change
Normal file
1
changelog.d/2205.change
Normal file
@@ -0,0 +1 @@
|
||||
Add notification toggle for invitations.
|
||||
Reference in New Issue
Block a user