Skip to content

Commit 7802a0f

Browse files
anhanh11001iamareebjamal
authored andcommitted
feat: Add pagination in search (#2072)
Details: - Add pagination in search - Split adapter class between FavoriteFragment and SearchResultsFragment - Split ViewModel between SearchFragment and SearchResultsFragment Fixes: #2013
1 parent 0b7bb65 commit 7802a0f

12 files changed

+553
-405
lines changed

app/src/main/java/org/fossasia/openevent/general/di/Modules.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ import org.fossasia.openevent.general.feedback.FeedbackViewModel
8484
import org.fossasia.openevent.general.feedback.Feedback
8585
import org.fossasia.openevent.general.feedback.FeedbackService
8686
import org.fossasia.openevent.general.feedback.FeedbackApi
87+
import org.fossasia.openevent.general.search.SearchResultsViewModel
8788
import org.fossasia.openevent.general.speakercall.SpeakersCall
8889
import org.fossasia.openevent.general.sessions.SessionViewModel
8990
import org.fossasia.openevent.general.sessions.microlocation.MicroLocation
@@ -120,7 +121,7 @@ val commonModule = module {
120121
single { Preference() }
121122
single { Network() }
122123
single { Resource() }
123-
single { MutableConnectionLiveData() }
124+
factory { MutableConnectionLiveData() }
124125
factory<LocationService> { LocationServiceImpl(androidContext()) }
125126
}
126127

@@ -216,7 +217,8 @@ val viewModelModule = module {
216217
viewModel { SignUpViewModel(get(), get(), get()) }
217218
viewModel { EventDetailsViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) }
218219
viewModel { SessionViewModel(get(), get(), get()) }
219-
viewModel { SearchViewModel(get(), get(), get(), get()) }
220+
viewModel { SearchViewModel(get(), get()) }
221+
viewModel { SearchResultsViewModel(get(), get(), get(), get(), get()) }
220222
viewModel { AttendeeViewModel(get(), get(), get(), get(), get(), get(), get()) }
221223
viewModel { SearchLocationViewModel(get(), get()) }
222224
viewModel { SearchTimeViewModel(get()) }

app/src/main/java/org/fossasia/openevent/general/event/EventApi.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ import retrofit2.http.Query
88

99
interface EventApi {
1010

11-
@GET("events?include=event-topic")
12-
fun getEvents(): Single<List<Event>>
13-
1411
@GET("events?include=event-sub-topic,event-topic,event-type,speakers-call")
1512
fun searchEvents(@Query("sort") sort: String, @Query("filter") eventName: String): Single<List<Event>>
1613

app/src/main/java/org/fossasia/openevent/general/event/EventService.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ class EventService(
4646
return eventTypesApi.getEventTypes()
4747
}
4848

49-
fun getSearchEvents(eventName: String, sortBy: String): Flowable<List<Event>> {
50-
return eventApi.searchEvents(sortBy, eventName).flatMapPublisher { eventsList ->
49+
fun getSearchEventsPaged(filter: String, sortBy: String, page: Int): Flowable<List<Event>> {
50+
return eventApi.searchEventsPaged(sortBy, filter, page).flatMapPublisher { eventsList ->
5151
eventsList.forEach {
5252
it.speakersCall?.let { sc -> speakersCallDao.insertSpeakerCall(sc) }
5353
}

app/src/main/java/org/fossasia/openevent/general/favorite/FavoriteEventsRecyclerAdapter.kt renamed to app/src/main/java/org/fossasia/openevent/general/favorite/FavoriteEventsListAdapter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import org.fossasia.openevent.general.databinding.ItemCardFavoriteEventBinding
1717
* @property onFavFabClick The callback to be invoked when the favorite FAB is clicked
1818
* @property onShareFabClick The callback to be invoked when the share FAB is clicked
1919
*/
20-
class FavoriteEventsRecyclerAdapter : ListAdapter<Event, FavoriteEventViewHolder>(EventsDiffCallback()) {
20+
class FavoriteEventsListAdapter : ListAdapter<Event, FavoriteEventViewHolder>(EventsDiffCallback()) {
2121

2222
var onEventClick: EventClickListener? = null
2323
var onFavFabClick: FavoriteFabClickListener? = null

app/src/main/java/org/fossasia/openevent/general/favorite/FavoriteFragment.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import org.jetbrains.anko.design.snackbar
4545
class FavoriteFragment : Fragment(), BottomIconDoubleClick {
4646
private val favoriteEventViewModel by viewModel<FavoriteEventsViewModel>()
4747
private lateinit var rootView: View
48-
private val favoriteEventsRecyclerAdapter = FavoriteEventsRecyclerAdapter()
48+
private val favoriteEventsRecyclerAdapter = FavoriteEventsListAdapter()
4949

5050
override fun onCreateView(
5151
inflater: LayoutInflater,
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.fossasia.openevent.general.search
2+
3+
import androidx.lifecycle.MutableLiveData
4+
import androidx.paging.PageKeyedDataSource
5+
import io.reactivex.disposables.CompositeDisposable
6+
import io.reactivex.rxkotlin.plusAssign
7+
import org.fossasia.openevent.general.event.Event
8+
import org.fossasia.openevent.general.event.EventService
9+
import org.fossasia.openevent.general.utils.extensions.withDefaultSchedulers
10+
import timber.log.Timber
11+
12+
class SearchEventsDataSource(
13+
private val eventService: EventService,
14+
private val compositeDisposable: CompositeDisposable,
15+
private val query: String,
16+
private val sortBy: String,
17+
private val mutableProgress: MutableLiveData<Boolean>
18+
) : PageKeyedDataSource<Int, Event>() {
19+
20+
override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, Event>) {
21+
compositeDisposable += eventService.getSearchEventsPaged(query, sortBy, 1)
22+
.take(1)
23+
.withDefaultSchedulers()
24+
.subscribe({ response ->
25+
if (response.isEmpty())
26+
mutableProgress.value = false
27+
callback.onResult(response, null, 2)
28+
}, { error ->
29+
Timber.e(error, "Fail on fetching page of events")
30+
})
31+
}
32+
33+
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Event>) {
34+
compositeDisposable += eventService.getSearchEventsPaged(query, sortBy, params.key)
35+
.take(1)
36+
.withDefaultSchedulers()
37+
.subscribe({ response ->
38+
if (response.isEmpty())
39+
mutableProgress.value = false
40+
callback.onResult(response, params.key + 1)
41+
}, { error ->
42+
Timber.e(error, "Fail on fetching page of events")
43+
})
44+
}
45+
46+
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Event>) {
47+
}
48+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.fossasia.openevent.general.search
2+
3+
import androidx.lifecycle.MutableLiveData
4+
import androidx.paging.DataSource
5+
import io.reactivex.disposables.CompositeDisposable
6+
import org.fossasia.openevent.general.event.Event
7+
import org.fossasia.openevent.general.event.EventService
8+
9+
data class SearchEventsDataSourceFactory(
10+
private val compositeDisposable: CompositeDisposable,
11+
private val eventService: EventService,
12+
private val query: String,
13+
private val sortBy: String,
14+
private val mutableProgress: MutableLiveData<Boolean>
15+
) : DataSource.Factory<Int, Event>() {
16+
override fun create(): DataSource<Int, Event> {
17+
return SearchEventsDataSource(
18+
eventService,
19+
compositeDisposable,
20+
query,
21+
sortBy,
22+
mutableProgress
23+
)
24+
}
25+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.fossasia.openevent.general.search
2+
3+
import org.fossasia.openevent.general.favorite.FavoriteEventViewHolder
4+
5+
import android.view.LayoutInflater
6+
import android.view.ViewGroup
7+
import androidx.paging.PagedListAdapter
8+
import org.fossasia.openevent.general.event.Event
9+
import org.fossasia.openevent.general.common.EventClickListener
10+
import org.fossasia.openevent.general.common.EventsDiffCallback
11+
import org.fossasia.openevent.general.common.FavoriteFabClickListener
12+
import org.fossasia.openevent.general.databinding.ItemCardFavoriteEventBinding
13+
14+
class SearchPagedListAdapter : PagedListAdapter<Event, FavoriteEventViewHolder>(EventsDiffCallback()) {
15+
16+
var onEventClick: EventClickListener? = null
17+
var onFavFabClick: FavoriteFabClickListener? = null
18+
19+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FavoriteEventViewHolder {
20+
val binding = ItemCardFavoriteEventBinding.inflate(LayoutInflater.from(parent.context), parent, false)
21+
return FavoriteEventViewHolder(binding)
22+
}
23+
24+
override fun onBindViewHolder(holder: FavoriteEventViewHolder, position: Int) {
25+
val event = getItem(position)
26+
if (event != null) {
27+
holder.apply {
28+
bind(event, position)
29+
eventClickListener = onEventClick
30+
favFabClickListener = onFavFabClick
31+
}
32+
}
33+
}
34+
35+
fun clear() {
36+
this.submitList(null)
37+
}
38+
}

0 commit comments

Comments
 (0)