mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-22 21:19:31 +01:00
RemoteFileBrowser: do sorting in ViewModel, not activity
Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
This commit is contained in:
parent
a41d14c33a
commit
9d4745ee9b
@ -45,10 +45,7 @@ import com.nextcloud.talk.remotefilebrowser.viewmodels.RemoteFileBrowserItemsVie
|
|||||||
import com.nextcloud.talk.ui.dialog.SortingOrderDialogFragment
|
import com.nextcloud.talk.ui.dialog.SortingOrderDialogFragment
|
||||||
import com.nextcloud.talk.utils.DisplayUtils
|
import com.nextcloud.talk.utils.DisplayUtils
|
||||||
import com.nextcloud.talk.utils.FileSortOrder
|
import com.nextcloud.talk.utils.FileSortOrder
|
||||||
import com.nextcloud.talk.utils.FileSortOrderNew
|
|
||||||
import com.nextcloud.talk.utils.database.user.UserUtils
|
import com.nextcloud.talk.utils.database.user.UserUtils
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
|
||||||
import net.orange_box.storebox.listeners.OnPreferenceValueChangedListener
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import java.util.TreeSet
|
import java.util.TreeSet
|
||||||
@ -60,9 +57,7 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||||
|
|
||||||
@Inject
|
// TODO use CurrentUserProvider instead for narrower scope
|
||||||
lateinit var appPreferences: AppPreferences
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var userUtils: UserUtils
|
lateinit var userUtils: UserUtils
|
||||||
|
|
||||||
@ -74,11 +69,6 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||||||
private val selectedPaths: MutableSet<String> = Collections.synchronizedSet(TreeSet())
|
private val selectedPaths: MutableSet<String> = Collections.synchronizedSet(TreeSet())
|
||||||
private var currentPath: String = "/"
|
private var currentPath: String = "/"
|
||||||
|
|
||||||
private var browserItems: List<RemoteFileBrowserItem> = emptyList()
|
|
||||||
private var adapter: RemoteFileBrowserItemsAdapter? = null
|
|
||||||
|
|
||||||
private var sortingChangeListener: OnPreferenceValueChangedListener<String>? = null
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
||||||
@ -107,11 +97,8 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||||||
binding.swipeRefreshList.setColorSchemeResources(R.color.colorPrimary)
|
binding.swipeRefreshList.setColorSchemeResources(R.color.colorPrimary)
|
||||||
binding.swipeRefreshList.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background)
|
binding.swipeRefreshList.setProgressBackgroundColorSchemeResource(R.color.refresh_spinner_background)
|
||||||
|
|
||||||
appPreferences.registerSortingChangeListener(
|
binding.pathNavigationBackButton.setOnClickListener { goBack() }
|
||||||
SortingChangeListener(this).also {
|
binding.sortButton.setOnClickListener { changeSorting() }
|
||||||
sortingChangeListener = it
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.loadItems(currentPath)
|
viewModel.loadItems(currentPath)
|
||||||
}
|
}
|
||||||
@ -125,11 +112,9 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||||||
is RemoteFileBrowserItemsViewModel.LoadingItemsState, RemoteFileBrowserItemsViewModel.InitialState -> {
|
is RemoteFileBrowserItemsViewModel.LoadingItemsState, RemoteFileBrowserItemsViewModel.InitialState -> {
|
||||||
showLoading()
|
showLoading()
|
||||||
}
|
}
|
||||||
|
|
||||||
is RemoteFileBrowserItemsViewModel.NoRemoteFileItemsState -> {
|
is RemoteFileBrowserItemsViewModel.NoRemoteFileItemsState -> {
|
||||||
showEmpty()
|
showEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
is RemoteFileBrowserItemsViewModel.LoadedState -> {
|
is RemoteFileBrowserItemsViewModel.LoadedState -> {
|
||||||
val remoteFileBrowserItems = state.items
|
val remoteFileBrowserItems = state.items
|
||||||
Log.d(TAG, "Items received: $remoteFileBrowserItems")
|
Log.d(TAG, "Items received: $remoteFileBrowserItems")
|
||||||
@ -144,6 +129,7 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||||||
|
|
||||||
// TODO make mimeTypeSelectionFilter a bundled arg for the activity
|
// TODO make mimeTypeSelectionFilter a bundled arg for the activity
|
||||||
val mimeTypeSelectionFilter = "image/"
|
val mimeTypeSelectionFilter = "image/"
|
||||||
|
// TODO do not needlesly recreate adapter if it can be reused
|
||||||
val adapter = RemoteFileBrowserItemsAdapter(
|
val adapter = RemoteFileBrowserItemsAdapter(
|
||||||
showGrid = showGrid,
|
showGrid = showGrid,
|
||||||
mimeTypeSelectionFilter = mimeTypeSelectionFilter,
|
mimeTypeSelectionFilter = mimeTypeSelectionFilter,
|
||||||
@ -158,7 +144,6 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||||||
} else {
|
} else {
|
||||||
ArrayList()
|
ArrayList()
|
||||||
}
|
}
|
||||||
browserItems = items
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.recyclerView.adapter = adapter
|
binding.recyclerView.adapter = adapter
|
||||||
@ -169,6 +154,12 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.fileSortOrder.observe(this) { sortOrder ->
|
||||||
|
if (sortOrder != null) {
|
||||||
|
binding.sortButton.setText(DisplayUtils.getSortOrderStringId(sortOrder))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
@ -190,20 +181,12 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
binding.pathNavigationBackButton.setOnClickListener { goBack() }
|
|
||||||
binding.sortButton.setOnClickListener { changeSorting() }
|
|
||||||
|
|
||||||
binding.sortButton.setText(
|
|
||||||
DisplayUtils.getSortOrderStringId(FileSortOrder.getFileSortOrder(appPreferences.sorting))
|
|
||||||
)
|
|
||||||
|
|
||||||
refreshCurrentPath()
|
refreshCurrentPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changeSorting() {
|
private fun changeSorting() {
|
||||||
val newFragment: DialogFragment = SortingOrderDialogFragment
|
val newFragment: DialogFragment = SortingOrderDialogFragment
|
||||||
.newInstance(FileSortOrder.getFileSortOrder(appPreferences.sorting))
|
.newInstance(FileSortOrder.getFileSortOrder(viewModel.fileSortOrder.value!!.name))
|
||||||
newFragment.show(
|
newFragment.show(
|
||||||
supportFragmentManager,
|
supportFragmentManager,
|
||||||
SortingOrderDialogFragment.SORTING_ORDER_FRAGMENT
|
SortingOrderDialogFragment.SORTING_ORDER_FRAGMENT
|
||||||
@ -321,25 +304,4 @@ class RemoteFileBrowserActivity : AppCompatActivity(), SelectionInterface, Swipe
|
|||||||
override fun shouldOnlySelectOneImageFile(): Boolean {
|
override fun shouldOnlySelectOneImageFile(): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
|
||||||
private class SortingChangeListener(private val activity: RemoteFileBrowserActivity) :
|
|
||||||
OnPreferenceValueChangedListener<String> {
|
|
||||||
override fun onChanged(newValue: String) {
|
|
||||||
try {
|
|
||||||
val sortOrder = FileSortOrderNew.getFileSortOrder(newValue)
|
|
||||||
|
|
||||||
activity.binding.sortButton.setText(DisplayUtils.getSortOrderStringId(sortOrder))
|
|
||||||
activity.browserItems = sortOrder.sortCloudFiles(activity.browserItems)
|
|
||||||
|
|
||||||
activity.runOnUiThread {
|
|
||||||
activity.adapter!!.updateDataSet(activity.browserItems)
|
|
||||||
}
|
|
||||||
} catch (npe: NullPointerException) {
|
|
||||||
// view binding can be null
|
|
||||||
// since this is called asynchronously and UI might have been destroyed in the meantime
|
|
||||||
Log.i(TAG, "UI destroyed - view binding already gone")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
package com.nextcloud.talk.remotefilebrowser.adapters
|
package com.nextcloud.talk.remotefilebrowser.adapters
|
||||||
|
|
||||||
import android.text.format.Formatter
|
import android.text.format.Formatter
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import autodagger.AutoInjector
|
import autodagger.AutoInjector
|
||||||
@ -51,8 +50,8 @@ class RemoteFileBrowserItemsListViewHolder(
|
|||||||
override val fileIcon: SimpleDraweeView
|
override val fileIcon: SimpleDraweeView
|
||||||
get() = binding.fileIcon
|
get() = binding.fileIcon
|
||||||
|
|
||||||
private var selectable : Boolean = true
|
private var selectable: Boolean = true
|
||||||
private var clickable : Boolean = true
|
private var clickable: Boolean = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
itemView.setOnClickListener {
|
itemView.setOnClickListener {
|
||||||
|
@ -26,14 +26,18 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem
|
import com.nextcloud.talk.remotefilebrowser.model.RemoteFileBrowserItem
|
||||||
import com.nextcloud.talk.remotefilebrowser.repositories.RemoteFileBrowserItemsRepository
|
import com.nextcloud.talk.remotefilebrowser.repositories.RemoteFileBrowserItemsRepository
|
||||||
|
import com.nextcloud.talk.utils.FileSortOrderNew
|
||||||
|
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||||
import io.reactivex.Observer
|
import io.reactivex.Observer
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import net.orange_box.storebox.listeners.OnPreferenceValueChangedListener
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class RemoteFileBrowserItemsViewModel @Inject constructor(
|
class RemoteFileBrowserItemsViewModel @Inject constructor(
|
||||||
private val repository: RemoteFileBrowserItemsRepository
|
private val repository: RemoteFileBrowserItemsRepository,
|
||||||
|
private val appPreferences: AppPreferences
|
||||||
) :
|
) :
|
||||||
ViewModel() {
|
ViewModel() {
|
||||||
|
|
||||||
@ -43,11 +47,33 @@ class RemoteFileBrowserItemsViewModel @Inject constructor(
|
|||||||
object LoadingItemsState : ViewState
|
object LoadingItemsState : ViewState
|
||||||
class LoadedState(val items: List<RemoteFileBrowserItem>) : ViewState
|
class LoadedState(val items: List<RemoteFileBrowserItem>) : ViewState
|
||||||
|
|
||||||
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
private val initialSortOrder = FileSortOrderNew.getFileSortOrder(appPreferences.sorting)
|
||||||
|
private val sortingPrefListener: SortChangeListener = SortChangeListener()
|
||||||
|
|
||||||
|
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
||||||
val viewState: LiveData<ViewState>
|
val viewState: LiveData<ViewState>
|
||||||
get() = _viewState
|
get() = _viewState
|
||||||
|
|
||||||
|
// TODO incorporate into view state object?
|
||||||
|
private val _fileSortOrder: MutableLiveData<FileSortOrderNew> = MutableLiveData(initialSortOrder)
|
||||||
|
val fileSortOrder: LiveData<FileSortOrderNew>
|
||||||
|
get() = _fileSortOrder
|
||||||
|
|
||||||
|
init {
|
||||||
|
appPreferences.registerSortingChangeListener(sortingPrefListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class SortChangeListener : OnPreferenceValueChangedListener<String> {
|
||||||
|
override fun onChanged(newValue: String) {
|
||||||
|
onSelectSortOrder(newValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCleared() {
|
||||||
|
super.onCleared()
|
||||||
|
appPreferences.unregisterSortingChangeListener(sortingPrefListener)
|
||||||
|
}
|
||||||
|
|
||||||
fun loadItems(path: String) {
|
fun loadItems(path: String) {
|
||||||
_viewState.value = LoadingItemsState
|
_viewState.value = LoadingItemsState
|
||||||
repository.listFolder(path).subscribeOn(Schedulers.io())
|
repository.listFolder(path).subscribeOn(Schedulers.io())
|
||||||
@ -62,7 +88,7 @@ class RemoteFileBrowserItemsViewModel @Inject constructor(
|
|||||||
override fun onSubscribe(d: Disposable) = Unit
|
override fun onSubscribe(d: Disposable) = Unit
|
||||||
|
|
||||||
override fun onNext(response: List<RemoteFileBrowserItem>) {
|
override fun onNext(response: List<RemoteFileBrowserItem>) {
|
||||||
newRemoteFileBrowserItems = response
|
newRemoteFileBrowserItems = fileSortOrder.value!!.sortCloudFiles(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(e: Throwable) {
|
override fun onError(e: Throwable) {
|
||||||
@ -87,6 +113,18 @@ class RemoteFileBrowserItemsViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onSelectSortOrder(newSortOrderString: String) {
|
||||||
|
val newSortOrder = FileSortOrderNew.getFileSortOrder(newSortOrderString)
|
||||||
|
if (newSortOrder.name != fileSortOrder.value?.name) {
|
||||||
|
_fileSortOrder.value = newSortOrder
|
||||||
|
val currentState = viewState.value
|
||||||
|
if (currentState is LoadedState) {
|
||||||
|
val sortedItems = newSortOrder.sortCloudFiles(currentState.items)
|
||||||
|
_viewState.value = LoadedState(sortedItems)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = RemoteFileBrowserItemsViewModel::class.simpleName
|
private val TAG = RemoteFileBrowserItemsViewModel::class.simpleName
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user