mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-16 06:28:27 +02:00
MESSENGER-3580 Several bugfixes to notification times
This commit is contained in:
@@ -121,14 +121,6 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
return
|
||||
}
|
||||
|
||||
// check if the event arrived outside the user defined working time for this room
|
||||
guard !isRoomMuted(roomID: roomId) else {
|
||||
// it's not a Matrix notification, do not change the content
|
||||
MXLog.debug("[NotificationService] didReceiveRequest: This is not a Matrix notification.")
|
||||
contentHandler(UNNotificationContent())
|
||||
return
|
||||
}
|
||||
|
||||
// save this content as fallback content
|
||||
guard let content = request.content.mutableCopy() as? UNMutableNotificationContent else {
|
||||
return
|
||||
@@ -146,10 +138,12 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
|
||||
// setup user account
|
||||
setup(withRoomId: roomId, eventId: eventId) {
|
||||
// preprocess the payload, will attempt to fetch room display name
|
||||
self.preprocessPayload(forEventId: eventId, roomId: roomId)
|
||||
// fetch the event first
|
||||
self.fetchAndProcessEvent(withEventId: eventId, roomId: roomId)
|
||||
do {
|
||||
try self.preprocessPayload(forEventId: eventId, roomId: roomId) // fetch displayname and check against notification times
|
||||
self.fetchAndProcessEvent(withEventId: eventId, roomId: roomId) // decrypt and parse
|
||||
} catch {
|
||||
contentHandler(UNNotificationContent())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,20 +186,60 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
}
|
||||
}
|
||||
|
||||
private func isGlobalSettingsNotificationTimesToggleOn() -> Bool {
|
||||
let sharedUserDefaults = MXKAppSettings.standard().sharedUserDefaults
|
||||
|
||||
guard let data = sharedUserDefaults?.data(forKey: NotificationTimes.sharedUserDefaultsKey) else {
|
||||
return false
|
||||
}
|
||||
guard let notificationTimes = try? JSONDecoder().decode(NotificationTimes.self, from: data) else {
|
||||
return false
|
||||
}
|
||||
|
||||
return notificationTimes.isEnabled
|
||||
}
|
||||
|
||||
private func isRoomMuted(roomID: String) -> Bool {
|
||||
private func isRoomSettingsNotificationTimesToggleOn(roomId: String, isDirect: Bool) -> Bool {
|
||||
let sharedUserDefaults = MXKAppSettings.standard().sharedUserDefaults
|
||||
|
||||
guard let data = sharedUserDefaults?.data(forKey: NotificationTimes.sharedUserDefaultsKey) else {
|
||||
return false
|
||||
}
|
||||
guard let notificationTimes = try? JSONDecoder().decode(NotificationTimes.self, from: data) else {
|
||||
return false
|
||||
}
|
||||
|
||||
if isDirect {
|
||||
return notificationTimes.rooms[roomId] == true
|
||||
} else {
|
||||
return notificationTimes.rooms[roomId] != false
|
||||
}
|
||||
}
|
||||
|
||||
private func notificationTimeCheckPassed(roomId: String, isDirect: Bool) -> Bool {
|
||||
guard isGlobalSettingsNotificationTimesToggleOn() else {
|
||||
return true
|
||||
}
|
||||
guard isRoomSettingsNotificationTimesToggleOn(roomId: roomId, isDirect: isDirect) else {
|
||||
return true
|
||||
}
|
||||
return isNotificationTimeEnabled(for: Date())
|
||||
}
|
||||
|
||||
private func isNotificationTimeEnabled(for date: Date) -> Bool {
|
||||
let sharedUserDefaults = MXKAppSettings.standard().sharedUserDefaults
|
||||
|
||||
if #available(iOSApplicationExtension 14.0, *) {
|
||||
guard let data = sharedUserDefaults?.data(forKey: NotificationTimes.sharedUserDefaultsKey), let notificationTimes = try? JSONDecoder().decode(NotificationTimes.self, from: data) else {
|
||||
return false
|
||||
guard let data = sharedUserDefaults?.data(forKey: NotificationTimes.sharedUserDefaultsKey) else {
|
||||
return true
|
||||
}
|
||||
guard let notificationTimes = try? JSONDecoder().decode(NotificationTimes.self, from: data) else {
|
||||
return true
|
||||
}
|
||||
|
||||
let now = Date()
|
||||
|
||||
let calendar = Calendar.current
|
||||
let weekday: NotificationTimesWeekday
|
||||
switch calendar.component(.weekday, from: now) {
|
||||
switch calendar.component(.weekday, from: date) {
|
||||
case 1: // sunday
|
||||
weekday = notificationTimes.weekday(index: 6)
|
||||
case 2: // monday
|
||||
@@ -222,12 +256,18 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
weekday = notificationTimes.weekday(index: 5)
|
||||
default:
|
||||
MXLog.error("[NotificationService] isRoomMuted failed because of an invalid day component.")
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
return notificationTimes.isEnabled && weekday.isEnabled && weekday.startTime <= now && weekday.endTime >= now
|
||||
let nowComponents = calendar.dateComponents([.hour, .minute], from: date)
|
||||
if let hour = nowComponents.hour, let minute = nowComponents.minute {
|
||||
let checkTime = Date.from(hour: hour, minute: minute)
|
||||
return notificationTimes.isEnabled && weekday.isEnabled && weekday.startTime <= checkTime && weekday.endTime >= checkTime
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,22 +342,49 @@ class NotificationService: UNNotificationServiceExtension {
|
||||
return true
|
||||
}
|
||||
|
||||
enum NSEError: Error, LocalizedError {
|
||||
case isProtectionSet
|
||||
case roomSummaryNotAvailable
|
||||
case mutedBecauseOfNotificationTimes
|
||||
case displayNameNotAvailable
|
||||
|
||||
public var errorDescription: String? {
|
||||
switch self {
|
||||
case .isProtectionSet:
|
||||
return "isProtectionSet"
|
||||
case .roomSummaryNotAvailable:
|
||||
return "roomSummaryNotAvailable"
|
||||
case .mutedBecauseOfNotificationTimes:
|
||||
return "isProtectionSet"
|
||||
case .displayNameNotAvailable:
|
||||
return "isProtectionSet"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to preprocess payload and attach room display name to the best attempt content
|
||||
/// - Parameters:
|
||||
/// - eventId: Event identifier to mutate best attempt content
|
||||
/// - roomId: Room identifier to fetch display name
|
||||
private func preprocessPayload(forEventId eventId: String, roomId: String) {
|
||||
if localAuthenticationService.isProtectionSet {
|
||||
MXLog.debug("[NotificationService] preprocessPayload: Do not preprocess because app protection is set")
|
||||
return
|
||||
private func preprocessPayload(forEventId eventId: String, roomId: String) throws {
|
||||
// If a room summary is available, use the displayname for the best attempt title.
|
||||
guard let roomSummary = NotificationService.backgroundSyncService.roomSummary(forRoomId: roomId) else {
|
||||
throw NSEError.roomSummaryNotAvailable
|
||||
}
|
||||
|
||||
// If a room summary is available, use the displayname for the best attempt title.
|
||||
guard let roomSummary = NotificationService.backgroundSyncService.roomSummary(forRoomId: roomId) else { return }
|
||||
guard let roomDisplayName = roomSummary.displayName else { return }
|
||||
bestAttemptContents[eventId]?.title = roomDisplayName
|
||||
guard notificationTimeCheckPassed(roomId: roomId, isDirect: roomSummary.isDirect) else {
|
||||
throw NSEError.mutedBecauseOfNotificationTimes
|
||||
}
|
||||
|
||||
// At this stage we don't know the message type, so leave the body as set in didReceive.
|
||||
if localAuthenticationService.isProtectionSet {
|
||||
MXLog.debug("[NotificationService] preprocessPayload: Do not preprocess because app protection is set")
|
||||
guard let roomDisplayName = roomSummary.displayName else {
|
||||
throw NSEError.displayNameNotAvailable
|
||||
}
|
||||
|
||||
bestAttemptContents[eventId]?.title = roomDisplayName
|
||||
// At this stage we don't know the message type, so leave the body as set in didReceive.
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchAndProcessEvent(withEventId eventId: String, roomId: String) {
|
||||
|
||||
Reference in New Issue
Block a user