Commit 420dfc3f authored by Vladislav Bogdashkin's avatar Vladislav Bogdashkin 🎣

albums sub

parent 9e6c70f1
package com.biganto.visual.roompark.domain.interactor package com.biganto.visual.roompark.domain.interactor
import com.biganto.visual.roompark.domain.model.AlbumSortedModel import com.biganto.visual.roompark.domain.model.AlbumSortedModel
import com.biganto.visual.roompark.domain.model.SubscriptionModel
import com.biganto.visual.roompark.domain.model.SubscriptionTopic
import com.biganto.visual.roompark.domain.use_case.AlbumsUseCase import com.biganto.visual.roompark.domain.use_case.AlbumsUseCase
import com.biganto.visual.roompark.domain.use_case.SubscriptionUseCase
import io.reactivex.Completable
import io.reactivex.Observable import io.reactivex.Observable
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
...@@ -11,9 +15,12 @@ import javax.inject.Inject ...@@ -11,9 +15,12 @@ import javax.inject.Inject
*/ */
class AlbumsInteractor @Inject constructor( class AlbumsInteractor @Inject constructor(
private val useCase: AlbumsUseCase) { private val useCase: AlbumsUseCase,
private val subUc: SubscriptionUseCase
) {
fun fetchHeaderAlbums() = useCase.getProgressAlbums() fun fetchHeaderAlbums() = useCase.getProgressAlbums()
fun fetchAlbumPhotos(parentId: Int): Observable<List<AlbumSortedModel>> = fun fetchAlbumPhotos(parentId: Int): Observable<List<AlbumSortedModel>> =
useCase.getChildAlbums(parentId) useCase.getChildAlbums(parentId)
.flatMap { .flatMap {
...@@ -31,6 +38,15 @@ class AlbumsInteractor @Inject constructor( ...@@ -31,6 +38,15 @@ class AlbumsInteractor @Inject constructor(
} }
.debounce(80L, TimeUnit.MILLISECONDS) // to reduce double list draw effect .debounce(80L, TimeUnit.MILLISECONDS) // to reduce double list draw effect
fun getSubscriptions(topic: SubscriptionTopic) =
subUc.getSubscriptions(topic)
fun switchSubscription(model: SubscriptionModel, newState: Boolean): Completable =
when(newState){
true -> subUc.subscribeTopic(model.id,model.topic)
false -> subUc.unSubscribeTopic(model.id,model.topic)
}
} }
......
...@@ -2,7 +2,11 @@ package com.biganto.visual.roompark.domain.interactor ...@@ -2,7 +2,11 @@ package com.biganto.visual.roompark.domain.interactor
import com.biganto.visual.roompark.domain.model.DealModel import com.biganto.visual.roompark.domain.model.DealModel
import com.biganto.visual.roompark.domain.model.StatusModel import com.biganto.visual.roompark.domain.model.StatusModel
import com.biganto.visual.roompark.domain.model.SubscriptionModel
import com.biganto.visual.roompark.domain.model.SubscriptionTopic
import com.biganto.visual.roompark.domain.use_case.DealseUseCase import com.biganto.visual.roompark.domain.use_case.DealseUseCase
import com.biganto.visual.roompark.domain.use_case.SubscriptionUseCase
import io.reactivex.Completable
import io.reactivex.Observable import io.reactivex.Observable
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
...@@ -12,7 +16,8 @@ import javax.inject.Inject ...@@ -12,7 +16,8 @@ import javax.inject.Inject
*/ */
class DealInteractor @Inject constructor( class DealInteractor @Inject constructor(
val useCase : DealseUseCase val useCase : DealseUseCase,
val subUc : SubscriptionUseCase
){ ){
fun getDeal(id:String): Observable<DealModel> = fun getDeal(id:String): Observable<DealModel> =
...@@ -26,6 +31,15 @@ class DealInteractor @Inject constructor( ...@@ -26,6 +31,15 @@ class DealInteractor @Inject constructor(
fun setDealRead(id:String) = useCase.setDealRead(id) fun setDealRead(id:String) = useCase.setDealRead(id)
fun getSubscriptions(dealId: String) =
subUc.getSubscriptions(SubscriptionTopic.Deals(dealId = dealId))
fun switchSubscription(model: SubscriptionModel, newState: Boolean): Completable =
when(newState){
true -> subUc.subscribeTopic(model.id,model.topic)
false -> subUc.unSubscribeTopic(model.id,model.topic)
}
companion object { companion object {
val statusList = arrayListOf<StatusModel>( val statusList = arrayListOf<StatusModel>(
......
...@@ -2,11 +2,11 @@ package com.biganto.visual.roompark.domain.interactor ...@@ -2,11 +2,11 @@ package com.biganto.visual.roompark.domain.interactor
import android.content.Context import android.content.Context
import com.biganto.visual.roompark.R import com.biganto.visual.roompark.R
import com.biganto.visual.roompark.domain.model.CachedDataModel import com.biganto.visual.roompark.domain.model.*
import com.biganto.visual.roompark.domain.model.PushSwitchModel
import com.biganto.visual.roompark.domain.model.SettingsModel
import com.biganto.visual.roompark.domain.use_case.AuthUseCase import com.biganto.visual.roompark.domain.use_case.AuthUseCase
import com.biganto.visual.roompark.domain.use_case.SettingsUseCase import com.biganto.visual.roompark.domain.use_case.SettingsUseCase
import com.biganto.visual.roompark.domain.use_case.SubscriptionUseCase
import io.reactivex.Completable
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import javax.inject.Inject import javax.inject.Inject
...@@ -18,9 +18,21 @@ import javax.inject.Inject ...@@ -18,9 +18,21 @@ import javax.inject.Inject
class SettingsInteractor @Inject constructor( class SettingsInteractor @Inject constructor(
private val auth: AuthUseCase, private val auth: AuthUseCase,
private val settingsUseCase: SettingsUseCase, private val settingsUseCase: SettingsUseCase,
private val activity: Context private val activity: Context,
private val subUc: SubscriptionUseCase
){ ){
fun getSubscriptions(topic: SubscriptionTopic) =
subUc.getSubscriptions(topic)
fun switchSubscription(model: SubscriptionModel, newState: Boolean): Completable =
when(newState){
true -> subUc.subscribeTopic(model.id,model.topic)
false -> subUc.unSubscribeTopic(model.id,model.topic)
}
private val plans private val plans
get() = settingsUseCase.planTypesSize.map { get() = settingsUseCase.planTypesSize.map {
CachedDataModel(activity.resources.getString(R.string.plans_cache),it,1) CachedDataModel(activity.resources.getString(R.string.plans_cache),it,1)
......
...@@ -12,4 +12,5 @@ import io.reactivex.Observable ...@@ -12,4 +12,5 @@ import io.reactivex.Observable
interface AlbumsScreen : BigantoBaseContract<AlbumsScreenViewState> { interface AlbumsScreen : BigantoBaseContract<AlbumsScreenViewState> {
fun onAlbumSelected(): Observable<AlbumPreviewModel> fun onAlbumSelected(): Observable<AlbumPreviewModel>
fun onPhotoSelected(): Observable<PhotoModel> fun onPhotoSelected(): Observable<PhotoModel>
fun onSubscription(): Observable<Boolean>
} }
\ No newline at end of file
...@@ -20,13 +20,16 @@ import com.biganto.visual.roompark.presentation.screen.albums.util.AlbumListAdap ...@@ -20,13 +20,16 @@ import com.biganto.visual.roompark.presentation.screen.albums.util.AlbumListAdap
import com.biganto.visual.roompark.presentation.screen.albums.util.AlbumsHeaderAdapter import com.biganto.visual.roompark.presentation.screen.albums.util.AlbumsHeaderAdapter
import com.biganto.visual.roompark.presentation.screen.albums.util.BubbleSlider import com.biganto.visual.roompark.presentation.screen.albums.util.BubbleSlider
import com.biganto.visual.roompark.presentation.screen.photo.PhotoScreenController import com.biganto.visual.roompark.presentation.screen.photo.PhotoScreenController
import com.biganto.visual.roompark.util.monades.ExceptionString
import com.biganto.visual.roompark.util.view_utils.grid.CeilsDecoration import com.biganto.visual.roompark.util.view_utils.grid.CeilsDecoration
import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.RouterTransaction
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition import com.bumptech.glide.request.transition.Transition
import com.google.android.material.switchmaterial.SwitchMaterial
import com.google.android.material.textview.MaterialTextView import com.google.android.material.textview.MaterialTextView
import com.jakewharton.rxbinding3.widget.checkedChanges
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import jp.wasabeef.glide.transformations.BlurTransformation import jp.wasabeef.glide.transformations.BlurTransformation
...@@ -123,20 +126,26 @@ class AlbumsScreenController : ...@@ -123,20 +126,26 @@ class AlbumsScreenController :
@Inject @Inject
override lateinit var injectedPresenter: AlbumsScreenPresenter override lateinit var injectedPresenter: AlbumsScreenPresenter
// @Inject
// lateinit var snacky:ISnackBarProvider
lateinit var rpActivity: RoomParkMainActivity
fun getComponent() = DaggerAlbumsScreenComponent.factory() fun getComponent() = DaggerAlbumsScreenComponent.factory()
.create(RoomParkApplication.component .create(RoomParkApplication.component
,activity as RoomParkMainActivity ,activity as RoomParkMainActivity
,args.getInt(SELECTED_ALBUM_INDEX_KEY)) ,args.getInt(SELECTED_ALBUM_INDEX_KEY))
.inject(this) .inject(this)
// @Inject
// lateinit var ac: RoomParkMainActivity override fun onSubscription(): Observable<Boolean> =
toolBar.headerToolbar.findViewById<SwitchMaterial>(R.id.switch1)
.checkedChanges()
.skip(1) //skip init switcher check state
.filter {
if (!silentCheck) return@filter !silentCheck
else silentCheck = false
silentCheck
}
.doOnNext { }
.debounce(600L, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
override fun render(viewState: AlbumsScreenViewState) { override fun render(viewState: AlbumsScreenViewState) {
...@@ -148,6 +157,8 @@ class AlbumsScreenController : ...@@ -148,6 +157,8 @@ class AlbumsScreenController :
is AlbumsScreenViewState.PhotoSelected -> render(viewState) is AlbumsScreenViewState.PhotoSelected -> render(viewState)
is AlbumsScreenViewState.SomeError -> render(viewState) is AlbumsScreenViewState.SomeError -> render(viewState)
is AlbumsScreenViewState.RestoreView -> render(viewState) is AlbumsScreenViewState.RestoreView -> render(viewState)
is AlbumsScreenViewState.SubscriptionStatus -> render(viewState)
is AlbumsScreenViewState.SubscriptionError -> render(viewState)
} }
} }
...@@ -163,6 +174,30 @@ class AlbumsScreenController : ...@@ -163,6 +174,30 @@ class AlbumsScreenController :
) )
} }
private var silentCheck = false
private fun render(viewState: AlbumsScreenViewState.SubscriptionStatus) {
val sw = toolBar.headerToolbar.findViewById<SwitchMaterial>(R.id.switch1)
if (sw.isChecked != viewState.subState)
{
silentCheck = true
sw.isChecked != sw.isChecked
}
}
private fun render(viewState: AlbumsScreenViewState.SubscriptionError) {
val sw = toolBar.headerToolbar.findViewById<SwitchMaterial>(R.id.switch1)
if (sw.isChecked != viewState.subState)
{
silentCheck = true
sw.isChecked = viewState.subState
}
if (viewState.subState)
showError(ExceptionString(R.string.unsubscribe_error_message,null))
else showError(ExceptionString(R.string.subscribe_error_message,null))
}
private fun render(viewState: AlbumsScreenViewState.SomeError) = private fun render(viewState: AlbumsScreenViewState.SomeError) =
showError(viewState.exception) showError(viewState.exception)
......
...@@ -4,10 +4,13 @@ import com.biganto.visual.roompark.conductor.BigantoBasePresenter ...@@ -4,10 +4,13 @@ import com.biganto.visual.roompark.conductor.BigantoBasePresenter
import com.biganto.visual.roompark.domain.interactor.AlbumsInteractor import com.biganto.visual.roompark.domain.interactor.AlbumsInteractor
import com.biganto.visual.roompark.domain.model.AlbumPreviewModel import com.biganto.visual.roompark.domain.model.AlbumPreviewModel
import com.biganto.visual.roompark.domain.model.AlbumSortedModel import com.biganto.visual.roompark.domain.model.AlbumSortedModel
import com.biganto.visual.roompark.domain.model.SubscriptionModel
import com.biganto.visual.roompark.domain.model.SubscriptionTopic
import com.biganto.visual.roompark.util.monades.ExceptionString import com.biganto.visual.roompark.util.monades.ExceptionString
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Named import javax.inject.Named
...@@ -21,22 +24,37 @@ class AlbumsScreenPresenter @Inject constructor( ...@@ -21,22 +24,37 @@ class AlbumsScreenPresenter @Inject constructor(
) )
: BigantoBasePresenter<AlbumsScreen, AlbumsScreenViewState>() { : BigantoBasePresenter<AlbumsScreen, AlbumsScreenViewState>() {
private var restoreModel = RestoreModel(listOf(), listOf(),selectedIndex) private var restoreModel = RestoreModel(listOf(), listOf(), selectedIndex,null)
override fun defaultErrorViewStateHandler() = override fun defaultErrorViewStateHandler() =
{e: ExceptionString -> AlbumsScreenViewState.SomeError(e) } { e: ExceptionString -> AlbumsScreenViewState.SomeError(e) }
private fun requestAlbum(id:Int):Observable<AlbumsScreenViewState> = private fun requestAlbum(id: Int): Observable<AlbumsScreenViewState> =
interactor.fetchAlbumPhotos(id) interactor.fetchAlbumPhotos(id)
.filter { !it.isNullOrEmpty() } .filter { !it.isNullOrEmpty() }
.doOnNext{ restoreModel.albumList = it } .doOnNext { restoreModel.albumList = it }
.map { AlbumsScreenViewState.AlbumsSelected(it)} .map { AlbumsScreenViewState.AlbumsSelected(it) }
override fun bindIntents() { override fun bindIntents() {
val onSubChecked = intent(AlbumsScreen::onSubscription)
.filter { restoreModel.sub != null }
.flatMap { newState ->
interactor.switchSubscription(restoreModel.sub!!, newState)
.andThen(
Observable.just<AlbumsScreenViewState>(
AlbumsScreenViewState.SubscriptionStatus(
newState
)
)
)
.onErrorReturn { AlbumsScreenViewState.SubscriptionError(!newState) }
}
val fetchParents = interactor.fetchHeaderAlbums() val fetchParents = interactor.fetchHeaderAlbums()
.filter { !it.isNullOrEmpty() } .filter { !it.isNullOrEmpty() }
.doOnNext{ restoreModel.albumsPreview = it } .doOnNext { restoreModel.albumsPreview = it }
.map { AlbumsScreenViewState.AlbumsListLoaded(it, selectedIndex) } .map { AlbumsScreenViewState.AlbumsListLoaded(it, selectedIndex) }
val fetchSelected = requestAlbum(selectedIndex) val fetchSelected = requestAlbum(selectedIndex)
...@@ -49,14 +67,28 @@ class AlbumsScreenPresenter @Inject constructor( ...@@ -49,14 +67,28 @@ class AlbumsScreenPresenter @Inject constructor(
.startWith(Observable.just(AlbumsScreenViewState.HeaderAlbumChoosed(item = model))) .startWith(Observable.just(AlbumsScreenViewState.HeaderAlbumChoosed(item = model)))
} }
val fetchSubscription = interactor.getSubscriptions(SubscriptionTopic.Progress_1())
.doAfterNext { restoreModel.sub = it }
.map<AlbumsScreenViewState> { AlbumsScreenViewState.SubscriptionStatus(it.state) }
.startWith(Observable.just<AlbumsScreenViewState>(AlbumsScreenViewState.Idle()))
val photoSelected = intent(AlbumsScreen::onPhotoSelected) val photoSelected = intent(AlbumsScreen::onPhotoSelected)
.map { AlbumsScreenViewState.PhotoSelected(it.photoId) } .map { AlbumsScreenViewState.PhotoSelected(it.photoId) }
val state = restoreStateObservable
.mergeWith(fetchParents) val state = Observable.mergeDelayError(
.mergeWith(fetchSelected) arrayListOf(
.mergeWith(headerItemSelected) fetchParents,
.mergeWith(photoSelected) fetchSelected,
headerItemSelected,
photoSelected,
fetchSubscription,
onSubChecked
)
)
.doOnError { Timber.e(it) }
.onErrorReturn(::parseError)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
subscribeViewState(state.cast(AlbumsScreenViewState::class.java), AlbumsScreen::render) subscribeViewState(state.cast(AlbumsScreenViewState::class.java), AlbumsScreen::render)
...@@ -70,4 +102,5 @@ class AlbumsScreenPresenter @Inject constructor( ...@@ -70,4 +102,5 @@ class AlbumsScreenPresenter @Inject constructor(
data class RestoreModel(var albumList:List<AlbumSortedModel> data class RestoreModel(var albumList:List<AlbumSortedModel>
,var albumsPreview:List<AlbumPreviewModel> ,var albumsPreview:List<AlbumPreviewModel>
, var currentIndex:Int) , var currentIndex:Int
\ No newline at end of file , var sub: SubscriptionModel?)
\ No newline at end of file
...@@ -18,4 +18,6 @@ sealed class AlbumsScreenViewState : BigantoBaseViewState() { ...@@ -18,4 +18,6 @@ sealed class AlbumsScreenViewState : BigantoBaseViewState() {
class PhotoSelected(val photoId:Int) : AlbumsScreenViewState() class PhotoSelected(val photoId:Int) : AlbumsScreenViewState()
class SomeError(val exception: ExceptionString) : AlbumsScreenViewState() class SomeError(val exception: ExceptionString) : AlbumsScreenViewState()
class RestoreView(val restore:RestoreModel) : AlbumsScreenViewState() class RestoreView(val restore:RestoreModel) : AlbumsScreenViewState()
class SubscriptionStatus(val subState: Boolean) : AlbumsScreenViewState()
class SubscriptionError(val subState: Boolean) : AlbumsScreenViewState()
} }
\ No newline at end of file
...@@ -2,6 +2,8 @@ package com.biganto.visual.roompark.presentation.screen.feed_list ...@@ -2,6 +2,8 @@ package com.biganto.visual.roompark.presentation.screen.feed_list
import com.biganto.visual.roompark.conductor.BigantoBasePresenter import com.biganto.visual.roompark.conductor.BigantoBasePresenter
import com.biganto.visual.roompark.domain.interactor.ArticlesInteractor import com.biganto.visual.roompark.domain.interactor.ArticlesInteractor
import com.biganto.visual.roompark.domain.model.ArticlePreviewModel
import com.biganto.visual.roompark.domain.model.SubscriptionModel
import com.biganto.visual.roompark.util.monades.ExceptionString import com.biganto.visual.roompark.util.monades.ExceptionString
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
...@@ -38,7 +40,6 @@ class ArticlesScreenPresenter @Inject constructor( ...@@ -38,7 +40,6 @@ class ArticlesScreenPresenter @Inject constructor(
Timber.d("feedId : $feedId") Timber.d("feedId : $feedId")
val onSubChecked = intent(ArticlesScreen::feedSubscription) val onSubChecked = intent(ArticlesScreen::feedSubscription)
// .skip(1)
.filter { restoreModel.sub != null } .filter { restoreModel.sub != null }
.flatMap { newState -> .flatMap { newState ->
interactor.switchSubscription(restoreModel.sub!!, newState) interactor.switchSubscription(restoreModel.sub!!, newState)
...@@ -52,6 +53,11 @@ class ArticlesScreenPresenter @Inject constructor( ...@@ -52,6 +53,11 @@ class ArticlesScreenPresenter @Inject constructor(
.onErrorReturn { ArticlesScreenViewState.SubscriptionError(!newState) } .onErrorReturn { ArticlesScreenViewState.SubscriptionError(!newState) }
} }
val fetchSubscription = interactor.getSubscriptions(feedId)
.doOnNext { Timber.w("got smthng: $it") }
.doAfterNext { restoreModel.sub = it }
.map<ArticlesScreenViewState> { ArticlesScreenViewState.SubscriptionStatus(it.state) }
.startWith(Observable.just<ArticlesScreenViewState>(ArticlesScreenViewState.Idle()))
val prefetchCards = interactor.fetchArticles(feedId) val prefetchCards = interactor.fetchArticles(feedId)
.map<ArticlesScreenViewState> { ArticlesScreenViewState.ArticlesLoaded(it.articles) } .map<ArticlesScreenViewState> { ArticlesScreenViewState.ArticlesLoaded(it.articles) }
...@@ -71,13 +77,6 @@ class ArticlesScreenPresenter @Inject constructor( ...@@ -71,13 +77,6 @@ class ArticlesScreenPresenter @Inject constructor(
.onErrorReturn(::parseError) .onErrorReturn(::parseError)
} }
val fetchSubscription = interactor.getSubscriptions(feedId)
.doOnNext { Timber.w("got smthng: $it") }
.doAfterNext { restoreModel.sub = it }
.map<ArticlesScreenViewState> { ArticlesScreenViewState.SubscriptionStatus(it.state) }
.startWith(Observable.just<ArticlesScreenViewState>(ArticlesScreenViewState.Idle()))
val state = Observable.mergeDelayError( val state = Observable.mergeDelayError(
arrayListOf( arrayListOf(
restoreStateObservable, restoreStateObservable,
...@@ -94,4 +93,11 @@ class ArticlesScreenPresenter @Inject constructor( ...@@ -94,4 +93,11 @@ class ArticlesScreenPresenter @Inject constructor(
subscribeViewState(state.cast(ArticlesScreenViewState::class.java), ArticlesScreen::render) subscribeViewState(state.cast(ArticlesScreenViewState::class.java), ArticlesScreen::render)
} }
} }
\ No newline at end of file
data class RestoreModel(
var articles:MutableList<ArticlePreviewModel>,
var sub: SubscriptionModel?
)
\ No newline at end of file
...@@ -2,7 +2,6 @@ package com.biganto.visual.roompark.presentation.screen.feed_list ...@@ -2,7 +2,6 @@ package com.biganto.visual.roompark.presentation.screen.feed_list
import com.biganto.visual.roompark.conductor.BigantoBaseViewState import com.biganto.visual.roompark.conductor.BigantoBaseViewState
import com.biganto.visual.roompark.domain.model.ArticlePreviewModel import com.biganto.visual.roompark.domain.model.ArticlePreviewModel
import com.biganto.visual.roompark.domain.model.SubscriptionModel
import com.biganto.visual.roompark.util.monades.ExceptionString import com.biganto.visual.roompark.util.monades.ExceptionString
/** /**
...@@ -19,9 +18,3 @@ sealed class ArticlesScreenViewState : BigantoBaseViewState() { ...@@ -19,9 +18,3 @@ sealed class ArticlesScreenViewState : BigantoBaseViewState() {
class SubscriptionStatus(val subState: Boolean) : ArticlesScreenViewState() class SubscriptionStatus(val subState: Boolean) : ArticlesScreenViewState()
class SubscriptionError(val subState: Boolean) : ArticlesScreenViewState() class SubscriptionError(val subState: Boolean) : ArticlesScreenViewState()
} }
data class RestoreModel(
var articles:MutableList<ArticlePreviewModel>,
var sub: SubscriptionModel?
)
\ No newline at end of file
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