Commit 0c141bec authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

fix estate offline behaviour

parent 65a0a1b2
......@@ -102,6 +102,7 @@ abstract class BigantoBaseController<VS : BigantoBaseViewState,V: BigantoBaseCon
}
override fun handleBack(): Boolean {
detachDisposable.clear()
router.popController(this)
return true
// return super.handleBack()
......
......@@ -47,17 +47,16 @@ class EstateRepository @Inject constructor(
.toList().toObservable()
.doOnError(Timber::e)
){apiList,dbList ->
if (dbList.isEmpty())
return@zip apiList
apiList.forEach { estate ->
estate.setFavorite(true)
estate.user = user
}
dbList
.filterNotNull()
.filter { dbFav ->!apiList.map{it.id}.contains(dbFav.id) }
.let{ db.deleteEstate(it) }
apiList.forEach { estate ->
estate.setFavorite(true)
estate.user = user
}
return@zip apiList
}
.flatMap(db::upsertEstates)
......@@ -72,54 +71,6 @@ class EstateRepository @Inject constructor(
.map { it.map {deal -> deal.estate as EstateEntity } }
.doOnNext { db.refreshUser(user) }
private val getFavoritesApi: Observable<List<EstateEntity>> =
local.recentUser()
.flatMap {
when (it) {
is UserState.Authenticated -> db.fetchUser(it.uuid.toInt())
else -> throw CustomApiException.NotAuthorizedException()
}
}
.flatMap { user ->
api.getFavorites(user.authToken)
.doOnError(Timber::e)
.map { fromRawList(it, ::fromRaw) }
.doOnNext {
it.forEach { estate ->
estate.setFavorite(true)
estate.user = user
}
}
.doOnNext(db::blockingUpsert)
.doOnNext{ db.refreshUser(user) }
}
private val getFavoritesDb: Observable<MutableList<EstateEntity?>>? =
local.recentUser()
.flatMap {
when (it) {
is UserState.Authenticated -> db.fetchUser(it.uuid.toInt()).take(1)
else -> throw CustomApiException.NotAuthorizedException()
}
}
.flatMap {
db.getUserFavorites(it.uuid)
.doOnError(Timber::e)
.toList().toObservable()
}
override fun getFavorites(user:UserEntity): Observable<List<EstateModel>> {
return Observable.mergeDelayError(
arrayListOf(
fetchFavorites(user), getFavoritesDb
)
)
.map { it.filterNotNull() }
.map { fromEntity(it, ::fromEntity) }
.doOnError(Timber::e)
}
private fun fetchEstateDb(id: Int) = db.getEstate(id)
......
......@@ -21,5 +21,4 @@ interface DealContract{
fun setDealRead(dealId: String): Completable
fun fetchDeals(user: UserEntity): Observable<List<EstateEntity>>
fun fetchFavorites(user: UserEntity): Observable<List<EstateEntity>>
fun getFavorites(user: UserEntity): Observable<List<EstateModel>>
}
\ No newline at end of file
......@@ -15,6 +15,9 @@ class FavoritesInteractor @Inject constructor(
private val estateUseCase: EstateUseCase
) {
fun cachedFavorites() =
estateUseCase.prefetchFavorites()
fun getFavoritesForCurrentUser() =
estateUseCase.fetchFavorites()
// Single.just(parkingEstateSample )
......@@ -52,6 +55,7 @@ class FavoritesInteractor @Inject constructor(
albumId = 10,
multitourId = null,
url = null
,availableStatus = true
),
EstateModel(
id = 1905,
......@@ -81,7 +85,7 @@ class FavoritesInteractor @Inject constructor(
albumId = 10,
multitourId = null,
url = null
),
,availableStatus = true),
EstateModel(
id = 1774,
type = FlatType.valueOf("flat".toUpperCase()),
......@@ -118,6 +122,7 @@ class FavoritesInteractor @Inject constructor(
albumId = 10,
url = null,
multitourId = 5790
,availableStatus = true
// ,explications = arrayListOf<ExplicationListModel>(
// ExplicationListModel(
// planId = 0,
......
......@@ -51,6 +51,7 @@ data class EstateModel(
val id:Int,
val type:FlatType,
val number:String,
val availableStatus:Boolean,
val sectionBegin:Int?=null,
val sectionEnd:Int?=null,
val planPNG:PlanModel?,
......@@ -90,6 +91,7 @@ fun fromEntity(entity:EstateEntity): EstateModel {
id = entity.id,
type = FlatType.valueOf(entity.type.toUpperCase()),
number = entity.number,
availableStatus = entity.available,
sectionBegin = entity.sectionBegin,
sectionEnd = entity.sectionEnd,
planPNG = null,
......
package com.biganto.visual.roompark.domain.use_case
import com.biganto.visual.roompark.data.repository.db.requrey.model.EstateEntity
import com.biganto.visual.roompark.domain.contract.AuthContract
import com.biganto.visual.roompark.domain.contract.DealContract
import com.biganto.visual.roompark.domain.contract.FlatPlanContract
import com.biganto.visual.roompark.domain.model.EstateModel
import com.biganto.visual.roompark.domain.model.fromEntity
import io.reactivex.Observable
import javax.inject.Inject
......@@ -17,9 +19,19 @@ class EstateUseCase @Inject constructor(
private val authContract: AuthContract
) {
fun prefetchFavorites() =
authContract.currentUser()
.map {user -> user.estates?.asSequence()
?.map { it as EstateEntity }
?.filter{ it.favorite }?.filterNotNull()?.toList()
}
.map { fromEntity(it, ::fromEntity) }
fun fetchFavorites(): Observable<List<EstateModel>> =
authContract.currentUser()
.flatMap (contract::getFavorites)
.flatMap (contract::fetchFavorites)
.map { fromEntity(it, ::fromEntity) }
fun getEstate(estateId: Int) = contract.getEstate(estateId)
......
......@@ -215,7 +215,8 @@ class EstateScreenController :
if (it.scrollY > flatTitle.measuredHeight) {
val status = estateModel?.to(
StatusToolbarModel(
StatusState.AVAILABLE
if (estateModel?.availableStatus == true) StatusState.AVAILABLE
else StatusState.SOLD_OUT
, null
, resources?.getString(
estateModel?.type?.typeShortString() ?: -1
......@@ -229,7 +230,8 @@ class EstateScreenController :
} else toolBar.setToolbar(
null,
StatusToolbarModel(
StatusState.AVAILABLE, null, null
if (estateModel?.availableStatus == true) StatusState.AVAILABLE
else StatusState.SOLD_OUT, null, null
)
)
}
......@@ -237,7 +239,8 @@ class EstateScreenController :
}
private fun bindRecycler() {
flatInfoRecyclerView.isNestedScrollingEnabled = true
flatScroll.isNestedScrollingEnabled = false
flatInfoRecyclerView.isNestedScrollingEnabled = false
flatInfoRecyclerView.layoutManager =
LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
flatInfoRecyclerView.adapter = FlatInfoAdapter()
......@@ -378,8 +381,15 @@ class EstateScreenController :
}
private fun setEstateInfo(estateModel: EstateModel?){
this.estateModel = estateModel
toolBar.setToolbar(
null, StatusToolbarModel(StatusState.AVAILABLE,null, null)
null,
StatusToolbarModel(
if (estateModel?.availableStatus == true) StatusState.AVAILABLE
else StatusState.SOLD_OUT
, null
, null
)
)
estateModel?.let {estate ->
flatTitle.text = resources?.getString(estate.type.typeShortString()
......@@ -402,6 +412,7 @@ class EstateScreenController :
.into(tourScreen)
}
when(estateModel?.type){
FlatType.FLAT -> {
flatTypeView.setGone(false)
......
......@@ -66,6 +66,7 @@ class FavoritesScreenController :
}
private fun setToolbar(){
R.string.area_living
favoritesRecyclerView.isNestedScrollingEnabled = false
toolBar.setToolbar(
......@@ -76,7 +77,7 @@ class FavoritesScreenController :
}
private fun bindRecycler() {
favoritesRecyclerView.isNestedScrollingEnabled = true
favoritesRecyclerView.isNestedScrollingEnabled = false
favoritesRecyclerView.layoutManager =
LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
favoritesRecyclerView.adapter = FavoritesListAdapter()
......@@ -104,6 +105,7 @@ class FavoritesScreenController :
is FavoritesScreenViewState.FavoriteEstatesLoaded -> render(viewState)
is FavoritesScreenViewState.SomeError -> render(viewState)
is FavoritesScreenViewState.ToursLoaded -> render(viewState)
is FavoritesScreenViewState.RestoreView -> render(viewState)
}
}
......
......@@ -34,14 +34,21 @@ class FavoritesScreenPresenter @Inject constructor(
override fun bindIntents() {
val prefetchCards = interactor.getFavoritesForCurrentUser()
val prefetchCards = interactor.cachedFavorites()
.doOnNext { restoreModel.list = it.toMutableList() }
.map { FavoritesScreenViewState.FavoriteEstatesLoaded(it) }
.map<FavoritesScreenViewState> { FavoritesScreenViewState.FavoriteEstatesLoaded(it) }
.onErrorReturn (::parseError)
val invalidateData = interactor.getFavoritesForCurrentUser()
.doOnNext { restoreModel.list = it.toMutableList() }
.map<FavoritesScreenViewState> { FavoritesScreenViewState.FavoriteEstatesLoaded(it) }
.onErrorReturn (::parseError)
val onStartTours = intent(FavoritesScreen::tourCardClicked)
.flatMap {estate -> toursInteractor.getEstateTourList(estate)
.map { FavoritesScreenViewState.ToursLoaded(it) }
.map<FavoritesScreenViewState> { FavoritesScreenViewState.ToursLoaded(it) }
.onErrorReturn (::parseError)
}
......@@ -49,6 +56,7 @@ class FavoritesScreenPresenter @Inject constructor(
arrayListOf(
restoreStateObservable,
prefetchCards,
invalidateData,
onStartTours
)
)
......
......@@ -14,6 +14,7 @@ import com.biganto.visual.roompark.presentation.screen.settings.util.CommonRecyc
import com.biganto.visual.roompark.presentation.screen.settings.util.CommonViewHolder
import com.biganto.visual.roompark.util.extensions.setGone
import com.biganto.visual.roompark.util.extensions.startUrl
import com.google.android.material.textview.MaterialTextView
import com.jakewharton.rxbinding3.view.clicks
import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject
......@@ -39,6 +40,9 @@ class FavoritesListAdapter : CommonRecyclerAdapter<FavoriteViewHolder,EstateMode
class FavoriteViewHolder(itemView: View) : CommonViewHolder<EstateModel>(itemView) {
@BindView(R.id.avaliable_text) lateinit var availableText: MaterialTextView
@BindView(R.id.avaliable_status) lateinit var availableStatus:View
@BindView(R.id.object_card_title) lateinit var estateTitle: TextView
@BindView(R.id.common_info_block) lateinit var commonInfo:View
@BindView(R.id.start_tour_button) lateinit var startTour:View
......@@ -62,7 +66,8 @@ class FavoriteViewHolder(itemView: View) : CommonViewHolder<EstateModel>(itemVie
ButterKnife.bind(this, itemView)
}
val onStartTourObs: Observable<EstateModel> get() = startTour.clicks().map { bindedModel }
val onStartTourObs: Observable<EstateModel> get() =
startTour.clicks().filter { bindedModel.availableStatus }.map { bindedModel }
override fun onViewBound(model: EstateModel) {
estateTitle.text =
......@@ -74,6 +79,13 @@ class FavoriteViewHolder(itemView: View) : CommonViewHolder<EstateModel>(itemVie
startTour.setGone(model.multitourId == null)
availableStatus.isEnabled = model.availableStatus
availableText.text = itemView.resources.getString(
if (model.availableStatus) R.string.estate_avalibale
else R.string.estate_sold_out
)
siteLink.setGone(model.url == null)
siteLinkDivider.setGone(model.url == null)
model.url?.let {url ->
......@@ -97,11 +109,11 @@ class FavoriteViewHolder(itemView: View) : CommonViewHolder<EstateModel>(itemVie
if (info.area == null) info1.visibility = View.GONE
else { info4.title().text = "Общая, м²"; info4.text().text = info.area.toString()}
if (info.price_meter == null) info1.visibility = View.GONE
else { info5.title().text = "Цена за м²"; info5.text().text = info.price_meter.toRubles()}
if (info.price_meter == null && !bindedModel.availableStatus) info1.visibility = View.GONE
else { info5.title().text = "Цена за м²"; info5.text().text = info.price_meter?.toRubles()}
if (info.price == null) info1.visibility = View.GONE
else { info6.title().text = "Стоимость"; info6.text().text = info.price.toRubles()}
if (info.price == null && !bindedModel.availableStatus) info1.visibility = View.GONE
else { info6.title().text = "Стоимость"; info6.text().text = info.price?.toRubles()}
if (true) info7.visibility = View.GONE
else { info7.title().text = "вщщ"; info7.text().text = info.building.toString()}
......
......@@ -18,17 +18,16 @@
android:padding="16dp">
<FrameLayout
android:id="@+id/feed_read"
android:id="@+id/avaliable_status"
android:layout_width="12dp"
android:layout_height="12dp"
android:background="@drawable/new_feed_icon"
android:backgroundTint="@color/colorAccent"
android:background="@drawable/available_status"
android:visibility="visible"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/feed_date_text_view3"
<com.google.android.material.textview.MaterialTextView
android:id="@+id/avaliable_text"
style="@style/LiteText.Accent"
android:layout_width="0dp"
android:layout_height="wrap_content"
......@@ -38,7 +37,7 @@
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/feed_read"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/feed_read"
app:layout_constraintStart_toEndOf="@+id/avaliable_status"
app:layout_constraintTop_toTopOf="@+id/feed_read" />
<com.google.android.material.textview.MaterialTextView
......@@ -50,7 +49,7 @@
android:text="\n"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/feed_date_text_view3" />
app:layout_constraintTop_toBottomOf="@+id/avaliable_text" />
<include
android:id="@+id/header_divider"
......
......@@ -16,7 +16,6 @@
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/available_status"
android:fitsSystemWindows="true"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
......@@ -27,9 +26,8 @@
style="@style/Accent_Minor_TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_marginStart="8dp"
android:fitsSystemWindows="true"
android:text="СВОБОДНА"
app:layout_constraintBottom_toBottomOf="@+id/status_icon"
app:layout_constraintStart_toEndOf="@+id/status_icon"
app:layout_constraintTop_toTopOf="@+id/status_icon" />
......
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