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 ...@@ -9,10 +9,11 @@ import chat.rocket.android.chatrooms.adapter.RoomMapper
import chat.rocket.android.chatrooms.domain.FetchChatRoomsInteractor import chat.rocket.android.chatrooms.domain.FetchChatRoomsInteractor
import chat.rocket.android.chatrooms.infrastructure.ChatRoomsRepository import chat.rocket.android.chatrooms.infrastructure.ChatRoomsRepository
import chat.rocket.android.server.infraestructure.ConnectionManager import chat.rocket.android.server.infraestructure.ConnectionManager
import chat.rocket.android.util.livedata.TransformedLiveData
import chat.rocket.core.internal.realtime.socket.model.State import chat.rocket.core.internal.realtime.socket.model.State
import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.newSingleThreadContext
import me.henrytao.livedataktx.distinct import me.henrytao.livedataktx.distinct
import me.henrytao.livedataktx.map
import me.henrytao.livedataktx.nonNull import me.henrytao.livedataktx.nonNull
import timber.log.Timber import timber.log.Timber
...@@ -23,30 +24,40 @@ class ChatRoomsViewModel( ...@@ -23,30 +24,40 @@ class ChatRoomsViewModel(
private val mapper: RoomMapper private val mapper: RoomMapper
) : ViewModel() { ) : ViewModel() {
private val ordering: MutableLiveData<ChatRoomsRepository.Order> = MutableLiveData() private val ordering: MutableLiveData<ChatRoomsRepository.Order> = MutableLiveData()
private val runContext = newSingleThreadContext("chat-rooms-view-model")
init { init {
ordering.value = ChatRoomsRepository.Order.ACTIVITY ordering.value = ChatRoomsRepository.Order.ACTIVITY
} }
fun getChatRooms(): LiveData<List<ItemHolder<*>>> { fun getChatRooms(): LiveData<List<ItemHolder<*>>> {
// TODO - add a loading status...
launch { interactor.refreshChatRooms() }
return Transformations.switchMap(ordering) { order -> return Transformations.switchMap(ordering) { order ->
Timber.d("Querying rooms for order: $order") Timber.d("Querying rooms for order: $order")
val grouped = order == ChatRoomsRepository.Order.GROUPED_ACTIVITY val grouped = order == ChatRoomsRepository.Order.GROUPED_ACTIVITY
|| order == ChatRoomsRepository.Order.GROUPED_NAME || order == ChatRoomsRepository.Order.GROUPED_NAME
repository.getChatRooms(order).nonNull() val roomData = repository.getChatRooms(order).nonNull().distinct()
.distinct() TransformedLiveData(runContext, roomData) { rooms ->
.map { rooms -> rooms?.let {
Timber.d("Mapping rooms to items: $rooms")
mapper.map(rooms, grouped) mapper.map(rooms, grouped)
} }
}.nonNull()
} }
} }
fun getStatus(): MutableLiveData<State> { 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) { fun setOrdering(order: ChatRoomsRepository.Order) {
......
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