TM-SGNL-iOS/SignalServiceKit/Messages/RecipientStateMerger.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

55 lines
2.2 KiB
Swift

//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
import LibSignalClient
final class RecipientStateMerger {
private let recipientDatabaseTable: RecipientDatabaseTable
private let signalServiceAddressCache: SignalServiceAddressCache
init(
recipientDatabaseTable: RecipientDatabaseTable,
signalServiceAddressCache: SignalServiceAddressCache
) {
self.recipientDatabaseTable = recipientDatabaseTable
self.signalServiceAddressCache = signalServiceAddressCache
}
func normalize(_ recipientStates: inout [SignalServiceAddress: TSOutgoingMessageRecipientState]?, tx: DBReadTransaction) {
guard let oldRecipientStates = recipientStates else {
return
}
var existingValues = [(SignalServiceAddress, TSOutgoingMessageRecipientState)]()
// If we convert a Pni to an Aci, it's possible the Aci is already in
// recipientStates. If that's the case, we want to throw away the Pni and
// defer to the Aci. We do this by handling Pnis after everything else.
var updatedValues = [(SignalServiceAddress, TSOutgoingMessageRecipientState)]()
for (oldAddress, recipientState) in oldRecipientStates {
if let normalizedAddress = normalizedAddressIfNeeded(for: oldAddress, tx: tx) {
updatedValues.append((normalizedAddress, recipientState))
} else {
existingValues.append((oldAddress, recipientState))
}
}
recipientStates = Dictionary(existingValues + updatedValues, uniquingKeysWith: { lhs, _ in lhs })
}
func normalizedAddressIfNeeded(for oldAddress: SignalServiceAddress, tx: DBReadTransaction) -> SignalServiceAddress? {
switch oldAddress.serviceId?.concreteType {
case .none, .aci:
return nil
case .pni(let pni):
guard let aci = recipientDatabaseTable.fetchRecipient(serviceId: pni, transaction: tx)?.aci else {
return nil
}
return SignalServiceAddress(
serviceId: aci,
phoneNumber: nil,
cache: signalServiceAddressCache
)
}
}
}