Эх сурвалжийг харах

FileActionsBottomSheet: show loading animation, load items in background

Since we're going to load the files in background too, it's a good idea to start doing this already

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
Álvaro Brey 2 жил өмнө
parent
commit
dd94167733

+ 12 - 3
app/src/main/java/com/nextcloud/ui/fileactions/FileActionsBottomSheet.kt

@@ -86,6 +86,7 @@ class FileActionsBottomSheet private constructor() : BottomSheetDialogFragment()
         _binding = FileActionsBottomSheetBinding.inflate(inflater, container, false)
 
         viewModel.uiState.observe(viewLifecycleOwner) { state ->
+            toggleLoadingOrContent(state)
             when (state) {
                 is FileActionsViewModel.UiState.LoadedForSingleFile -> {
                     if (state.lockInfo != null) {
@@ -98,9 +99,7 @@ class FileActionsBottomSheet private constructor() : BottomSheetDialogFragment()
                     displayActions(state.actions, inflater)
                     displayTitle(state.fileCount)
                 }
-                FileActionsViewModel.UiState.Loading -> {
-                    // TODO show spinner
-                }
+                FileActionsViewModel.UiState.Loading -> {}
             }
         }
 
@@ -113,6 +112,16 @@ class FileActionsBottomSheet private constructor() : BottomSheetDialogFragment()
         return binding.root
     }
 
+    private fun toggleLoadingOrContent(state: FileActionsViewModel.UiState) {
+        if (state is FileActionsViewModel.UiState.Loading) {
+            binding.bottomSheetLoading.isVisible = true
+            binding.bottomSheetContent.isVisible = false
+        } else {
+            binding.bottomSheetLoading.isVisible = false
+            binding.bottomSheetContent.isVisible = true
+        }
+    }
+
     private fun displayActions(
         actions: List<FileAction>,
         inflater: LayoutInflater

+ 32 - 5
app/src/main/java/com/nextcloud/ui/fileactions/FileActionsViewModel.kt

@@ -26,12 +26,15 @@ import androidx.annotation.IdRes
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
 import com.nextcloud.client.account.CurrentAccountProvider
 import com.nextcloud.utils.TimeConstants
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.files.FileMenuFilter
 import com.owncloud.android.lib.resources.files.model.FileLockType
 import com.owncloud.android.ui.activity.ComponentsGetter
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 import javax.inject.Inject
 
 class FileActionsViewModel @Inject constructor(
@@ -69,7 +72,20 @@ class FileActionsViewModel @Inject constructor(
         isOverflow: Boolean?,
         additionalFilter: IntArray?
     ) {
-        val toHide = filterFactory.newInstance(
+        viewModelScope.launch(Dispatchers.IO) {
+            val toHide = getHiddenActions(numberOfAllFiles, files, componentsGetter, isOverflow)
+            val availableActions = getActionsToShow(additionalFilter, toHide)
+            updateStateLoaded(files, availableActions)
+        }
+    }
+
+    private fun getHiddenActions(
+        numberOfAllFiles: Int?,
+        files: Collection<OCFile>,
+        componentsGetter: ComponentsGetter,
+        isOverflow: Boolean?
+    ): List<Int> {
+        return filterFactory.newInstance(
             numberOfAllFiles ?: 1,
             files.toList(),
             componentsGetter,
@@ -77,16 +93,27 @@ class FileActionsViewModel @Inject constructor(
             currentAccountProvider.user
         )
             .getToHide(false)
-        val availableActions = FileAction.SORTED_VALUES
-            .filter { additionalFilter == null || it.id !in additionalFilter }
-            .filter { it.id !in toHide }
-        _uiState.value = when (files.size) {
+    }
+
+    private fun getActionsToShow(
+        additionalFilter: IntArray?,
+        toHide: List<Int>
+    ) = FileAction.SORTED_VALUES
+        .filter { additionalFilter == null || it.id !in additionalFilter }
+        .filter { it.id !in toHide }
+
+    private fun updateStateLoaded(
+        files: Collection<OCFile>,
+        availableActions: List<FileAction>
+    ) {
+        val state: UiState = when (files.size) {
             1 -> {
                 val file = files.first()
                 UiState.LoadedForSingleFile(availableActions, file, getLockInfo(file))
             }
             else -> UiState.LoadedForMultipleFiles(availableActions, files.size)
         }
+        _uiState.postValue(state)
     }
 
     private fun getLockInfo(file: OCFile): LockInfo? {

+ 33 - 17
app/src/main/res/layout/file_actions_bottom_sheet.xml

@@ -31,34 +31,50 @@
         android:layout_height="match_parent"
         android:layout_width="match_parent"
         android:orientation="vertical"
+        android:minHeight="@dimen/bottom_sheet_min_height"
         app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
 
         <com.google.android.material.bottomsheet.BottomSheetDragHandleView
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
 
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="match_parent"
+        <com.google.android.material.progressindicator.CircularProgressIndicator
+            android:indeterminate="true"
+            android:id="@+id/bottom_sheet_loading"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
-            android:lines="1"
-            android:ellipsize="middle"
-            android:padding="@dimen/standard_padding"
-            tools:text="Test file name which is very very very very very long.pdf" />
-
+            android:layout_gravity="center" />
 
-        <androidx.core.widget.NestedScrollView
+        <LinearLayout
+            android:id="@+id/bottom_sheet_content"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-            <!-- TODO maybe convert to listview instead -->
-            <LinearLayout
-                android:id="@+id/file_actions_list"
+            android:layout_height="match_parent"
+            android:orientation="vertical"
+            android:visibility="gone"
+            tools:visibility="gone">
+
+            <TextView
+                android:id="@+id/title"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:orientation="vertical">
-            </LinearLayout>
-        </androidx.core.widget.NestedScrollView>
+                android:ellipsize="middle"
+                android:lines="1"
+                android:padding="@dimen/standard_padding"
+                android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
+                tools:text="Test file name which is very very very very very long.pdf" />
+
+
+            <androidx.core.widget.NestedScrollView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+                <!-- TODO maybe convert to listview instead -->
+                <LinearLayout
+                    android:id="@+id/file_actions_list"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical" />
+            </androidx.core.widget.NestedScrollView>
+        </LinearLayout>
     </LinearLayout>
 
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 0
app/src/main/res/values/dims.xml

@@ -23,6 +23,7 @@
     <dimen name="bottom_sheet_text_start_margin">40dp</dimen>
     <dimen name="bottom_sheet_item_height">56dp</dimen>
     <dimen name="bottom_sheet_menu_item_divider_standard_margin">80dp</dimen>
+    <dimen name="bottom_sheet_min_height">112dp</dimen>
     <dimen name="file_icon_size">40dp</dimen>
     <dimen name="file_icon_size_grid">128dp</dimen>
     <dimen name="file_icon_rounded_corner_radius">8dp</dimen>