55 lines
2.2 KiB
Swift
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
|
|
)
|
|
}
|
|
}
|
|
}
|