mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Switch from an always returning the notification content approach at every step to passing it in as mutable.
This commit is contained in:
committed by
Stefan Ceriu
parent
c33a164354
commit
f71e5facb8
@@ -22,9 +22,9 @@ struct NotificationContentBuilder {
|
|||||||
/// - notificationItem: The notification item
|
/// - notificationItem: The notification item
|
||||||
/// - mediaProvider: Media provider to process also media. May be passed nil to ignore media operations.
|
/// - mediaProvider: Media provider to process also media. May be passed nil to ignore media operations.
|
||||||
/// - Returns: A notification content object if the notification should be displayed. Otherwise nil.
|
/// - Returns: A notification content object if the notification should be displayed. Otherwise nil.
|
||||||
func process(notificationContent: UNMutableNotificationContent,
|
func process(notificationContent: inout UNMutableNotificationContent,
|
||||||
notificationItem: NotificationItemProxyProtocol,
|
notificationItem: NotificationItemProxyProtocol,
|
||||||
mediaProvider: MediaProviderProtocol) async -> UNMutableNotificationContent {
|
mediaProvider: MediaProviderProtocol) async {
|
||||||
notificationContent.receiverID = notificationItem.receiverID
|
notificationContent.receiverID = notificationItem.receiverID
|
||||||
notificationContent.roomID = notificationItem.roomID
|
notificationContent.roomID = notificationItem.roomID
|
||||||
|
|
||||||
@@ -44,55 +44,51 @@ struct NotificationContentBuilder {
|
|||||||
|
|
||||||
switch notificationItem.event {
|
switch notificationItem.event {
|
||||||
case .none:
|
case .none:
|
||||||
return processEmpty(notificationContent)
|
processEmpty(¬ificationContent)
|
||||||
case .invite:
|
case .invite:
|
||||||
return await processInvited(notificationContent: notificationContent,
|
await processInvited(notificationContent: ¬ificationContent,
|
||||||
notificationItem: notificationItem,
|
notificationItem: notificationItem,
|
||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
case .timeline(let event):
|
case .timeline(let event):
|
||||||
guard let eventType = try? event.eventType(),
|
guard let eventType = try? event.eventType(),
|
||||||
case let .messageLike(content) = eventType else {
|
case let .messageLike(content) = eventType else {
|
||||||
return processEmpty(notificationContent)
|
processEmpty(¬ificationContent)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let notificationContent = await processMessageLike(notificationContent: notificationContent,
|
await processMessageLike(notificationContent: ¬ificationContent,
|
||||||
notificationItem: notificationItem,
|
notificationItem: notificationItem,
|
||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
|
|
||||||
switch content {
|
switch content {
|
||||||
case .roomMessage(let messageType, _):
|
case .roomMessage(let messageType, _):
|
||||||
return await processRoomMessage(notificationContent: notificationContent,
|
await processRoomMessage(notificationContent: ¬ificationContent,
|
||||||
notificationItem: notificationItem,
|
notificationItem: notificationItem,
|
||||||
messageType: messageType,
|
messageType: messageType,
|
||||||
mediaProvider: mediaProvider)
|
mediaProvider: mediaProvider)
|
||||||
case .poll(let question):
|
case .poll(let question):
|
||||||
notificationContent.body = L10n.commonPollSummary(question)
|
notificationContent.body = L10n.commonPollSummary(question)
|
||||||
return notificationContent
|
|
||||||
case .callInvite:
|
case .callInvite:
|
||||||
notificationContent.body = L10n.commonUnsupportedCall
|
notificationContent.body = L10n.commonUnsupportedCall
|
||||||
return notificationContent
|
|
||||||
case .callNotify:
|
case .callNotify:
|
||||||
notificationContent.body = L10n.notificationIncomingCall
|
notificationContent.body = L10n.notificationIncomingCall
|
||||||
return notificationContent
|
|
||||||
default:
|
default:
|
||||||
return processEmpty(notificationContent)
|
processEmpty(¬ificationContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func processEmpty(_ notificationContent: UNMutableNotificationContent) -> UNMutableNotificationContent {
|
private func processEmpty(_ notificationContent: inout UNMutableNotificationContent) {
|
||||||
notificationContent.title = InfoPlistReader(bundle: .app).bundleDisplayName
|
notificationContent.title = InfoPlistReader(bundle: .app).bundleDisplayName
|
||||||
notificationContent.body = L10n.notification
|
notificationContent.body = L10n.notification
|
||||||
notificationContent.categoryIdentifier = NotificationConstants.Category.message
|
notificationContent.categoryIdentifier = NotificationConstants.Category.message
|
||||||
|
|
||||||
return notificationContent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func processInvited(notificationContent: UNMutableNotificationContent,
|
private func processInvited(notificationContent: inout UNMutableNotificationContent,
|
||||||
notificationItem: NotificationItemProxyProtocol,
|
notificationItem: NotificationItemProxyProtocol,
|
||||||
mediaProvider: MediaProviderProtocol) async -> UNMutableNotificationContent {
|
mediaProvider: MediaProviderProtocol) async {
|
||||||
notificationContent.categoryIdentifier = NotificationConstants.Category.invite
|
notificationContent.categoryIdentifier = NotificationConstants.Category.invite
|
||||||
|
|
||||||
let body: String
|
let body: String
|
||||||
@@ -104,21 +100,17 @@ struct NotificationContentBuilder {
|
|||||||
|
|
||||||
notificationContent.body = body
|
notificationContent.body = body
|
||||||
|
|
||||||
do {
|
await addSenderIcon(notificationContent: ¬ificationContent,
|
||||||
return try await addSenderIcon(notificationContent: notificationContent,
|
senderID: notificationItem.senderID,
|
||||||
senderID: notificationItem.senderID,
|
senderName: notificationItem.senderDisplayName ?? notificationItem.roomDisplayName,
|
||||||
senderName: notificationItem.senderDisplayName ?? notificationItem.roomDisplayName,
|
icon: icon(for: notificationItem),
|
||||||
icon: icon(for: notificationItem),
|
forcePlaceholder: settings.hideInviteAvatars,
|
||||||
forcePlaceholder: settings.hideInviteAvatars,
|
mediaProvider: mediaProvider)
|
||||||
mediaProvider: mediaProvider)
|
|
||||||
} catch {
|
|
||||||
return notificationContent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func processMessageLike(notificationContent: UNMutableNotificationContent,
|
private func processMessageLike(notificationContent: inout UNMutableNotificationContent,
|
||||||
notificationItem: NotificationItemProxyProtocol,
|
notificationItem: NotificationItemProxyProtocol,
|
||||||
mediaProvider: MediaProviderProtocol) async -> UNMutableNotificationContent {
|
mediaProvider: MediaProviderProtocol) async {
|
||||||
notificationContent.title = notificationItem.senderDisplayName ?? notificationItem.roomDisplayName
|
notificationContent.title = notificationItem.senderDisplayName ?? notificationItem.roomDisplayName
|
||||||
if notificationContent.title != notificationItem.roomDisplayName {
|
if notificationContent.title != notificationItem.roomDisplayName {
|
||||||
notificationContent.subtitle = notificationItem.roomDisplayName
|
notificationContent.subtitle = notificationItem.roomDisplayName
|
||||||
@@ -131,15 +123,11 @@ struct NotificationContentBuilder {
|
|||||||
notificationItem.roomDisplayName
|
notificationItem.roomDisplayName
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
await addSenderIcon(notificationContent: ¬ificationContent,
|
||||||
return try await addSenderIcon(notificationContent: notificationContent,
|
senderID: notificationItem.senderID,
|
||||||
senderID: notificationItem.senderID,
|
senderName: senderName,
|
||||||
senderName: senderName,
|
icon: icon(for: notificationItem),
|
||||||
icon: icon(for: notificationItem),
|
mediaProvider: mediaProvider)
|
||||||
mediaProvider: mediaProvider)
|
|
||||||
} catch {
|
|
||||||
return notificationContent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func icon(for notificationItem: NotificationItemProxyProtocol) -> NotificationIcon {
|
private func icon(for notificationItem: NotificationItemProxyProtocol) -> NotificationIcon {
|
||||||
@@ -151,43 +139,41 @@ struct NotificationContentBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func processRoomMessage(notificationContent: UNMutableNotificationContent,
|
private func processRoomMessage(notificationContent: inout UNMutableNotificationContent,
|
||||||
notificationItem: NotificationItemProxyProtocol,
|
notificationItem: NotificationItemProxyProtocol,
|
||||||
messageType: MessageType,
|
messageType: MessageType,
|
||||||
mediaProvider: MediaProviderProtocol) async -> UNMutableNotificationContent {
|
mediaProvider: MediaProviderProtocol) async {
|
||||||
let displayName = notificationItem.senderDisplayName ?? notificationItem.roomDisplayName
|
let displayName = notificationItem.senderDisplayName ?? notificationItem.roomDisplayName
|
||||||
notificationContent.body = String(messageEventStringBuilder.buildAttributedString(for: messageType, senderDisplayName: displayName, isOutgoing: false).characters)
|
notificationContent.body = String(messageEventStringBuilder.buildAttributedString(for: messageType, senderDisplayName: displayName, isOutgoing: false).characters)
|
||||||
|
|
||||||
guard settings.timelineMediaVisibility == .always ||
|
guard settings.timelineMediaVisibility == .always ||
|
||||||
(settings.timelineMediaVisibility == .privateOnly && notificationItem.isRoomPrivate)
|
(settings.timelineMediaVisibility == .privateOnly && notificationItem.isRoomPrivate)
|
||||||
else {
|
else {
|
||||||
return notificationContent
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch messageType {
|
switch messageType {
|
||||||
case .image(content: let content):
|
case .image(content: let content):
|
||||||
await addMediaAttachment(notificationContent: notificationContent,
|
await addMediaAttachment(notificationContent: ¬ificationContent,
|
||||||
using: mediaProvider,
|
using: mediaProvider,
|
||||||
mediaSource: .init(source: content.source,
|
mediaSource: .init(source: content.source,
|
||||||
mimeType: content.info?.mimetype))
|
mimeType: content.info?.mimetype))
|
||||||
case .audio(content: let content):
|
case .audio(content: let content):
|
||||||
await addMediaAttachment(notificationContent: notificationContent,
|
await addMediaAttachment(notificationContent: ¬ificationContent,
|
||||||
using: mediaProvider,
|
using: mediaProvider,
|
||||||
mediaSource: .init(source: content.source,
|
mediaSource: .init(source: content.source,
|
||||||
mimeType: content.info?.mimetype))
|
mimeType: content.info?.mimetype))
|
||||||
case .video(content: let content):
|
case .video(content: let content):
|
||||||
await addMediaAttachment(notificationContent: notificationContent,
|
await addMediaAttachment(notificationContent: ¬ificationContent,
|
||||||
using: mediaProvider,
|
using: mediaProvider,
|
||||||
mediaSource: .init(source: content.source,
|
mediaSource: .init(source: content.source,
|
||||||
mimeType: content.info?.mimetype))
|
mimeType: content.info?.mimetype))
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
return notificationContent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addMediaAttachment(notificationContent: UNMutableNotificationContent,
|
private func addMediaAttachment(notificationContent: inout UNMutableNotificationContent,
|
||||||
using mediaProvider: MediaProviderProtocol,
|
using mediaProvider: MediaProviderProtocol,
|
||||||
mediaSource: MediaSourceProxy) async {
|
mediaSource: MediaSourceProxy) async {
|
||||||
switch await mediaProvider.loadFileFromSource(mediaSource) {
|
switch await mediaProvider.loadFileFromSource(mediaSource) {
|
||||||
@@ -214,12 +200,12 @@ struct NotificationContentBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addSenderIcon(notificationContent: UNMutableNotificationContent,
|
private func addSenderIcon(notificationContent: inout UNMutableNotificationContent,
|
||||||
senderID: String,
|
senderID: String,
|
||||||
senderName: String,
|
senderName: String,
|
||||||
icon: NotificationIcon,
|
icon: NotificationIcon,
|
||||||
forcePlaceholder: Bool = false,
|
forcePlaceholder: Bool = false,
|
||||||
mediaProvider: MediaProviderProtocol) async throws -> UNMutableNotificationContent {
|
mediaProvider: MediaProviderProtocol) async {
|
||||||
var fetchedImage: INImage?
|
var fetchedImage: INImage?
|
||||||
let image: INImage
|
let image: INImage
|
||||||
if !forcePlaceholder,
|
if !forcePlaceholder,
|
||||||
@@ -279,14 +265,15 @@ struct NotificationContentBuilder {
|
|||||||
interaction.direction = .incoming
|
interaction.direction = .incoming
|
||||||
|
|
||||||
// Donate the interaction before updating notification content.
|
// Donate the interaction before updating notification content.
|
||||||
try await interaction.donate()
|
try? await interaction.donate()
|
||||||
|
|
||||||
// Update notification content before displaying the
|
// Update notification content before displaying the
|
||||||
// communication notification.
|
// communication notification.
|
||||||
let updatedContent = try notificationContent.updating(from: intent)
|
if let updatedContent = try? notificationContent.updating(from: intent) {
|
||||||
|
// swiftlint:disable:next force_cast
|
||||||
// swiftlint:disable:next force_cast
|
let content = updatedContent.mutableCopy() as! UNMutableNotificationContent
|
||||||
return updatedContent.mutableCopy() as! UNMutableNotificationContent
|
notificationContent = content
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
|
|||||||
@@ -125,9 +125,9 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
|||||||
case .processedShouldDiscard, .unsupportedShouldDiscard:
|
case .processedShouldDiscard, .unsupportedShouldDiscard:
|
||||||
discardNotification()
|
discardNotification()
|
||||||
case .shouldDisplay:
|
case .shouldDisplay:
|
||||||
notificationContent = await notificationContentBuilder.process(notificationContent: notificationContent,
|
await notificationContentBuilder.process(notificationContent: ¬ificationContent,
|
||||||
notificationItem: notificationItemProxy,
|
notificationItem: notificationItemProxy,
|
||||||
mediaProvider: userSession.mediaProvider)
|
mediaProvider: userSession.mediaProvider)
|
||||||
|
|
||||||
deliverNotification()
|
deliverNotification()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user