mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Notification Placeholder Image Caching (#1248)
* placeholder image caching * code improvement * code is now clearer
This commit is contained in:
@@ -44,7 +44,8 @@ extension FileManager {
|
|||||||
|
|
||||||
return newURL
|
return newURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
func writeDataToTemporaryDirectory(data: Data, fileName: String) throws -> URL {
|
func writeDataToTemporaryDirectory(data: Data, fileName: String) throws -> URL {
|
||||||
let newURL = URL.temporaryDirectory.appendingPathComponent(fileName)
|
let newURL = URL.temporaryDirectory.appendingPathComponent(fileName)
|
||||||
|
|
||||||
|
|||||||
@@ -106,22 +106,31 @@ extension UNMutableNotificationContent {
|
|||||||
senderID: String,
|
senderID: String,
|
||||||
senderName: String,
|
senderName: String,
|
||||||
icon: NotificationIcon) async throws -> UNMutableNotificationContent {
|
icon: NotificationIcon) async throws -> UNMutableNotificationContent {
|
||||||
|
// We display the placeholder only if...
|
||||||
|
var needsPlaceholder = false
|
||||||
|
|
||||||
var fetchedImage: INImage?
|
var fetchedImage: INImage?
|
||||||
let image: INImage
|
let image: INImage
|
||||||
if let mediaSource = icon.mediaSource {
|
if let mediaSource = icon.mediaSource {
|
||||||
switch await mediaProvider?.loadImageDataFromSource(mediaSource) {
|
if let mediaProvider {
|
||||||
case .success(let data):
|
switch await mediaProvider.loadImageDataFromSource(mediaSource) {
|
||||||
fetchedImage = INImage(imageData: data)
|
case .success(let data):
|
||||||
case .failure(let error):
|
fetchedImage = INImage(imageData: data)
|
||||||
MXLog.error("Couldn't add sender icon: \(error)")
|
case .failure(let error):
|
||||||
case .none:
|
MXLog.error("Couldn't add sender icon: \(error)")
|
||||||
break
|
// ...The provider failed to fetch
|
||||||
|
needsPlaceholder = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// ...There is no media
|
||||||
|
needsPlaceholder = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if let fetchedImage {
|
if let fetchedImage {
|
||||||
image = fetchedImage
|
image = fetchedImage
|
||||||
} else if let data = await getPlaceholderAvatarImageData(name: icon.groupInfo?.name ?? senderName,
|
} else if needsPlaceholder,
|
||||||
|
let data = await getPlaceholderAvatarImageData(name: icon.groupInfo?.name ?? senderName,
|
||||||
id: icon.groupInfo?.id ?? senderID) {
|
id: icon.groupInfo?.id ?? senderID) {
|
||||||
image = INImage(imageData: data)
|
image = INImage(imageData: data)
|
||||||
} else {
|
} else {
|
||||||
@@ -176,26 +185,46 @@ extension UNMutableNotificationContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func getPlaceholderAvatarImageData(name: String, id: String) async -> Data? {
|
private func getPlaceholderAvatarImageData(name: String, id: String) async -> Data? {
|
||||||
|
let fileName = "notification_placeholder_\(name)_\(id).png"
|
||||||
|
if let data = try? Data(contentsOf: URL.temporaryDirectory.appendingPathComponent(fileName)) {
|
||||||
|
MXLog.info("Found existing notification icon placeholder")
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
MXLog.info("Generating notification icon placeholder")
|
||||||
let image = PlaceholderAvatarImage(name: name,
|
let image = PlaceholderAvatarImage(name: name,
|
||||||
contentID: id)
|
contentID: id)
|
||||||
.clipShape(Circle())
|
.clipShape(Circle())
|
||||||
.frame(width: 100, height: 100)
|
.frame(width: 50, height: 50)
|
||||||
let renderer = await ImageRenderer(content: image)
|
let renderer = await ImageRenderer(content: image)
|
||||||
guard let image = await renderer.uiImage else {
|
guard let image = await renderer.uiImage else {
|
||||||
|
MXLog.info("Generating notification icon placeholder failed")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let data: Data?
|
||||||
// On simulator and macOS the image is rendered correctly
|
// On simulator and macOS the image is rendered correctly
|
||||||
// But on other devices is rendered upside down so we need to flip it
|
// But on other devices is rendered upside down so we need to flip it
|
||||||
#if targetEnvironment(simulator)
|
#if targetEnvironment(simulator)
|
||||||
return image.pngData()
|
data = image.pngData()
|
||||||
#else
|
#else
|
||||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||||
return image.pngData()
|
data = image.pngData()
|
||||||
} else {
|
} else {
|
||||||
return image.flippedVertically().pngData()
|
data = image.flippedVertically().pngData()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if let data {
|
||||||
|
do {
|
||||||
|
// cache image data
|
||||||
|
try FileManager.default.writeDataToTemporaryDirectory(data: data, fileName: fileName)
|
||||||
|
} catch {
|
||||||
|
MXLog.error("Could not store placeholder image")
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -163,8 +163,9 @@ extension NotificationItemProxyProtocol {
|
|||||||
return notification
|
return notification
|
||||||
}
|
}
|
||||||
|
|
||||||
var requiresMediaProvider: Bool {
|
var hasMedia: Bool {
|
||||||
if senderAvatarMediaSource != nil || roomAvatarMediaSource != nil {
|
if (isDirect && senderAvatarMediaSource != nil) ||
|
||||||
|
(!isDirect && roomAvatarMediaSource != nil) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
switch event.type {
|
switch event.type {
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
|
|||||||
// After the first processing, update the modified content
|
// After the first processing, update the modified content
|
||||||
modifiedContent = try await itemProxy.process(mediaProvider: nil)
|
modifiedContent = try await itemProxy.process(mediaProvider: nil)
|
||||||
|
|
||||||
guard itemProxy.requiresMediaProvider else {
|
guard itemProxy.hasMedia else {
|
||||||
MXLog.info("\(tag) no media needed")
|
MXLog.info("\(tag) no media needed")
|
||||||
|
|
||||||
// We've processed the item and no media operations needed, so no need to go further
|
// We've processed the item and no media operations needed, so no need to go further
|
||||||
|
|||||||
Reference in New Issue
Block a user