You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

214 lines
9.9 KiB

//
// HealthHomeViewModels.swift
// FireBoltt
//
// Created by Sheldon on 2021/9/19.
// Copyright © 2021 Sheldon. All rights reserved.
//
import UIKit
class HealthHomeViewModels: ViewModel {
//
let userIcon = BehaviorRelay<UIImage?>(value: R.image.user_Icon_header())
let userNickname = BehaviorRelay<String?>(value: nil)
//
let relay = BehaviorRelay<[HealthSection]>(value: [])
///
private var userInfo = BehaviorRelay<UserInfo?>(value: nil)
private var sleepHeartCellVM: SleepHeartCellViewModels?
/// DFU
let dfuDeviceUpgrate = PublishSubject<FirmwareUpdateViewModels>()
private var tempDisposeBag = DisposeBag()
override init() {
super.init()
//
var currenDay = DateClass.todayString()
kNotificationCenter.rx.notification(UIApplication.significantTimeChangeNotification)
.subscribe(onNext: { notication in
//
let newDay = DateClass.todayString()
if currenDay != newDay {
currenDay = newDay
kNotificationCenter.post(name: NSNotification.Name(rawValue: DateChangeFireBoltt), object: nil)
}
})
.disposed(by: rx.disposeBag)
fbloadDefaultData()
fbloadHealthData()
monitor()
}
private func fbloadDefaultData() {
userInfo.accept(UserDefaultsManagerFrieBoltt.getUserInfo())
userInfo.flatMapLatest({ (userInfo) -> Observable<UIImage?> in
return Observable.just(userInfo?.avatarImg)
})
.filter { $0 != nil }
.bind(to: userIcon)
.disposed(by: rx.disposeBag)
userInfo.flatMapLatest({ (userInfo) -> Observable<String?> in
return Observable.just(userInfo?.nickname)
})
.bind(to: userNickname)
.disposed(by: rx.disposeBag)
}
private func fbloadHealthData() {
tempDisposeBag = DisposeBag()
var items: [HealthSectionItem] = []
//
var defaultTypes: [HealthType] = [.step,]
if let adapterInfo = UserDefaultsManagerFrieBoltt.getDeviceInfo()?.adapterInfo {
if adapterInfo.sleep { defaultTypes.insert(.sleep, at: 1) }
if adapterInfo.heartRate { defaultTypes.append(.heartRate) }
// if adapterInfo.bodyTemperature { defaultTypes.append(.temperature) }
// if adapterInfo.bloodPressure { defaultTypes.append(.bloodPressure) }
// if adapterInfo.bloodOxygen { defaultTypes.append(.bloodOxygen) }
// defaultTypes.append(.temperature)
// defaultTypes.append(.bloodPressure)
// defaultTypes.append(.bloodOxygen)
}
//
defaultTypes.forEach { type in
var item: HealthSectionItem
if type == .step {
let stepCellVM = StepCellViewModels()
let stepItem = HealthSectionItem.stepItem(viewModel: stepCellVM)
item = stepItem
//
BluetoothService.shared.realStep
.bind(to: stepCellVM.realStepModel)
.disposed(by: tempDisposeBag)
}else {
let healthItemCellVM = HealthCellViewModels(type: type)
let healthItem = HealthSectionItem.healthItem(viewModel: healthItemCellVM)
item = healthItem
//
switch type {
case .sleep:
BluetoothService.shared.sleepUpdate
.subscribe(onNext: { _ in
DataBaseManagerFireBoltt.shared.fbquerySleepModel(dataDate: DateClass.todayString(), queryType: .day) { [weak self] (model) in
guard let sleepModel = model.first as? SleepModel else { return }
let sleep = String(format: "%.1f", Float(sleepModel.totalSleepDuration) / 60.0)
let progress = Float(sleepModel.totalSleepDuration) / Float(self?.userInfo.value?.sleepTarget ?? 480)
healthItemCellVM.value.accept(sleep)
healthItemCellVM.progress.accept(progress)
}
})
.disposed(by: tempDisposeBag)
userInfo.flatMapLatest { (userInfo) -> Observable<String> in
let sleepTarget = String(format: "%.1f", Float(userInfo?.sleepTarget ?? 480) / 60.0)
let value = MultiLanguageKey_FB.sleepTargetFB.localized + "" + sleepTarget
return Observable.just(value)
}.bind(to: healthItemCellVM.target)
.disposed(by: tempDisposeBag)
case .heartRate:
BluetoothService.shared.realHeartRate
.flatMapLatest { (heartRate) -> Observable<String> in
let value = heartRate.heartRate == 0 ? "--" : String(heartRate.heartRate)
return Observable.just(value)
}
.bind(to: healthItemCellVM.value)
.disposed(by: tempDisposeBag)
case .temperature:
BluetoothService.shared.realTemperature
.flatMapLatest { (temperature) -> Observable<String> in
let value = temperature.temperature == 0 ? "--" : String(format: "%.1f", temperature.temperature)
return Observable.just(value)
}
.bind(to: healthItemCellVM.value)
.disposed(by: tempDisposeBag)
case .bloodPressure:
BluetoothService.shared.realBloodPressure
.flatMapLatest { (model) -> Observable<String> in
let value = model.sbp == 0 ? "--" : String(format: "%ld/%ld", model.sbp, model.dbp)
return Observable.just(value)
}
.bind(to: healthItemCellVM.value)
.disposed(by: tempDisposeBag)
case .bloodOxygen:
BluetoothService.shared.realBloodOxygen
.flatMapLatest { (model) -> Observable<String> in
let value = model.bloodOxygen == 0 ? "--" : String(model.bloodOxygen) + "%"
return Observable.just(value)
}
.bind(to: healthItemCellVM.value)
.disposed(by: tempDisposeBag)
default: break
}
}
items.append(item)
}
// Item(Item,)
// let tempItems = items[1...items.count - 1]
// let totalRow = tempItems.count/2 + tempItems.count%2
// for i in (0..<totalRow) {
// items.insert(HealthSectionItem.blankItem, at: 1 + i * 4)
// var endIndex = 4 + i * 4
// if endIndex > items.count {
// endIndex = items.count
// }
// items.insert(HealthSectionItem.blankItem, at: endIndex)
// }
items.insert(HealthSectionItem.blankItem, at: 1)
let section = HealthSection.health(title: "", items: items)
relay.accept([section])
}
private func monitor() {
//
kNotificationCenter.rx.notification(Notification.Name(rawValue: UserInfoUpdateFireBoltt))
.flatMapLatest({ _ -> Observable<UserInfo?> in
return Observable.just(UserDefaultsManagerFrieBoltt.getUserInfo())
})
.bind(to: userInfo)
.disposed(by: rx.disposeBag)
//
BluetoothService.shared.syncState.skip(1)
.subscribe(onNext: { [weak self] (syncState) in
guard let `self` = self else { return }
switch syncState {
case .normal:
DataBaseManagerFireBoltt.shared.fbquerySleepModel(dataDate: DateClass.getCurrentTimeStr(formatStr: "yyyy-MM-dd"), queryType: .day) { (model) in
guard let sleepModel = model.first as? SleepModel else { return }
let sleep = String(format: "%.1f", Float(sleepModel.totalSleepDuration) / 60.0)
let progress = Float(sleepModel.totalSleepDuration) / Float(self.userInfo.value?.sleepTarget ?? 480)
self.sleepHeartCellVM?.sleep.accept(sleep)
self.sleepHeartCellVM?.sleepProgress.accept(progress)
}
default: break
}
})
.disposed(by: rx.disposeBag)
//
kNotificationCenter.rx.notification(Notification.Name(rawValue: DateChangeFireBoltt))
.subscribe(onNext: { [weak self] notication in
guard let `self` = self else { return }
self.fbloadHealthData()
})
.disposed(by: rx.disposeBag)
//
BluetoothService.shared.adapterInfoUpdate
.subscribe(onNext: { [weak self] _ in
guard let `self` = self else { return }
self.fbloadHealthData()
})
.disposed(by: rx.disposeBag)
// DFU
kNotificationCenter.rx.notification(Notification.Name(rawValue: BluetoothNotificationAtDFUConnectSuccess))
.subscribe(onNext: { [weak self] _ in
guard let `self` = self else { return }
let viewModel = FirmwareUpdateViewModels(isDFU: true)
self.dfuDeviceUpgrate.onNext(viewModel)
})
.disposed(by: rx.disposeBag)
}
}