Commit b18b3d12 authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

added pull-to-request articles pages

parent 00b2983d
......@@ -15,6 +15,7 @@ import io.reactivex.schedulers.Schedulers
import timber.log.Timber
import timber.log.Timber.e
import javax.inject.Inject
import kotlin.math.floor
/**
* Created by Vladislav Bogdashkin on 29.10.2019.
......@@ -26,15 +27,15 @@ class FeedsContractModule @Inject constructor(
private val db: IDb
): FeedsContract {
override fun fetchFeeds(): Observable<List<FeedModel>> =
fetchAllFeeds().doOnError (::e)
override fun fetchFeedObservable(id: Int): Observable<ArticlesPreviewModel> =
fetchArticles(id)
override fun fetchFeedObservable(id: Int,pageSize:Int, startIndex:Int)
: Observable<ArticlesPreviewModel> = fetchArticles(id,pageSize,startIndex)
override fun getArticle(id: Int): Observable<ArticlePreviewModel> {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
......@@ -44,14 +45,14 @@ class FeedsContractModule @Inject constructor(
}
private fun fetchArticlessApi(feedId:Int): Observable<List<ArticleEntity>>? {
private fun fetchArticlessApi(feedId:Int,pageSize:Int, startIndex:Int): Observable<List<ArticleEntity>>? {
val feed = db.getFeed(feedId)?.firstOrNull()
if (feed == null) {
e("Unknown feedId: $feedId - cann't resolve feed_alias!")
throw CustomApiException.UnknownCustomApiException(-1,null,"Unknown Feed!")
}
else {
return api.getArticlesPage(feed.alias, 11, 1)
return api.getArticlesPage(feed.alias, pageSize, floor(startIndex.toDouble()/pageSize.toDouble()).toInt())
.doOnNext { Timber.d("raw0 $it") }
.map { it.items }
.map { fromRaw(it, feedId) }
......@@ -61,21 +62,21 @@ class FeedsContractModule @Inject constructor(
}
private fun fetchArticlesDb(feedId:Int): Observable<MutableList<ArticleEntity>>? {
private fun fetchArticlesDb(feedId:Int,pageSize:Int, startIndex:Int): Observable<MutableList<ArticleEntity>>? {
val feed = db.getFeed(feedId)?.firstOrNull()
if (feed == null) {
e("Unknown feedId: $feedId - cann't resolve feed_alias!")
throw CustomApiException.UnknownCustomApiException(-1, null, "Unknown Feed!")
} else return db.fetchArticles(feed.alias, 11, 1)
} else return db.fetchArticles(feed.alias, pageSize, startIndex)
.toList()
.toObservable()
.subscribeOn(Schedulers.io())
}
private fun fetchArticles(feedId:Int): Observable<ArticlesPreviewModel> =
private fun fetchArticles(feedId:Int,pageSize:Int = 10, startIndex:Int = 0): Observable<ArticlesPreviewModel> =
Observable.mergeDelayError(
arrayListOf(fetchArticlessApi(feedId),fetchArticlesDb(feedId))
).map { fromEntity(feedId,it) }
arrayListOf(fetchArticlessApi(feedId,pageSize,startIndex),fetchArticlesDb(feedId,pageSize,startIndex))
).take(1).map { fromEntity(feedId,it) }
private fun fetchFeedsApi() =
......
package com.biganto.visual.roompark.di.dagger
import android.app.Application
import com.biganto.visual.androidplayer.data.repository.local.ILocalStore
import com.biganto.visual.roompark.base.RoomParkApplication
import com.biganto.visual.roompark.data.local.UserState
import com.biganto.visual.roompark.data.repository.api.IRoomParkApi
import com.biganto.visual.roompark.data.repository.db.IDb
import com.biganto.visual.roompark.data.repository.mapper.fromRaw
import com.biganto.visual.roompark.domain.contract.AuthContract
import com.biganto.visual.roompark.domain.model.AuthInfoModel
import com.biganto.visual.roompark.domain.model.fromEntity
import dagger.Binds
import dagger.Module
import io.reactivex.Completable
import io.reactivex.Observable
import timber.log.Timber
import javax.inject.Inject
/**
* Created by Vladislav Bogdashkin on 13.06.2018.
......@@ -33,7 +21,7 @@ const val ESTATES_CACHE_LIMIT_SECONDS_INACTIVE = 200L
const val FILES_CACHE_LIMIT_SIZE = 10000
const val FILES_CACHE_LIMIT_SECONDS_INACTIVE = 60L
const val DATABASE_VERSION = 6
const val DATABASE_VERSION = 7
@Module
abstract class AppModule{
......
......@@ -14,4 +14,9 @@ interface FeedsContract{
fun fetchFeeds(): Observable<List<FeedModel>>
fun getArticle(id:Int): Observable<ArticlePreviewModel>
fun fetchFeedObservable(id: Int): Observable<ArticlesPreviewModel>
fun fetchFeedObservable(
id: Int,
pageSize: Int,
startIndex: Int
): Observable<ArticlesPreviewModel>
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import com.biganto.visual.roompark.domain.model.*
import com.biganto.visual.roompark.domain.use_case.FeedUseCase
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
import java.util.*
import javax.inject.Inject
......@@ -29,7 +30,8 @@ class FeedsInteractor @Inject constructor(
// else -> error("unknown feedId")
// }
// )
fun fetchArticles(feedId: Int,pageSize:Int,startIndex:Int): Observable<ArticlesPreviewModel> =
feedsUseCase.fetchArticlesPage(feedId,pageSize,startIndex)
fun fetchAlbums(): Single<List<AlbumPreviewModel>> = Single.just(albumsPreviews)
......
......@@ -16,6 +16,9 @@ class FeedUseCase @Inject constructor(
fun getArticles(feedId:Int) =
contract.fetchFeedObservable(feedId)
fun fetchArticlesPage(feedId:Int,pageSize:Int,startIndex:Int) =
contract.fetchFeedObservable(feedId,pageSize,startIndex)
}
\ No newline at end of file
package com.biganto.visual.roompark.presentation.screen.feeds
import com.biganto.visual.roompark.conductor.BigantoBaseContract
import com.biganto.visual.roompark.domain.model.FeedModel
import io.reactivex.Observable
/**
......@@ -9,6 +10,7 @@ import io.reactivex.Observable
interface FeedsScreen : BigantoBaseContract<FeedsScreenViewState> {
fun feedsTabSelected(): Observable<Int>
fun requsetsNewArticles(): Observable<Pair<FeedModel, Int>>
}
......
......@@ -22,6 +22,7 @@ import com.google.android.material.button.MaterialButton
import com.google.android.material.tabs.TabLayout
import com.google.android.material.textview.MaterialTextView
import com.jakewharton.rxbinding3.material.selections
import com.jakewharton.rxbinding3.recyclerview.scrollStateChanges
import com.jakewharton.rxbinding3.view.clicks
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
......@@ -70,6 +71,18 @@ class FeedsScreenController :
lateinit var feedsBlockView:ViewGroup
override fun requsetsNewArticles() =
feedsRecyclerView.scrollStateChanges()
.filter { it == RecyclerView.SCROLL_STATE_IDLE}
.map { feedsRecyclerView.layoutManager as LinearLayoutManager }
.map { it.findLastCompletelyVisibleItemPosition() }
.doOnNext { Timber.d("Visible items $it of ${(feedsRecyclerView.adapter?.itemCount?:0) - 3}") }
.filter { it>(feedsRecyclerView.adapter?.itemCount?:0)-2 }
.map { feedsRecyclerView.adapter?.itemCount?:0 }
.map { Pair(storedFeedsList[feedsTabs.selectedTabPosition],it)}
.debounce(120L,TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
private fun bindRecycler(){
feedsRecyclerView.isNestedScrollingEnabled = true
feedsRecyclerView.layoutManager =
......@@ -120,6 +133,7 @@ class FeedsScreenController :
is FeedsScreenViewState.Idle -> render(viewState)
is FeedsScreenViewState.FeedsPages -> render(viewState)
is FeedsScreenViewState.AlbumsPages -> render(viewState)
is FeedsScreenViewState.ArticlesScrollPage -> render(viewState)
is FeedsScreenViewState.CamsList -> render(viewState)
is FeedsScreenViewState.GetFeedArticlesPreview -> render(viewState)
is FeedsScreenViewState.RestoreView -> render(viewState)
......@@ -161,6 +175,10 @@ class FeedsScreenController :
(devProgressRecyclerView.adapter as AlbumsPreviewAdapter).setItems(viewState.items)
}
private fun render(viewState: FeedsScreenViewState.ArticlesScrollPage){
(feedsRecyclerView.adapter as ArticlesPreviewAdapter).addItems(viewState.items)
}
private fun render(viewState: FeedsScreenViewState.GetFeedArticlesPreview){
(feedsRecyclerView.adapter as ArticlesPreviewAdapter).setItems(viewState.items)
}
......
......@@ -12,6 +12,7 @@ import javax.inject.Inject
* Created by Vladislav Bogdashkin on 30.09.2019.
*/
const val FEED_PREVIEW_PAGE_SIZE = 10
class FeedsScreenPresenter @Inject constructor(
private val interactor: FeedsInteractor
......@@ -62,11 +63,19 @@ class FeedsScreenPresenter @Inject constructor(
FeedsScreenViewState.GetFeedArticlesPreview(it.articles.toList())
}
val getNewArticlesPage = intent(FeedsScreen::requsetsNewArticles)
.flatMap { interactor.fetchArticles(it.first.feedId, FEED_PREVIEW_PAGE_SIZE,it.second) }
.map {
restoreModel.articles = it.articles
FeedsScreenViewState.ArticlesScrollPage(it.articles.toList())
}
val state = restoreStateObservable
.mergeWith(fetchFeeds)
.mergeWith(getFeedArticlesPreview)
.mergeWith(fetchAlbums)
.mergeWith(fetchCams)
.mergeWith(getNewArticlesPage)
.doOnError{ Timber.e(it)}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
......
......@@ -19,6 +19,7 @@ sealed class FeedsScreenViewState : BigantoBaseViewState() {
class CamsList(val items:List<WebCamModel>) : FeedsScreenViewState()
class GetFeedArticlesPreview(val items:List<ArticlePreviewModel>) : FeedsScreenViewState()
class ArticlesScrollPage(val items:List<ArticlePreviewModel>) : FeedsScreenViewState()
class RestoreView(val restore:RestoreModel) : FeedsScreenViewState()
......
......@@ -20,6 +20,8 @@ class AlbumsPreviewAdapter : CommonRecyclerAdapter<AlbumCardViewHolder,AlbumPrev
override val vhKlazz = AlbumCardViewHolder::class
override fun getVhLayout(): Int = R.layout.estate_card_viewholder
}
......
......@@ -40,6 +40,11 @@ abstract class CommonRecyclerAdapter<VH:CommonViewHolder<M>,M:Any> : RecyclerVie
notifyDataSetChanged()
}
fun addItems(items:List<M>){
this.list.addAll(list)
notifyItemRangeInserted(list.size-items.size,items.size)
}
protected abstract val vhKlazz : KClass<VH>
@LayoutRes
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment