124 lines
3.6 KiB
Swift
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
|
|
}
|
|
}
|