Simplify closure to create CallViewModels

This commit is contained in:
Max Radermacher 2024-09-27 11:41:11 -05:00 committed by GitHub
parent ef678d2720
commit 4e69ff6705
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 45 deletions

View File

@ -29,9 +29,8 @@ extension CallsListViewController {
/// changes. When the user scrolls to the bottom of the list, callers should
/// request additional items.
struct ViewModelLoader {
typealias CreateCallViewModelBlock = (
_ primaryCallRecord: CallRecord,
_ coalescedCallRecords: [CallRecord],
typealias CallViewModelForCallRecords = (
_ callRecords: [CallRecord],
_ tx: DBReadTransaction
) -> CallViewModel
@ -46,7 +45,7 @@ extension CallsListViewController {
}
private let callRecordLoader: CallRecordLoader
private let createCallViewModelBlock: CreateCallViewModelBlock
private let callViewModelForCallRecords: CallViewModelForCallRecords
private let fetchCallRecordBlock: FetchCallRecordBlock
private let viewModelPageSize: Int
private let maxCachedViewModelCount: Int
@ -54,7 +53,7 @@ extension CallsListViewController {
init(
callRecordLoader: CallRecordLoader,
createCallViewModelBlock: @escaping CreateCallViewModelBlock,
callViewModelForCallRecords: @escaping CallViewModelForCallRecords,
fetchCallRecordBlock: @escaping FetchCallRecordBlock,
viewModelPageSize: Int = 50,
maxCachedViewModelCount: Int = 150,
@ -66,7 +65,7 @@ extension CallsListViewController {
)
self.callRecordLoader = callRecordLoader
self.createCallViewModelBlock = createCallViewModelBlock
self.callViewModelForCallRecords = callViewModelForCallRecords
self.fetchCallRecordBlock = fetchCallRecordBlock
self.viewModelPageSize = viewModelPageSize
self.maxCachedViewModelCount = maxCachedViewModelCount
@ -250,9 +249,8 @@ extension CallsListViewController {
callHistoryItemReferences[0] = CallHistoryItemReference(
callRecordIds: combinedGroupOfCallRecords.map(\.id)
)
viewModels[0] = createCallViewModelBlock(
combinedGroupOfCallRecords.first,
Array(combinedGroupOfCallRecords.rawValue.dropFirst()),
viewModels[0] = callViewModelForCallRecords(
combinedGroupOfCallRecords.rawValue,
tx
)
fetchResult = fetchResult.dropLast()
@ -293,7 +291,7 @@ extension CallsListViewController {
let callRecords = reference.callRecordIds.map {
return fetchCallRecordBlock($0, tx)!
}
return createCallViewModelBlock(callRecords.first, Array(callRecords.rawValue.dropFirst()), tx)
return callViewModelForCallRecords(callRecords.rawValue, tx)
}
return newViewModels
@ -458,7 +456,7 @@ extension CallsListViewController {
continue
}
let newCallRecords = viewModel.callRecords.map(refreshIfPossible(_:))
viewModels[index] = createCallViewModelBlock(newCallRecords.first!, Array(newCallRecords.dropFirst()), tx)
viewModels[index] = callViewModelForCallRecords(newCallRecords, tx)
refreshedViewModelReferences.append(viewModels[index].reference)
}

View File

@ -685,10 +685,9 @@ class CallsListViewController: OWSViewController, HomeTabViewController, CallSer
// Reset our loaded calls.
self.viewModelLoader = ViewModelLoader(
callRecordLoader: callRecordLoader,
createCallViewModelBlock: { primaryCallRecord, coalescedCallRecords, tx in
return Self.createCallViewModel(
primaryCallRecord: primaryCallRecord,
coalescedCallRecords: coalescedCallRecords,
callViewModelForCallRecords: { callRecords, tx in
return Self.callViewModel(
forCallRecords: callRecords,
deps: capturedDeps,
tx: SDSDB.shimOnlyBridge(tx)
)
@ -752,42 +751,44 @@ class CallsListViewController: OWSViewController, HomeTabViewController, CallSer
/// - Important
/// The primary and and coalesced call records *must* all have the same
/// thread, direction, missed status, and call type.
private static func createCallViewModel(
primaryCallRecord: CallRecord,
coalescedCallRecords: [CallRecord],
private static func callViewModel(
forCallRecords callRecords: [CallRecord],
deps: Dependencies,
tx: SDSAnyReadTransaction
) -> CallViewModel {
owsPrecondition(!callRecords.isEmpty)
owsPrecondition(
coalescedCallRecords.allSatisfy { $0.threadRowId == primaryCallRecord.threadRowId },
Set(callRecords.map(\.threadRowId)).count == 1,
"Coalesced call records were for a different thread than the primary!"
)
owsPrecondition(
coalescedCallRecords.allSatisfy { $0.callDirection == primaryCallRecord.callDirection },
Set(callRecords.map(\.callDirection)).count == 1,
"Coalesced call records were of a different direction than the primary!"
)
owsPrecondition(
coalescedCallRecords.allSatisfy { $0.callStatus.isMissedCall == primaryCallRecord.callStatus.isMissedCall },
Set(callRecords.map(\.callStatus.isMissedCall)).count == 1,
"Coalesced call records were of a different missed status than the primary!"
)
owsPrecondition(
([primaryCallRecord] + coalescedCallRecords).isSortedByTimestamp(.descending),
callRecords.isSortedByTimestamp(.descending),
"Primary and coalesced call records were not ordered descending by timestamp!"
)
let mostRecentCallRecord = callRecords.first!
guard let callThread = deps.threadStore.fetchThread(
rowId: primaryCallRecord.threadRowId,
rowId: mostRecentCallRecord.threadRowId,
tx: tx.asV2Read
) else {
owsFail("Missing thread for call record! This should be impossible, per the DB schema.")
}
let callDirection: CallViewModel.Direction = {
if primaryCallRecord.callStatus.isMissedCall {
if mostRecentCallRecord.callStatus.isMissedCall {
return .missed
}
switch primaryCallRecord.callDirection {
switch mostRecentCallRecord.callDirection {
case .incoming: return .incoming
case .outgoing: return .outgoing
}
@ -798,9 +799,9 @@ class CallsListViewController: OWSViewController, HomeTabViewController, CallSer
let callState: CallViewModel.State = {
let currentCallId: UInt64? = deps.callService.callServiceState.currentCall?.callId
switch primaryCallRecord.callStatus {
switch mostRecentCallRecord.callStatus {
case .individual:
if primaryCallRecord.callId == currentCallId {
if mostRecentCallRecord.callId == currentCallId {
// We can have at most one 1:1 call active at a time, and if
// we have an active 1:1 call we must be in it. All other
// 1:1 calls must have ended.
@ -809,7 +810,7 @@ class CallsListViewController: OWSViewController, HomeTabViewController, CallSer
case .group:
guard let groupCallInteraction: OWSGroupCallMessage = deps.interactionStore
.fetchAssociatedInteraction(
callRecord: primaryCallRecord, tx: tx.asV2Read
callRecord: mostRecentCallRecord, tx: tx.asV2Read
)
else {
owsFail("Missing interaction for group call. This should be impossible per the DB schema!")
@ -820,7 +821,7 @@ class CallsListViewController: OWSViewController, HomeTabViewController, CallSer
// leetle wonky that we use the interaction to store that info,
// but such is life.
if !groupCallInteraction.hasEnded {
if primaryCallRecord.callId == currentCallId {
if mostRecentCallRecord.callId == currentCallId {
return .participating
}
@ -838,7 +839,7 @@ class CallsListViewController: OWSViewController, HomeTabViewController, CallSer
case let contactThread as TSContactThread:
title = deps.contactsManager.displayName(for: contactThread.contactAddress, tx: tx).resolvedValue()
let callType: CallViewModel.RecipientType.CallType = {
switch primaryCallRecord.callType {
switch mostRecentCallRecord.callType {
case .audioCall:
return .audio
case .groupCall:
@ -857,8 +858,8 @@ class CallsListViewController: OWSViewController, HomeTabViewController, CallSer
}
return CallViewModel(
reference: .callRecords(primaryId: primaryCallRecord.id, coalescedIds: coalescedCallRecords.map(\.id)),
callRecords: [primaryCallRecord] + coalescedCallRecords,
reference: .callRecords(primaryId: mostRecentCallRecord.id, coalescedIds: callRecords.dropFirst().map(\.id)),
callRecords: callRecords,
title: title,
recipientType: recipientType,
direction: callDirection,

View File

@ -16,20 +16,16 @@ final class CallsListViewControllerViewModelLoaderTest: XCTestCase {
private var mockDB: MockDB!
private var mockCallRecordLoader: MockCallRecordLoader!
private lazy var createCallViewModelBlock: ViewModelLoader.CreateCallViewModelBlock! = {
self.createCallViewModel(primaryCallRecord: $0, coalescedCallRecords: $1, tx: $2)
private lazy var callViewModelForCallRecords: ViewModelLoader.CallViewModelForCallRecords! = {
self.createCallViewModel(callRecords: $0, tx: $1)
}
private lazy var fetchCallRecordBlock: ViewModelLoader.FetchCallRecordBlock! = { (callRecordId, tx) -> CallRecord? in
return self.mockCallRecordLoader.callRecordsById[callRecordId]
}
private func createCallViewModel(
primaryCallRecord: CallRecord,
coalescedCallRecords: [CallRecord],
tx: DBReadTransaction
) -> CallViewModel {
private func createCallViewModel(callRecords: [CallRecord], tx: DBReadTransaction) -> CallViewModel {
let recipientType: CallViewModel.RecipientType = {
switch primaryCallRecord.callStatus {
switch callRecords.first!.callStatus {
case .individual:
return .individual(type: .audio, contactThread: TSContactThread(
contactUUID: UUID().uuidString,
@ -41,19 +37,19 @@ final class CallsListViewControllerViewModelLoaderTest: XCTestCase {
}()
let direction: CallViewModel.Direction = {
if primaryCallRecord.callStatus.isMissedCall {
if callRecords.first!.callStatus.isMissedCall {
return .missed
}
switch primaryCallRecord.callDirection {
switch callRecords.first!.callDirection {
case .incoming: return .incoming
case .outgoing: return .outgoing
}
}()
return CallViewModel(
reference: .callRecords(primaryId: primaryCallRecord.id, coalescedIds: coalescedCallRecords.map(\.id)),
callRecords: [primaryCallRecord] + coalescedCallRecords,
reference: .callRecords(primaryId: callRecords.first!.id, coalescedIds: callRecords.dropFirst().map(\.id)),
callRecords: callRecords,
title: "Hey, I just met you, and this is crazy, but here's my number, so call me maybe?",
recipientType: recipientType,
direction: direction,
@ -68,7 +64,7 @@ final class CallsListViewControllerViewModelLoaderTest: XCTestCase {
) {
viewModelLoader = ViewModelLoader(
callRecordLoader: mockCallRecordLoader,
createCallViewModelBlock: { self.createCallViewModelBlock($0, $1, $2) },
callViewModelForCallRecords: { self.callViewModelForCallRecords($0, $1) },
fetchCallRecordBlock: { self.fetchCallRecordBlock($0, $1) },
viewModelPageSize: viewModelPageSize,
maxCachedViewModelCount: maxCachedViewModelCount,