Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort by name, size, and date #3478

Merged
merged 5 commits into from
Dec 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,5 @@ val viewModelModule = module {
viewModel { PreviewImageViewModel(get(), get(), get()) }
viewModel { FileDetailsViewModel(get(), get(), get(), get(), get()) }
viewModel { FileOperationViewModel(get(), get(), get(), get(), get(), get()) }
viewModel { MainFileListViewModel(get(), get(), get(), get(), get()) }
viewModel { MainFileListViewModel(get(), get(), get(), get(), get(), get()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ import androidx.recyclerview.widget.RecyclerView
import com.owncloud.android.R
import com.owncloud.android.databinding.ItemFileListBinding
import com.owncloud.android.databinding.ListFooterBinding
import com.owncloud.android.db.PreferenceManager
import com.owncloud.android.domain.files.model.OCFile
import com.owncloud.android.domain.files.model.OCFooterFile
import com.owncloud.android.extensions.setPicture
import com.owncloud.android.presentation.diffutils.FileListDiffCallback
import com.owncloud.android.utils.DisplayUtils
import com.owncloud.android.utils.FileStorageUtils
import com.owncloud.android.utils.MimetypeIconUtil

class FileListAdapter(
Expand All @@ -45,7 +47,8 @@ class FileListAdapter(
private val listener: FileListAdapterListener,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

private val files = mutableListOf<Any>()

private var files = mutableListOf<Any>()
private lateinit var viewHolder: RecyclerView.ViewHolder

private val TYPE_ITEMS = 0
Expand All @@ -56,9 +59,11 @@ class FileListAdapter(
val diffResult = DiffUtil.calculateDiff(diffUtilCallback)
files.clear()
files.addAll(filesToAdd)

if (filesToAdd.isNotEmpty()) {
files.add(OCFooterFile(manageListOfFilesAndGenerateText(filesToAdd)))
}

diffResult.dispatchUpdatesTo(this)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,33 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.owncloud.android.databinding.MainFileListFragmentBinding
import com.owncloud.android.db.PreferenceManager
import com.owncloud.android.domain.files.model.OCFile
import com.owncloud.android.domain.utils.Event
import com.owncloud.android.extensions.cancel
import com.owncloud.android.presentation.adapters.filelist.FileListAdapter
import com.owncloud.android.presentation.observers.EmptyDataObserver
import com.owncloud.android.presentation.onSuccess
import com.owncloud.android.presentation.ui.files.SortBottomSheetFragment
import com.owncloud.android.presentation.ui.files.SortBottomSheetFragment.Companion.newInstance
import com.owncloud.android.presentation.ui.files.SortBottomSheetFragment.SortDialogListener
import com.owncloud.android.presentation.ui.files.SortOptionsView
import com.owncloud.android.presentation.ui.files.SortOrder
import com.owncloud.android.presentation.ui.files.SortType
import com.owncloud.android.presentation.ui.files.ViewType
import com.owncloud.android.ui.activity.FileListOption
import com.owncloud.android.utils.FileStorageUtils
import org.koin.androidx.viewmodel.ext.android.viewModel

class MainFileListFragment : Fragment() {
class MainFileListFragment : Fragment(), SortDialogListener, SortOptionsView.SortOptionsListener, SortOptionsView.CreateFolderListener {

private val mainFileListViewModel by viewModel<MainFileListViewModel>()

private var _binding: MainFileListFragmentBinding? = null
private val binding get() = _binding!!

private lateinit var fileListAdapter: FileListAdapter
private lateinit var files: List<OCFile>

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
Expand Down Expand Up @@ -80,13 +90,27 @@ class MainFileListFragment : Fragment() {

// Set Swipe to refresh and its listener
binding.swipeRefreshMainFileList.setOnRefreshListener { mainFileListViewModel.refreshDirectory() }

//Set SortOptions and its listeners
binding.optionsLayout.let {
it.onSortOptionsListener = this
if (isPickingAFolder()) {
it.onCreateFolderListener = this
it.selectAdditionalView(SortOptionsView.AdditionalView.CREATE_FOLDER)
}
}
}

private fun subscribeToViewModels() {
// Observe the action of retrieving the list of files from DB.
mainFileListViewModel.getFilesListStatusLiveData.observe(viewLifecycleOwner, Event.EventObserver {
it.onSuccess { data ->
updateFileListData(files = data ?: emptyList())
files = data ?: emptyList()
val sortedFiles = mainFileListViewModel.sortList(files)
fileListAdapter.updateFileList(filesToAdd = sortedFiles)
registerListAdapterDataObserver()
binding.swipeRefreshMainFileList.cancel()
}
})

Expand Down Expand Up @@ -119,6 +143,41 @@ class MainFileListFragment : Fragment() {
fileListAdapter.registerAdapterDataObserver(emptyDataObserver)
}

override fun onSortTypeListener(sortType: SortType, sortOrder: SortOrder) {
val sortBottomSheetFragment = newInstance(sortType, sortOrder)
sortBottomSheetFragment.sortDialogListener = this
sortBottomSheetFragment.show(childFragmentManager, SortBottomSheetFragment.TAG)
}

override fun onViewTypeListener(viewType: ViewType) {
//TODO("Not yet implemented")
}

override fun onSortSelected(sortType: SortType) {
binding.optionsLayout.sortTypeSelected = sortType

val isAscending = binding.optionsLayout.sortOrderSelected == SortOrder.SORT_ORDER_ASCENDING

when (sortType) {
SortType.SORT_TYPE_BY_NAME -> sortAdapterBy(FileStorageUtils.SORT_NAME, isAscending)
SortType.SORT_TYPE_BY_DATE -> sortAdapterBy(FileStorageUtils.SORT_DATE, isAscending)
SortType.SORT_TYPE_BY_SIZE -> sortAdapterBy(FileStorageUtils.SORT_SIZE, isAscending)
}
}

private fun sortAdapterBy(sortType: Int, isDescending: Boolean) {
PreferenceManager.setSortOrder(sortType, requireContext(), FileStorageUtils.FILE_DISPLAY_SORT)
PreferenceManager.setSortAscending(isDescending, requireContext(), FileStorageUtils.FILE_DISPLAY_SORT)

val sortedFiles = mainFileListViewModel.sortList(files)
fileListAdapter.updateFileList(filesToAdd = sortedFiles)
}

private fun isPickingAFolder(): Boolean {
val args = arguments
return args != null && args.getBoolean(ARG_PICKING_A_FOLDER, false)
}

override fun onDestroy() {
super.onDestroy()
_binding = null
Expand All @@ -131,25 +190,32 @@ class MainFileListFragment : Fragment() {
}

fun updateFileListOption(newFileListOption: FileListOption) {
when(newFileListOption) {
FileListOption.ALL_FILES -> mainFileListViewModel.listCurrentDirectory()
FileListOption.AV_OFFLINE -> mainFileListViewModel.getAvailableOfflineFilesList()
FileListOption.SHARED_BY_LINK -> mainFileListViewModel.getSharedByLinkFilesList()
when (newFileListOption) {
FileListOption.ALL_FILES -> mainFileListViewModel.listCurrentDirectory()
FileListOption.AV_OFFLINE -> mainFileListViewModel.getAvailableOfflineFilesList()
FileListOption.SHARED_BY_LINK -> mainFileListViewModel.getSharedByLinkFilesList()
}

// TODO Manage FAB button
}

companion object {
val ARG_JUST_FOLDERS = MainFileListFragment::class.java.canonicalName + ".JUST_FOLDERS"
val ARG_JUST_FOLDERS = "${MainFileListFragment::class.java.canonicalName}.JUST_FOLDERS"
val ARG_PICKING_A_FOLDER = "${MainFileListFragment::class.java.canonicalName}.ARG_PICKING_A_FOLDER}"

fun newInstance(
justFolders: Boolean
justFolders: Boolean,
pickingAFolder: Boolean = false
): MainFileListFragment {
val args = Bundle()
args.putBoolean(ARG_JUST_FOLDERS, justFolders)
args.putBoolean(ARG_PICKING_A_FOLDER, pickingAFolder)
return MainFileListFragment().apply { arguments = args }
}
}

override fun onCreateFolderListener() {
//TODO("Not yet implemented")
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,28 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.owncloud.android.domain.UseCaseResult
import androidx.lifecycle.viewModelScope
import com.owncloud.android.db.PreferenceManager
import com.owncloud.android.domain.UseCaseResult
import com.owncloud.android.domain.files.model.OCFile
import com.owncloud.android.domain.files.usecases.GetFilesAvailableOfflineUseCase
import com.owncloud.android.domain.files.usecases.GetFilesSharedByLinkUseCase
import com.owncloud.android.domain.files.usecases.GetFolderContentAsLiveDataUseCase
import com.owncloud.android.domain.files.usecases.RefreshFolderFromServerAsyncUseCase
import com.owncloud.android.domain.utils.Event
import com.owncloud.android.presentation.UIResult
import com.owncloud.android.providers.ContextProvider
import com.owncloud.android.providers.CoroutinesDispatcherProvider
import com.owncloud.android.utils.FileStorageUtils
import kotlinx.coroutines.launch

class MainFileListViewModel(
private val getFolderContentAsLiveDataUseCase: GetFolderContentAsLiveDataUseCase,
private val getFilesSharedByLinkUseCase: GetFilesSharedByLinkUseCase,
private val getFilesAvailableOfflineUseCase: GetFilesAvailableOfflineUseCase,
private val refreshFolderFromServerAsyncUseCase: RefreshFolderFromServerAsyncUseCase,
private val coroutinesDispatcherProvider: CoroutinesDispatcherProvider
private val coroutinesDispatcherProvider: CoroutinesDispatcherProvider,
private val contextProvider: ContextProvider,
) : ViewModel() {

private lateinit var file: OCFile
Expand All @@ -58,7 +62,6 @@ class MainFileListViewModel(
val getFilesAvailableOfflineData: LiveData<Event<UIResult<List<OCFile>>>>
get() = _getFilesAvailableOfflineData


private fun getFilesList(folderId: Long) {
val filesListLiveData: LiveData<List<OCFile>> =
getFolderContentAsLiveDataUseCase.execute(GetFolderContentAsLiveDataUseCase.Params(folderId = folderId))
Expand Down Expand Up @@ -109,5 +112,15 @@ class MainFileListViewModel(
fun refreshDirectory() {
refreshFilesList(file.remotePath)
}

fun sortList(files: List<OCFile>): List<OCFile> {
val sortOrderSaved = PreferenceManager.getSortOrder(contextProvider.getContext(), FileStorageUtils.FILE_DISPLAY_SORT)
val ascendingModeSaved = PreferenceManager.getSortAscending(contextProvider.getContext(), FileStorageUtils.FILE_DISPLAY_SORT)

return FileStorageUtils.sortFolder(
files, sortOrderSaved,
ascendingModeSaved
)
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ import com.owncloud.android.BuildConfig
import com.owncloud.android.MainApp
import com.owncloud.android.R
import com.owncloud.android.authentication.BiometricManager
import com.owncloud.android.presentation.ui.security.PassCodeManager
import com.owncloud.android.authentication.PatternManager
import com.owncloud.android.databinding.ActivityMainBinding
import com.owncloud.android.datamodel.FileDataStorageManager
Expand All @@ -80,9 +79,9 @@ import com.owncloud.android.operations.UploadFileOperation
import com.owncloud.android.presentation.UIResult
import com.owncloud.android.presentation.manager.DOWNLOAD_ADDED_MESSAGE
import com.owncloud.android.presentation.manager.DOWNLOAD_FINISH_MESSAGE
import com.owncloud.android.presentation.ui.files.filelist.MainFileListFragment
import com.owncloud.android.presentation.ui.files.operations.FileOperation
import com.owncloud.android.presentation.ui.files.operations.FileOperationViewModel
import com.owncloud.android.presentation.ui.security.PassCodeManager
import com.owncloud.android.syncadapter.FileSyncAdapter
import com.owncloud.android.ui.errorhandling.ErrorMessageAdapter
import com.owncloud.android.ui.fragment.FileDetailFragment
Expand Down Expand Up @@ -149,9 +148,6 @@ class FileDisplayActivity : FileActivity(), FileFragment.ContainerActivity, OnEn
private val listOfFilesFragment: OCFileListFragment?
get() = supportFragmentManager.findFragmentByTag(TAG_LIST_OF_FILES) as OCFileListFragment?

private val listMainFileFragment: MainFileListFragment?
get() = supportFragmentManager.findFragmentByTag(TAG_LIST_OF_FILES_BIS) as MainFileListFragment?

private val secondFragment: FileFragment?
get() = supportFragmentManager.findFragmentByTag(TAG_SECOND_FRAGMENT) as FileFragment?

Expand Down Expand Up @@ -343,21 +339,17 @@ class FileDisplayActivity : FileActivity(), FileFragment.ContainerActivity, OnEn

// TODO Change to start using new MainListFragment
private fun createMinFragments() {
/* val listOfFiles = OCFileListFragment.newInstance(false, fileListOption, false, false, true)
listOfFiles.setSearchListener(findViewById(R.id.root_toolbar_search_view))*/

val list = MainFileListFragment.newInstance(justFolders = false)


val listOfFiles = OCFileListFragment.newInstance(false, fileListOption, false, false, true)
listOfFiles.setSearchListener(findViewById(R.id.root_toolbar_search_view))
val transaction = supportFragmentManager.beginTransaction()
transaction.add(R.id.left_fragment_container, list, TAG_LIST_OF_FILES_BIS)
transaction.add(R.id.left_fragment_container, listOfFiles, TAG_LIST_OF_FILES)
transaction.commit()
}

private fun initFragmentsWithFile() {
if (account != null && file != null) {
/// First fragment
listMainFileFragment?.listDirectory(currentDir)
listOfFilesFragment?.listDirectory(currentDir)
?: Timber.e("Still have a chance to lose the initialization of list fragment >(")

/// Second fragment
Expand Down Expand Up @@ -477,10 +469,8 @@ class FileDisplayActivity : FileActivity(), FileFragment.ContainerActivity, OnEn
}

fun refreshListOfFilesFragment(reloadData: Boolean) {
/*val fileListFragment = listOfFilesFragment
fileListFragment?.listDirectory(reloadData)*/
val fileListFragment = listMainFileFragment
fileListFragment?.listDirectory(file)
val fileListFragment = listOfFilesFragment
fileListFragment?.listDirectory(reloadData)
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
Expand Down Expand Up @@ -1617,10 +1607,10 @@ class FileDisplayActivity : FileActivity(), FileFragment.ContainerActivity, OnEn

private fun navigateTo(newFileListOption: FileListOption) {
if (fileListOption != newFileListOption) {
if (listMainFileFragment != null) {
if (listOfFilesFragment != null) {
fileListOption = newFileListOption
file = storageManager.getFileByPath(OCFile.ROOT_PATH)
listMainFileFragment?.updateFileListOption(newFileListOption)
listOfFilesFragment?.updateFileListOption(newFileListOption)
updateToolbar(null)
} else {
super.navigateToOption(FileListOption.ALL_FILES)
Expand Down Expand Up @@ -1656,7 +1646,6 @@ class FileDisplayActivity : FileActivity(), FileFragment.ContainerActivity, OnEn
}

companion object {
private const val TAG_LIST_OF_FILES_BIS = "TAG_LIST_OF_FILES_BIS"
private const val TAG_LIST_OF_FILES = "LIST_OF_FILES"
private const val TAG_SECOND_FRAGMENT = "SECOND_FRAGMENT"

Expand Down
Loading