Last active
August 16, 2018 18:54
-
-
Save erkattak/7741a4e201c6366cf34d17bec0c87911 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.oddnetworks.oddnexttv.ui | |
import android.accounts.Account | |
import android.content.Intent | |
import android.graphics.drawable.Drawable | |
import android.os.Bundle | |
import androidx.leanback.app.BackgroundManager | |
import androidx.leanback.app.BrowseSupportFragment | |
import androidx.leanback.widget.* | |
import androidx.core.content.ContextCompat | |
import com.oddnetworks.oddnexttv.BuildConfig | |
import com.oddnetworks.oddnexttv.R | |
import com.oddnetworks.oddnexttv.lib.Constants | |
import com.oddnetworks.oddnexttv.lib.Utils | |
import com.oddnetworks.oddnexttv.presenters.CardPresenter | |
import com.oddnetworks.oddnexttv.presenters.SideInfoCardPresenter | |
import io.oddworks.device.model.OddCollection | |
import io.oddworks.device.model.OddVideo | |
import io.oddworks.device.model.OddView | |
import io.oddworks.device.model.common.OddResource | |
import io.oddworks.device.model.common.OddResourceType | |
import io.oddworks.device.request.OddRequest | |
import io.oddworks.device.request.RxOddCall | |
import rx.Observable | |
import rx.android.schedulers.AndroidSchedulers | |
import rx.schedulers.Schedulers | |
import timber.log.Timber | |
const val LARGE_CARD_WIDTH = 659 | |
const val LARGE_CARD_HEIGHT = 371 | |
class MainFragment : BrowseSupportFragment() { | |
private lateinit var rowsAdapter : ArrayObjectAdapter | |
private var backgroundManager: BackgroundManager? = null | |
private var defaultBackground: Drawable? = null | |
private val account : Account? | |
get() { | |
return (activity as ActivityBase).account | |
} | |
override fun onActivityCreated(savedInstanceState: Bundle?) { | |
super.onActivityCreated(savedInstanceState) | |
prepareBackgroundManager() | |
loadUIElements() | |
loadData() | |
setEventListeners() | |
rowsAdapter = ArrayObjectAdapter(ListRowPresenter()) | |
adapter = rowsAdapter | |
// don't run entrance transition if fragment is restored. | |
if (savedInstanceState == null) { | |
prepareEntranceTransition() | |
} | |
} | |
override fun onResume() { | |
super.onResume() | |
backgroundManager?.drawable = defaultBackground | |
} | |
private fun prepareBackgroundManager() { | |
backgroundManager = BackgroundManager.getInstance(activity) | |
backgroundManager?.attach(requireActivity().window) | |
defaultBackground = resources.getDrawable(R.drawable.background, null) | |
backgroundManager?.drawable = defaultBackground | |
} | |
// Load the BrowserFragment UI elements | |
private fun loadUIElements() { | |
headersState = HEADERS_DISABLED | |
isHeadersTransitionOnBackEnabled = true | |
badgeDrawable = ContextCompat.getDrawable(requireActivity(), R.drawable.logo) | |
searchAffordanceColors = SearchOrbView.Colors( | |
ContextCompat.getColor(requireActivity(), R.color.colorPrimaryDark), | |
ContextCompat.getColor(requireActivity(), R.color.colorPrimary)) | |
} | |
private fun loadData() { | |
val oddResourceId = requireActivity().intent.getStringExtra(Constants.INTENT_RESOURCE_ID) | |
val viewObservable = fetchOddView(oddResourceId) | |
val mainCollectionsObservable = viewObservable.flatMap { oddView -> | |
Observable.zip<List<OddCollection>>(fetchMainCollectionEntities(oddView)) { collectionResources -> | |
collectionResources.map { | |
it as OddCollection | |
} | |
} | |
}.defaultIfEmpty(emptyList()) | |
viewObservable.zipWith(mainCollectionsObservable) {oddView, collections -> Pair(oddView, collections)} | |
.subscribeOn(Schedulers.io()) | |
.observeOn(AndroidSchedulers.mainThread()) | |
.subscribe({ (oddView, collections) -> | |
loadRows(oddView, collections) | |
}, { | |
// TODO - handle error? | |
Timber.w("we should definitely handle this error", it) | |
}) | |
} | |
private fun fetchOddView(id: String) : Observable<OddView> { | |
return RxOddCall.observableFrom<OddView> { | |
OddRequest.Builder(requireContext(), OddResourceType.VIEW) | |
.resourceId(id) | |
.account(account) | |
.include(Constants.MAIN_VIEW_RELATIONSHIP_INCLUDE) | |
.build() | |
.enqueueRequest(it) | |
} | |
} | |
private fun fetchMainCollectionEntities(oddView: OddView) : List<Observable<OddCollection>> { | |
val mainItems = oddView.getIncludedByRelationship(Constants.MAIN_VIEW_RELATIONSHIP_MAIN) | |
return mainItems | |
.filter { | |
it.type == OddResourceType.COLLECTION | |
} | |
.map { subCollection -> | |
RxOddCall.observableFrom<OddCollection> { callback -> | |
OddRequest.Builder(requireContext(), OddResourceType.COLLECTION) | |
.resourceId(subCollection.id) | |
.account(account) | |
.include("${OddCollection.RELATIONSHIPS.FEATURED},${OddCollection.RELATIONSHIPS.ENTITIES}") | |
.build() | |
.enqueueRequest(callback) | |
} | |
} | |
} | |
private fun loadRows(oddView: OddView, hydratedCollections: List<OddCollection>) { | |
val rows = mutableListOf<ListRow>() | |
// Resources in the "featured" relationship will be displayed in a | |
// single row at the top of the screen. The cards in that row will | |
// be larger than the resources in subsequent rows. | |
val featuredResources = oddView.getIncludedByRelationship(Constants.MAIN_VIEW_RELATIONSHIP_FEATURED) | |
if (featuredResources.count() > 0) { | |
// use a CardPresenter that's larger | |
val featuredListRowAdapter = ArrayObjectAdapter(CardPresenter(LARGE_CARD_WIDTH, LARGE_CARD_HEIGHT)) | |
val featuredListRow = ListRow(1, null, featuredListRowAdapter) | |
featuredListRowAdapter.setItems(featuredResources.toList(), object: DiffCallback<ListRow>() { | |
override fun areItemsTheSame(oldItem: ListRow, newItem: ListRow): Boolean { | |
return oldItem.id == newItem.id | |
} | |
override fun areContentsTheSame(oldItem: ListRow, newItem: ListRow): Boolean { | |
return oldItem == newItem | |
} | |
}) | |
rows.add(featuredListRow) | |
} | |
val mainResources = oddView.getIncludedByRelationship(Constants.MAIN_VIEW_RELATIONSHIP_MAIN) | |
mainResources.forEachIndexed{ idx, resource -> | |
if (resource is OddCollection) { | |
val collection = hydratedCollections.find { | |
it.id == resource.id | |
} | |
if (collection != null) { | |
val listRow = mapResourceToRow(idx + 1L, collection) | |
listRow?.let { rows.add(it) } | |
} | |
} else { | |
val listRow = mapResourceToRow(idx + 1L, resource) | |
listRow?.let { rows.add(it) } | |
} | |
} | |
rowsAdapter.setItems(rows, object: DiffCallback<ListRow>() { | |
override fun areItemsTheSame(oldItem: ListRow, newItem: ListRow): Boolean { | |
return oldItem.id == newItem.id | |
} | |
override fun areContentsTheSame(oldItem: ListRow, newItem: ListRow): Boolean { | |
return oldItem == newItem | |
} | |
}) | |
startEntranceTransition() | |
} | |
private fun mapResourceToRow(index: Long, oddResource: OddResource): ListRow? { | |
val listRow: ListRow? | |
val listRowAdapter = ArrayObjectAdapter(CardPresenter()) | |
val videoRowAdapter = ArrayObjectAdapter(SideInfoCardPresenter(requireContext())) | |
when (oddResource) { | |
is OddVideo -> { | |
val resources = Utils.newList(oddResource, "") | |
val header = null | |
resources.forEach { | |
videoRowAdapter.add(it) | |
} | |
listRow = ListRow(index, header, videoRowAdapter) | |
} | |
is OddCollection -> { | |
val resources = Utils.newList(oddResource, Constants.COLLECTION_RELATIONSHIP_ENTITIES) | |
val header = HeaderItem(oddResource.title) | |
resources.forEach { | |
listRowAdapter.add(it) | |
} | |
listRow = ListRow(index, header, listRowAdapter) | |
} | |
else -> listRow = null | |
} | |
return listRow | |
} | |
private fun setEventListeners() { | |
if (BuildConfig.ENABLE_SEARCH) { | |
setOnSearchClickedListener { | |
val intent = Intent(activity, SearchActivity::class.java) | |
startActivity(intent) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment