jsdw_ios/QuickLocation/Section/Home/TodayTrackDetail/TodayTrackDetailViewModel.s...

124 lines
3.6 KiB
Swift

//
// TodayTrackDetailViewModel.swift
// QuickLocation
//
import Foundation
import RxSwift
import RxCocoa
import SwiftDate
final class TodayTrackDetailViewModel {
struct DateItem {
let date: Date
let title: String
let key: String
}
let members: [GroupMemberModel]
let selectedMemberId: BehaviorRelay<String>
let selectedDateKey: BehaviorRelay<String>
let stayPoints = BehaviorRelay<[StayPoint]>(value: [])
let trajectoryPoints = BehaviorRelay<[TrackPoint]>(value: [])
let isEmpty = BehaviorRelay<Bool>(value: true)
let loading = BehaviorRelay<Bool>(value: false)
private let disposeBag = DisposeBag()
let dateItems: [DateItem]
init(members: [GroupMemberModel], selectedUserId: String, initialDate: Date = Date()) {
self.members = members
self.dateItems = Self.makeDateItems(around: initialDate)
self.selectedMemberId = BehaviorRelay(value: selectedUserId)
self.selectedDateKey = BehaviorRelay(value: Self.dayKey(initialDate))
bindSelection()
reloadPlayback()
}
private func bindSelection() {
selectedMemberId
.asObservable()
.skip(1)
.subscribe(onNext: { [weak self] _ in
self?.reloadPlayback()
})
.disposed(by: disposeBag)
selectedDateKey
.asObservable()
.skip(1)
.subscribe(onNext: { [weak self] _ in
self?.reloadPlayback()
})
.disposed(by: disposeBag)
}
private func reloadPlayback() {
let userId = selectedMemberId.value
let dateKey = selectedDateKey.value
loadPlayback(userId: userId, dateKey: dateKey)
}
private func loadPlayback(userId: String, dateKey: String) {
if userId.isEmpty {
clearPlayback()
return
}
loading.accept(true)
DrivingService.playback(user_id: userId, date: dateKey)
.observe(on: MainScheduler.instance)
.subscribe(onNext: { [weak self] response in
self?.applyPlayback(response)
}, onError: { [weak self] _ in
self?.clearPlayback()
})
.disposed(by: disposeBag)
}
private func applyPlayback(_ response: ScheduleRecordListResponse) {
let trips = response.list
let stays = trips.flatMap { $0.stay_points }.sorted { lhs, rhs in
lhs.start_time > rhs.start_time
}
let path = trips.flatMap { $0.trajectory_path }
stayPoints.accept(stays)
trajectoryPoints.accept(path)
isEmpty.accept(stays.isEmpty && path.isEmpty)
loading.accept(false)
}
private func clearPlayback() {
stayPoints.accept([])
trajectoryPoints.accept([])
isEmpty.accept(true)
loading.accept(false)
}
private static func dayKey(_ date: Date) -> String {
date.toFormat("yyyy-MM-dd")
}
private static func makeDateItems(around date: Date) -> [DateItem] {
let calendar = Calendar.current
let today = calendar.startOfDay(for: date)
var items: [DateItem] = []
for offset in -4...0 {
guard let day = calendar.date(byAdding: .day, value: offset, to: today) else {
continue
}
let title: String
switch offset {
case 0:
title = "今天"
case -1:
title = "昨天"
default:
title = day.toFormat("MM-dd")
}
items.append(DateItem(date: day, title: title, key: dayKey(day)))
}
return items
}
}