Skip to content

Commit

Permalink
NT-1996:UI/UX – Error loading thread (#1320)
Browse files Browse the repository at this point in the history
* Use same cell to show error and view more action

* Refactor root comment in separate layout to solve sections binding issue

* Remove unneeded   displayPaginationError

* Fix crash for first reply

* Fix crash for first reply

* ConcatAdapter and create 3 different adapters

* Fix Scroll issue

* Fix Scroll issue

* Rename variables

* add code comments

* add code comments

* Remove Delegate

* Fix code adapter

* addInitiallyLoadingErrorCell

* add Initially Loading Error Cell

* Rename var

* Rename var
  • Loading branch information
hadia committed Jul 14, 2021
1 parent c6f42dc commit bf4ba9e
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 18 deletions.
13 changes: 11 additions & 2 deletions app/src/main/java/com/kickstarter/ui/activities/ThreadActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ class ThreadActivity :
repliesStatusAdapter.addErrorPaginationCell(it)
}

viewModel.outputs.initialLoadCommentsError()
.compose(bindToLifecycle())
.observeOn(AndroidSchedulers.mainThread())
.filter { it }
.subscribe {
/** bind Error initial loading cell **/
repliesStatusAdapter.addInitiallyLoadingErrorCell(it)
}

viewModel.outputs.isFetchingReplies()
.compose(bindToLifecycle())
.observeOn(AndroidSchedulers.mainThread())
Expand Down Expand Up @@ -199,11 +208,11 @@ class ThreadActivity :
}

override fun loadMoreCallback() {
viewModel.inputs.onViewMoreClicked()
viewModel.inputs.reloadRepliesPage()
}

override fun retryCallback() {
viewModel.inputs.onViewMoreClicked()
viewModel.inputs.reloadRepliesPage()
}

override fun onDestroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ class RepliesStatusAdapter(private val delegate: Delegate) : KSListAdapter() {
submitList(items())
}

fun addInitiallyLoadingErrorCell(shouldShowErrorCell: Boolean) {
if (shouldShowErrorCell)
setSection(SECTION_SHOW_MORE_REPLIES_PAGINATING, listOf(RepliesStatusCellType.INITIAL_ERROR))
else
setSection(SECTION_SHOW_MORE_REPLIES_PAGINATING, emptyList<RepliesStatusCellType>())
submitList(items())
}

override fun layout(sectionRow: SectionRow): Int = R.layout.item_show_more_replies

override fun viewHolder(@LayoutRes layout: Int, viewGroup: ViewGroup): KSViewHolder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ class RepliesStatusCellViewHolder(

enum class RepliesStatusCellType {
PAGINATION_ERROR,
VIEW_MORE
VIEW_MORE,
INITIAL_ERROR
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ interface RepliesStatusCellViewHolderViewModel {
this.isErrorPaginationVisible.onNext(false)
this.isViewMoreRepliesPaginationVisible.onNext(true)
}
RepliesStatusCellType.PAGINATION_ERROR -> {
RepliesStatusCellType.PAGINATION_ERROR, RepliesStatusCellType.INITIAL_ERROR -> {
this.isErrorPaginationVisible.onNext(true)
this.isViewMoreRepliesPaginationVisible.onNext(false)
}
Expand Down
39 changes: 26 additions & 13 deletions app/src/main/java/com/kickstarter/viewmodels/ThreadViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface ThreadViewModel {

interface Inputs {
fun nextPage()
fun onViewMoreClicked()
fun reloadRepliesPage()
fun insertNewReplyToList(comment: String, createdAt: DateTime)
fun onShowGuideLinesLinkClicked()
}
Expand All @@ -54,6 +54,10 @@ interface ThreadViewModel {

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

fun refresh(): Observable<Void>

fun showCommentGuideLinesLink(): Observable<Void>
}
Expand All @@ -63,7 +67,7 @@ interface ThreadViewModel {
private val currentUser: CurrentUserType = environment.currentUser()

private val nextPage = PublishSubject.create<Void>()
private val onViewMoreClicked = PublishSubject.create<Void>()
private val onLoadingReplies = PublishSubject.create<Void>()
private val insertNewReplyToList = PublishSubject.create<Pair<String, DateTime>>()
private val onShowGuideLinesLinkClicked = PublishSubject.create<Void>()

Expand All @@ -78,6 +82,7 @@ interface ThreadViewModel {
private val refresh = PublishSubject.create<Void>()
private val loadMoreReplies = PublishSubject.create<Void>()
private val displayPaginationError = BehaviorSubject.create<Boolean>()
private val initialLoadCommentsError = BehaviorSubject.create<Boolean>()
private val showGuideLinesLink = BehaviorSubject.create<Void>()

private val onCommentReplies =
Expand Down Expand Up @@ -186,10 +191,22 @@ interface ThreadViewModel {
replyComposerStatus.onNext(composerStatus)
}

this.onViewMoreClicked
this.onLoadingReplies
.map {
this.onCommentReplies.value
}.compose(bindToLifecycle())
.subscribe {
if (it?.first?.isNotEmpty() == true) {
this.loadMoreReplies.onNext(null)
} else {
this.refresh.onNext(null)
}
}

this.initialError
.compose(bindToLifecycle())
.subscribe {
this.loadMoreReplies.onNext(null)
this.initialLoadCommentsError.onNext(true)
}

this.paginationError
Expand Down Expand Up @@ -249,13 +266,9 @@ interface ThreadViewModel {
}

this.internalError
.compose(Transformers.combineLatestPair(onCommentReplies))
.filter {
it.second.first.isNullOrEmpty()
}
.compose(bindToLifecycle())
.subscribe {
this.initialError.onNext(it.first)
this.initialError.onNext(it)
}

this.internalError
Expand Down Expand Up @@ -313,7 +326,7 @@ interface ThreadViewModel {
.ofType(CommentCardData::class.java)

override fun nextPage() = nextPage.onNext(null)
override fun onViewMoreClicked() = onViewMoreClicked.onNext(null)
override fun reloadRepliesPage() = onLoadingReplies.onNext(null)

override fun getRootComment(): Observable<Comment> = this.rootComment
override fun onCommentReplies(): Observable<Pair<List<CommentCardData>, Boolean>> =
Expand All @@ -333,9 +346,9 @@ interface ThreadViewModel {
override fun showReplyComposer(): Observable<Boolean> = showReplyComposer
override fun isFetchingReplies(): Observable<Boolean> = this.isFetchingReplies
override fun loadMoreReplies(): Observable<Void> = this.loadMoreReplies
override fun shouldShowPaginationErrorUI(): Observable<Boolean> =
this.displayPaginationError

override fun showCommentGuideLinesLink(): Observable<Void> = showGuideLinesLink
override fun shouldShowPaginationErrorUI(): Observable<Boolean> = this.displayPaginationError
override fun initialLoadCommentsError(): Observable<Boolean> = this.initialLoadCommentsError
override fun refresh(): Observable<Void> = this.refresh
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.junit.Test
import rx.Observable
import rx.observers.TestSubscriber
import rx.subjects.BehaviorSubject
import java.io.IOException

class ThreadViewModelTest : KSRobolectricTestCase() {

Expand All @@ -33,6 +34,7 @@ class ThreadViewModelTest : KSRobolectricTestCase() {
private val showReplyComposer = TestSubscriber<Boolean>()
private val loadMoreReplies = TestSubscriber<Void>()
private val openCommentGuideLines = TestSubscriber<Void>()
private val refresh = TestSubscriber<Void>()

private fun setUpEnvironment() {
setUpEnvironment(environment())
Expand All @@ -44,6 +46,7 @@ class ThreadViewModelTest : KSRobolectricTestCase() {
this.vm.shouldFocusOnCompose().subscribe(focusCompose)
this.vm.onCommentReplies().subscribe(onReplies)
this.vm.loadMoreReplies().subscribe(loadMoreReplies)
this.vm.refresh().subscribe(refresh)
}

@Test
Expand Down Expand Up @@ -213,6 +216,32 @@ class ThreadViewModelTest : KSRobolectricTestCase() {
this.onReplies.assertValueCount(2)
}

@Test
fun testLoadCommentReplies_Error() {
val createdAt = DateTime.now()
val env = environment().toBuilder()
.apolloClient(object : MockApolloClient() {
override fun getRepliesForComment(
comment: Comment,
cursor: String?,
pageSize: Int
): Observable<CommentEnvelope> {
return Observable.error(IOException())
}
})
.build()

setUpEnvironment(env)

// Start the view model with a backed project and comment.
vm.intent(Intent().putExtra(IntentKey.COMMENT_CARD_DATA, CommentCardDataFactory.commentCardData()))

this.onReplies.assertValueCount(0)

vm.reloadRepliesPage()
this.refresh.assertValueCount(1)
}

@Test
fun testLoadCommentReplies_pagination() {
val createdAt = DateTime.now()
Expand Down Expand Up @@ -242,7 +271,7 @@ class ThreadViewModelTest : KSRobolectricTestCase() {
assertEquals(replies.comments?.size, onRepliesResult?.first?.size)
assertEquals(true, onRepliesResult?.second)

vm.inputs.onViewMoreClicked()
vm.inputs.reloadRepliesPage()

this.loadMoreReplies.assertValueCount(1)
}
Expand Down

0 comments on commit bf4ba9e

Please sign in to comment.