Skip to content

Commit a1ecbd8

Browse files
committed
refactoring pagination, query system, filters and order
1 parent 2c91f7d commit a1ecbd8

File tree

11 files changed

+96
-129
lines changed

11 files changed

+96
-129
lines changed

app/src/main/java/com/codingwithmitch/openapi/di/main/MainViewModelModule.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.codingwithmitch.openapi.di.main
33
import androidx.lifecycle.ViewModel
44
import com.codingwithmitch.openapi.di.ViewModelKey
55
import com.codingwithmitch.openapi.ui.main.account.AccountViewModel
6-
import com.codingwithmitch.openapi.ui.main.blog.state.BlogViewModel
6+
import com.codingwithmitch.openapi.ui.main.blog.viewmodel.BlogViewModel
77
import com.codingwithmitch.openapi.ui.main.create_blog.CreateBlogViewModel
88
import dagger.Binds
99
import dagger.Module

app/src/main/java/com/codingwithmitch/openapi/repository/main/BlogQueryUtils.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ class BlogQueryUtils{
6565
query = query,
6666
page = page)
6767
}
68-
else -> throw Exception("Must specify a valid order for all blog queries. See BLogQueryUtils class.")
68+
else ->
69+
return blogPostDao.searchBlogPostsOrderByDateASC(
70+
query = query,
71+
page = page
72+
)
6973
}
7074
}
7175
}

app/src/main/java/com/codingwithmitch/openapi/ui/main/blog/BaseBlogFragment.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import com.bumptech.glide.RequestManager
1313
import com.codingwithmitch.openapi.R
1414
import com.codingwithmitch.openapi.ui.DataStateChangeListener
1515
import com.codingwithmitch.openapi.ui.UICommunicationListener
16-
import com.codingwithmitch.openapi.ui.main.blog.state.BlogViewModel
16+
import com.codingwithmitch.openapi.ui.main.blog.viewmodel.BlogViewModel
1717
import com.codingwithmitch.openapi.viewmodels.ViewModelProviderFactory
1818
import dagger.android.support.DaggerFragment
1919
import javax.inject.Inject

app/src/main/java/com/codingwithmitch/openapi/ui/main/blog/BlogFragment.kt

Lines changed: 25 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,28 @@ import kotlinx.android.synthetic.main.fragment_blog.*
1818
import javax.inject.Inject
1919
import android.view.inputmethod.EditorInfo
2020
import android.widget.*
21-
import androidx.fragment.app.FragmentActivity
2221
import androidx.navigation.fragment.findNavController
2322
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
2423
import com.afollestad.materialdialogs.MaterialDialog
2524
import com.afollestad.materialdialogs.customview.customView
2625
import com.afollestad.materialdialogs.customview.getCustomView
27-
import com.bumptech.glide.RequestManager
2826
import com.codingwithmitch.openapi.models.BlogPost
2927
import com.codingwithmitch.openapi.repository.main.BlogQueryUtils.Companion.BLOG_FILTER_DATE_UPDATED
3028
import com.codingwithmitch.openapi.repository.main.BlogQueryUtils.Companion.BLOG_FILTER_USERNAME
3129
import com.codingwithmitch.openapi.repository.main.BlogQueryUtils.Companion.BLOG_ORDER_ASC
3230
import com.codingwithmitch.openapi.ui.DataState
3331
import com.codingwithmitch.openapi.ui.main.blog.state.*
3432
import com.codingwithmitch.openapi.ui.main.blog.state.BlogStateEvent.*
33+
import com.codingwithmitch.openapi.ui.main.blog.viewmodel.*
3534
import com.codingwithmitch.openapi.util.ErrorHandling
3635
import com.codingwithmitch.openapi.util.PreferenceKeys.Companion.BLOG_FILTER
3736
import com.codingwithmitch.openapi.util.PreferenceKeys.Companion.BLOG_ORDER
3837

3938
class BlogFragment : BaseBlogFragment(),
4039
BlogListAdapter.BlogViewHolder.Interaction,
41-
SharedPreferences.OnSharedPreferenceChangeListener,
4240
SwipeRefreshLayout.OnRefreshListener
4341
{
4442

45-
@Inject
46-
lateinit var sharedPreferences: SharedPreferences
47-
48-
@Inject
49-
lateinit var editor: SharedPreferences.Editor
50-
5143
private lateinit var searchView: SearchView
5244
private lateinit var recyclerAdapter: BlogListAdapter
5345

@@ -66,7 +58,10 @@ class BlogFragment : BaseBlogFragment(),
6658
setHasOptionsMenu(true)
6759
initRecyclerView()
6860
subscribeObservers()
69-
viewModel.loadFirstPage()
61+
62+
if(savedInstanceState == null){
63+
viewModel.loadFirstPage()
64+
}
7065
}
7166

7267
private fun subscribeObservers(){
@@ -140,27 +135,14 @@ class BlogFragment : BaseBlogFragment(),
140135
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
141136
val lastPosition = layoutManager.findLastVisibleItemPosition()
142137
if (lastPosition == recyclerAdapter.itemCount.minus(1)) {
143-
Log.d(TAG, "BlogFragment: attempting to load next page...")
144-
viewModel.setStateEvent(NextPageEvent())
138+
viewModel.nextPage()
145139
}
146140
}
147141
})
148142
adapter = recyclerAdapter
149143
}
150144
}
151145

152-
fun onBlogSearchOrFilter(){
153-
viewModel.loadFirstPage().let {
154-
onQuerySubmitted()
155-
}
156-
}
157-
158-
fun onQuerySubmitted(){
159-
blog_post_recyclerview.smoothScrollToPosition(0)
160-
stateChangeListener.hideSoftKeyboard()
161-
focusable_view.requestFocus()
162-
}
163-
164146
private fun initSearchView(menu: Menu){
165147
activity?.apply {
166148
val searchManager: SearchManager = getSystemService(SEARCH_SERVICE) as SearchManager
@@ -198,6 +180,18 @@ class BlogFragment : BaseBlogFragment(),
198180
}
199181
}
200182

183+
fun onBlogSearchOrFilter(){
184+
viewModel.loadFirstPage().let {
185+
resetUI()
186+
}
187+
}
188+
189+
fun resetUI(){
190+
blog_post_recyclerview.smoothScrollToPosition(0)
191+
stateChangeListener.hideSoftKeyboard()
192+
focusable_view.requestFocus()
193+
}
194+
201195
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
202196
super.onCreateOptionsMenu(menu, inflater)
203197
inflater.inflate(R.menu.search_menu, menu)
@@ -215,16 +209,6 @@ class BlogFragment : BaseBlogFragment(),
215209
return super.onOptionsItemSelected(item)
216210
}
217211

218-
override fun onResume() {
219-
super.onResume()
220-
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
221-
}
222-
223-
override fun onPause() {
224-
super.onPause()
225-
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
226-
}
227-
228212
override fun onRefresh() {
229213
onBlogSearchOrFilter()
230214
swipe_refresh.isRefreshing = false
@@ -250,8 +234,8 @@ class BlogFragment : BaseBlogFragment(),
250234

251235
val view = dialog.getCustomView()
252236

253-
val filter = sharedPreferences.getString(BLOG_FILTER, BLOG_FILTER_DATE_UPDATED)
254-
val order = sharedPreferences.getString(BLOG_ORDER, BLOG_ORDER_ASC)
237+
val filter = viewModel.getFilter()
238+
val order = viewModel.getOrder()
255239

256240
if(filter.equals(BLOG_FILTER_DATE_UPDATED)){
257241
view.findViewById<RadioGroup>(R.id.filter_group).check(R.id.filter_date)
@@ -286,10 +270,11 @@ class BlogFragment : BaseBlogFragment(),
286270
if(selectedOrder.text.toString().equals(getString(R.string.filter_desc))){
287271
order = "-"
288272
}
289-
applyFilterOptions(
290-
filter,
291-
order
292-
)
273+
viewModel.saveFilterOptions(filter, order).let{
274+
viewModel.setBlogFilter(filter)
275+
viewModel.setBlogOrder(order)
276+
onBlogSearchOrFilter()
277+
}
293278
dialog.dismiss()
294279
}
295280

@@ -302,31 +287,6 @@ class BlogFragment : BaseBlogFragment(),
302287
}
303288
}
304289

305-
fun applyFilterOptions(filter: String, order: String){
306-
Log.d(TAG, "applyFilterOptions: $filter, $order")
307-
editor.putString(BLOG_FILTER, filter)
308-
editor.apply()
309-
310-
editor.putString(BLOG_ORDER, order)
311-
editor.apply()
312-
}
313-
314-
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
315-
316-
sharedPreferences?.let{
317-
when(key){
318-
319-
BLOG_FILTER ->{
320-
onBlogSearchOrFilter()
321-
}
322-
323-
BLOG_ORDER ->{
324-
onBlogSearchOrFilter()
325-
}
326-
else -> return
327-
}
328-
}
329-
}
330290
}
331291

332292

app/src/main/java/com/codingwithmitch/openapi/ui/main/blog/UpdateBlogFragment.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ import android.net.Uri
1414
import android.util.Log
1515
import com.codingwithmitch.openapi.ui.*
1616
import com.codingwithmitch.openapi.ui.main.blog.state.BlogStateEvent
17-
import com.codingwithmitch.openapi.ui.main.blog.state.setBlogPost
18-
import com.codingwithmitch.openapi.ui.main.blog.state.setUpdatedBlogFields
19-
import com.codingwithmitch.openapi.ui.main.blog.state.updateListItem
17+
import com.codingwithmitch.openapi.ui.main.blog.viewmodel.setBlogPost
18+
import com.codingwithmitch.openapi.ui.main.blog.viewmodel.setUpdatedBlogFields
19+
import com.codingwithmitch.openapi.ui.main.blog.viewmodel.updateListItem
2020
import com.codingwithmitch.openapi.util.Constants.Companion.GALLERY_REQUEST_CODE
2121
import com.codingwithmitch.openapi.util.FileUtil
2222
import com.theartofdev.edmodo.cropper.CropImage

app/src/main/java/com/codingwithmitch/openapi/ui/main/blog/ViewBlogFragment.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,12 @@ import androidx.navigation.fragment.findNavController
1111
import com.codingwithmitch.openapi.R
1212
import com.codingwithmitch.openapi.models.BlogPost
1313
import com.codingwithmitch.openapi.ui.AreYouSureCallback
14-
import com.codingwithmitch.openapi.ui.BaseActivity
1514
import com.codingwithmitch.openapi.ui.UIMessage
1615
import com.codingwithmitch.openapi.ui.UIMessageType
1716
import com.codingwithmitch.openapi.ui.main.blog.state.BlogStateEvent.*
18-
import com.codingwithmitch.openapi.ui.main.blog.state.removeDeletedBlogPost
19-
import com.codingwithmitch.openapi.ui.main.blog.state.setIsAuthorOfBlogPost
20-
import com.codingwithmitch.openapi.ui.main.blog.state.setUpdatedBlogFields
17+
import com.codingwithmitch.openapi.ui.main.blog.viewmodel.removeDeletedBlogPost
18+
import com.codingwithmitch.openapi.ui.main.blog.viewmodel.setIsAuthorOfBlogPost
19+
import com.codingwithmitch.openapi.ui.main.blog.viewmodel.setUpdatedBlogFields
2120
import com.codingwithmitch.openapi.util.DateUtils
2221
import com.codingwithmitch.openapi.util.SuccessHandling.Companion.SUCCESS_BLOG_DELETED
2322
import kotlinx.android.synthetic.main.fragment_view_blog.*

app/src/main/java/com/codingwithmitch/openapi/ui/main/blog/state/BlogStateEvent.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ sealed class BlogStateEvent{
77

88
class BlogSearchEvent: BlogStateEvent()
99

10-
class NextPageEvent: BlogStateEvent()
11-
1210
class CheckAuthorOfBlogPost: BlogStateEvent()
1311

1412
class DeleteBlogPostEvent: BlogStateEvent()

app/src/main/java/com/codingwithmitch/openapi/ui/main/blog/state/BlogViewModel.kt renamed to app/src/main/java/com/codingwithmitch/openapi/ui/main/blog/viewmodel/BlogViewModel.kt

Lines changed: 35 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
1-
package com.codingwithmitch.openapi.ui.main.blog.state
1+
package com.codingwithmitch.openapi.ui.main.blog.viewmodel
22

33
import android.content.SharedPreferences
4-
import android.net.Uri
54
import android.util.Log
65
import androidx.lifecycle.*
7-
import com.bumptech.glide.RequestManager
86
import com.codingwithmitch.openapi.models.BlogPost
97
import com.codingwithmitch.openapi.repository.main.BlogQueryUtils
108
import com.codingwithmitch.openapi.repository.main.BlogRepository
119
import com.codingwithmitch.openapi.session.SessionManager
1210
import com.codingwithmitch.openapi.ui.BaseViewModel
1311
import com.codingwithmitch.openapi.ui.DataState
1412
import com.codingwithmitch.openapi.ui.Loading
13+
import com.codingwithmitch.openapi.ui.main.blog.state.BlogStateEvent
1514
import com.codingwithmitch.openapi.ui.main.blog.state.BlogStateEvent.*
15+
import com.codingwithmitch.openapi.ui.main.blog.state.BlogViewState
1616
import com.codingwithmitch.openapi.util.AbsentLiveData
17-
import com.codingwithmitch.openapi.util.PreferenceKeys
1817
import com.codingwithmitch.openapi.util.PreferenceKeys.Companion.BLOG_FILTER
1918
import com.codingwithmitch.openapi.util.PreferenceKeys.Companion.BLOG_ORDER
2019
import okhttp3.MediaType
@@ -26,49 +25,44 @@ class BlogViewModel
2625
constructor(
2726
private val sessionManager: SessionManager,
2827
private val blogRepository: BlogRepository,
29-
private val sharedPreferences: SharedPreferences
28+
sharedPreferences: SharedPreferences,
29+
private val editor: SharedPreferences.Editor
3030
)
3131
: BaseViewModel<BlogStateEvent, BlogViewState>()
3232
{
3333

3434
init {
3535
// set empty list to start
3636
setBlogListData(ArrayList<BlogPost>())
37+
38+
setBlogFilter(
39+
sharedPreferences.getString(
40+
BLOG_FILTER,
41+
BlogQueryUtils.BLOG_FILTER_DATE_UPDATED
42+
)
43+
)
44+
setBlogOrder(
45+
sharedPreferences.getString(
46+
BLOG_ORDER,
47+
BlogQueryUtils.BLOG_ORDER_ASC
48+
)
49+
)
3750
}
51+
3852
override fun handleStateEvent(stateEvent: BlogStateEvent): LiveData<DataState<BlogViewState>> {
3953
when(stateEvent){
4054
is BlogSearchEvent -> {
4155
return sessionManager.cachedToken.value?.let { authToken ->
4256
blogRepository.searchBlogPosts(
4357
authToken,
4458
viewState.value!!.blogFields.searchQuery,
45-
viewState.value!!.blogFields.order + viewState.value!!.blogFields.filter,
59+
viewState.value!!.blogFields.order
60+
+ viewState.value!!.blogFields.filter,
4661
viewState.value!!.blogFields.page
4762
)
4863
}?: AbsentLiveData.create()
4964
}
5065

51-
is NextPageEvent -> {
52-
Log.d(TAG, "BlogViewModel: NextPageEvent detected...")
53-
if(!viewState.value!!.blogFields.isQueryInProgress
54-
&& !viewState.value!!.blogFields.isQueryExhausted){
55-
Log.d(TAG, "BlogViewModel: Attempting to load next page...")
56-
setQueryInProgress(true)
57-
incrementPageNumber()
58-
return sessionManager.cachedToken.value?.let { authToken ->
59-
blogRepository.searchBlogPosts(
60-
authToken,
61-
viewState.value!!.blogFields.searchQuery,
62-
viewState.value!!.blogFields.order + viewState.value!!.blogFields.filter,
63-
viewState.value!!.blogFields.page
64-
)
65-
}?: AbsentLiveData.create()
66-
}
67-
else{
68-
return AbsentLiveData.create()
69-
}
70-
}
71-
7266
is CheckAuthorOfBlogPost ->{
7367
Log.d(TAG, "CheckAuthorOfBlogPost: called.")
7468
if(sessionManager.isConnectedToTheInternet()){
@@ -127,31 +121,26 @@ constructor(
127121
return BlogViewState()
128122
}
129123

130-
fun loadFirstPage() {
131-
setQueryInProgress(true)
132-
setQueryExhausted(false)
133-
resetPage()
134-
setBlogFilter(
135-
sharedPreferences.getString(
136-
BLOG_FILTER,
137-
BlogQueryUtils.BLOG_FILTER_DATE_UPDATED
138-
)
139-
)
140-
setBlogOrder(
141-
sharedPreferences.getString(
142-
BLOG_ORDER,
143-
BlogQueryUtils.BLOG_ORDER_DESC
144-
)
145-
)
146-
setStateEvent(BlogSearchEvent())
147-
Log.e(TAG, "BlogViewModel: loadFirstPage: ${viewState.value!!.blogFields.searchQuery}")
124+
fun getFilter(): String{
125+
return viewState.value!!.blogFields.filter
126+
}
127+
128+
fun getOrder(): String {
129+
return viewState.value!!.blogFields.order
148130
}
149131

150132
fun isAuthorOfBlogPost(): Boolean{
151-
Log.d(TAG, "isAuthorOfBlogPost: ${viewState.value!!.viewBlogFields.isAuthorOfBlogPost}")
152133
return viewState.value!!.viewBlogFields.isAuthorOfBlogPost
153134
}
154135

136+
fun saveFilterOptions(filter: String, order: String){
137+
editor.putString(BLOG_FILTER, filter)
138+
editor.apply()
139+
140+
editor.putString(BLOG_ORDER, order)
141+
editor.apply()
142+
}
143+
155144
fun cancelActiveJobs(){
156145
blogRepository.cancelActiveJobs()
157146
handlePendingData()

0 commit comments

Comments
 (0)