import HUD import UIKit import Shared import Models import Combine import XXModels import Defaults import Integration import DependencyInjection enum SearchSection { case chats case connections } //enum SearchItem: Equatable, Hashable { // case chat(Chat) // case connection(Contact) //} typealias RecentsSnapshot = NSDiffableDataSourceSnapshot<SectionId, Contact> //typealias SearchSnapshot = NSDiffableDataSourceSnapshot<SearchSection, SearchItem> final class ChatListViewModel { @Dependency private var session: SessionType var isOnline: AnyPublisher<Bool, Never> { session.isOnline } // var chatsPublisher: AnyPublisher<[Chat], Never> { // chatsSubject.eraseToAnyPublisher() // } var hudPublisher: AnyPublisher<HUDStatus, Never> { hudSubject.eraseToAnyPublisher() } // var recentsPublisher: AnyPublisher<RecentsSnapshot, Never> { // session.contacts(.isRecent).map { // let section = SectionId() // var snapshot = RecentsSnapshot() // snapshot.appendSections([section]) // snapshot.appendItems($0, toSection: section) // return snapshot // }.eraseToAnyPublisher() // } // var searchPublisher: AnyPublisher<SearchSnapshot, Never> { // Publishers.CombineLatest3( // session.contacts(.all), // chatsPublisher, // searchSubject // .removeDuplicates() // .debounce(for: .milliseconds(100), scheduler: DispatchQueue.main) // .eraseToAnyPublisher() // ) // .map { (contacts, chats, query) in // let connectionItems = contacts.filter { // let username = $0.username.lowercased().contains(query.lowercased()) // let nickname = $0.nickname?.lowercased().contains(query.lowercased()) ?? false // return username || nickname // }.map(SearchItem.connection) // // let chatItems = chats.filter { // switch $0 { // case .contact(let info): // let username = info.contact.username.lowercased().contains(query.lowercased()) // let nickname = info.contact.nickname?.lowercased().contains(query.lowercased()) ?? false // let lastMessage = info.lastMessage?.payload.text.lowercased().contains(query.lowercased()) ?? false // return username || nickname || lastMessage // // case .group(let info): // let name = info.group.name.lowercased().contains(query.lowercased()) // let last = info.lastMessage?.payload.text.lowercased().contains(query.lowercased()) ?? false // return name || last // } // }.map(SearchItem.chat) // // var snapshot = SearchSnapshot() // // if connectionItems.count > 0 { // snapshot.appendSections([.connections]) // snapshot.appendItems(connectionItems, toSection: .connections) // } // // if chatItems.count > 0 { // snapshot.appendSections([.chats]) // snapshot.appendItems(chatItems, toSection: .chats) // } // // return snapshot // }.eraseToAnyPublisher() // } // // var badgeCountPublisher: AnyPublisher<Int, Never> { // Publishers.CombineLatest( // session.contacts(.received), // session.groups(.pending) // ) // .map { $0.0.count + $0.1.count } // .eraseToAnyPublisher() // } private var cancellables = Set<AnyCancellable>() private let searchSubject = CurrentValueSubject<String, Never>("") // private let chatsSubject = CurrentValueSubject<[Chat], Never>([]) private let hudSubject = CurrentValueSubject<HUDStatus, Never>(.none) init() { // Publishers.CombineLatest( // session.singleChats(.all), // session.groupChats(.accepted) // ).map { // let groups = $0.1.map(Chat.group) // let chats = $0.0.map(Chat.contact) // return (chats + groups).sorted { $0.orderingDate > $1.orderingDate } // } // .sink { [unowned self] in chatsSubject.send($0) } // .store(in: &cancellables) } func updateSearch(query: String) { searchSubject.send(query) } func leave(_ group: Group) { hudSubject.send(.on(nil)) do { try session.leave(group: group) try session.dbManager.deleteMessages(.init(chat: .group(group.id))) hudSubject.send(.none) } catch { hudSubject.send(.error(.init(with: error))) } } func clear(_ contact: Contact) { _ = try? session.dbManager.deleteMessages(.init(chat: .direct(session.myId, contact.id))) } }