Placeholders added in push notifications (#1176)

* placeholders added in push notifications

* this code is a bit easier to read

* code improvement
This commit is contained in:
Mauro
2023-06-27 13:44:19 +02:00
committed by GitHub
parent 66e94ed922
commit ff8728b86c
6 changed files with 66 additions and 19 deletions

View File

@@ -216,6 +216,7 @@
5455147CAC63F71E48F7D699 /* NSELogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3D455BC2423D911A62ACFB2 /* NSELogger.swift */; };
54AE8860D668AFD96E7E177B /* UITestsScreenIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEBE5EA91E8691EDF364EC2 /* UITestsScreenIdentifier.swift */; };
54C774874BED4A8FAD1F22FE /* AnalyticsConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77B3D4950F1707E66E4A45A /* AnalyticsConfiguration.swift */; };
55CDD3968D95D1A820B5491E /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C705E605EF57C19DBE86FFA1 /* PlaceholderAvatarImage.swift */; };
564BF06B3E93D6DD55F903B2 /* CreateRoomCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C618CA2B6C8758B06C88013C /* CreateRoomCoordinator.swift */; };
565868808A1DA565707394ED /* CurrentValuePublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */; };
56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F5530B2212862FA4BEFF2D /* HomeScreenViewModelProtocol.swift */; };
@@ -594,6 +595,7 @@
D55AF9B5B55FEED04771A461 /* RoomFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A008E57D52B07B78DFAD1BB /* RoomFlowCoordinator.swift */; };
D5C805F49B2C75DC3793E780 /* EmojiItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A243E04B58DC6E41FDCD82 /* EmojiItem.swift */; };
D5EA4C6C80579279770D5804 /* ImageRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */; };
D63974A88CF2BC721F109C77 /* Compound in Frameworks */ = {isa = PBXBuildFile; productRef = DCA3C4A997AD28E6918D4CE5 /* Compound */; };
D6661A94DBD97658B2ADBD6A /* MapTilerStaticMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */; };
D7CDBAE82782BD0529DECB5F /* AttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52BD6ED18E2EB61E28C340AD /* AttributedString.swift */; };
D8359F67AF3A83516E9083C1 /* MockUserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4756C5A8C8649AD6C10C615 /* MockUserSession.swift */; };
@@ -609,6 +611,7 @@
DE0BBA736557B42BC0DA6CBF /* TimelineEventProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B62EE933FC3D5651AF4607 /* TimelineEventProxy.swift */; };
DE4F8C4E0F1DB4832F09DE97 /* HomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */; };
DF004A5B2EABBD0574D06A04 /* SplashScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 854BCEAF2A832176FAACD2CB /* SplashScreenCoordinator.swift */; };
DF05F9C9D3D977EB77E13692 /* DesignKit in Frameworks */ = {isa = PBXBuildFile; productRef = A593735D882778FD2C9A185B /* DesignKit */; };
DF504B10A4918F971A57BEF2 /* PostHogAnalyticsClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1715E3D7F53C0748AA50C91C /* PostHogAnalyticsClient.swift */; };
DFCA89C4EC2A5332ED6B441F /* DataProtectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4959CECEC984B3995616F427 /* DataProtectionManager.swift */; };
DFD5AA8688A34C72D48AF3B1 /* StaticLocationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5311C989EC15B4C2D699025 /* StaticLocationScreenViewModel.swift */; };
@@ -1430,6 +1433,8 @@
53DEF39F0C4DE02E3FC56D91 /* KeychainAccess in Frameworks */,
F06CE9132855E81EBB6DDC32 /* Kingfisher in Frameworks */,
67D6E0700A9C1E676F6231F8 /* Collections in Frameworks */,
D63974A88CF2BC721F109C77 /* Compound in Frameworks */,
DF05F9C9D3D977EB77E13692 /* DesignKit in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3582,6 +3587,8 @@
800631D7250B7F93195035F1 /* KeychainAccess */,
940C605265DD82DA0C655E23 /* Kingfisher */,
AD544C0FA48DFFB080920061 /* Collections */,
DCA3C4A997AD28E6918D4CE5 /* Compound */,
A593735D882778FD2C9A185B /* DesignKit */,
);
productName = NSE;
productReference = 0D8F620C8B314840D8602E3F /* NSE.appex */;
@@ -3849,6 +3856,7 @@
5C02841B2A86327B2C377682 /* NotificationConstants.swift in Sources */,
5D70FAE4D2BF4553AFFFFE41 /* NotificationItemProxy.swift in Sources */,
B14BC354E56616B6B7D9A3D7 /* NotificationServiceExtension.swift in Sources */,
55CDD3968D95D1A820B5491E /* PlaceholderAvatarImage.swift in Sources */,
414F50CFCFEEE2611127DCFB /* RestorationToken.swift in Sources */,
7354D094A4C59B555F407FA1 /* RustTracing.swift in Sources */,
6C5A2C454E6C198AB39ED760 /* SharedUserDefaultsKeys.swift in Sources */,
@@ -5337,6 +5345,10 @@
package = 395DE6AE429B7ACC7C7FE31D /* XCRemoteSwiftPackageReference "KZFileWatchers" */;
productName = KZFileWatchers;
};
A593735D882778FD2C9A185B /* DesignKit */ = {
isa = XCSwiftPackageProductDependency;
productName = DesignKit;
};
A5A56C4F47C368EBE5C5E870 /* DesignKit */ = {
isa = XCSwiftPackageProductDependency;
productName = DesignKit;
@@ -5391,6 +5403,11 @@
package = AC3475112CA40C2C6E78D1EB /* XCRemoteSwiftPackageReference "matrix-analytics-events" */;
productName = AnalyticsEvents;
};
DCA3C4A997AD28E6918D4CE5 /* Compound */ = {
isa = XCSwiftPackageProductDependency;
package = 9754C4B03F6255F67FC15E52 /* XCRemoteSwiftPackageReference "compound-ios" */;
productName = Compound;
};
DE8DC9B3FBA402117DC4C49F /* Kingfisher */ = {
isa = XCSwiftPackageProductDependency;
package = D283517192CAC3E2E6920765 /* XCRemoteSwiftPackageReference "Kingfisher" */;

View File

@@ -16,15 +16,21 @@
import Foundation
import Intents
import SwiftUI
import UserNotifications
struct NotificationIcon {
struct GroupInfo {
let name: String
let id: String
}
let mediaSource: MediaSourceProxy?
// Required as the key to set images for groups
let groupName: String?
let groupInfo: GroupInfo?
var shouldDisplayAsGroup: Bool {
groupName != nil
groupInfo != nil
}
}
@@ -99,11 +105,12 @@ extension UNMutableNotificationContent {
senderID: String,
senderName: String,
icon: NotificationIcon) async throws -> UNMutableNotificationContent {
var image = INImage(named: "")
var fetchedImage: INImage?
let image: INImage
if let mediaSource = icon.mediaSource {
switch await mediaProvider?.loadImageDataFromSource(mediaSource) {
case .success(let data):
image = INImage(imageData: data)
fetchedImage = INImage(imageData: data)
case .failure(let error):
MXLog.error("Couldn't add sender icon: \(error)")
case .none:
@@ -111,6 +118,15 @@ extension UNMutableNotificationContent {
}
}
if let fetchedImage {
image = fetchedImage
} else if let data = await getPlaceholderAvatarImageData(name: icon.groupInfo?.name ?? senderName,
id: icon.groupInfo?.name ?? senderName) {
image = INImage(imageData: data)
} else {
image = INImage(named: "")
}
let senderHandle = INPersonHandle(value: senderID, type: .unknown)
let sender = INPerson(personHandle: senderHandle,
nameComponents: nil,
@@ -122,10 +138,10 @@ extension UNMutableNotificationContent {
// These are required to show the group name as subtitle
var speakableGroupName: INSpeakableString?
var recipients: [INPerson]?
if let groupName = icon.groupName {
if let groupInfo = icon.groupInfo {
let meHandle = INPersonHandle(value: receiverID, type: .unknown)
let me = INPerson(personHandle: meHandle, nameComponents: nil, displayName: nil, image: nil, contactIdentifier: nil, customIdentifier: nil, isMe: true)
speakableGroupName = INSpeakableString(spokenPhrase: groupName)
speakableGroupName = INSpeakableString(spokenPhrase: groupInfo.name)
recipients = [sender, me]
}
@@ -157,4 +173,13 @@ extension UNMutableNotificationContent {
// swiftlint:disable:next force_cast
return updatedContent.mutableCopy() as! UNMutableNotificationContent
}
private func getPlaceholderAvatarImageData(name: String, id: String) async -> Data? {
let image = PlaceholderAvatarImage(name: name,
contentID: id)
.clipShape(Circle())
.frame(width: 100, height: 100)
let renderer = await ImageRenderer(content: image)
return await renderer.uiImage?.jpegData(compressionQuality: 0.8)
}
}

View File

@@ -16,8 +16,11 @@
import SwiftUI
import Compound
import DesignKit
struct PlaceholderAvatarImage: View {
@Environment(\.redactionReasons) var redactionReasons
@Environment(\.redactionReasons) private var redactionReasons
private let textForImage: String
private let contentID: String?

View File

@@ -185,6 +185,15 @@ extension NotificationItemProxyProtocol {
}
}
var icon: NotificationIcon {
if isDirect {
return NotificationIcon(mediaSource: senderAvatarMediaSource, groupInfo: nil)
} else {
return NotificationIcon(mediaSource: roomAvatarMediaSource,
groupInfo: .init(name: roomDisplayName, id: roomID))
}
}
/// Process the receiver item proxy
/// - Parameters:
/// - receiverId: identifier of the user that has received the notification
@@ -236,13 +245,10 @@ extension NotificationItemProxyProtocol {
notification.categoryIdentifier = NotificationConstants.Category.invite
let icon: NotificationIcon
let body: String
if !isDirect {
icon = NotificationIcon(mediaSource: roomAvatarMediaSource, groupName: roomDisplayName)
body = L10n.notificationRoomInviteBody
} else {
icon = NotificationIcon(mediaSource: senderAvatarMediaSource, groupName: nil)
body = L10n.notificationInviteBody
}
@@ -292,17 +298,9 @@ extension NotificationItemProxyProtocol {
}
notification.categoryIdentifier = NotificationConstants.Category.message
let senderName = senderDisplayName ?? roomDisplayName
let icon: NotificationIcon
if !isDirect {
icon = NotificationIcon(mediaSource: roomAvatarMediaSource, groupName: roomDisplayName)
} else {
icon = NotificationIcon(mediaSource: senderAvatarMediaSource, groupName: nil)
}
notification = try await notification.addSenderIcon(using: mediaProvider,
senderID: event.senderID,
senderName: senderName,
senderName: senderDisplayName ?? roomDisplayName,
icon: icon)
return notification
}

View File

@@ -36,6 +36,8 @@ targets:
- package: KeychainAccess
- package: Kingfisher
- package: Collections
- package: Compound
- package: DesignKit
info:
path: ../SupportingFiles/Info.plist
@@ -91,3 +93,4 @@ targets:
- path: ../../ElementX/Sources/Other/Extensions/UNNotificationContent.swift
- path: ../../ElementX/Sources/Other/UserPreference.swift
- path: ../../ElementX/Sources/Other/SharedUserDefaultsKeys.swift
- path: ../../ElementX/Sources/Other/SwiftUI/Views/PlaceholderAvatarImage.swift

1
changelog.d/1168.feature Normal file
View File

@@ -0,0 +1 @@
Push Notifications of rooms/dm without avatars will now display the default placeholder used in app.