Bitwarden-app-android-iphon.../src/watchOS/bitwarden/bitwarden WatchKit Extension/ViewModels/CipherListViewModel.swift

115 lines
3.5 KiB
Swift

import Combine
import CoreData
import Foundation
class CipherListViewModel : ObservableObject {
var cipherService: CipherServiceProtocol
var watchConnectivityManager = WatchConnectivityManager.shared
@Published private var ciphers: [Cipher] = []
@Published var filteredCiphers: [Cipher] = []
@Published var updateHack:Bool = false
@Published var showingSheet = false
@Published var currentState = BWState.valid
@Published var user: User?
@Published var searchTerm: String = ""
var debugText: String? = nil
private var subscriber: AnyCancellable?
init(_ cipherService: CipherServiceProtocol){
self.cipherService = cipherService
subscriber = watchConnectivityManager.watchConnectivitySubject.sink { completion in
print("WCM subject: \(completion)")
} receiveValue: { value in
self.debugText = value.debugText
self.checkStateAndFetch(value.state)
}
Publishers.CombineLatest($ciphers, $searchTerm)
.map { allCiphers, searchTerm in
var returnCiphers = allCiphers.filter { c in
self.cipherContains(c, searchTerm)
}
// WORKAROUND: To display 0 search results
if !searchTerm.isEmpty, returnCiphers.count == 0 {
returnCiphers.append(Cipher(id: "-1", name: "NoItemsFound", login: Login(username: "", totp: "", uris: nil)))
}
if searchTerm.isEmpty {
self.updateHack = !self.updateHack
}
return returnCiphers
}
.assign(to: &$filteredCiphers)
}
func checkStateAndFetch(_ state: BWState? = nil) {
guard checkDeviceOwnerAuth() else {
return
}
StateService.shared.checkIntegrity()
user = StateService.shared.getUser()
currentState = state ?? StateService.shared.currentState
showingSheet = currentState != .valid
if state != nil {
return
}
guard currentState == .valid else {
ciphers = []
return
}
self.fetchCiphers()
}
func fetchCiphers() {
let c = cipherService.fetchCiphers(user?.id)
DispatchQueue.main.async {
self.ciphers = c
}
}
func cipherContains(_ cipher: Cipher, _ searchText: String) -> Bool {
if searchTerm.isEmpty {
return true
}
if(cipher.name?.lowercased().contains(searchTerm.lowercased()) ?? false) {
return true
}
if (cipher.login.username?.lowercased().contains(searchTerm.lowercased()) ?? false) {
return true
}
return false
}
func checkDeviceOwnerAuth() -> Bool {
guard KeychainHelper.standard.hasDeviceOwnerAuth() else {
currentState = .needDeviceOwnerAuth
showingSheet = true
StateService.shared.lackedDeviceOwnerAuthLastTime = true
return false
}
if StateService.shared.lackedDeviceOwnerAuthLastTime {
watchConnectivityManager.triggerSync()
StateService.shared.lackedDeviceOwnerAuthLastTime = false
}
return true
}
}