diff --git a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt
index 0291aff625e..12529861277 100644
--- a/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt
+++ b/owncloudApp/src/main/java/com/owncloud/android/dependecyinjection/ViewModelModule.kt
@@ -23,6 +23,7 @@
package com.owncloud.android.dependecyinjection
import com.owncloud.android.MainApp
+import com.owncloud.android.presentation.ui.files.filelist.MainFileListViewModel
import com.owncloud.android.presentation.ui.files.operations.FileOperationViewModel
import com.owncloud.android.presentation.viewmodels.authentication.OCAuthenticationViewModel
import com.owncloud.android.presentation.viewmodels.capabilities.OCCapabilityViewModel
@@ -74,4 +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()) }
}
diff --git a/owncloudApp/src/main/java/com/owncloud/android/extensions/ImageViewExt.kt b/owncloudApp/src/main/java/com/owncloud/android/extensions/ImageViewExt.kt
new file mode 100644
index 00000000000..c29c0a2fbb0
--- /dev/null
+++ b/owncloudApp/src/main/java/com/owncloud/android/extensions/ImageViewExt.kt
@@ -0,0 +1,34 @@
+/**
+ * ownCloud Android client application
+ *
+ * @author Fernando Sanz Velasco
+ * Copyright (C) 2021 ownCloud GmbH.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.extensions
+
+import android.annotation.SuppressLint
+import android.widget.ImageView
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.engine.DiskCacheStrategy
+
+@SuppressLint("CheckResult")
+fun ImageView.setPicture(imageToLoad: Int) {
+ Glide.with(this)
+ .load(imageToLoad)
+ .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
+ .into(this)
+}
diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/adapters/filelist/FileListAdapter.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/adapters/filelist/FileListAdapter.kt
new file mode 100644
index 00000000000..10f36472049
--- /dev/null
+++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/adapters/filelist/FileListAdapter.kt
@@ -0,0 +1,113 @@
+/**
+ * ownCloud Android client application
+ *
+ * @author Fernando Sanz Velasco
+ * Copyright (C) 2021 ownCloud GmbH.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.presentation.adapters.filelist
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.core.content.ContextCompat
+import androidx.core.view.isVisible
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.RecyclerView
+import com.owncloud.android.R
+import com.owncloud.android.databinding.ItemFileListBinding
+import com.owncloud.android.domain.files.model.OCFile
+import com.owncloud.android.extensions.setPicture
+import com.owncloud.android.presentation.diffutils.FileListDiffCallback
+import com.owncloud.android.utils.DisplayUtils
+import com.owncloud.android.utils.MimetypeIconUtil
+
+class FileListAdapter(
+ private val context: Context
+) : RecyclerView.Adapter() {
+
+ private val files = mutableListOf()
+
+ fun updateFileList(filesToAdd: List) {
+ val diffUtilCallback = FileListDiffCallback(oldList = files, newList = filesToAdd)
+ val diffResult = DiffUtil.calculateDiff(diffUtilCallback)
+ files.clear()
+ files.addAll(filesToAdd)
+ diffResult.dispatchUpdatesTo(this)
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = ItemFileListBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+
+ return ViewHolder(binding)
+ }
+
+ override fun getItemCount(): Int = files.size
+
+ override fun getItemId(position: Int): Long = position.toLong()
+
+ override fun getItemViewType(position: Int): Int = position
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ with(holder) {
+ with(files[position]) {
+ binding.Filename.text = this.fileName
+ binding.fileListSize.text = DisplayUtils.bytesToHumanReadable(this.length, context)
+ binding.fileListLastMod.text = DisplayUtils.getRelativeTimestamp(context, this.modificationTimestamp)
+ binding.localFileIndicator.isVisible = false //TODO Modify in the future, when we start the synchronization task.
+ binding.customCheckbox.isVisible = false //TODO Modify in the future, when we start the multi selection task.
+ binding.thumbnail.let {
+ it.tag = this.id
+ getThumbnailPicture(imageView = it, file = this)
+ }
+ //TODO Check this with FileListListAdapter.java and its viewType (LIST or GRID)
+ getSharedIcon(imageView = binding.sharedIcon, file = this)
+ }
+ }
+ }
+
+ private fun getThumbnailPicture(imageView: ImageView, file: OCFile) {
+ if (file.isFolder) {
+ imageView.setPicture(
+ MimetypeIconUtil.getFolderTypeIconId(file.isSharedWithMe || file.sharedWithSharee ?: false, file.sharedByLink)
+ )
+ } else {
+ // Set file icon depending on its mimetype.
+ imageView.setPicture(MimetypeIconUtil.getFileTypeIconId(file.mimeType, file.fileName))
+ if (file.mimeType.contentEquals("image/png")) {
+ imageView.setBackgroundColor(ContextCompat.getColor(context, R.color.background_color))
+ }
+ }
+ }
+
+ private fun getSharedIcon(imageView: ImageView, file: OCFile) {
+ if (file.sharedByLink) {
+ imageView.setImageResource(R.drawable.ic_shared_by_link)
+ imageView.visibility = View.VISIBLE
+ imageView.bringToFront()
+ } else if (file.sharedWithSharee == true || file.isSharedWithMe) {
+ imageView.setImageResource(R.drawable.shared_via_users)
+ imageView.visibility = View.VISIBLE
+ imageView.bringToFront()
+ } else {
+ imageView.visibility = View.GONE
+ }
+ }
+
+ inner class ViewHolder(val binding: ItemFileListBinding) : RecyclerView.ViewHolder(binding.root)
+}
diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/diffutils/FileListDiffCallback.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/diffutils/FileListDiffCallback.kt
new file mode 100644
index 00000000000..d2c09afad6d
--- /dev/null
+++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/diffutils/FileListDiffCallback.kt
@@ -0,0 +1,41 @@
+/**
+ * ownCloud Android client application
+ *
+ * @author Fernando Sanz Velasco
+ * Copyright (C) 2021 ownCloud GmbH.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.presentation.diffutils
+
+import androidx.recyclerview.widget.DiffUtil
+import com.owncloud.android.domain.files.model.OCFile
+
+class FileListDiffCallback(private val oldList: List, private val newList: List) : DiffUtil.Callback() {
+
+ override fun getOldListSize(): Int = oldList.size
+
+ override fun getNewListSize(): Int = newList.size
+
+ override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+ return oldList[oldItemPosition].id === newList[newItemPosition].id
+ }
+
+ override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+ val (_, value, name) = oldList[oldItemPosition]
+ val (_, value1, name1) = newList[newItemPosition]
+ return name == name1 && value == value1
+ }
+}
diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/ui/files/filelist/MainFileListFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/ui/files/filelist/MainFileListFragment.kt
index efaa9f1b797..747bb775eb2 100644
--- a/owncloudApp/src/main/java/com/owncloud/android/presentation/ui/files/filelist/MainFileListFragment.kt
+++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/ui/files/filelist/MainFileListFragment.kt
@@ -25,23 +25,72 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
-import androidx.fragment.app.viewModels
+import androidx.recyclerview.widget.LinearLayoutManager
import com.owncloud.android.databinding.MainFileListFragmentBinding
+import com.owncloud.android.domain.files.model.OCFile
+import com.owncloud.android.domain.utils.Event
+import com.owncloud.android.presentation.UIResult
+import com.owncloud.android.presentation.adapters.filelist.FileListAdapter
+import org.koin.androidx.viewmodel.ext.android.viewModel
class MainFileListFragment : Fragment() {
- private val viewModel by viewModels()
+ private val mainFileListViewModel by viewModel()
private var _binding: MainFileListFragmentBinding? = null
private val binding get() = _binding!!
+ private lateinit var fileListAdapter: FileListAdapter
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = MainFileListFragmentBinding.inflate(inflater, container, false)
-
return binding.root
}
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ initViews()
+ subscribeToViewModels()
+ }
+
+ private fun initViews() {
+ //Set RecyclerView and its adapter.
+ fileListAdapter = FileListAdapter(context = requireContext())
+ binding.recyclerViewMainFileList.apply {
+ layoutManager = LinearLayoutManager(requireContext())
+ adapter = fileListAdapter
+
+ }
+ }
+
+ private fun subscribeToViewModels() {
+ //Observe the action of retrieving the list of files.
+ mainFileListViewModel.getFilesListStatusLiveData.observe(viewLifecycleOwner, Event.EventObserver { result ->
+ when (result) {
+ is UIResult.Error -> {} //TODO Manage Error
+ is UIResult.Loading -> {} //TODO Manage Loading
+ is UIResult.Success -> fileListAdapter.updateFileList(filesToAdd = result.data ?: emptyList())
+ }
+ })
+ }
+
+ fun listDirectory(directory: OCFile) {
+ mainFileListViewModel.listDirectory(directory = directory)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ _binding = null
+ }
+
+ companion object {
+ fun newInstance(): MainFileListFragment {
+ val args = Bundle()
+ return MainFileListFragment().apply { arguments = args }
+ }
+ }
}
+
diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/ui/files/filelist/MainFileListViewModel.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/ui/files/filelist/MainFileListViewModel.kt
index 092788de184..84322752f87 100644
--- a/owncloudApp/src/main/java/com/owncloud/android/presentation/ui/files/filelist/MainFileListViewModel.kt
+++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/ui/files/filelist/MainFileListViewModel.kt
@@ -1,7 +1,60 @@
+/**
+ * ownCloud Android client application
+ *
+ * @author Fernando Sanz Velasco
+ * Copyright (C) 2021 ownCloud GmbH.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
package com.owncloud.android.presentation.ui.files.filelist
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.owncloud.android.domain.UseCaseResult
+import com.owncloud.android.domain.files.model.OCFile
+import com.owncloud.android.domain.files.usecases.GetFolderContentUseCase
+import com.owncloud.android.domain.utils.Event
+import com.owncloud.android.presentation.UIResult
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+class MainFileListViewModel(
+ private val getFolderContentUseCase: GetFolderContentUseCase
+) : ViewModel() {
+
+ private var file: OCFile? = null
+
+ private val _getFilesListStatusLiveData = MutableLiveData>>>()
+ val getFilesListStatusLiveData: LiveData>>>
+ get() = _getFilesListStatusLiveData
+
+ private fun getFilesList(folderId: Long) {
+ viewModelScope.launch(Dispatchers.IO) {
+ _getFilesListStatusLiveData.postValue(Event(UIResult.Loading()))
+ getFolderContentUseCase.execute(GetFolderContentUseCase.Params(folderId = folderId)).let {
+ when (it) {
+ is UseCaseResult.Error -> _getFilesListStatusLiveData.postValue(Event(UIResult.Error(it.getThrowableOrNull())))
+ is UseCaseResult.Success -> _getFilesListStatusLiveData.postValue(Event(UIResult.Success(it.getDataOrNull())))
+ }
+ }
+ }
+ }
-class MainFileListViewModel : ViewModel() {
- // TODO: Implement the ViewModel
-}
\ No newline at end of file
+ fun listDirectory(directory: OCFile) {
+ getFilesList(directory.id!!)
+ }
+}
diff --git a/owncloudApp/src/main/res/layout/main_file_list_fragment.xml b/owncloudApp/src/main/res/layout/main_file_list_fragment.xml
index bbcde0ae65b..43ef57b5021 100644
--- a/owncloudApp/src/main/res/layout/main_file_list_fragment.xml
+++ b/owncloudApp/src/main/res/layout/main_file_list_fragment.xml
@@ -1,5 +1,4 @@
-
-
-
-
+
-
+