فهرست منبع

Merge pull request #9761 from nextcloud/fix/local-files-freeze

Improve freezes in local files screens when folder contains many files
Álvaro Brey 3 سال پیش
والد
کامیت
3e97e1e212

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

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

+ 2 - 2
src/androidTest/java/com/owncloud/android/util/TestSorting.java

@@ -419,13 +419,13 @@ public class TestSorting {
         if (sortedList.get(0) instanceof OCFile) {
             Collections.sort(unsortedList, (Comparator<OCFile>) (o1, o2) -> {
                 if (o1.isFolder() && o2.isFolder()) {
-                    return new AlphanumComparator().compare(o1, o2);
+                    return AlphanumComparator.compare(o1, o2);
                 } else if (o1.isFolder()) {
                     return -1;
                 } else if (o2.isFolder()) {
                     return 1;
                 }
-                return new AlphanumComparator().compare(o1, o2);
+                return AlphanumComparator.compare(o1, o2);
             });
         } else {
             Collections.sort(unsortedList, new AlphanumComparator<>());

+ 2 - 2
src/main/java/com/owncloud/android/datamodel/OCFile.java

@@ -478,13 +478,13 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
     @Override
     public int compareTo(@NonNull OCFile another) {
         if (isFolder() && another.isFolder()) {
-            return new AlphanumComparator().compare(this, another);
+            return AlphanumComparator.compare(this, another);
         } else if (isFolder()) {
             return -1;
         } else if (another.isFolder()) {
             return 1;
         }
-        return new AlphanumComparator().compare(this, another);
+        return AlphanumComparator.compare(this, another);
     }
 
     @Override

+ 47 - 24
src/main/java/com/owncloud/android/ui/adapter/LocalFileListAdapter.java

@@ -23,6 +23,8 @@ package com.owncloud.android.ui.adapter;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.os.Handler;
+import android.os.Looper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -49,6 +51,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Set;
+import java.util.concurrent.Executors;
 
 import androidx.annotation.NonNull;
 import androidx.recyclerview.widget.RecyclerView;
@@ -79,9 +82,10 @@ public class LocalFileListAdapter extends RecyclerView.Adapter<RecyclerView.View
         this.preferences = preferences;
         mContext = context;
         mLocalFolderPicker = localFolderPickerMode;
-        swapDirectory(directory);
         this.localFileListFragmentInterface = localFileListFragmentInterface;
         checkedFiles = new HashSet<>();
+
+        swapDirectory(directory);
     }
 
     @Override
@@ -313,39 +317,58 @@ public class LocalFileListAdapter extends RecyclerView.Adapter<RecyclerView.View
      * @param directory New file to adapt. Can be NULL, meaning "no content to adapt".
      */
     public void swapDirectory(final File directory) {
-        if (mLocalFolderPicker) {
-            if (directory == null) {
-                mFiles.clear();
-            } else {
-                mFiles = getFolders(directory);
-            }
-        } else {
+        localFileListFragmentInterface.setLoading(true);
+        final Handler uiHandler = new Handler(Looper.getMainLooper());
+        Executors.newSingleThreadExecutor().execute(() -> {
+            List<File> fileList;
             if (directory == null) {
-                mFiles.clear();
+                fileList = new ArrayList<>();
             } else {
-                mFiles = getFiles(directory);
+                if (mLocalFolderPicker) {
+                    fileList = getFolders(directory);
+                } else {
+                    fileList = getFiles(directory);
+                }
             }
-        }
 
-        FileSortOrder sortOrder = preferences.getSortOrderByType(FileSortOrder.Type.localFileListView);
-        mFiles = sortOrder.sortLocalFiles(mFiles);
+            if (!fileList.isEmpty()) {
+                FileSortOrder sortOrder = preferences.getSortOrderByType(FileSortOrder.Type.localFileListView);
+                fileList = sortOrder.sortLocalFiles(fileList);
 
-        // Fetch preferences for showing hidden files
-        boolean showHiddenFiles = preferences.isShowHiddenFilesEnabled();
-        if (!showHiddenFiles) {
-            mFiles = filterHiddenFiles(mFiles);
-        }
+                // Fetch preferences for showing hidden files
+                boolean showHiddenFiles = preferences.isShowHiddenFilesEnabled();
+                if (!showHiddenFiles) {
+                    fileList = filterHiddenFiles(fileList);
+                }
+            }
+            final List<File> newFiles = fileList;
 
-        mFilesAll.clear();
-        mFilesAll.addAll(mFiles);
+            uiHandler.post(() -> {
+                mFiles = newFiles;
+                mFilesAll = new ArrayList<>();
+                mFilesAll.addAll(mFiles);
+
+                notifyDataSetChanged();
+                localFileListFragmentInterface.setLoading(false);
+            });
+        });
 
-        notifyDataSetChanged();
     }
 
     public void setSortOrder(FileSortOrder sortOrder) {
-        preferences.setSortOrder(FileSortOrder.Type.localFileListView, sortOrder);
-        mFiles = sortOrder.sortLocalFiles(mFiles);
-        notifyDataSetChanged();
+        localFileListFragmentInterface.setLoading(true);
+        final Handler uiHandler = new Handler(Looper.getMainLooper());
+        Executors.newSingleThreadExecutor().execute(() -> {
+            preferences.setSortOrder(FileSortOrder.Type.localFileListView, sortOrder);
+            mFiles = sortOrder.sortLocalFiles(mFiles);
+
+            uiHandler.post(() -> {
+                notifyDataSetChanged();
+                localFileListFragmentInterface.setLoading(false);
+            });
+        });
+
+
     }
 
     private List<File> getFolders(final File directory) {

+ 17 - 0
src/main/java/com/owncloud/android/ui/fragment/LocalFileListFragment.java

@@ -24,6 +24,7 @@ import android.app.Activity;
 import android.content.Context;
 import android.os.Bundle;
 import android.os.Environment;
+import android.os.Handler;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -367,6 +368,22 @@ public class LocalFileListFragment extends ExtendedListFragment implements
         super.switchToListView();
     }
 
+    @Override
+    public void setLoading(boolean enabled) {
+        super.setLoading(enabled);
+        if (enabled) {
+            setEmptyListLoadingMessage();
+        } else {
+            // ugly hack because setEmptyListLoadingMessage also uses a handler and there's a race condition otherwise
+            new Handler().post(() -> {
+                mAdapter.notifyDataSetChanged();
+                if(mAdapter.getFilesCount() == 0){
+                    setEmptyListMessage(SearchType.NO_SEARCH);
+                }
+            });
+        }
+    }
+
     /**
      * Interface to implement by any Activity that includes some instance of LocalFileListFragment
      */

+ 1 - 0
src/main/java/com/owncloud/android/ui/interfaces/LocalFileListFragmentInterface.java

@@ -32,4 +32,5 @@ public interface LocalFileListFragmentInterface {
     int getColumnsCount();
     void onItemClicked(File file);
     void onItemCheckboxClicked(File file);
+    void setLoading(boolean loading);
 }

+ 0 - 107
src/main/java/com/owncloud/android/utils/FileSortOrder.java

@@ -1,107 +0,0 @@
-/*
- * Nextcloud Android client application
- *
- * @author Sven R. Kunze
- * Copyright (C) 2017 Sven R. Kunze
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * 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 AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.owncloud.android.utils;
-
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.lib.resources.trashbin.model.TrashbinFile;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Sort order
- */
-
-public class FileSortOrder {
-    public static final String sort_a_to_z_id = "sort_a_to_z";
-    public static final String sort_z_to_a_id = "sort_z_to_a";
-    public static final String sort_old_to_new_id = "sort_old_to_new";
-    public static final String sort_new_to_old_id = "sort_new_to_old";
-    public static final String sort_small_to_big_id = "sort_small_to_big";
-    public static final String sort_big_to_small_id = "sort_big_to_small";
-
-    public static final FileSortOrder sort_a_to_z = new FileSortOrderByName(sort_a_to_z_id, true);
-    public static final FileSortOrder sort_z_to_a = new FileSortOrderByName(sort_z_to_a_id, false);
-    public static final FileSortOrder sort_old_to_new = new FileSortOrderByDate(sort_old_to_new_id, true);
-    public static final FileSortOrder sort_new_to_old = new FileSortOrderByDate(sort_new_to_old_id, false);
-    public static final FileSortOrder sort_small_to_big = new FileSortOrderBySize(sort_small_to_big_id, true);
-    public static final FileSortOrder sort_big_to_small = new FileSortOrderBySize(sort_big_to_small_id, false);
-
-    public static final Map<String, FileSortOrder> sortOrders;
-
-    public enum Type {
-        trashBinView, localFileListView
-    }
-    static {
-        HashMap<String, FileSortOrder> temp = new HashMap<>();
-        temp.put(sort_a_to_z.name, sort_a_to_z);
-        temp.put(sort_z_to_a.name, sort_z_to_a);
-        temp.put(sort_old_to_new.name, sort_old_to_new);
-        temp.put(sort_new_to_old.name, sort_new_to_old);
-        temp.put(sort_small_to_big.name, sort_small_to_big);
-        temp.put(sort_big_to_small.name, sort_big_to_small);
-
-        sortOrders = Collections.unmodifiableMap(temp);
-    }
-
-    public String name;
-    public boolean isAscending;
-
-    public FileSortOrder(String name, boolean ascending) {
-        this.name = name;
-        isAscending = ascending;
-    }
-
-    public List<OCFile> sortCloudFiles(List<OCFile> files) {
-        return sortCloudFilesByFavourite(files);
-    }
-
-    public List<File> sortLocalFiles(List<File> files) {
-        return files;
-    }
-
-    public List<TrashbinFile> sortTrashbinFiles(List<TrashbinFile> files) {
-        return files;
-    }
-
-    /**
-     * Sorts list by Favourites.
-     *
-     * @param files files to sort
-     */
-    public static List<OCFile> sortCloudFilesByFavourite(List<OCFile> files) {
-        Collections.sort(files, (o1, o2) -> {
-            if (o1.isFavorite() && o2.isFavorite()) {
-                return 0;
-            } else if (o1.isFavorite()) {
-                return -1;
-            } else if (o2.isFavorite()) {
-                return 1;
-            }
-            return 0;
-        });
-
-        return files;
-    }
-}

+ 109 - 0
src/main/java/com/owncloud/android/utils/FileSortOrder.kt

@@ -0,0 +1,109 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Sven R. Kunze
+ * Copyright (C) 2017 Sven R. Kunze
+ * Copyright (C) 2022 Álvaro Brey Vilas
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.owncloud.android.utils
+
+import com.owncloud.android.datamodel.OCFile
+import com.owncloud.android.lib.resources.trashbin.model.TrashbinFile
+import java.io.File
+import java.util.Collections
+
+/**
+ * Sort order
+ */
+open class FileSortOrder(@JvmField var name: String, var isAscending: Boolean) {
+
+    val sortMultiplier: Int
+        get() = if (isAscending) 1 else -1
+
+    @Suppress("EnumNaming") // already saved in user preferences -.-'
+    enum class Type {
+        trashBinView, localFileListView
+    }
+
+    companion object {
+        const val sort_a_to_z_id = "sort_a_to_z"
+        const val sort_z_to_a_id = "sort_z_to_a"
+        const val sort_old_to_new_id = "sort_old_to_new"
+        const val sort_new_to_old_id = "sort_new_to_old"
+        const val sort_small_to_big_id = "sort_small_to_big"
+        const val sort_big_to_small_id = "sort_big_to_small"
+
+        @JvmField
+        val sort_a_to_z: FileSortOrder = FileSortOrderByName(sort_a_to_z_id, true)
+
+        @JvmField
+        val sort_z_to_a: FileSortOrder = FileSortOrderByName(sort_z_to_a_id, false)
+
+        @JvmField
+        val sort_old_to_new: FileSortOrder = FileSortOrderByDate(sort_old_to_new_id, true)
+
+        @JvmField
+        val sort_new_to_old: FileSortOrder = FileSortOrderByDate(sort_new_to_old_id, false)
+
+        @JvmField
+        val sort_small_to_big: FileSortOrder = FileSortOrderBySize(sort_small_to_big_id, true)
+
+        @JvmField
+        val sort_big_to_small: FileSortOrder = FileSortOrderBySize(sort_big_to_small_id, false)
+
+        @JvmField
+        val sortOrders: Map<String, FileSortOrder> = Collections.unmodifiableMap(
+            mapOf(
+                sort_a_to_z.name to sort_a_to_z,
+                sort_z_to_a.name to sort_z_to_a,
+                sort_old_to_new.name to sort_old_to_new,
+                sort_new_to_old.name to sort_new_to_old,
+                sort_small_to_big.name to sort_small_to_big,
+                sort_big_to_small.name to sort_big_to_small
+            )
+        )
+
+        /**
+         * Sorts list by Favourites.
+         *
+         * @param files files to sort
+         */
+        @JvmStatic
+        fun sortCloudFilesByFavourite(files: MutableList<OCFile>): List<OCFile> {
+            files.sortWith { o1: OCFile, o2: OCFile ->
+                when {
+                    o1.isFavorite && o2.isFavorite -> 0
+                    o1.isFavorite -> -1
+                    o2.isFavorite -> 1
+                    else -> 0
+                }
+            }
+            return files
+        }
+    }
+
+    open fun sortCloudFiles(files: MutableList<OCFile>): List<OCFile> {
+        return sortCloudFilesByFavourite(files)
+    }
+
+    open fun sortLocalFiles(files: MutableList<File>): List<File> {
+        return files
+    }
+
+    open fun sortTrashbinFiles(files: MutableList<TrashbinFile>): List<TrashbinFile> {
+        return files
+    }
+}

+ 0 - 82
src/main/java/com/owncloud/android/utils/FileSortOrderByDate.java

@@ -1,82 +0,0 @@
-/*
- * Nextcloud Android client application
- *
- * @author Sven R. Kunze
- * Copyright (C) 2017 Sven R. Kunze
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * 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 AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.owncloud.android.utils;
-
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.lib.resources.trashbin.model.TrashbinFile;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Created by srkunze on 28.08.17.
- */
-public class FileSortOrderByDate extends FileSortOrder {
-
-    FileSortOrderByDate(String name, boolean ascending) {
-        super(name, ascending);
-    }
-
-    /**
-     * Sorts list by Date.
-     *
-     * @param files list of files to sort
-     */
-    public List<OCFile> sortCloudFiles(List<OCFile> files) {
-        final int multiplier = isAscending ? 1 : -1;
-
-        Collections.sort(files, (o1, o2) ->
-                multiplier * Long.compare(o1.getModificationTimestamp(), o2.getModificationTimestamp()));
-
-        return super.sortCloudFiles(files);
-    }
-
-    /**
-     * Sorts list by Date.
-     *
-     * @param files list of files to sort
-     */
-    @Override
-    public List<TrashbinFile> sortTrashbinFiles(List<TrashbinFile> files) {
-        final int multiplier = isAscending ? 1 : -1;
-
-        Collections.sort(files, (o1, o2) -> {
-            return multiplier * Long.compare(o1.getDeletionTimestamp(),o2.getDeletionTimestamp());
-        });
-
-        return super.sortTrashbinFiles(files);
-    }
-
-    /**
-     * Sorts list by Date.
-     *
-     * @param files list of files to sort
-     */
-    @Override
-    public List<File> sortLocalFiles(List<File> files) {
-        final int multiplier = isAscending ? 1 : -1;
-
-        Collections.sort(files, (o1, o2) -> multiplier * Long.compare(o1.lastModified(),o2.lastModified()));
-
-        return files;
-    }
-}

+ 69 - 0
src/main/java/com/owncloud/android/utils/FileSortOrderByDate.kt

@@ -0,0 +1,69 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Sven R. Kunze
+ * Copyright (C) 2017 Sven R. Kunze
+ * Copyright (C) 2022 Álvaro Brey Vilas
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.owncloud.android.utils
+
+import com.owncloud.android.datamodel.OCFile
+import com.owncloud.android.lib.resources.trashbin.model.TrashbinFile
+import java.io.File
+
+/**
+ * Created by srkunze on 28.08.17.
+ */
+class FileSortOrderByDate(name: String, ascending: Boolean) : FileSortOrder(name, ascending) {
+    /**
+     * Sorts list by Date.
+     *
+     * @param files list of files to sort
+     */
+    override fun sortCloudFiles(files: MutableList<OCFile>): List<OCFile> {
+        val multiplier = if (isAscending) 1 else -1
+        files.sortWith { o1: OCFile, o2: OCFile ->
+            multiplier * o1.modificationTimestamp.compareTo(o2.modificationTimestamp)
+        }
+        return super.sortCloudFiles(files)
+    }
+
+    /**
+     * Sorts list by Date.
+     *
+     * @param files list of files to sort
+     */
+    override fun sortTrashbinFiles(files: MutableList<TrashbinFile>): List<TrashbinFile> {
+        val multiplier = if (isAscending) 1 else -1
+        files.sortWith { o1: TrashbinFile, o2: TrashbinFile ->
+            multiplier * o1.deletionTimestamp.compareTo(o2.deletionTimestamp)
+        }
+        return super.sortTrashbinFiles(files)
+    }
+
+    /**
+     * Sorts list by Date.
+     *
+     * @param files list of files to sort
+     */
+    override fun sortLocalFiles(files: MutableList<File>): List<File> {
+        val multiplier = if (isAscending) 1 else -1
+        files.sortWith { o1: File, o2: File ->
+            multiplier * o1.lastModified().compareTo(o2.lastModified())
+        }
+        return files
+    }
+}

+ 0 - 115
src/main/java/com/owncloud/android/utils/FileSortOrderByName.java

@@ -1,115 +0,0 @@
-/*
- * Nextcloud Android client application
- *
- * @author Sven R. Kunze
- * Copyright (C) 2017 Sven R. Kunze
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * 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 AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.owncloud.android.utils;
-
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.lib.resources.trashbin.model.TrashbinFile;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import third_parties.daveKoeller.AlphanumComparator;
-
-/**
- * Created by srkunze on 28.08.17.
- */
-public class FileSortOrderByName extends FileSortOrder {
-
-    FileSortOrderByName(String name, boolean ascending) {
-        super(name, ascending);
-    }
-
-    /**
-     * Sorts list by Name.
-     *
-     * @param files files to sort
-     */
-    @SuppressFBWarnings("Bx")
-    public List<OCFile> sortCloudFiles(List<OCFile> files) {
-        final int multiplier = isAscending ? 1 : -1;
-
-        Collections.sort(files, (o1, o2) -> {
-            if (o1.isFolder() && o2.isFolder()) {
-                return multiplier * new AlphanumComparator().compare(o1, o2);
-            } else if (o1.isFolder()) {
-                return -1;
-            } else if (o2.isFolder()) {
-                return 1;
-            }
-            return multiplier * new AlphanumComparator().compare(o1, o2);
-        });
-
-        return super.sortCloudFiles(files);
-    }
-
-    /**
-     * Sorts list by Name.
-     *
-     * @param files files to sort
-     */
-    @SuppressFBWarnings("Bx")
-    @Override
-    public List<TrashbinFile> sortTrashbinFiles(List<TrashbinFile> files) {
-        final int multiplier = isAscending ? 1 : -1;
-
-        Collections.sort(files, (o1, o2) -> {
-            if (o1.isFolder() && o2.isFolder()) {
-                return multiplier * new AlphanumComparator().compare(o1, o2);
-            } else if (o1.isFolder()) {
-                return -1;
-            } else if (o2.isFolder()) {
-                return 1;
-            }
-            return multiplier * new AlphanumComparator().compare(o1, o2);
-        });
-
-        return super.sortTrashbinFiles(files);
-    }
-
-    /**
-     * Sorts list by Name.
-     *
-     * @param files files to sort
-     */
-    @Override
-    public List<File> sortLocalFiles(List<File> files) {
-        final int multiplier = isAscending ? 1 : -1;
-
-        Collections.sort(files, (o1, o2) -> {
-            if (o1.isDirectory() && o2.isDirectory()) {
-                return multiplier * o1.getPath().toLowerCase(Locale.getDefault())
-                        .compareTo(o2.getPath().toLowerCase(Locale.getDefault()));
-            } else if (o1.isDirectory()) {
-                return -1;
-            } else if (o2.isDirectory()) {
-                return 1;
-            }
-            return multiplier * new AlphanumComparator().compare(o1.getPath()
-                            .toLowerCase(Locale.getDefault()),
-                    o2.getPath().toLowerCase(Locale.getDefault()));
-        });
-
-        return files;
-    }
-}

+ 89 - 0
src/main/java/com/owncloud/android/utils/FileSortOrderByName.kt

@@ -0,0 +1,89 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Sven R. Kunze
+ * Copyright (C) 2017 Sven R. Kunze
+ * Copyright (C) 2022 Álvaro Brey Vilas
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.owncloud.android.utils
+
+import com.owncloud.android.datamodel.OCFile
+import com.owncloud.android.lib.resources.files.model.ServerFileInterface
+import com.owncloud.android.lib.resources.trashbin.model.TrashbinFile
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
+import third_parties.daveKoeller.AlphanumComparator
+import java.io.File
+import java.util.Locale
+
+/**
+ * Sorts list by Name.
+ *
+ * Created by srkunze on 28.08.17.
+ */
+class FileSortOrderByName internal constructor(name: String?, ascending: Boolean) : FileSortOrder(name!!, ascending) {
+    /**
+     *
+     * @param files files to sort
+     */
+    @SuppressFBWarnings("Bx")
+    override fun sortCloudFiles(files: MutableList<OCFile>): List<OCFile> {
+        val sortedByName = sortServerFiles(files)
+        return super.sortCloudFiles(sortedByName)
+    }
+
+    /**
+     * Sorts list by Name.
+     *
+     * @param files files to sort
+     */
+    override fun sortTrashbinFiles(files: MutableList<TrashbinFile>): List<TrashbinFile> {
+        val sortedByName = sortServerFiles(files)
+        return super.sortTrashbinFiles(sortedByName)
+    }
+
+    private fun <T : ServerFileInterface> sortServerFiles(files: MutableList<T>): MutableList<T> {
+        files.sortWith { o1: ServerFileInterface, o2: ServerFileInterface ->
+            when {
+                o1.isFolder && o2.isFolder -> sortMultiplier * AlphanumComparator.compare(o1, o2)
+                o1.isFolder -> -1
+                o2.isFolder -> 1
+                else -> sortMultiplier * AlphanumComparator.compare(o1, o2)
+            }
+        }
+        return files
+    }
+
+    /**
+     * Sorts list by Name.
+     *
+     * @param files files to sort
+     */
+    override fun sortLocalFiles(files: MutableList<File>): List<File> {
+        files.sortWith { o1: File, o2: File ->
+            when {
+                o1.isDirectory && o2.isDirectory -> sortMultiplier * o1.path.lowercase(Locale.getDefault())
+                    .compareTo(o2.path.lowercase(Locale.getDefault()))
+                o1.isDirectory -> -1
+                o2.isDirectory -> 1
+                else -> sortMultiplier * AlphanumComparator.compare(
+                    o1.path.lowercase(Locale.getDefault()),
+                    o2.path.lowercase(Locale.getDefault())
+                )
+            }
+        }
+        return files
+    }
+}

+ 0 - 112
src/main/java/com/owncloud/android/utils/FileSortOrderBySize.java

@@ -1,112 +0,0 @@
-/*
- * Nextcloud Android client application
- *
- * @author Sven R. Kunze
- * Copyright (C) 2017 Sven R. Kunze
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * 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 AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package com.owncloud.android.utils;
-
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.lib.resources.trashbin.model.TrashbinFile;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-
-
-/**
- * Sorts files by sizes
- */
-public class FileSortOrderBySize extends FileSortOrder {
-
-    FileSortOrderBySize(String name, boolean ascending) {
-        super(name, ascending);
-    }
-
-    /**
-     * Sorts list by Size.
-     *
-     * @param files list of files to sort
-     */
-    public List<OCFile> sortCloudFiles(List<OCFile> files) {
-        final int multiplier = isAscending ? 1 : -1;
-
-        Collections.sort(files, (o1, o2) -> {
-            if (o1.isFolder() && o2.isFolder()) {
-                return multiplier * Long.compare(o1.getFileLength(), o2.getFileLength());
-            } else if (o1.isFolder()) {
-                return -1;
-            } else if (o2.isFolder()) {
-                return 1;
-            } else {
-                return multiplier * Long.compare(o1.getFileLength(),o2.getFileLength());
-            }
-        });
-
-        return super.sortCloudFiles(files);
-    }
-
-    /**
-     * Sorts list by Size.
-     *
-     * @param files list of files to sort
-     */
-    @Override
-    public List<TrashbinFile> sortTrashbinFiles(List<TrashbinFile> files) {
-        final int multiplier = isAscending ? 1 : -1;
-
-        Collections.sort(files, (o1, o2) -> {
-            if (o1.isFolder() && o2.isFolder()) {
-                return multiplier * Long.compare(o1.getFileLength(), o2.getFileLength());
-            } else if (o1.isFolder()) {
-                return -1;
-
-            } else if (o2.isFolder()) {
-                return 1;
-            } else {
-                return multiplier * Long.compare(o1.getFileLength(),o2.getFileLength());
-            }
-        });
-
-        return super.sortTrashbinFiles(files);
-    }
-
-    /**
-     * Sorts list by Size.
-     *
-     * @param files list of files to sort
-     */
-    @Override
-    public List<File> sortLocalFiles(List<File> files) {
-        final int multiplier = isAscending ? 1 : -1;
-
-        Collections.sort(files, (o1, o2) -> {
-            if (o1.isDirectory() && o2.isDirectory()) {
-                return multiplier * Long.compare(FileStorageUtils.getFolderSize(o1),
-                                                 FileStorageUtils.getFolderSize(o2));
-            } else if (o1.isDirectory()) {
-                return -1;
-            } else if (o2.isDirectory()) {
-                return 1;
-            } else {
-                return multiplier * Long.compare(o1.length(),o2.length());
-            }
-        });
-
-        return files;
-    }
-}

+ 68 - 0
src/main/java/com/owncloud/android/utils/FileSortOrderBySize.kt

@@ -0,0 +1,68 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Sven R. Kunze
+ * Copyright (C) 2017 Sven R. Kunze
+ * Copyright (C) 2022 Álvaro Brey Vilas
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.owncloud.android.utils
+
+import com.owncloud.android.datamodel.OCFile
+import com.owncloud.android.lib.resources.files.model.ServerFileInterface
+import com.owncloud.android.lib.resources.trashbin.model.TrashbinFile
+import java.io.File
+
+/**
+ * Sorts files by sizes
+ */
+class FileSortOrderBySize internal constructor(name: String?, ascending: Boolean) : FileSortOrder(name!!, ascending) {
+
+    override fun sortCloudFiles(files: MutableList<OCFile>): List<OCFile> {
+        val sortedBySize = sortServerFiles(files)
+        return super.sortCloudFiles(sortedBySize)
+    }
+
+    override fun sortTrashbinFiles(files: MutableList<TrashbinFile>): List<TrashbinFile> {
+        val sortedBySize = sortServerFiles(files)
+        return super.sortTrashbinFiles(sortedBySize)
+    }
+
+    private fun <T : ServerFileInterface> sortServerFiles(files: MutableList<T>): MutableList<T> {
+        files.sortWith { o1: ServerFileInterface, o2: ServerFileInterface ->
+            when {
+                o1.isFolder && o2.isFolder -> sortMultiplier * o1.fileLength.compareTo(o2.fileLength)
+                o1.isFolder -> -1
+                o2.isFolder -> 1
+                else -> sortMultiplier * o1.fileLength.compareTo(o2.fileLength)
+            }
+        }
+        return files
+    }
+
+    override fun sortLocalFiles(files: MutableList<File>): List<File> {
+
+        files.sortWith { o1: File, o2: File ->
+            when {
+                o1.isDirectory && o2.isDirectory -> sortMultiplier * FileStorageUtils.getFolderSize(o1)
+                    .compareTo(FileStorageUtils.getFolderSize(o2))
+                o1.isDirectory -> -1
+                o2.isDirectory -> 1
+                else -> sortMultiplier * o1.length().compareTo(o2.length())
+            }
+        }
+        return files
+    }
+}

+ 6 - 6
src/main/java/third_parties/daveKoeller/AlphanumComparator.java

@@ -49,18 +49,18 @@ import java.util.Comparator;
  * by Tobias Kaminsky
  */
 public class AlphanumComparator<T> implements Comparator<T>, Serializable {
-    private boolean isDigit(char ch) {
+    private static boolean isDigit(char ch) {
         return ch >= 48 && ch <= 57;
     }
 
-    private boolean isSpecialChar(char ch) {
+    private static boolean isSpecialChar(char ch) {
         return ch <= 47 || ch >= 58 && ch <= 64 || ch >= 91 && ch <= 96 || ch >= 123 && ch <= 126;
     }
 
     /**
      * Length of string is passed in for improved efficiency (only need to calculate it once)
      **/
-    private String getChunk(String string, int stringLength, int marker) {
+    private static String getChunk(String string, int stringLength, int marker) {
         StringBuilder chunk = new StringBuilder();
         char c = string.charAt(marker);
         chunk.append(c);
@@ -87,14 +87,14 @@ public class AlphanumComparator<T> implements Comparator<T>, Serializable {
         return chunk.toString();
     }
 
-    public int compare(ServerFileInterface o1, ServerFileInterface o2) {
+    public static int compare(ServerFileInterface o1, ServerFileInterface o2) {
         String s1 = o1.getFileName();
         String s2 = o2.getFileName();
 
         return compare(s1, s2);
     }
 
-    public int compare(File f1, File f2) {
+    public static int compare(File f1, File f2) {
         String s1 = f1.getPath();
         String s2 = f2.getPath();
 
@@ -105,7 +105,7 @@ public class AlphanumComparator<T> implements Comparator<T>, Serializable {
         return compare(t1.toString(), t2.toString());
     }
 
-    public int compare(String s1, String s2) {
+    public static int compare(String s1, String s2) {
         int thisMarker = 0;
         int thatMarker = 0;
         int s1Length = s1.length();