Skip to content

Commit

Permalink
NT-2037: Pagination Error Cell displayed at the same time as the comm…
Browse files Browse the repository at this point in the history
…ents cells (#1286)
  • Loading branch information
Arkariang committed Jun 11, 2021
1 parent b052d4d commit 057876a
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,17 @@ class CommentsActivity :

viewModel.outputs.closeCommentsPage()
.compose(bindToLifecycle())
.subscribe { closeCommentsActivity() }
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
closeCommentsActivity()
}

viewModel.outputs.shouldShowPaginationErrorUI()
.compose(bindToLifecycle())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
adapter.addErrorPaginationCell()
}

binding.commentComposer.setCommentComposerActionClickListener(object : OnCommentComposerViewClickedListener {
override fun onClickActionListener(string: String) {
Expand Down
61 changes: 32 additions & 29 deletions app/src/main/java/com/kickstarter/ui/adapters/CommentsAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import android.view.ViewGroup
import androidx.annotation.LayoutRes
import com.kickstarter.R
import com.kickstarter.databinding.CommentInitialLoadErrorLayoutBinding
import com.kickstarter.databinding.EmptyViewBinding
import com.kickstarter.databinding.ItemCommentCardBinding
import com.kickstarter.databinding.ItemErrorPaginationBinding
import com.kickstarter.ui.data.CommentCardData
import com.kickstarter.ui.viewholders.CommentCardViewHolder
import com.kickstarter.ui.viewholders.EmptyCommentsViewHolder
Expand All @@ -15,51 +17,52 @@ import com.kickstarter.ui.viewholders.KSViewHolder
class CommentsAdapter(private val delegate: Delegate) : KSListAdapter() {
interface Delegate : EmptyCommentsViewHolder.Delegate, CommentCardViewHolder.Delegate

companion object {
private const val SECTION_INITIAL_LOAD_ERROR = 0
private const val SECTION_COMMENT_CARD = 1
}

init {
resetList()
}

@LayoutRes
override fun layout(sectionRow: SectionRow): Int {
return when (sectionRow.section()) {
SECTION_COMMENT_CARD -> R.layout.item_comment_card
SECTION_INITIAL_LOAD_ERROR -> R.layout.comment_initial_load_error_layout
else -> 0
}
}

private fun resetList() {
clearSections()
insertSection(SECTION_INITIAL_LOAD_ERROR, emptyList<Boolean>())
insertSection(SECTION_COMMENT_CARD, emptyList<CommentCardData>())
insertSection(SECTION_COMMENTS, emptyList<CommentCardData>())
insertSection(SECTION_ERROR_PAGINATING, emptyList<Boolean>())
}

fun takeData(comments: List<CommentCardData>) {
resetList()
setSection(SECTION_COMMENT_CARD, comments)
setSection(SECTION_COMMENTS, comments)
setSection(SECTION_ERROR_PAGINATING, emptyList<Boolean>())
setSection(SECTION_INITIAL_LOAD_ERROR, emptyList<Boolean>())
submitList(items())
}

fun insertPageError() {
resetList()
setSection(SECTION_INITIAL_LOAD_ERROR, listOf(true))
setSection(SECTION_COMMENTS, emptyList<CommentCardData>())
setSection(SECTION_ERROR_PAGINATING, emptyList<Boolean>())
submitList(items())
}

fun addErrorPaginationCell() {
// - we want to display SECTION_COMMENTS & SECTION_ERROR_PAGINATING at the same time so we should not clean SECTION_COMMENTS
setSection(SECTION_ERROR_PAGINATING, listOf(true))
setSection(SECTION_INITIAL_LOAD_ERROR, emptyList<Boolean>())
submitList(items())
}

override fun layout(sectionRow: SectionRow): Int = when (sectionRow.section()) {
SECTION_COMMENTS -> R.layout.item_comment_card
SECTION_ERROR_PAGINATING -> R.layout.item_error_pagination
SECTION_INITIAL_LOAD_ERROR -> R.layout.comment_initial_load_error_layout
else -> 0
}

override fun viewHolder(@LayoutRes layout: Int, viewGroup: ViewGroup): KSViewHolder {
return when (layout) {
R.layout.item_comment_card -> CommentCardViewHolder(ItemCommentCardBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false), delegate)
R.layout.comment_initial_load_error_layout -> EmptyViewHolder(
CommentInitialLoadErrorLayoutBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
)
else -> EmptyViewHolder(
CommentInitialLoadErrorLayoutBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
)
R.layout.comment_initial_load_error_layout -> EmptyViewHolder(CommentInitialLoadErrorLayoutBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false))
R.layout.item_error_pagination -> EmptyViewHolder(ItemErrorPaginationBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false))
else -> EmptyViewHolder(EmptyViewBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false))
}
}

companion object {
private const val SECTION_INITIAL_LOAD_ERROR = 0
private const val SECTION_COMMENTS = 1
private const val SECTION_ERROR_PAGINATING = 2
}
}
21 changes: 14 additions & 7 deletions app/src/main/java/com/kickstarter/viewmodels/CommentsViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ interface CommentsViewModel {
fun initialLoadCommentsError(): Observable<Throwable>
fun paginateCommentsError(): Observable<Throwable>
fun pullToRefreshError(): Observable<Throwable>

/** Display the bottom pagination Error Cell **/
fun shouldShowPaginationErrorUI(): Observable<Boolean>
}

class ViewModel(@NonNull val environment: Environment) : ActivityViewModel<CommentsActivity>(environment), Inputs, Outputs {
Expand Down Expand Up @@ -80,6 +83,7 @@ interface CommentsViewModel {
private val isRefreshing = BehaviorSubject.create<Boolean>()
private val enablePagination = BehaviorSubject.create<Boolean>()
private val setEmptyState = BehaviorSubject.create<Boolean>()
private val displayPaginationError = BehaviorSubject.create<Boolean>()

// - Error observables to handle the 3 different use cases
private val internalError = BehaviorSubject.create<Throwable>()
Expand Down Expand Up @@ -203,9 +207,7 @@ interface CommentsViewModel {
this.internalError
.filter { this.lastCommentCursor != null }
.compose(bindToLifecycle())
.subscribe {
this.paginationError.onNext(it)
}
.subscribe(this.paginationError)

this.internalError
.compose(combineLatestPair(isFetchingData))
Expand All @@ -215,10 +217,15 @@ interface CommentsViewModel {
}
.compose(bindToLifecycle())
.subscribe {
it.first.localizedMessage
this.isRefreshing.onNext(false)
}

this.paginationError
.compose(bindToLifecycle())
.subscribe {
this.displayPaginationError.onNext(true)
}

this.backPressed
.compose(bindToLifecycle())
.subscribe { this.closeCommentsPage.onNext(it) }
Expand All @@ -235,9 +242,6 @@ interface CommentsViewModel {
// - Load comments from pagination & Handle pagination errors
initialProject
.compose(Transformers.takeWhen(this.nextPage))
.doOnNext {
this.isLoadingMoreItems.onNext(true)
}
.switchMap { getProjectComments(Observable.just(it), PAGE_LOAD) }
.compose(bindToLifecycle())
.subscribe {
Expand Down Expand Up @@ -269,6 +273,8 @@ interface CommentsViewModel {
isFetchingData.onNext(state)
return project.switchMap {
return@switchMap apolloClient.getProjectComments(it.slug() ?: "", lastCommentCursor)
}.doOnSubscribe {
this.isLoadingMoreItems.onNext(true)
}.doOnError {
this.internalError.onNext(it)
this.isLoadingMoreItems.onNext(false)
Expand Down Expand Up @@ -328,6 +334,7 @@ interface CommentsViewModel {
override fun paginateCommentsError(): Observable<Throwable> = this.paginationError
override fun pullToRefreshError(): Observable<Throwable> = this.pullToRefreshError
override fun scrollToTop(): Observable<Boolean> = this.scrollToTop
override fun shouldShowPaginationErrorUI(): Observable<Boolean> = this.displayPaginationError

override fun setEmptyState(): Observable<Boolean> = setEmptyState
override fun isLoadingMoreItems(): Observable<Boolean> = isLoadingMoreItems
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/layout/activity_comments_layout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:background="@color/comment_background"
tools:context="com.kickstarter.ui.activities.CommentsActivity"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:orientation="vertical">
Expand Down Expand Up @@ -72,13 +73,13 @@
android:background="@color/kds_white"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/comment_card" />

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

<ProgressBar
android:id="@+id/comments_loading_indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/comment_composer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
Expand All @@ -91,7 +92,6 @@
app:composer_action_button_gone="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
17 changes: 17 additions & 0 deletions app/src/main/res/layout/item_error_pagination.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/pagination_error_component"
android:layout_width="match_parent"
android:layout_height="@dimen/grid_8"
android:background="@color/kds_alert"
android:animateLayoutChanges="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class CommentsViewModelTest : KSRobolectricTestCase() {
private val pullToRefreshError = TestSubscriber.create<Throwable>()
private val initialLoadError = TestSubscriber.create<Throwable>()
private val paginationError = TestSubscriber.create<Throwable>()
private val shouldShowPaginatedCell = TestSubscriber.create<Boolean>()
private val openCommentGuideLines = TestSubscriber<Void>()

@Test
Expand Down Expand Up @@ -263,6 +264,7 @@ class CommentsViewModelTest : KSRobolectricTestCase() {
vm.outputs.pullToRefreshError().subscribe(pullToRefreshError)
vm.outputs.initialLoadCommentsError().subscribe(initialLoadError)
vm.outputs.paginateCommentsError().subscribe(paginationError)
vm.outputs.shouldShowPaginationErrorUI().subscribe(shouldShowPaginatedCell)

// Start the view model with a project.
vm.inputs.refresh()
Expand All @@ -273,6 +275,7 @@ class CommentsViewModelTest : KSRobolectricTestCase() {
commentsList.assertValueCount(0)
initialLoadError.assertValueCount(1)
paginationError.assertNoValues()
shouldShowPaginatedCell.assertNoValues()
}

@Test
Expand All @@ -294,6 +297,7 @@ class CommentsViewModelTest : KSRobolectricTestCase() {
vm.outputs.isLoadingMoreItems().subscribe(isLoadingMoreItems)
vm.outputs.commentsList().subscribe(commentsList)
vm.outputs.paginateCommentsError().subscribe(paginationError)
vm.outputs.shouldShowPaginationErrorUI().subscribe(shouldShowPaginatedCell)

enablePagination.assertValues(true)

Expand All @@ -304,6 +308,7 @@ class CommentsViewModelTest : KSRobolectricTestCase() {
enablePagination.assertValues(true)
commentsList.assertValueCount(1)
paginationError.assertValueCount(1)
shouldShowPaginatedCell.assertValue(true)
}

/*
Expand Down

0 comments on commit 057876a

Please sign in to comment.