Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notification Improvements API part 1 #1410

Merged
merged 6 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 17 additions & 19 deletions ElementX.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -378,17 +378,21 @@ class SDKClientMock: SDKClientProtocol {
}
//MARK: - `notificationClient`

public var notificationClientThrowableError: Error?
public var notificationClientCallsCount = 0
public var notificationClientCalled: Bool {
return notificationClientCallsCount > 0
}
public var notificationClientReturnValue: NotificationClientBuilder!
public var notificationClientClosure: (() -> NotificationClientBuilder)?
public var notificationClientClosure: (() throws -> NotificationClientBuilder)?

public func `notificationClient`() -> NotificationClientBuilder {
public func `notificationClient`() throws -> NotificationClientBuilder {
if let error = notificationClientThrowableError {
throw error
}
notificationClientCallsCount += 1
if let notificationClientClosure = notificationClientClosure {
return notificationClientClosure()
return try notificationClientClosure()
} else {
return notificationClientReturnValue
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ import UserNotifications
import MatrixRustSDK

protocol NotificationItemProxyProtocol {
var event: TimelineEventProxyProtocol { get }
var event: NotificationEvent? { get }

var eventID: String { get }

var senderID: String { get }

var roomID: String { get }

Expand All @@ -46,16 +50,21 @@ protocol NotificationItemProxyProtocol {

extension NotificationItemProxyProtocol {
var isEncrypted: Bool {
switch event.type {
case .messageLike(let content):
switch content {
case .roomEncrypted:
return true
switch event {
case .none, .invite:
return false
case .timeline(let event):
switch try? event.eventType() {
case .messageLike(let content):
switch content {
case .roomEncrypted:
return true
default:
return false
}
default:
return false
Velin92 marked this conversation as resolved.
Show resolved Hide resolved
}
default:
return false
}
}

Expand All @@ -66,23 +75,22 @@ extension NotificationItemProxyProtocol {

struct NotificationItemProxy: NotificationItemProxyProtocol {
let notificationItem: NotificationItem
let eventID: String
let receiverID: String
let roomID: String

var event: TimelineEventProxyProtocol {
switch notificationItem.event {
case .timeline(let timelineEvent):
return TimelineEventProxy(timelineEvent: timelineEvent)
case .invite:
#warning("Review me")
fatalError(".invite not supported yet")
}
var event: NotificationEvent? {
notificationItem.event
}

var senderDisplayName: String? {
notificationItem.senderInfo.displayName
}

var senderID: String {
notificationItem.senderInfo.userId
}

var roomDisplayName: String {
notificationItem.roomInfo.displayName
}
Expand All @@ -100,7 +108,7 @@ struct NotificationItemProxy: NotificationItemProxyProtocol {
}

var isNoisy: Bool {
notificationItem.isNoisy == true
notificationItem.isNoisy ?? false
}

var senderAvatarMediaSource: MediaSourceProxy? {
Expand All @@ -123,14 +131,16 @@ struct NotificationItemProxy: NotificationItemProxyProtocol {
struct EmptyNotificationItemProxy: NotificationItemProxyProtocol {
let eventID: String

var event: TimelineEventProxyProtocol {
MockTimelineEventProxy(eventID: eventID)
var event: NotificationEvent? {
nil
}

let roomID: String

let receiverID: String

var senderID: String { "" }

var senderDisplayName: String? { nil }

var senderAvatarURL: String? { nil }
Expand Down Expand Up @@ -161,7 +171,7 @@ extension NotificationItemProxyProtocol {
let notification = UNMutableNotificationContent()
notification.receiverID = receiverID
notification.roomID = roomID
notification.eventID = event.eventID
notification.eventID = eventID
notification.sound = isNoisy ? UNNotificationSound(named: UNNotificationSoundName(rawValue: "message.caf")) : nil
// So that the UI groups notification that are received for the same room but also for the same user
notification.threadIdentifier = "\(receiverID)\(roomID)"
Expand All @@ -173,20 +183,25 @@ extension NotificationItemProxyProtocol {
(!isDM && roomAvatarMediaSource != nil) {
return true
}
switch event.type {
case .state, .none:
switch event {
case .invite, .none:
return false
case let .messageLike(content):
switch content {
case let .roomMessage(messageType):
switch messageType {
case .image, .video, .audio:
return true
case .timeline(let event):
switch try? event.eventType() {
case .state, .none:
return false
case let .messageLike(content):
switch content {
case let .roomMessage(messageType):
switch messageType {
case .image, .video, .audio:
return true
default:
return false
}
default:
return false
}
default:
return false
}
}
}
Expand All @@ -207,45 +222,28 @@ extension NotificationItemProxyProtocol {
/// - 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.
func process(mediaProvider: MediaProviderProtocol?) async throws -> UNMutableNotificationContent {
if self is EmptyNotificationItemProxy {
switch event {
case .none:
return processEmpty()
} else {
switch event.type {
case .none:
return processEmpty()
case let .state(content):
return try await processStateEvent(content: content, mediaProvider: mediaProvider)
case .invite:
return try await processInvited(mediaProvider: mediaProvider)
case .timeline(let event):
switch try? event.eventType() {
case let .messageLike(content):
switch content {
case .roomMessage(messageType: let messageType):
return try await processRoomMessage(messageType: messageType, mediaProvider: mediaProvider)
default:
return processEmpty()
}
}
}
}

// MARK: - Private

private func processStateEvent(content: StateEventContent, mediaProvider: MediaProviderProtocol?) async throws -> UNMutableNotificationContent {
switch content {
case let .roomMemberContent(userId, membershipState):
switch membershipState {
case .invite:
if userId == receiverID {
return try await processInvited(mediaProvider: mediaProvider)
} else {
return processEmpty()
}
default:
return processEmpty()
}
default:
return processEmpty()
}
}

// MARK: - Private

private func processInvited(mediaProvider: MediaProviderProtocol?) async throws -> UNMutableNotificationContent {
var notification = baseMutableContent

Expand All @@ -259,7 +257,7 @@ extension NotificationItemProxyProtocol {
}

notification = try await notification.addSenderIcon(using: mediaProvider,
senderID: event.senderID,
senderID: senderID,
senderName: senderDisplayName ?? roomDisplayName,
icon: icon)
notification.body = body
Expand Down Expand Up @@ -305,7 +303,7 @@ extension NotificationItemProxyProtocol {
notification.categoryIdentifier = NotificationConstants.Category.message

notification = try await notification.addSenderIcon(using: mediaProvider,
senderID: event.senderID,
senderID: senderID,
senderName: senderDisplayName ?? roomDisplayName,
icon: icon)
return notification
Expand Down
59 changes: 0 additions & 59 deletions ElementX/Sources/Services/Timeline/TimelineEventProxy.swift

This file was deleted.

10 changes: 7 additions & 3 deletions NSE/Sources/Other/NSEUserSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,15 @@ final class NSEUserSession {
func notificationItemProxy(roomID: String, eventID: String) async -> NotificationItemProxyProtocol? {
await Task.dispatch(on: .global()) {
do {
#warning("Review me")
guard let notification = try self.notificationClient.legacyGetNotification(roomId: roomID, eventId: eventID) else {
let notification = try self.notificationClient.getNotificationWithSlidingSync(roomId: roomID, eventId: eventID)

guard let notification else {
return nil
}
return NotificationItemProxy(notificationItem: notification, receiverID: self.userID, roomID: roomID)
return NotificationItemProxy(notificationItem: notification,
eventID: eventID,
receiverID: self.userID,
roomID: roomID)
} catch {
MXLog.error("NSE: Could not get notification's content creating an empty notification instead, error: \(error)")
return EmptyNotificationItemProxy(eventID: eventID, roomID: roomID, receiverID: self.userID)
Expand Down
3 changes: 0 additions & 3 deletions NSE/SupportingFiles/target.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ targets:
- path: ../Sources
- path: ../SupportingFiles
- path: ../../ElementX/Sources/Generated
- path: ../../ElementX/Sources/Services/Timeline/TimelineItemProxy.swift
- path: ../../ElementX/Sources/Services/Timeline/TimelineEventProxy.swift
- path: ../../ElementX/Sources/Services/Timeline/TimelineItemSender.swift
- path: ../../ElementX/Sources/Services/Keychain/KeychainControllerProtocol.swift
- path: ../../ElementX/Sources/Services/Keychain/KeychainController.swift
- path: ../../ElementX/Sources/Services/UserSession/RestorationToken.swift
Expand Down
Loading