Skip to content

Commit

Permalink
Fix part oppia#632: Replace current recyclerview implementation with …
Browse files Browse the repository at this point in the history
…BindableAdapter usage. (oppia#641)

* working on topic practice.

* reverted

* updated implementation

* Update ContinuePlayingFragmentPresenter.kt

* Update ContinuePlayingFragmentPresenter.kt

* Update ContinuePlayingItemViewModel.kt

* Delete OngoingListAdapter.kt

* nit change

* Update ContinuePlayViewModel.kt

* fixed nit
  • Loading branch information
veena14cs authored and PrarabdhGarg committed Feb 12, 2020
1 parent efd93c9 commit d9d4c8a
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 135 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.oppia.app.home.continueplaying

import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import org.oppia.app.R
import org.oppia.app.model.OngoingStoryList
import org.oppia.domain.topic.TopicListController
import org.oppia.util.data.AsyncResult
import javax.inject.Inject

// TODO(#297): Add download status information to promoted-story-card.

/** [ViewModel] for displaying a promoted story. */
class ContinuePlayViewModel @Inject constructor(
private val fragment: Fragment,
private val topicListController: TopicListController
) : ContinuePlayingItemViewModel() {

private val itemList: MutableList<ContinuePlayingItemViewModel> = ArrayList()

private val ongoingStoryListSummaryResultLiveData: LiveData<AsyncResult<OngoingStoryList>> by lazy {
topicListController.getOngoingStoryList()
}

val ongoingStoryLiveData: LiveData<List<ContinuePlayingItemViewModel>>by lazy {
Transformations.map(ongoingStoryListSummaryResultLiveData, ::processOngoingStoryList)
}

private fun processOngoingStoryList(ongoingStoryList: AsyncResult<OngoingStoryList>): List<ContinuePlayingItemViewModel> {
if (ongoingStoryList.isSuccess()) {
if (ongoingStoryList.getOrThrow().recentStoryList.isNotEmpty()) {
val recentSectionTitleViewModel =
SectionTitleViewModel(fragment.getString(R.string.ongoing_story_last_week), false)
itemList.add(recentSectionTitleViewModel)
for (promotedStory in ongoingStoryList.getOrThrow().recentStoryList) {
val ongoingStoryViewModel = OngoingStoryViewModel(promotedStory, fragment as OngoingStoryClickListener)
itemList.add(ongoingStoryViewModel)
}
}

if (ongoingStoryList.getOrThrow().olderStoryList.isNotEmpty()) {
val showDivider = itemList.isNotEmpty()
val olderSectionTitleViewModel =
SectionTitleViewModel(fragment.getString(R.string.ongoing_story_last_month), showDivider)
itemList.add(olderSectionTitleViewModel)
for (promotedStory in ongoingStoryList.getOrThrow().olderStoryList) {
val ongoingStoryViewModel = OngoingStoryViewModel(promotedStory, fragment as OngoingStoryClickListener)
itemList.add(ongoingStoryViewModel)
}
}
}
return itemList
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@ import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.Transformations
import org.oppia.app.R
import org.oppia.app.databinding.ContinuePlayingFragmentBinding
import org.oppia.app.databinding.OngoingStoryCardBinding
import org.oppia.app.databinding.SectionTitleBinding
import org.oppia.app.fragment.FragmentScope
import org.oppia.app.home.RouteToExplorationListener
import org.oppia.app.model.OngoingStoryList
import org.oppia.app.model.PromotedStory
import org.oppia.app.recyclerview.BindableAdapter
import org.oppia.app.viewmodel.ViewModelProvider
import org.oppia.domain.exploration.ExplorationDataController
import org.oppia.domain.topic.TopicListController
import org.oppia.util.data.AsyncResult
import org.oppia.util.logging.Logger
import javax.inject.Inject
Expand All @@ -27,71 +26,56 @@ class ContinuePlayingFragmentPresenter @Inject constructor(
private val fragment: Fragment,
private val logger: Logger,
private val explorationDataController: ExplorationDataController,
private val topicListController: TopicListController
private val viewModelProvider: ViewModelProvider<ContinuePlayViewModel>
) {

private val routeToExplorationListener = activity as RouteToExplorationListener

private lateinit var binding: ContinuePlayingFragmentBinding

private lateinit var ongoingListAdapter: OngoingListAdapter

private val itemList: MutableList<ContinuePlayingItemViewModel> = ArrayList()

fun handleCreateView(inflater: LayoutInflater, container: ViewGroup?): View? {
binding = ContinuePlayingFragmentBinding.inflate(inflater, container, /* attachToRoot= */ false)

val viewModel = getContinuePlayModel()
binding.continuePlayingToolbar.setNavigationOnClickListener {
(activity as ContinuePlayingActivity).finish()
}

ongoingListAdapter = OngoingListAdapter(itemList)

binding.ongoingStoryRecyclerView.apply {
adapter = ongoingListAdapter
adapter = createRecyclerViewAdapter()
}
binding.let {
it.lifecycleOwner = fragment
it.viewModel = viewModel
}

subscribeToOngoingStoryList()

return binding.root
}

private val ongoingStoryListSummaryResultLiveData: LiveData<AsyncResult<OngoingStoryList>> by lazy {
topicListController.getOngoingStoryList()
}

private fun subscribeToOngoingStoryList() {
getAssumedSuccessfulOngoingStoryList().observe(fragment, Observer<OngoingStoryList> { it ->
if (it.recentStoryCount > 0) {
val recentSectionTitleViewModel =
SectionTitleViewModel(activity.getString(R.string.ongoing_story_last_week), false)
itemList.add(recentSectionTitleViewModel)
for (promotedStory in it.recentStoryList) {
val ongoingStoryViewModel = OngoingStoryViewModel(promotedStory, fragment as OngoingStoryClickListener)
itemList.add(ongoingStoryViewModel)
}
}

if (it.olderStoryCount > 0) {
val showDivider = itemList.isNotEmpty()
val olderSectionTitleViewModel =
SectionTitleViewModel(activity.getString(R.string.ongoing_story_last_month), showDivider)
itemList.add(olderSectionTitleViewModel)
for (promotedStory in it.olderStoryList) {
val ongoingStoryViewModel = OngoingStoryViewModel(promotedStory, fragment as OngoingStoryClickListener)
itemList.add(ongoingStoryViewModel)
private fun createRecyclerViewAdapter(): BindableAdapter<ContinuePlayingItemViewModel> {
return BindableAdapter.MultiTypeBuilder
.newBuilder<ContinuePlayingItemViewModel, ContinuePlayingItemViewModel.ViewType> { viewModel ->
when (viewModel) {
is SectionTitleViewModel -> ContinuePlayingItemViewModel.ViewType.VIEW_TYPE_SECTION_TITLE_TEXT
is OngoingStoryViewModel -> ContinuePlayingItemViewModel.ViewType.VIEW_TYPE_SECTION_STORY_ITEM
else -> throw IllegalArgumentException("Encountered unexpected view model: $viewModel")
}
}
ongoingListAdapter.notifyDataSetChanged()
})
.registerViewDataBinder(
viewType = ContinuePlayingItemViewModel.ViewType.VIEW_TYPE_SECTION_TITLE_TEXT,
inflateDataBinding = SectionTitleBinding::inflate,
setViewModel = SectionTitleBinding::setViewModel,
transformViewModel = { it as SectionTitleViewModel }
)
.registerViewDataBinder(
viewType = ContinuePlayingItemViewModel.ViewType.VIEW_TYPE_SECTION_STORY_ITEM,
inflateDataBinding = OngoingStoryCardBinding::inflate,
setViewModel = OngoingStoryCardBinding::setViewModel,
transformViewModel = { it as OngoingStoryViewModel }
)
.build()
}

private fun getAssumedSuccessfulOngoingStoryList(): LiveData<OngoingStoryList> {
// If there's an error loading the data, assume the default.
return Transformations.map(ongoingStoryListSummaryResultLiveData) { it.getOrDefault(OngoingStoryList.getDefaultInstance()) }
private fun getContinuePlayModel(): ContinuePlayViewModel {
return viewModelProvider.getForFragment(fragment, ContinuePlayViewModel::class.java)
}

fun onOngoingStoryClicked(promotedStory: PromotedStory) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@ package org.oppia.app.home.continueplaying

import org.oppia.app.viewmodel.ObservableViewModel

/** The root [ViewModel] for all individual items that may be displayed in continue-playing fragment recycler view. */
abstract class ContinuePlayingItemViewModel: ObservableViewModel()
/** The root [ViewModel] for all individual items that may be displayed in [ContinuePlayingFragment] [RecyclerView]. */
abstract class ContinuePlayingItemViewModel : ObservableViewModel() {
enum class ViewType {
VIEW_TYPE_SECTION_TITLE_TEXT,
VIEW_TYPE_SECTION_STORY_ITEM
}
}

This file was deleted.

8 changes: 8 additions & 0 deletions app/src/main/res/layout/continue_playing_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

<variable
name="viewModel"
type="org.oppia.app.home.continueplaying.ContinuePlayViewModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
Expand Down Expand Up @@ -47,6 +54,7 @@
android:paddingTop="8dp"
android:paddingBottom="172dp"
android:scrollbars="none"
app:data="@{viewModel.ongoingStoryLiveData}"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

<View
Expand Down

0 comments on commit d9d4c8a

Please sign in to comment.