Browse Source

Merge pull request #9920 from nextcloud/fix/autoupload-select-folder

Fix folder selection in custom autoupload folders
Álvaro Brey 3 years ago
parent
commit
d4d18307b7

BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.UploadFilesActivityIT_localFolderPickerMode.png


BIN
app/screenshots/gplay/debug/com.owncloud.android.ui.activity.UploadFilesActivityIT_noneSelected.png


+ 64 - 1
app/src/androidTest/java/com/owncloud/android/ui/activity/UploadFilesActivityIT.kt

@@ -21,20 +21,83 @@
  */
 package com.owncloud.android.ui.activity
 
+import android.content.Intent
 import androidx.test.espresso.intent.rule.IntentsTestRule
+import com.nextcloud.client.GrantStoragePermissionRule
 import com.owncloud.android.AbstractIT
+import com.owncloud.android.utils.FileStorageUtils
+import com.owncloud.android.utils.ScreenshotTest
+import org.junit.After
+import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
+import java.io.File
 
 class UploadFilesActivityIT : AbstractIT() {
     @get:Rule
     var activityRule = IntentsTestRule(UploadFilesActivity::class.java, true, false)
 
+    @get:Rule
+    var permissionRule = GrantStoragePermissionRule.grant()
+
+    private val directories = listOf("A", "B", "C", "D")
+        .map { File("${FileStorageUtils.getTemporalPath(account.name)}${File.separator}$it") }
+
+    @Before
+    fun setUp() {
+        directories.forEach { it.mkdirs() }
+    }
+
+    @After
+    fun tearDown() {
+        directories.forEach { it.deleteRecursively() }
+    }
+
     @Test
-    // @ScreenshotTest // TODO re-enable and make sure that folder content on emulator is the same on all devices
+    @ScreenshotTest
     fun noneSelected() {
         val sut: UploadFilesActivity = activityRule.launchActivity(null)
 
+        sut.runOnUiThread {
+            sut.fileListFragment.setFiles(
+                directories +
+                    listOf(
+                        File("1.txt"),
+                        File("2.pdf"),
+                        File("3.mp3")
+                    )
+            )
+        }
+
+        waitForIdleSync()
+
+        screenshot(sut)
+    }
+
+    @Test
+    @ScreenshotTest
+    fun localFolderPickerMode() {
+        val sut: UploadFilesActivity = activityRule.launchActivity(
+            Intent().apply {
+                putExtra(
+                    UploadFilesActivity.KEY_LOCAL_FOLDER_PICKER_MODE,
+                    true
+                )
+                putExtra(
+                    UploadFilesActivity.REQUEST_CODE_KEY,
+                    FileDisplayActivity.REQUEST_CODE__SELECT_FILES_FROM_FILE_SYSTEM
+                )
+            }
+        )
+
+        sut.runOnUiThread {
+            sut.fileListFragment.setFiles(
+                directories
+            )
+        }
+
+        waitForIdleSync()
+
         screenshot(sut)
     }
 

+ 10 - 3
app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java

@@ -70,6 +70,7 @@ import java.util.List;
 import javax.inject.Inject;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.ActionBar;
 import androidx.appcompat.widget.SearchView;
 import androidx.core.view.MenuItemCompat;
@@ -117,6 +118,12 @@ public class UploadFilesActivity extends DrawerActivity implements LocalFileList
     private Spinner mBehaviourSpinner;
     private MaterialButton uploadButton;
 
+
+    @VisibleForTesting
+    public LocalFileListFragment getFileListFragment() {
+        return mFileListFragment;
+    }
+
     /**
      * Helper to launch the UploadFilesActivity for which you would like a result when it finished. Your
      * onActivityResult() method will be called with the given requestCode.
@@ -189,7 +196,7 @@ public class UploadFilesActivity extends DrawerActivity implements LocalFileList
         uploadButton = findViewById(R.id.upload_files_btn_upload);
         ThemeButtonUtils.colorPrimaryButton(uploadButton, this);
         uploadButton.setOnClickListener(this);
-        uploadButton.setEnabled(false);
+        uploadButton.setEnabled(mLocalFolderPickerMode);
 
         int localBehaviour = preferences.getUploaderBehaviour();
 
@@ -458,7 +465,7 @@ public class UploadFilesActivity extends DrawerActivity implements LocalFileList
 
     private void updateUploadButtonActive() {
         final boolean anySelected = mFileListFragment.getCheckedFilesCount() > 0;
-        uploadButton.setEnabled(anySelected);
+        uploadButton.setEnabled(anySelected || mLocalFolderPickerMode);
     }
 
     private void setSelectAllMenuItem(MenuItem selectAll, boolean checked) {
@@ -600,7 +607,7 @@ public class UploadFilesActivity extends DrawerActivity implements LocalFileList
      */
     @Override
     public void onFileClick(File file) {
-        uploadButton.setEnabled(mFileListFragment.getCheckedFilesCount() > 0);
+        updateUploadButtonActive();
 
         boolean selectAll = mFileListFragment.getCheckedFilesCount() == mFileListFragment.getFilesCount();
         setSelectAllMenuItem(mOptionsMenu.findItem(R.id.action_select_all), selectAll);

+ 30 - 16
app/src/main/java/com/owncloud/android/ui/adapter/LocalFileListAdapter.java

@@ -54,6 +54,7 @@ import java.util.Set;
 import java.util.concurrent.Executors;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
 import androidx.recyclerview.widget.RecyclerView;
 
 /**
@@ -159,31 +160,34 @@ public class LocalFileListAdapter extends RecyclerView.Adapter<RecyclerView.View
             }
 
             if (file != null) {
+                File finalFile = file;
+
                 LocalFileListGridImageViewHolder gridViewHolder = (LocalFileListGridImageViewHolder) holder;
 
-                // checkbox
-                if (isCheckedFile(file)) {
-                    gridViewHolder.itemLayout.setBackgroundColor(mContext.getResources()
-                            .getColor(R.color.selected_item_background));
-                    gridViewHolder.checkbox.setImageDrawable(
-                        ThemeDrawableUtils.tintDrawable(R.drawable.ic_checkbox_marked,
-                                                        ThemeColorUtils.primaryColor(mContext)));
-                } else {
+                if (mLocalFolderPicker) {
                     gridViewHolder.itemLayout.setBackgroundColor(mContext.getResources().getColor(R.color.bg_default));
-                    gridViewHolder.checkbox.setImageResource(R.drawable.ic_checkbox_blank_outline);
+                    gridViewHolder.checkbox.setVisibility(View.GONE);
+                } else {
+                    gridViewHolder.checkbox.setVisibility(View.VISIBLE);
+                    if (isCheckedFile(file)) {
+                        gridViewHolder.itemLayout.setBackgroundColor(mContext.getResources()
+                                                                         .getColor(R.color.selected_item_background));
+                        gridViewHolder.checkbox.setImageDrawable(
+                            ThemeDrawableUtils.tintDrawable(R.drawable.ic_checkbox_marked,
+                                                            ThemeColorUtils.primaryColor(mContext)));
+                    } else {
+                        gridViewHolder.itemLayout.setBackgroundColor(mContext.getResources().getColor(R.color.bg_default));
+                        gridViewHolder.checkbox.setImageResource(R.drawable.ic_checkbox_blank_outline);
+                    }
+                    gridViewHolder.checkbox.setOnClickListener(v -> localFileListFragmentInterface
+                        .onItemCheckboxClicked(finalFile));
                 }
 
                 gridViewHolder.thumbnail.setTag(file.hashCode());
                 setThumbnail(file, gridViewHolder.thumbnail, mContext);
 
-                gridViewHolder.checkbox.setVisibility(View.VISIBLE);
-
-                File finalFile = file;
                 gridViewHolder.itemLayout.setOnClickListener(v -> localFileListFragmentInterface
-                        .onItemClicked(finalFile));
-                gridViewHolder.checkbox.setOnClickListener(v -> localFileListFragmentInterface
-                        .onItemCheckboxClicked(finalFile));
-
+                    .onItemClicked(finalFile));
 
                 if (holder instanceof LocalFileListItemViewHolder) {
                     LocalFileListItemViewHolder itemViewHolder = (LocalFileListItemViewHolder) holder;
@@ -521,4 +525,14 @@ public class LocalFileListAdapter extends RecyclerView.Adapter<RecyclerView.View
             footerText = itemView.findViewById(R.id.footerText);
         }
     }
+
+    @VisibleForTesting
+    public void setFiles(List<File> newFiles) {
+        mFiles = newFiles;
+        mFilesAll = new ArrayList<>();
+        mFilesAll.addAll(mFiles);
+
+        notifyDataSetChanged();
+        localFileListFragmentInterface.setLoading(false);
+    }
 }

+ 8 - 1
app/src/main/java/com/owncloud/android/ui/fragment/LocalFileListFragment.java

@@ -41,10 +41,12 @@ import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.FileSortOrder;
 
 import java.io.File;
+import java.util.List;
 
 import javax.inject.Inject;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
 import androidx.recyclerview.widget.GridLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
@@ -377,13 +379,18 @@ public class LocalFileListFragment extends ExtendedListFragment implements
             // ugly hack because setEmptyListLoadingMessage also uses a handler and there's a race condition otherwise
             new Handler().post(() -> {
                 mAdapter.notifyDataSetChanged();
-                if(mAdapter.getFilesCount() == 0){
+                if (mAdapter.getFilesCount() == 0) {
                     setEmptyListMessage(SearchType.NO_SEARCH);
                 }
             });
         }
     }
 
+    @VisibleForTesting
+    public void setFiles(List<File> newFiles) {
+        mAdapter.setFiles(newFiles);
+    }
+
     /**
      * Interface to implement by any Activity that includes some instance of LocalFileListFragment
      */

+ 1 - 1
scripts/analysis/findbugs-results.txt

@@ -1 +1 @@
-626
+627

+ 1 - 1
scripts/analysis/lint-results.txt

@@ -1,2 +1,2 @@
 DO NOT TOUCH; GENERATED BY DRONE
-      <span class="mdl-layout-title">Lint Report: 92 warnings</span>
+      <span class="mdl-layout-title">Lint Report: 93 warnings</span>