mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
86 lines
2.4 KiB
Swift
86 lines
2.4 KiB
Swift
|
|
//
|
||
|
|
// SetMessageAttributeIntentHandler.swift
|
||
|
|
// Meshtastic
|
||
|
|
//
|
||
|
|
// Handles INSetMessageAttributeIntent for CarPlay and Siri.
|
||
|
|
// Marks messages as read or unread in Core Data.
|
||
|
|
//
|
||
|
|
|
||
|
|
import CoreData
|
||
|
|
import Intents
|
||
|
|
import OSLog
|
||
|
|
|
||
|
|
final class SetMessageAttributeIntentHandler: NSObject, INSetMessageAttributeIntentHandling {
|
||
|
|
|
||
|
|
// MARK: - Resolution
|
||
|
|
|
||
|
|
func resolveAttribute(for intent: INSetMessageAttributeIntent) async -> INMessageAttributeResolutionResult {
|
||
|
|
let attribute = intent.attribute
|
||
|
|
guard attribute != .unknown else {
|
||
|
|
return .needsValue()
|
||
|
|
}
|
||
|
|
return .success(with: attribute)
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Confirmation
|
||
|
|
|
||
|
|
func confirm(intent: INSetMessageAttributeIntent) async -> INSetMessageAttributeIntentResponse {
|
||
|
|
guard let identifiers = intent.identifiers, !identifiers.isEmpty else {
|
||
|
|
return INSetMessageAttributeIntentResponse(code: .failure, userActivity: nil)
|
||
|
|
}
|
||
|
|
return INSetMessageAttributeIntentResponse(code: .ready, userActivity: nil)
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Handling
|
||
|
|
|
||
|
|
func handle(intent: INSetMessageAttributeIntent) async -> INSetMessageAttributeIntentResponse {
|
||
|
|
guard let identifiers = intent.identifiers, !identifiers.isEmpty else {
|
||
|
|
return INSetMessageAttributeIntentResponse(code: .failure, userActivity: nil)
|
||
|
|
}
|
||
|
|
|
||
|
|
let attribute = intent.attribute
|
||
|
|
let context = PersistenceController.shared.container.viewContext
|
||
|
|
|
||
|
|
let success: Bool = await MainActor.run {
|
||
|
|
let messageIds = identifiers.compactMap { Int64($0) }
|
||
|
|
guard !messageIds.isEmpty else { return false }
|
||
|
|
|
||
|
|
let fetchRequest: NSFetchRequest<MessageEntity> = MessageEntity.fetchRequest()
|
||
|
|
fetchRequest.predicate = NSPredicate(format: "messageId IN %@", messageIds)
|
||
|
|
|
||
|
|
do {
|
||
|
|
let messages = try context.fetch(fetchRequest)
|
||
|
|
guard !messages.isEmpty else { return false }
|
||
|
|
|
||
|
|
for message in messages {
|
||
|
|
switch attribute {
|
||
|
|
case .read:
|
||
|
|
message.read = true
|
||
|
|
case .unread:
|
||
|
|
message.read = false
|
||
|
|
case .flagged, .unflagged:
|
||
|
|
// Meshtastic does not support message flagging
|
||
|
|
break
|
||
|
|
default:
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if context.hasChanges {
|
||
|
|
try context.save()
|
||
|
|
}
|
||
|
|
Logger.services.info("CarPlay/Siri: Updated \(messages.count) message(s) to \(String(describing: attribute))")
|
||
|
|
return true
|
||
|
|
} catch {
|
||
|
|
Logger.services.error("CarPlay/Siri: Failed to update message attributes: \(error.localizedDescription)")
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return INSetMessageAttributeIntentResponse(
|
||
|
|
code: success ? .success : .failure,
|
||
|
|
userActivity: nil
|
||
|
|
)
|
||
|
|
}
|
||
|
|
}
|