Commit 0ab68898 authored by Lucio Maciel's avatar Lucio Maciel

Add a TransformedLiveData that do transformations on the background

parent 2651841e
......@@ -9,10 +9,11 @@ import chat.rocket.android.chatrooms.adapter.RoomMapper
import chat.rocket.android.chatrooms.domain.FetchChatRoomsInteractor
import chat.rocket.android.chatrooms.infrastructure.ChatRoomsRepository
import chat.rocket.android.server.infraestructure.ConnectionManager
import chat.rocket.android.util.livedata.TransformedLiveData
import chat.rocket.core.internal.realtime.socket.model.State
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.newSingleThreadContext
import me.henrytao.livedataktx.distinct
import me.henrytao.livedataktx.map
import me.henrytao.livedataktx.nonNull
import timber.log.Timber
......@@ -23,33 +24,43 @@ class ChatRoomsViewModel(
private val mapper: RoomMapper
) : ViewModel() {
private val ordering: MutableLiveData<ChatRoomsRepository.Order> = MutableLiveData()
private val runContext = newSingleThreadContext("chat-rooms-view-model")
init {
ordering.value = ChatRoomsRepository.Order.ACTIVITY
}
fun getChatRooms(): LiveData<List<ItemHolder<*>>> {
// TODO - add a loading status...
launch { interactor.refreshChatRooms() }
return Transformations.switchMap(ordering) { order ->
Timber.d("Querying rooms for order: $order")
val grouped = order == ChatRoomsRepository.Order.GROUPED_ACTIVITY
|| order == ChatRoomsRepository.Order.GROUPED_NAME
repository.getChatRooms(order).nonNull()
.distinct()
.map { rooms ->
Timber.d("Mapping rooms to items: $rooms")
mapper.map(rooms, grouped)
}
val roomData = repository.getChatRooms(order).nonNull().distinct()
TransformedLiveData(runContext, roomData) { rooms ->
rooms?.let {
mapper.map(rooms, grouped)
}
}.nonNull()
}
}
fun getStatus(): MutableLiveData<State> {
return connectionManager.statusLiveData.nonNull().distinct()
return Transformations.map(connectionManager.statusLiveData.nonNull().distinct()) { state ->
if (state is State.Connected) {
// TODO - add a loading status...
fetchRooms()
}
state
}.nonNull()
}
private fun fetchRooms() {
launch {
interactor.refreshChatRooms()
}
}
fun setOrdering(order: ChatRoomsRepository.Order) {
ordering.value = order
}
}
\ No newline at end of file
}
package chat.rocket.android.util.livedata
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.withContext
import timber.log.Timber
import kotlin.coroutines.experimental.CoroutineContext
class TransformedLiveData<Source, Output>(
private val runContext: CoroutineContext = CommonPool,
private val source: LiveData<Source>,
private val transformation: (Source?) -> Output?)
: LiveData<Output>() {
private var job: Job? = null
private val observer = Observer<Source> { source ->
job?.cancel()
job = launch(runContext) {
transformation(source)?.let { transformed ->
withContext(UI) {
value = transformed
}
}
}
}
override fun onActive() {
Timber.d("Attaching observer")
source.observeForever(observer)
}
override fun onInactive() {
Timber.d("Detaching observer")
job?.cancel()
source.removeObserver(observer)
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment