ursus
09/29/2018, 5:04 PMclass SyncManager(
private val syncer: Syncer,
private val appVisibilityManager: AppVisibilityManager,
private val authTokenManager: AuthTokenManager) {
private val manualTriggerRelay = PublishRelay.create<Unit>()
private val eventsRelay = BehaviorRelay.createDefault<Event>(Event.Idle)
val eventsObservable: Observable<Event>
get() = eventsRelay.distinctUntilChanged()
fun init() {
// When logged in, and in foreground, or manual, sync all data
syncTriggeredObservable()
.flatMapDrop {
syncObservable()
.subscribeOn(Schedulers.single())
}
.throwingSubscribe(eventsRelay)
// When logged out, clear all data
authTokenManager.tokenObservable
.filter { it.isEmpty() }
.flatMapCompletable {
Completable.fromAction { syncer.deleteAll() }
}
.subscribeOn(Schedulers.single())
.throwingSubscribe { }
}
fun sync() = manualTriggerRelay.accept(Unit)
private fun syncTriggeredObservable(): Observable<Unit> {
return Observables
.combineLatest(
authTokenManager.tokenObservable.map { it.isNotEmpty() },
appVisibilityManager.inForegroundObservable,
manualTriggerRelay.startWith(Unit))
{ hasToken, inForeground, _ -> hasToken && inForeground }
.filter { it }
.map { Unit }
}
private fun syncObservable(): Observable<Event> {
return Observable
.fromCallable {
syncer.syncAll()
}
.emitEvents(
{ Event.Started },
{ Event.Success },
{ Event.Error }
)
.endWith(Event.Idle)
}
sealed class Event {
object Idle : Event()
object Started : Event()
object Success : Event()
object Error : Event()
}
}
class App {
onCreate() {
SyncManager(...).init()
}
}