Skip to content

Commit 308733b

Browse files
committed
Retry load next page in horizontal list
1 parent 88c6a88 commit 308733b

File tree

5 files changed

+66
-5
lines changed

5 files changed

+66
-5
lines changed

app/src/main/java/com/hoc/pagination_mvi/ui/main/HorizontalAdapter.kt

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@ import androidx.recyclerview.widget.DiffUtil
99
import androidx.recyclerview.widget.ListAdapter
1010
import androidx.recyclerview.widget.RecyclerView
1111
import com.hoc.pagination_mvi.R
12+
import com.hoc.pagination_mvi.asObservable
1213
import com.hoc.pagination_mvi.ui.main.MainContract.Item.HorizontalList.HorizontalItem
1314
import com.hoc.pagination_mvi.ui.main.MainContract.PlaceholderState
1415
import com.hoc.pagination_mvi.ui.main.MainContract.PostVS
16+
import com.jakewharton.rxbinding3.view.clicks
17+
import com.jakewharton.rxbinding3.view.detaches
18+
import io.reactivex.disposables.CompositeDisposable
19+
import io.reactivex.rxkotlin.addTo
20+
import io.reactivex.rxkotlin.subscribeBy
21+
import io.reactivex.subjects.PublishSubject
1522
import kotlinx.android.synthetic.main.recycler_item_horizontal_placeholder.view.*
1623
import kotlinx.android.synthetic.main.recycler_item_horizontal_post.view.*
1724

@@ -36,14 +43,19 @@ private object HorizontalItemItemCallback : DiffUtil.ItemCallback<HorizontalItem
3643
}
3744
}
3845

39-
class HorizontalAdapter :
46+
class HorizontalAdapter(
47+
private val compositeDisposable: CompositeDisposable
48+
) :
4049
ListAdapter<HorizontalItem, HorizontalAdapter.VH>(HorizontalItemItemCallback) {
4150

51+
private val retryS = PublishSubject.create<Unit>()
52+
val retryObservable get() = retryS.asObservable()
53+
4254
override fun onCreateViewHolder(parent: ViewGroup, @LayoutRes viewType: Int): VH {
4355
val itemView = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
4456
return when (viewType) {
4557
R.layout.recycler_item_horizontal_post -> PostVH(itemView)
46-
R.layout.recycler_item_horizontal_placeholder -> PlaceholderVH(itemView)
58+
R.layout.recycler_item_horizontal_placeholder -> PlaceholderVH(itemView, parent)
4759
else -> error("Unknown viewType=$viewType")
4860
}
4961
}
@@ -82,11 +94,26 @@ class HorizontalAdapter :
8294
}
8395
}
8496

85-
private class PlaceholderVH(itemView: View) : VH(itemView) {
97+
private inner class PlaceholderVH(itemView: View, parent: ViewGroup) : VH(itemView) {
8698
private val progressBar = itemView.progress_bar!!
8799
private val textError = itemView.text_error!!
88100
private val buttonRetry = itemView.button_retry!!
89101

102+
init {
103+
buttonRetry
104+
.clicks()
105+
.takeUntil(parent.detaches())
106+
.filter {
107+
val position = adapterPosition
108+
if (position == RecyclerView.NO_POSITION) {
109+
false
110+
} else {
111+
(getItem(position) as? HorizontalItem.Placeholder)?.state is PlaceholderState.Error
112+
}
113+
}
114+
.subscribeBy { retryS.onNext(Unit) }
115+
.addTo(compositeDisposable)
116+
}
90117

91118
override fun bind(item: HorizontalItem) {
92119
if (item !is HorizontalItem.Placeholder) return

app/src/main/java/com/hoc/pagination_mvi/ui/main/MainAdapter.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class MainAdapter(private val compositeDisposable: CompositeDisposable) :
5858
private val loadNextPageHorizontalS = PublishSubject.create<Unit>()
5959
val loadNextPageHorizontalObservable get() = loadNextPageHorizontalS.asObservable()
6060

61+
private val retryHorizontalS = PublishSubject.create<Unit>()
62+
val retryHorizontalObservable get() = retryHorizontalS.asObservable()
63+
6164
override fun onCreateViewHolder(parent: ViewGroup, @LayoutRes viewType: Int): VH {
6265
val itemView = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
6366
return when (viewType) {
@@ -161,7 +164,7 @@ class MainAdapter(private val compositeDisposable: CompositeDisposable) :
161164
private val progressBar = itemView.progress_bar_horizontal!!
162165
private val textError = itemView.text_error_horizontal!!
163166
private val buttonRetry = itemView.button_retry_horizontal!!
164-
private val adapter = HorizontalAdapter()
167+
private val adapter = HorizontalAdapter(compositeDisposable)
165168
private val visibleThreshold get() = 2
166169

167170
init {
@@ -182,6 +185,11 @@ class MainAdapter(private val compositeDisposable: CompositeDisposable) :
182185
})
183186
}
184187

188+
adapter
189+
.retryObservable
190+
.subscribe(retryHorizontalS::onNext)
191+
.addTo(compositeDisposable)
192+
185193
recycler
186194
.scrollEvents()
187195
.takeUntil(parent.detaches())

app/src/main/java/com/hoc/pagination_mvi/ui/main/MainContract.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ interface MainContract {
4040
return horizontalList.postItems.size
4141
}
4242

43+
fun shouldRetryHorizontal(): Boolean {
44+
val horizontalList =
45+
items.singleOrNull { it is Item.HorizontalList } as? Item.HorizontalList ?: return false
46+
return !horizontalList.isLoading &&
47+
horizontalList.error == null &&
48+
horizontalList.postItems.isNotEmpty() &&
49+
(horizontalList.items.singleOrNull { it is HorizontalItem.Placeholder } as? HorizontalItem.Placeholder)
50+
?.state is PlaceholderState.Error
51+
}
52+
4353
companion object Factory {
4454
@JvmStatic
4555
fun initial() = ViewState(

app/src/main/java/com/hoc/pagination_mvi/ui/main/MainFragment.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,11 @@ class MainFragment : Fragment() {
143143
.map { ViewIntent.RetryLoadPage },
144144
adapter
145145
.loadNextPageHorizontalObservable
146-
.map { ViewIntent.LoadNextPageHorizontal }
146+
.map { ViewIntent.LoadNextPageHorizontal },
147+
adapter
148+
.retryHorizontalObservable
149+
.throttleFirst(500, TimeUnit.MILLISECONDS)
150+
.map { ViewIntent.RetryLoadPageHorizontal }
147151
)
148152
).addTo(compositeDisposable)
149153
}

app/src/main/java/com/hoc/pagination_mvi/ui/main/MainVM.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ class MainVM @Inject constructor(
8181
.exhaustMap { interactor.postNextPageChanges(start = it, limit = POST_PAGE_SIZE) }
8282
}
8383

84+
private val retryLoadPageHorizontalProcessor =
85+
ObservableTransformer<ViewIntent.RetryLoadPageHorizontal, PartialStateChange> { intents ->
86+
intents
87+
.withLatestFrom(stateObservable)
88+
.filter { (_, vs) -> vs.shouldRetryHorizontal() }
89+
.map { (_, vs) -> vs.getHorizontalListCount() }
90+
.exhaustMap { interactor.postNextPageChanges(start = it, limit = POST_PAGE_SIZE) }
91+
}
92+
8493
private val toPartialStateChange =
8594
ObservableTransformer<ViewIntent, PartialStateChange> { intents ->
8695
intents
@@ -91,6 +100,9 @@ class MainVM @Inject constructor(
91100
shared.ofType<ViewIntent.RetryLoadPage>().compose(retryLoadPageProcessor),
92101
shared.ofType<ViewIntent.LoadNextPageHorizontal>().compose(
93102
loadNextPageHorizontalProcessor
103+
),
104+
shared.ofType<ViewIntent.RetryLoadPageHorizontal>().compose(
105+
retryLoadPageHorizontalProcessor
94106
)
95107
)
96108
}

0 commit comments

Comments
 (0)