mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-24 05:55:39 +03:00
SharedItems: show loading state when initially loading a tab, and clear remaining TODOs
Co-authored-by: Tim Krüger <t@timkrueger.me> Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
This commit is contained in:
parent
5310ed3f3d
commit
05340fc466
2 changed files with 112 additions and 104 deletions
|
@ -85,13 +85,13 @@ class SharedItemsActivity : AppCompatActivity() {
|
|||
viewModel = ViewModelProvider(this, viewModelFactory)[SharedItemsViewModel::class.java]
|
||||
|
||||
viewModel.viewState.observe(this) { state ->
|
||||
handleEmptyView(state)
|
||||
handleEmptyLoadingView(state)
|
||||
when (state) {
|
||||
is SharedItemsViewModel.LoadedState -> {
|
||||
val sharedMediaItems = state.items
|
||||
Log.d(TAG, "Items received: $sharedMediaItems")
|
||||
|
||||
val showGrid = viewModel.currentItemType == SharedItemType.MEDIA
|
||||
val showGrid = state.selectedType == SharedItemType.MEDIA
|
||||
val layoutManager = if (showGrid) {
|
||||
GridLayoutManager(this, SPAN_COUNT)
|
||||
} else {
|
||||
|
@ -104,7 +104,9 @@ class SharedItemsActivity : AppCompatActivity() {
|
|||
binding.imageRecycler.adapter = adapter
|
||||
binding.imageRecycler.layoutManager = layoutManager
|
||||
}
|
||||
is SharedItemsViewModel.TabsLoadedState -> initTabs(state.types)
|
||||
is SharedItemsViewModel.TypesLoadedState -> {
|
||||
initTabs(state.types)
|
||||
}
|
||||
else -> {
|
||||
// noop
|
||||
}
|
||||
|
@ -120,25 +122,28 @@ class SharedItemsActivity : AppCompatActivity() {
|
|||
}
|
||||
})
|
||||
|
||||
viewModel.initialize(userEntity, roomToken, SharedItemType.MEDIA)
|
||||
viewModel.initialize(userEntity, roomToken)
|
||||
}
|
||||
|
||||
private fun handleEmptyView(state: SharedItemsViewModel.ViewState?) {
|
||||
when (state) {
|
||||
SharedItemsViewModel.NoSharedItemsState -> {
|
||||
binding.emptyContainer.emptyListViewHeadline.text = getString(R.string.nc_shared_items_empty)
|
||||
binding.emptyContainer.emptyListView.visibility = View.VISIBLE
|
||||
binding.sharedItemsTabs.visibility = View.GONE
|
||||
}
|
||||
else -> {
|
||||
binding.emptyContainer.emptyListView.visibility = View.GONE
|
||||
binding.sharedItemsTabs.visibility = View.VISIBLE
|
||||
}
|
||||
private fun handleEmptyLoadingView(state: SharedItemsViewModel.ViewState?) {
|
||||
binding.emptyContainer.emptyListViewHeadline.text = when (state) {
|
||||
SharedItemsViewModel.NoSharedItemsState -> getString(R.string.nc_shared_items_description)
|
||||
else -> getString(R.string.file_list_loading)
|
||||
}
|
||||
binding.emptyContainer.emptyListView.visibility = when (state) {
|
||||
SharedItemsViewModel.NoSharedItemsState, is SharedItemsViewModel.LoadingItemsState -> View.VISIBLE
|
||||
else -> View.GONE
|
||||
}
|
||||
binding.sharedItemsTabs.visibility = when (state) {
|
||||
SharedItemsViewModel.NoSharedItemsState -> View.GONE
|
||||
else -> View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
private fun initTabs(sharedItemTypes: Set<SharedItemType>) {
|
||||
|
||||
binding.sharedItemsTabs.removeAllTabs()
|
||||
|
||||
if (sharedItemTypes.contains(SharedItemType.MEDIA)) {
|
||||
val tabMedia: TabLayout.Tab = binding.sharedItemsTabs.newTab()
|
||||
tabMedia.tag = SharedItemType.MEDIA
|
||||
|
@ -190,15 +195,13 @@ class SharedItemsActivity : AppCompatActivity() {
|
|||
|
||||
binding.sharedItemsTabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||
viewModel.loadItems(tab.tag as SharedItemType)
|
||||
viewModel.initialLoadItems(tab.tag as SharedItemType)
|
||||
}
|
||||
|
||||
override fun onTabUnselected(tab: TabLayout.Tab) = Unit
|
||||
|
||||
override fun onTabReselected(tab: TabLayout.Tab) = Unit
|
||||
})
|
||||
|
||||
viewModel.loadItems(SharedItemType.MEDIA)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
|
|
@ -42,90 +42,29 @@ class SharedItemsViewModel @Inject constructor(
|
|||
ViewModel() {
|
||||
|
||||
private lateinit var repositoryParameters: SharedItemsRepository.Parameters
|
||||
private lateinit var _currentItemType: SharedItemType
|
||||
val currentItemType: SharedItemType
|
||||
get() = _currentItemType
|
||||
|
||||
// items
|
||||
sealed interface ViewState
|
||||
object InitialState : ViewState
|
||||
object NoSharedItemsState : ViewState
|
||||
open class TabsLoadedState(val types: Set<SharedItemType>) : ViewState
|
||||
class LoadedState(types: Set<SharedItemType>, val items: SharedMediaItems) : TabsLoadedState(types)
|
||||
open class TypesLoadedState(val types: Set<SharedItemType>, val selectedType: SharedItemType) : ViewState
|
||||
class LoadingItemsState(types: Set<SharedItemType>, selectedType: SharedItemType) :
|
||||
TypesLoadedState(types, selectedType)
|
||||
|
||||
class LoadedState(types: Set<SharedItemType>, selectedType: SharedItemType, val items: SharedMediaItems) :
|
||||
TypesLoadedState(types, selectedType)
|
||||
|
||||
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
||||
val viewState: LiveData<ViewState>
|
||||
get() = _viewState
|
||||
|
||||
fun loadNextItems() {
|
||||
when (val currentState = _viewState.value) {
|
||||
is LoadedState -> {
|
||||
val currentSharedItems = currentState.items
|
||||
if (currentSharedItems.moreItemsExisting) {
|
||||
repository.media(repositoryParameters, _currentItemType, currentSharedItems.lastSeenId)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(observer(_currentItemType, false))
|
||||
}
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
|
||||
fun loadItems(type: SharedItemType) {
|
||||
|
||||
_currentItemType = type
|
||||
|
||||
repository.media(repositoryParameters, type)?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(observer(type, true))
|
||||
}
|
||||
|
||||
private fun observer(type: SharedItemType, initModel: Boolean): Observer<SharedMediaItems> {
|
||||
return object : Observer<SharedMediaItems> {
|
||||
|
||||
var newSharedItems: SharedMediaItems? = null
|
||||
|
||||
override fun onSubscribe(d: Disposable) = Unit
|
||||
|
||||
override fun onNext(response: SharedMediaItems) {
|
||||
newSharedItems = response
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.d(TAG, "An error occurred: $e")
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
val items = newSharedItems!!
|
||||
// todo replace initmodel with tabsloadedstate
|
||||
if (initModel) {
|
||||
setCurrentState(items)
|
||||
} else {
|
||||
val state = this@SharedItemsViewModel._viewState.value as LoadedState
|
||||
val oldItems = state.items.items
|
||||
val newItems =
|
||||
SharedMediaItems(
|
||||
oldItems + newSharedItems!!.items,
|
||||
newSharedItems!!.lastSeenId,
|
||||
newSharedItems!!.moreItemsExisting
|
||||
)
|
||||
setCurrentState(newItems)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setCurrentState(items: SharedMediaItems) {
|
||||
when (val state = this@SharedItemsViewModel._viewState.value) {
|
||||
is TabsLoadedState -> {
|
||||
this@SharedItemsViewModel._viewState.value = LoadedState(
|
||||
state.types,
|
||||
items
|
||||
)
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
}
|
||||
fun initialize(userEntity: UserEntity, roomToken: String) {
|
||||
repositoryParameters = SharedItemsRepository.Parameters(
|
||||
userEntity.userId,
|
||||
userEntity.token,
|
||||
userEntity.baseUrl,
|
||||
roomToken
|
||||
)
|
||||
loadAvailableTypes()
|
||||
}
|
||||
|
||||
private fun loadAvailableTypes() {
|
||||
|
@ -150,22 +89,88 @@ class SharedItemsViewModel @Inject constructor(
|
|||
if (newTypes.isNullOrEmpty()) {
|
||||
this@SharedItemsViewModel._viewState.value = NoSharedItemsState
|
||||
} else {
|
||||
this@SharedItemsViewModel._viewState.value = TabsLoadedState(newTypes)
|
||||
val selectedType = chooseInitialType(newTypes)
|
||||
this@SharedItemsViewModel._viewState.value =
|
||||
TypesLoadedState(newTypes, selectedType)
|
||||
initialLoadItems(selectedType)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TODO cleanup
|
||||
fun initialize(userEntity: UserEntity, roomToken: String, initialType: SharedItemType) {
|
||||
repositoryParameters = SharedItemsRepository.Parameters(
|
||||
userEntity.userId,
|
||||
userEntity.token,
|
||||
userEntity.baseUrl,
|
||||
roomToken
|
||||
)
|
||||
_currentItemType = initialType
|
||||
loadAvailableTypes()
|
||||
private fun chooseInitialType(newTypes: Set<SharedItemType>): SharedItemType = when {
|
||||
newTypes.contains(SharedItemType.MEDIA) -> SharedItemType.MEDIA
|
||||
else -> newTypes.toList().first()
|
||||
}
|
||||
|
||||
fun initialLoadItems(type: SharedItemType) {
|
||||
val state = _viewState.value
|
||||
if (state is TypesLoadedState) {
|
||||
_viewState.value = LoadingItemsState(state.types, type)
|
||||
repository.media(repositoryParameters, type)?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(SharedMediaItemsObserver())
|
||||
}
|
||||
}
|
||||
|
||||
fun loadNextItems() {
|
||||
when (val currentState = _viewState.value) {
|
||||
is LoadedState -> {
|
||||
val currentSharedItems = currentState.items
|
||||
if (currentSharedItems.moreItemsExisting) {
|
||||
repository.media(repositoryParameters, currentState.selectedType, currentSharedItems.lastSeenId)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(SharedMediaItemsObserver())
|
||||
}
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
|
||||
inner class SharedMediaItemsObserver : Observer<SharedMediaItems> {
|
||||
|
||||
var newSharedItems: SharedMediaItems? = null
|
||||
|
||||
override fun onSubscribe(d: Disposable) = Unit
|
||||
|
||||
override fun onNext(response: SharedMediaItems) {
|
||||
newSharedItems = response
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.d(TAG, "An error occurred: $e")
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
val items = newSharedItems!!
|
||||
val state = this@SharedItemsViewModel._viewState.value
|
||||
if (state is LoadedState) {
|
||||
val oldItems = state.items.items
|
||||
val newItems =
|
||||
SharedMediaItems(
|
||||
oldItems + newSharedItems!!.items,
|
||||
newSharedItems!!.lastSeenId,
|
||||
newSharedItems!!.moreItemsExisting
|
||||
)
|
||||
setCurrentState(newItems)
|
||||
} else {
|
||||
setCurrentState(items)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setCurrentState(items: SharedMediaItems) {
|
||||
when (val state = this@SharedItemsViewModel._viewState.value) {
|
||||
is TypesLoadedState -> {
|
||||
this@SharedItemsViewModel._viewState.value = LoadedState(
|
||||
state.types,
|
||||
state.selectedType,
|
||||
items
|
||||
)
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
Loading…
Reference in a new issue