ContactPagerViewModel.swift
75 lignes · 2634 octets
import Combine import Foundation // Port of ui/contact/ContactPagerViewModel.kt — ordered contacts for the // pager (same order as the carnet for the given sort) + duplicate counts. // Adds delete and notes-save actions surfaced by the iOS fiche. @MainActor final class ContactPagerViewModel: ObservableObject { @Published private(set) var contacts: [CrmContactEntity] = [] @Published private(set) var duplicateCountById: [Int64: Int] = [:] let initialContactId: Int64 let sort: ContactSort private let repository: ContactRepository private var cancellables: Set<AnyCancellable> = [] init( initialContactId: Int64, sort: ContactSort, repository: ContactRepository = ContactRepository( dao: Card2vcfDatabase.shared.crmContactDao, images: ContactImageStore() ) ) { self.initialContactId = initialContactId self.sort = sort self.repository = repository NotificationCenter.default.publisher(for: .card2vcfDatabaseDidChange) .receive(on: RunLoop.main) .sink { [weak self] _ in Task { await self?.refresh() } } .store(in: &cancellables) } func refresh() async { do { let list = try await repository.fetchAll() let exclusions = (try? await repository.getExclusions()) ?? [] let clusters = DuplicateDetector.clusters(contacts: list, exclusions: exclusions) contacts = AlphabetIndex.group(contacts: list, sort: sort).flatMap { $0.contacts } duplicateCountById = Dictionary( uniqueKeysWithValues: list.map { ($0.id, DuplicateDetector.duplicateCount($0.id, clusters: clusters)) } ) } catch { contacts = [] duplicateCountById = [:] } } func initialPageIndex(_ list: [CrmContactEntity]) -> Int { let idx = list.firstIndex { $0.id == initialContactId } return idx ?? 0 } /// Inline notes editor on the fiche (Android edited notes in the edit form). func saveNotes(contactId: Int64, notes: String) async { guard let entity = try? await repository.getById(contactId) else { return } var card = entity.toCard() card.note = notes.nilIfBlank try? await repository.updateFromCard( id: contactId, card: card, preserveNotesIfBlankDraft: false ) await refresh() } func delete(contactId: Int64) async { try? await repository.delete(contactId) await refresh() } }
GitRust