blob: e66e777717f31cc422ebf0d67754e216c48011be [file] [log] [blame]
package com.airbnb.lottie.samples
import androidx.fragment.app.FragmentActivity
import com.airbnb.epoxy.EpoxyController
import com.airbnb.lottie.samples.model.AnimationData
import com.airbnb.lottie.samples.model.AnimationResponse
import com.airbnb.lottie.samples.model.CompositionArgs
import com.airbnb.lottie.samples.views.loadingView
import com.airbnb.lottie.samples.views.lottiefilesTabBar
import com.airbnb.lottie.samples.views.marquee
import com.airbnb.lottie.samples.views.searchInputItemView
import com.airbnb.mvrx.*
data class LottiefilesState(
val mode: LottiefilesMode = LottiefilesMode.Recent,
val items: List<AnimationData> = emptyList(),
val request: Async<AnimationResponse> = Uninitialized,
val query: String = ""
) : MvRxState
class LottiefilesViewModel(
initialState: LottiefilesState,
private val service: LottiefilesService) : MvRxViewModel<LottiefilesState>(initialState
) {
init {
selectSubscribe(LottiefilesState::mode) { fetchMoreItems() }
}
fun fetchMoreItems() = withState { state ->
if (state.request is Loading) return@withState
val page = (state.request()?.currentPage ?: -1) + 1
if (state.request()?.lastPage == page && page > 0) return@withState
when (state.mode) {
LottiefilesMode.Recent -> service.getRecent(page)
LottiefilesMode.Popular -> service.getPopular(page)
LottiefilesMode.Search -> service.search(state.query)
}.execute { copy(request = it, items = items + (it()?.data ?: emptyList())) }
}
fun setMode(mode: LottiefilesMode, query: String = "") = setState {
if (this.mode == mode && mode != LottiefilesMode.Search) return@setState this
if (this.mode == mode && mode == LottiefilesMode.Search && this.query == query) return@setState this
copy(mode = mode, request = Uninitialized, items = emptyList(), query = query)
}
companion object : MvRxViewModelFactory<LottiefilesState> {
@JvmStatic
override fun create(activity: FragmentActivity, state: LottiefilesState): LottiefilesViewModel {
val service = (activity.applicationContext as LottieApplication).lottiefilesService
return LottiefilesViewModel(state, service)
}
}
}
class LottiefilesFragment : BaseEpoxyFragment() {
private val viewModel: LottiefilesViewModel by fragmentViewModel()
override fun EpoxyController.buildModels() = withState(viewModel) { state ->
marquee {
id("lottiefiles")
title(R.string.lottiefiles)
subtitle(R.string.lottiefiles_airbnb)
}
lottiefilesTabBar {
id("mode")
mode(state.mode)
recentClickListener { _ -> viewModel.setMode(LottiefilesMode.Recent) }
popularClickListener { _ -> viewModel.setMode(LottiefilesMode.Popular) }
searchClickListener { _ -> viewModel.setMode(LottiefilesMode.Search) }
}
if (state.mode == LottiefilesMode.Search) {
searchInputItemView {
id("search")
searchClickListener { viewModel.setMode(LottiefilesMode.Search, it) }
}
}
state.items.forEach {
val args = CompositionArgs(animationData = it)
animationItemView {
id(it.id)
animationData(it)
clickListener { _ ->
startActivity(PlayerActivity.intent(requireContext(), args))
}
onBind { _, _, _ -> viewModel.fetchMoreItems() }
}
}
if (state.request is Loading) {
loadingView {
id("loading")
onBind { _, _, _ -> viewModel.fetchMoreItems() }
}
}
}
}