Browse Source

Merge pull request #13599 from nextcloud/bugfix/filter-root

BugFix - Filter Root
Tobias Kaminsky 6 months ago
parent
commit
8fdba73b92

+ 13 - 0
app/src/main/java/com/nextcloud/model/OCFileFilterType.kt

@@ -0,0 +1,13 @@
+/*
+ * Nextcloud - Android Client
+ *
+ * SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+package com.nextcloud.model
+
+enum class OCFileFilterType {
+    Shared,
+    Favorite
+}

+ 29 - 0
app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -40,6 +40,7 @@ import com.nextcloud.client.database.entity.FileEntity;
 import com.nextcloud.client.database.entity.OfflineOperationEntity;
 import com.nextcloud.client.jobs.offlineOperations.repository.OfflineOperationsRepository;
 import com.nextcloud.client.jobs.offlineOperations.repository.OfflineOperationsRepositoryType;
+import com.nextcloud.model.OCFileFilterType;
 import com.nextcloud.model.OfflineOperationType;
 import com.nextcloud.utils.date.DateFormatPattern;
 import com.nextcloud.utils.extensions.DateExtensionsKt;
@@ -259,6 +260,11 @@ public class FileDataStorageManager {
         return fileDao.getFileByEncryptedRemotePath(path, user.getAccountName()) != null;
     }
 
+    public OCFile getTopParent(OCFile file) {
+        long topParentId = getTopParentId(file);
+        return getFileById(topParentId);
+    }
+
     public long getTopParentId(OCFile file) {
         if (file.getParentId() == 1) {
             return file.getFileId();
@@ -2593,4 +2599,27 @@ public class FileDataStorageManager {
         }
         return false;
     }
+
+    public List<OCFile> filter(OCFile file, OCFileFilterType filterType) {
+        if (!file.isRootDirectory()) {
+            return getFolderContent(file,false);
+        }
+
+        final List<OCFile> result = new ArrayList<>();
+        final List<OCFile> allFiles = getAllFiles();
+        for (OCFile ocFile: allFiles) {
+            boolean condition = false;
+            if (filterType == OCFileFilterType.Shared) {
+                condition = ocFile.isShared();
+            } else if (filterType == OCFileFilterType.Favorite) {
+                condition = ocFile.isFavorite();
+            }
+
+            if (condition) {
+                result.add(ocFile);
+            }
+        }
+
+        return result;
+    }
 }

+ 4 - 0
app/src/main/java/com/owncloud/android/datamodel/OCFile.java

@@ -760,6 +760,10 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
         return this.sharedViaLink;
     }
 
+    public boolean isShared() {
+        return isSharedViaLink() || isSharedWithSharee() || isSharedWithMe();
+    }
+
     public String getPermissions() {
         return this.permissions;
     }

+ 1 - 0
app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -1018,6 +1018,7 @@ public class FileDisplayActivity extends FileActivity
      */
     @SuppressFBWarnings("ITC_INHERITANCE_TYPE_CHECKING")
     @Override
+    // TODO Apply fail fast principle
     public void onBackPressed() {
         if (isSearchOpen()) {
             resetSearchAction();

+ 0 - 3
app/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java

@@ -91,9 +91,6 @@ public class UploadListActivity extends FileActivity {
     @Inject
     LocalBroadcastManager localBroadcastManager;
 
-    @Inject
-    ViewThemeUtils viewThemeUtils;
-
     @Inject Throttler throttler;
 
     private UploadListLayoutBinding binding;

+ 12 - 0
app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java

@@ -33,6 +33,7 @@ import com.nextcloud.android.common.ui.theme.utils.ColorRole;
 import com.nextcloud.client.account.User;
 import com.nextcloud.client.jobs.upload.FileUploadHelper;
 import com.nextcloud.client.preferences.AppPreferences;
+import com.nextcloud.model.OCFileFilterType;
 import com.nextcloud.utils.extensions.ViewExtensionsKt;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
@@ -60,6 +61,7 @@ import com.owncloud.android.lib.resources.shares.ShareeUser;
 import com.owncloud.android.operations.RefreshFolderOperation;
 import com.owncloud.android.operations.RemoteOperationFailedException;
 import com.owncloud.android.ui.activity.ComponentsGetter;
+import com.owncloud.android.ui.activity.DrawerActivity;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
 import com.owncloud.android.ui.fragment.SearchType;
 import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface;
@@ -755,6 +757,7 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
             this.user = account;
         }
         if (mStorageManager != null) {
+            // TODO refactor filtering mechanism for mFiles
             mFiles = mStorageManager.getFolderContent(directory, onlyOnDevice);
             if (!preferences.isShowHiddenFilesEnabled()) {
                 mFiles = filterHiddenFiles(mFiles);
@@ -765,6 +768,15 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
             if (OCFile.ROOT_PATH.equals(directory.getRemotePath()) && MainApp.isOnlyPersonFiles()) {
                 mFiles = limitToPersonalFiles(mFiles);
             }
+
+            // TODO refactor add DrawerState instead of using static menuItemId
+            if (DrawerActivity.menuItemId == R.id.nav_shared && currentDirectory != null) {
+                mFiles = updatedStorageManager.filter(currentDirectory, OCFileFilterType.Shared);
+            }
+            if (DrawerActivity.menuItemId == R.id.nav_favorites && currentDirectory != null) {
+                mFiles = updatedStorageManager.filter(currentDirectory, OCFileFilterType.Favorite);
+            }
+
             sortOrder = preferences.getSortOrderByFolder(directory);
             mFiles = sortOrder.sortCloudFiles(mFiles);
             prepareListOfHiddenFiles();

+ 112 - 29
app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -80,6 +80,7 @@ import com.owncloud.android.lib.resources.files.SearchRemoteOperation;
 import com.owncloud.android.lib.resources.files.ToggleFavoriteRemoteOperation;
 import com.owncloud.android.lib.resources.status.E2EVersion;
 import com.owncloud.android.lib.resources.status.OCCapability;
+import com.owncloud.android.ui.activity.DrawerActivity;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
 import com.owncloud.android.ui.activity.FolderPickerActivity;
@@ -128,6 +129,10 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
 
 import javax.inject.Inject;
 
@@ -915,50 +920,128 @@ public class OCFileListFragment extends ExtendedListFragment implements
         }
     }
 
-    /**
-     * Call this, when the user presses the up button.
-     * <p>
-     * Tries to move up the current folder one level. If the parent folder was removed from the database, it continues
-     * browsing up until finding an existing folders.
-     * <p>
-     * return       Count of folder levels browsed up.
-     */
-    public int onBrowseUp() {
-        OCFile parentDir;
+    private boolean shouldNavigateWithoutFilter(OCFile topParent) {
+        int menuItemId = DrawerActivity.menuItemId;
+        return (menuItemId != R.id.nav_shared && menuItemId != R.id.nav_favorites) ||
+            (menuItemId == R.id.nav_shared && topParent != null && topParent.isShared()) ||
+            (menuItemId == R.id.nav_favorites && topParent != null && topParent.isFavorite());
+    }
+
+    private boolean shouldNavigateWithFilter() {
+        int menuItemId = DrawerActivity.menuItemId;
+        return menuItemId == R.id.nav_shared || menuItemId == R.id.nav_favorites;
+    }
+
+    private Pair<Integer, OCFile> getPreviousFileWithoutFilter(FileDataStorageManager storageManager) {
         int moveCount = 0;
+        OCFile parentDir = null;
+        String parentPath = null;
 
-        if (mFile != null) {
-            FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
+        if (mFile.getParentId() != FileDataStorageManager.ROOT_PARENT_ID) {
+            parentPath = new File(mFile.getRemotePath()).getParent();
 
-            String parentPath = null;
-            if (mFile.getParentId() != FileDataStorageManager.ROOT_PARENT_ID) {
-                parentPath = new File(mFile.getRemotePath()).getParent();
-                parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath :
-                    parentPath + OCFile.PATH_SEPARATOR;
+            if (parentPath != null) {
+                parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
                 parentDir = storageManager.getFileByPath(parentPath);
                 moveCount++;
-            } else {
-                parentDir = storageManager.getFileByPath(ROOT_PATH);
             }
-            while (parentDir == null) {
-                parentPath = new File(parentPath).getParent();
+        } else {
+            parentDir = storageManager.getFileByPath(ROOT_PATH);
+        }
+
+        while (parentDir == null) {
+            parentPath = new File(parentPath).getParent();
+
+            if (parentPath != null) {
                 parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath :
                     parentPath + OCFile.PATH_SEPARATOR;
                 parentDir = storageManager.getFileByPath(parentPath);
                 moveCount++;
-            }   // exit is granted because storageManager.getFileByPath("/") never returns null
-            mFile = parentDir;
+            }
+        }
 
-            listDirectory(mFile, MainApp.isOnlyOnDevice(), false);
+        return new Pair<>(moveCount, parentDir);
+    }
 
-            onRefresh(false);
+    private OCFile getPreviousFileWithFilter(FileDataStorageManager storageManager, OCFile currentFile) {
+        while (true) {
+            OCFile parent = storageManager.getFileById(currentFile.getParentId());
+            if (parent == null) {
+                return currentFile;
+            }
 
-            // restore index and top position
-            restoreIndexAndTopPosition();
+            if (parent.isRootDirectory()) {
+                return parent;
+            }
 
-        }   // else - should never happen now
+            if ((DrawerActivity.menuItemId == R.id.nav_shared && parent.isShared()) ||
+                (DrawerActivity.menuItemId == R.id.nav_favorites && parent.isFavorite())) {
+                return parent;
+            }
+
+            currentFile = parent;
+        }
+    }
+
+    private Future<Pair<Integer, OCFile>> getPreviousFile() {
+        CompletableFuture<Pair<Integer, OCFile>> completableFuture = new CompletableFuture<>();
+
+        Executors.newCachedThreadPool().submit(() -> {
+            var result = new Pair<Integer, OCFile>(null, null);
+
+            FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
+            OCFile currentFile = getCurrentFile();
+            OCFile topParent = storageManager.getTopParent(currentFile);
+
+            if (shouldNavigateWithoutFilter(topParent)) {
+                result = getPreviousFileWithoutFilter(storageManager);
+            } else if (shouldNavigateWithFilter()) {
+                OCFile previousFileWithFilter = getPreviousFileWithFilter(storageManager, currentFile);
+                result = new Pair<>(0, previousFileWithFilter);
+            }
+
+            completableFuture.complete(result);
+
+            return null;
+        });
+
+        return completableFuture;
+    }
+
+    /**
+     * Call this, when the user presses the up button.
+     * <p>
+     * Tries to move up the current folder one level. If the parent folder was removed from the database, it continues
+     * browsing up until finding an existing folders.
+     * <p>
+     * return       Count of folder levels browsed up.
+     */
+    public int onBrowseUp() {
+        if (mFile == null) {
+            return 0;
+        }
+
+        try {
+            Future<Pair<Integer, OCFile>> futureResult = getPreviousFile();
+            Pair<Integer, OCFile> result = futureResult.get();
+            mFile = result.second;
+            updateFileList();
+            return result.first;
+        } catch (Exception e) {
+            Log_OC.e(TAG,"Error caught in onBrowseUp " + e + " getPreviousFileWithoutFilter() used: ");
+
+            FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
+            var result = getPreviousFileWithoutFilter(storageManager);
+            mFile = result.second;
+            updateFileList();
+            return result.first;
+        }
+    }
 
-        return moveCount;
+    private void updateFileList() {
+        listDirectory(mFile, MainApp.isOnlyOnDevice(), false);
+        onRefresh(false);
+        restoreIndexAndTopPosition();
     }
 
     /**