From e2f6c7dbbf19ee9181c030c05a700e1ff9f4ddbe Mon Sep 17 00:00:00 2001 From: Jose Antonio Barros Date: Wed, 24 Nov 2021 11:25:35 +0100 Subject: [PATCH 1/4] Empty files view --- .../observers/EmptyDataObserver.kt | 35 +++++++++++++ .../ui/files/filelist/MainFileListFragment.kt | 4 ++ .../main/res/layout/item_empty_dataset.xml | 51 +++++++++++++++++++ .../res/layout/main_file_list_fragment.xml | 10 ++++ owncloudApp/src/main/res/values/strings.xml | 2 + 5 files changed, 102 insertions(+) create mode 100644 owncloudApp/src/main/java/com/owncloud/android/presentation/observers/EmptyDataObserver.kt create mode 100644 owncloudApp/src/main/res/layout/item_empty_dataset.xml diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/observers/EmptyDataObserver.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/observers/EmptyDataObserver.kt new file mode 100644 index 00000000000..6771b34f17b --- /dev/null +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/observers/EmptyDataObserver.kt @@ -0,0 +1,35 @@ +package com.owncloud.android.presentation.observers + +import android.view.View +import androidx.recyclerview.widget.RecyclerView + +class EmptyDataObserver constructor(rv: RecyclerView?, ev: View?): RecyclerView.AdapterDataObserver() { + + private var emptyView: View? = null + private var recyclerView: RecyclerView? = null + + init { + recyclerView = rv + emptyView = ev + checkIfEmpty() + } + + + private fun checkIfEmpty() { + if (emptyView != null && recyclerView!!.adapter != null) { + val emptyViewVisible = recyclerView!!.adapter!!.itemCount == 0 + emptyView!!.visibility = if (emptyViewVisible) View.VISIBLE else View.GONE + recyclerView!!.visibility = if (emptyViewVisible) View.GONE else View.VISIBLE + } + } + + override fun onChanged() { + super.onChanged() + checkIfEmpty() + } + + override fun onItemRangeChanged(positionStart: Int, itemCount: Int) { + super.onItemRangeChanged(positionStart, itemCount) + } + +} \ No newline at end of file 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 8877eb385c8..8e89ed7e18f 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 @@ -30,6 +30,7 @@ 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.adapters.filelist.FileListAdapter +import com.owncloud.android.presentation.observers.EmptyDataObserver import com.owncloud.android.presentation.onError import com.owncloud.android.presentation.onLoading import com.owncloud.android.presentation.onSuccess @@ -66,6 +67,9 @@ class MainFileListFragment : Fragment() { adapter = fileListAdapter } + + val emptyDataObserver = EmptyDataObserver(binding.recyclerViewMainFileList, binding.emptyDataParent.root) + fileListAdapter.registerAdapterDataObserver(emptyDataObserver) } private fun subscribeToViewModels() { diff --git a/owncloudApp/src/main/res/layout/item_empty_dataset.xml b/owncloudApp/src/main/res/layout/item_empty_dataset.xml new file mode 100644 index 00000000000..0c15296a370 --- /dev/null +++ b/owncloudApp/src/main/res/layout/item_empty_dataset.xml @@ -0,0 +1,51 @@ + + + + + + + + + \ No newline at end of file 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 820ad5d1fb8..d62a891a1be 100644 --- a/owncloudApp/src/main/res/layout/main_file_list_fragment.xml +++ b/owncloudApp/src/main/res/layout/main_file_list_fragment.xml @@ -35,6 +35,16 @@ app:layout_constraintTop_toTopOf="parent" tools:listitem="@layout/item_file_list" /> + + Migrating your files. Please don’t turn your device off. Working… Please wait More security for your files + + Upload some content or sync with your devices! From 01962650dbf3b579b1661fd0865b26d7b14f8731 Mon Sep 17 00:00:00 2001 From: Jose Antonio Barros Date: Wed, 24 Nov 2021 13:28:43 +0100 Subject: [PATCH 2/4] Load list of files contained on a folder. If empty show view --- .../adapters/filelist/FileListAdapter.kt | 9 ++++++- .../ui/files/filelist/MainFileListFragment.kt | 26 ++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) 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 index f5a37455693..dd36783b487 100644 --- 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 @@ -41,6 +41,7 @@ class FileListAdapter( private val context: Context ) : RecyclerView.Adapter() { + var onItemClick: ((OCFile) -> Unit)? = null private val files = mutableListOf() fun updateFileList(filesToAdd: List) { @@ -115,5 +116,11 @@ class FileListAdapter( } } - inner class ViewHolder(val binding: ItemFileListBinding) : RecyclerView.ViewHolder(binding.root) + inner class ViewHolder(val binding: ItemFileListBinding) : RecyclerView.ViewHolder(binding.root) { + init { + itemView.setOnClickListener { + onItemClick?.invoke(files[adapterPosition]) + } + } + } } 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 8e89ed7e18f..ed4e73c55fe 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 @@ -34,7 +34,15 @@ import com.owncloud.android.presentation.observers.EmptyDataObserver import com.owncloud.android.presentation.onError import com.owncloud.android.presentation.onLoading import com.owncloud.android.presentation.onSuccess +import com.owncloud.android.ui.activity.FileDisplayActivity +import com.owncloud.android.ui.preview.PreviewAudioFragment +import com.owncloud.android.ui.preview.PreviewAudioFragment.Companion.canBePreviewed +import com.owncloud.android.ui.preview.PreviewImageFragment +import com.owncloud.android.ui.preview.PreviewImageFragment.Companion.canBePreviewed +import com.owncloud.android.ui.preview.PreviewTextFragment +import com.owncloud.android.ui.preview.PreviewVideoFragment import org.koin.androidx.viewmodel.ext.android.viewModel +import timber.log.Timber class MainFileListFragment : Fragment() { @@ -62,14 +70,18 @@ class MainFileListFragment : Fragment() { private fun initViews() { //Set RecyclerView and its adapter. fileListAdapter = FileListAdapter(context = requireContext()) + fileListAdapter.onItemClick = { file -> + if (file.isFolder) { + mainFileListViewModel.listDirectory(file) + // TODO Manage animation listDirectoryWithAnimationDown + } else { /// Click on a file + // TODO Click on a file + } + } binding.recyclerViewMainFileList.apply { layoutManager = LinearLayoutManager(requireContext()) adapter = fileListAdapter - } - - val emptyDataObserver = EmptyDataObserver(binding.recyclerViewMainFileList, binding.emptyDataParent.root) - fileListAdapter.registerAdapterDataObserver(emptyDataObserver) } private fun subscribeToViewModels() { @@ -79,6 +91,7 @@ class MainFileListFragment : Fragment() { it.onSuccess { data -> val files = data ?: emptyList() fileListAdapter.updateFileList(filesToAdd = files) + registerListAdapterDataObserver() mainFileListViewModel.manageListOfFiles(files) } it.onError { /*TODO Manage Error*/ } @@ -118,6 +131,11 @@ class MainFileListFragment : Fragment() { return args != null && args.getBoolean(ARG_JUST_FOLDERS, false) } + private fun registerListAdapterDataObserver(){ + val emptyDataObserver = EmptyDataObserver(binding.recyclerViewMainFileList, binding.emptyDataParent.root) + fileListAdapter.registerAdapterDataObserver(emptyDataObserver) + } + override fun onDestroy() { super.onDestroy() _binding = null From 1ce888ebc11a1313135ac4824eb548772b98bd93 Mon Sep 17 00:00:00 2001 From: Jose Antonio Barros Date: Wed, 24 Nov 2021 15:15:29 +0100 Subject: [PATCH 3/4] Remove unnecessary imports --- .../ui/files/filelist/MainFileListFragment.kt | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) 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 ed4e73c55fe..7e2b5bf9d06 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 @@ -34,15 +34,7 @@ import com.owncloud.android.presentation.observers.EmptyDataObserver import com.owncloud.android.presentation.onError import com.owncloud.android.presentation.onLoading import com.owncloud.android.presentation.onSuccess -import com.owncloud.android.ui.activity.FileDisplayActivity -import com.owncloud.android.ui.preview.PreviewAudioFragment -import com.owncloud.android.ui.preview.PreviewAudioFragment.Companion.canBePreviewed -import com.owncloud.android.ui.preview.PreviewImageFragment -import com.owncloud.android.ui.preview.PreviewImageFragment.Companion.canBePreviewed -import com.owncloud.android.ui.preview.PreviewTextFragment -import com.owncloud.android.ui.preview.PreviewVideoFragment import org.koin.androidx.viewmodel.ext.android.viewModel -import timber.log.Timber class MainFileListFragment : Fragment() { @@ -131,7 +123,7 @@ class MainFileListFragment : Fragment() { return args != null && args.getBoolean(ARG_JUST_FOLDERS, false) } - private fun registerListAdapterDataObserver(){ + private fun registerListAdapterDataObserver() { val emptyDataObserver = EmptyDataObserver(binding.recyclerViewMainFileList, binding.emptyDataParent.root) fileListAdapter.registerAdapterDataObserver(emptyDataObserver) } From 22beeb7c277fc5296f2c9e1cc55407b9022c6c6c Mon Sep 17 00:00:00 2001 From: Jose Antonio Barros Date: Thu, 25 Nov 2021 11:45:25 +0100 Subject: [PATCH 4/4] Changes after CR --- .../adapters/filelist/FileListAdapter.kt | 17 +++++++++-------- .../observers/EmptyDataObserver.kt | 11 ++++++----- .../ui/files/filelist/MainFileListFragment.kt | 19 +++++++++++-------- .../main/res/layout/item_empty_dataset.xml | 18 ++++++++---------- .../res/layout/main_file_list_fragment.xml | 2 +- 5 files changed, 35 insertions(+), 32 deletions(-) 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 index dd36783b487..2fe6a55080f 100644 --- 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 @@ -38,10 +38,10 @@ import com.owncloud.android.utils.DisplayUtils import com.owncloud.android.utils.MimetypeIconUtil class FileListAdapter( - private val context: Context + private val context: Context, + private val listener: FileListAdapterListener ) : RecyclerView.Adapter() { - var onItemClick: ((OCFile) -> Unit)? = null private val files = mutableListOf() fun updateFileList(filesToAdd: List) { @@ -84,6 +84,9 @@ class FileListAdapter( } //TODO Check this with FileListListAdapter.java and its viewType (LIST or GRID) getSharedIcon(imageView = binding.sharedIcon, file = this) + binding.root.setOnClickListener { + listener.clickItem(this) + } } } } @@ -116,11 +119,9 @@ class FileListAdapter( } } - inner class ViewHolder(val binding: ItemFileListBinding) : RecyclerView.ViewHolder(binding.root) { - init { - itemView.setOnClickListener { - onItemClick?.invoke(files[adapterPosition]) - } - } + interface FileListAdapterListener { + fun clickItem(ocFile: OCFile) } + + inner class ViewHolder(val binding: ItemFileListBinding) : RecyclerView.ViewHolder(binding.root) } diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/observers/EmptyDataObserver.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/observers/EmptyDataObserver.kt index 6771b34f17b..b2c585f40fe 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/observers/EmptyDataObserver.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/observers/EmptyDataObserver.kt @@ -1,16 +1,17 @@ package com.owncloud.android.presentation.observers import android.view.View +import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView -class EmptyDataObserver constructor(rv: RecyclerView?, ev: View?): RecyclerView.AdapterDataObserver() { +class EmptyDataObserver constructor(recyclerView: RecyclerView?, emptyView: View?): RecyclerView.AdapterDataObserver() { private var emptyView: View? = null private var recyclerView: RecyclerView? = null init { - recyclerView = rv - emptyView = ev + this.recyclerView = recyclerView + this.emptyView = emptyView checkIfEmpty() } @@ -18,8 +19,8 @@ class EmptyDataObserver constructor(rv: RecyclerView?, ev: View?): RecyclerView. private fun checkIfEmpty() { if (emptyView != null && recyclerView!!.adapter != null) { val emptyViewVisible = recyclerView!!.adapter!!.itemCount == 0 - emptyView!!.visibility = if (emptyViewVisible) View.VISIBLE else View.GONE - recyclerView!!.visibility = if (emptyViewVisible) View.GONE else View.VISIBLE + emptyView!!.isVisible = emptyViewVisible + recyclerView!!.isVisible = !emptyViewVisible } } 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 7e2b5bf9d06..e77f8efb370 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 @@ -61,15 +61,18 @@ class MainFileListFragment : Fragment() { private fun initViews() { //Set RecyclerView and its adapter. - fileListAdapter = FileListAdapter(context = requireContext()) - fileListAdapter.onItemClick = { file -> - if (file.isFolder) { - mainFileListViewModel.listDirectory(file) - // TODO Manage animation listDirectoryWithAnimationDown - } else { /// Click on a file - // TODO Click on a file + fileListAdapter = FileListAdapter(context = requireContext(), listener = object : + FileListAdapter.FileListAdapterListener { + override fun clickItem(ocFile: OCFile) { + if (ocFile.isFolder) { + mainFileListViewModel.listDirectory(ocFile) + // TODO Manage animation listDirectoryWithAnimationDown + } else { /// Click on a file + // TODO Click on a file + } } - } + + } ) binding.recyclerViewMainFileList.apply { layoutManager = LinearLayoutManager(requireContext()) adapter = fileListAdapter diff --git a/owncloudApp/src/main/res/layout/item_empty_dataset.xml b/owncloudApp/src/main/res/layout/item_empty_dataset.xml index 0c15296a370..fe17d69be37 100644 --- a/owncloudApp/src/main/res/layout/item_empty_dataset.xml +++ b/owncloudApp/src/main/res/layout/item_empty_dataset.xml @@ -6,23 +6,21 @@ android:layout_gravity="center" android:gravity="center" android:orientation="vertical" - android:paddingTop="10dp" - android:paddingBottom="10dp"> + android:paddingTop="@dimen/standard_half_padding" + android:paddingBottom="@dimen/standard_half_padding"> + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toBottomOf="@id/list_empty_dataset_icon" /> + app:layout_constraintTop_toBottomOf="@id/list_empty_dataset_title" /> \ No newline at end of file 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 d62a891a1be..ab316253e13 100644 --- a/owncloudApp/src/main/res/layout/main_file_list_fragment.xml +++ b/owncloudApp/src/main/res/layout/main_file_list_fragment.xml @@ -41,7 +41,7 @@ android:layout_width="match_parent" android:visibility="gone" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintTop_toBottomOf="@+id/recyclerView_main_file_list" + app:layout_constraintTop_toBottomOf="@id/recyclerView_main_file_list" android:layout_height="match_parent" android:layout_gravity="center" />