diff --git a/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java b/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java
index 438fa1768cf5..7cd7c1112326 100644
--- a/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java
+++ b/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java
@@ -108,7 +108,7 @@
import com.owncloud.android.ui.fragment.GalleryFragment;
import com.owncloud.android.ui.fragment.GalleryFragmentBottomSheetDialog;
import com.owncloud.android.ui.fragment.GroupfolderListFragment;
-import com.owncloud.android.ui.fragment.LocalFileListFragment;
+import com.owncloud.android.ui.fragment.localfilelist.LocalFileListFragment;
import com.owncloud.android.ui.fragment.OCFileListBottomSheetDialog;
import com.owncloud.android.ui.fragment.OCFileListFragment;
import com.owncloud.android.ui.fragment.SharedListFragment;
diff --git a/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java
index 5dab3516d444..4280eac6bf6f 100644
--- a/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java
+++ b/app/src/main/java/com/owncloud/android/ui/activity/UploadFilesActivity.java
@@ -49,7 +49,8 @@
import com.owncloud.android.ui.dialog.LocalStoragePathPickerDialogFragment;
import com.owncloud.android.ui.dialog.SortingOrderDialogFragment;
import com.owncloud.android.ui.fragment.ExtendedListFragment;
-import com.owncloud.android.ui.fragment.LocalFileListFragment;
+import com.owncloud.android.ui.fragment.localfilelist.LocalFileListFragment;
+import com.owncloud.android.ui.fragment.localfilelist.LocalFileListListener;
import com.owncloud.android.utils.FileSortOrder;
import com.owncloud.android.utils.FileUtil;
import com.owncloud.android.utils.PermissionUtil;
@@ -70,14 +71,13 @@
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import kotlin.Unit;
-import kotlin.jvm.functions.Function1;
import static com.owncloud.android.ui.activity.FileActivity.EXTRA_USER;
/**
* Displays local files and let the user choose what of them wants to upload to the current Nextcloud account.
*/
-public class UploadFilesActivity extends DrawerActivity implements LocalFileListFragment.ContainerActivity,
+public class UploadFilesActivity extends DrawerActivity implements LocalFileListListener,
OnClickListener, ConfirmationDialogFragmentListener, SortingOrderDialogFragment.OnSortingOrderListener,
CheckAvailableSpaceTask.CheckAvailableSpaceListener, StoragePathAdapter.StoragePathAdapterListener, Injectable {
diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/localFileList/LocalFileListAdapter.kt b/app/src/main/java/com/owncloud/android/ui/adapter/localFileList/LocalFileListAdapter.kt
index 90f49c7a8fc9..6719469c7bf1 100644
--- a/app/src/main/java/com/owncloud/android/ui/adapter/localFileList/LocalFileListAdapter.kt
+++ b/app/src/main/java/com/owncloud/android/ui/adapter/localFileList/LocalFileListAdapter.kt
@@ -99,6 +99,19 @@ class LocalFileListAdapter(
fun isCheckedFile(file: File): Boolean = checkedFiles.contains(file)
+ fun onItemCheckboxClicked(file: File) {
+ if (isCheckedFile(file)) {
+ removeCheckedFile(file)
+ } else {
+ addCheckedFile(file)
+ }
+
+ val position = getItemPosition(file)
+ if (position != RecyclerView.NO_POSITION) {
+ notifyItemChanged(position)
+ }
+ }
+
fun addCheckedFile(file: File) {
checkedFiles.add(file)
}
diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/LocalFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/LocalFileListFragment.java
deleted file mode 100644
index e9ace77bed2a..000000000000
--- a/app/src/main/java/com/owncloud/android/ui/fragment/LocalFileListFragment.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Nextcloud Android client application
- *
- * @author Tobias Kaminsky
- * Copyright (C) 2018 Tobias Kaminsky
- * Copyright (C) 2018 Nextcloud
- *
- * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
- */
-package com.owncloud.android.ui.fragment;
-
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.Environment;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.nextcloud.client.di.Injectable;
-import com.owncloud.android.R;
-import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.ui.adapter.localFileList.LocalFileListAdapter;
-import com.owncloud.android.ui.interfaces.LocalFileListFragmentInterface;
-import com.owncloud.android.utils.DisplayUtils;
-import com.owncloud.android.utils.FileSortOrder;
-
-import java.io.File;
-import java.util.List;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import static com.owncloud.android.utils.DisplayUtils.openSortingOrderDialogFragment;
-
-
-/**
- * A Fragment that lists all files and folders in a given LOCAL path.
- */
-public class LocalFileListFragment extends ExtendedListFragment implements
- LocalFileListFragmentInterface,
- Injectable {
-
- private static final String TAG = LocalFileListFragment.class.getSimpleName();
-
- /** Reference to the Activity which this fragment is attached to. For callbacks */
- private LocalFileListFragment.ContainerActivity mContainerActivity;
-
- /** Directory to show */
- private File mDirectory;
-
- /** Adapter to connect the data from the directory with the View object */
- private LocalFileListAdapter mAdapter;
-
- @Override
- public void onAttach(@NonNull Context context) {
- super.onAttach(context);
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onAttach(@NonNull Activity activity) {
- super.onAttach(activity);
- try {
- mContainerActivity = (ContainerActivity) activity;
- } catch (ClassCastException e) {
- throw new IllegalArgumentException(activity.toString() + " must implement " +
- LocalFileListFragment.ContainerActivity.class.getSimpleName(), e);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- Log_OC.i(TAG, "onCreateView() start");
- View v = super.onCreateView(inflater, container, savedInstanceState);
-
- if (mContainerActivity.isFolderPickerMode()) {
- setEmptyListMessage(EmptyListState.LOCAL_FILE_LIST_EMPTY_FOLDER);
- } else {
- setEmptyListMessage(EmptyListState.LOCAL_FILE_LIST_EMPTY_FILE);
- }
-
- setSwipeEnabled(false); // Disable pull-to-refresh
-
- Log_OC.i(TAG, "onCreateView() end");
- return v;
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- Log_OC.i(TAG, "onActivityCreated() start");
-
- super.onActivityCreated(savedInstanceState);
-
- mAdapter = new LocalFileListAdapter(mContainerActivity.isFolderPickerMode(),
- this,
- preferences,
- getActivity(),
- viewThemeUtils,
- mContainerActivity.isWithinEncryptedFolder());
- setRecyclerViewAdapter(mAdapter);
-
- listDirectory(mContainerActivity.getInitialDirectory());
-
- if (mSortButton != null) {
- mSortButton.setOnClickListener(v -> {
- FileSortOrder sortOrder = preferences.getSortOrderByType(FileSortOrder.Type.localFileListView);
- openSortingOrderDialogFragment(requireFragmentManager(), sortOrder);
- });
-
- FileSortOrder sortOrder = preferences.getSortOrderByType(FileSortOrder.Type.localFileListView);
- if (sortOrder != null) {
- mSortButton.setText(DisplayUtils.getSortOrderStringId(sortOrder));
- }
- }
-
- setLayoutSwitchButton();
-
- if (mSwitchGridViewButton != null) {
- mSwitchGridViewButton.setOnClickListener(v -> {
- if (isGridEnabled()) {
- switchToListView();
- } else {
- switchToGridView();
- }
- setLayoutSwitchButton();
- });
- }
-
- Log_OC.i(TAG, "onActivityCreated() stop");
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onCreateOptionsMenu(Menu menu, @NonNull MenuInflater inflater) {
- if (mContainerActivity.isFolderPickerMode()) {
- menu.removeItem(R.id.action_select_all);
- menu.removeItem(R.id.action_search);
- } else {
- super.onCreateOptionsMenu(menu, inflater);
- }
- }
-
- /**
- * Checks the file clicked over. Browses inside if it is a directory. Otherwise behaves like the checkbox was
- * clicked.
- * Notifies the container activity in any case.
- */
- @Override
- public void onItemClicked(File file) {
- if (file != null) {
- /// Click on a directory
- if (file.isDirectory()) {
- // just local updates
- listDirectory(file);
- // notify the click to container Activity
- mContainerActivity.onDirectoryClick(file);
-
- // save index and top position
- saveIndexAndTopPosition(mAdapter.getItemPosition(file));
-
- } else { /// Click on a file, behave like checkbox was clicked
- onItemCheckboxClicked(file);
- }
-
- } else {
- Log_OC.w(TAG, "Null object in ListAdapter!!");
- }
- }
-
- /**
- * Toggle selection of checked/unchecked file and notify adapter.
- */
- @Override
- public void onItemCheckboxClicked(File file) {
- if (file != null) {
- if (mAdapter.isCheckedFile(file)) {
- // uncheck
- mAdapter.removeCheckedFile(file);
- } else {
- // check
- mAdapter.addCheckedFile(file);
- }
-
- final int position = mAdapter.getItemPosition(file);
- if (position != RecyclerView.NO_POSITION) {
- mAdapter.notifyItemChanged(position);
- }
-
- // notify the change to the container Activity
- mContainerActivity.onFileClick(file);
- } else {
- Log_OC.w(TAG, "Null object in ListAdapter!!");
- }
- }
-
- /**
- * Call this, when the user presses the up button
- */
- public void onNavigateUp() {
- File parentDir = null;
- if (mDirectory != null) {
- parentDir = mDirectory.getParentFile(); // can be null
- }
- listDirectory(parentDir);
-
- // restore index and top position
- restoreIndexAndTopPosition();
- }
-
-
- /**
- * Use this to query the {@link File} object for the directory
- * that is currently being displayed by this fragment
- *
- * @return File The currently displayed directory
- */
- public File getCurrentDirectory() {
- return mDirectory;
- }
-
-
- /**
- * Calls {@link LocalFileListFragment#listDirectory(File)} with a null parameter
- * to refresh the current directory.
- */
- public void listDirectory() {
- listDirectory(null);
- }
-
-
- /**
- * Lists the given directory on the view. When the input parameter is null,
- * it will either refresh the last known directory. list the root
- * if there never was a directory.
- *
- * @param directory Directory to be listed
- */
- public void listDirectory(File directory) {
- if (directory == null) {
- directory = (mDirectory != null) ? mDirectory : Environment.getExternalStorageDirectory();
- if (directory == null) return;
- }
-
- // If input is not a directory, list its parent
- if (!directory.isDirectory()) {
- Log_OC.w(TAG, "You see, that is not a directory -> " + directory);
- directory = directory.getParentFile();
- if (directory == null) {
- Log_OC.w(TAG, "parent directory is null, cannot swap directory");
- return;
- }
- }
-
- mAdapter.removeAllFilesFromCheckedFiles();
- mAdapter.swapDirectory(directory);
-
- mDirectory = directory;
-
- final var recyclerView = getRecyclerView();
- if (recyclerView != null) {
- recyclerView.scrollToPosition(0);
- }
- }
-
-
- /**
- * Returns the full paths to the files checked by the user
- *
- * @return File paths to the files checked by the user.
- */
- public String[] getCheckedFilePaths() {
- return mAdapter.getCheckedFilesPath();
- }
-
- public int getCheckedFilesCount() {
- return mAdapter.checkedFilesCount();
- }
-
- public int getFilesCount() {
- return mAdapter.getFilesCount();
- }
-
- public void sortFiles(FileSortOrder sortOrder) {
- if (mSortButton != null) {
- mSortButton.setText(DisplayUtils.getSortOrderStringId(sortOrder));
- }
- mAdapter.setSortOrder(sortOrder);
- }
-
- /**
- * De-/select all elements in the local file list.
- *
- * @param select true to select all, false to deselect all
- */
- public void selectAllFiles(boolean select) {
- if (getRecyclerView() == null) {
- return;
- }
-
- final var localFileListAdapter = (LocalFileListAdapter) getRecyclerView().getAdapter();
- if (localFileListAdapter == null) {
- return;
- }
-
- if (select) {
- localFileListAdapter.addAllFilesToCheckedFiles();
- } else {
- localFileListAdapter.removeAllFilesFromCheckedFiles();
- }
-
- mAdapter.notifyItemRangeChanged(0, mAdapter.getItemCount());
- }
-
- @Override
- public void switchToGridView() {
- if (getRecyclerView() == null) {
- return;
- }
-
- mAdapter.setGridView(true);
- /*
- * Set recyclerview adapter again to force new view for items. If this is not done
- * a few items keep their old view.
- *
- * https://stackoverflow.com/questions/36495009/force-recyclerview-to-redraw-android
- */
- getRecyclerView().setAdapter(mAdapter);
-
- if (!isGridEnabled()) {
- RecyclerView.LayoutManager layoutManager;
- layoutManager = new GridLayoutManager(getContext(), getColumnsCount());
- ((GridLayoutManager) layoutManager).setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
- @Override
- public int getSpanSize(int position) {
- if (position == mAdapter.getItemCount() - 1) {
- return ((GridLayoutManager) layoutManager).getSpanCount();
- } else {
- return 1;
- }
- }
- });
-
- getRecyclerView().setLayoutManager(layoutManager);
- }
- }
-
- @Override
- public void switchToListView() {
- if (getRecyclerView() == null) {
- return;
- }
-
- mAdapter.setGridView(false);
- /* Same problem here, see switchToGridView() */
- getRecyclerView().setAdapter(mAdapter);
- super.switchToListView();
- }
-
- @VisibleForTesting
- public void setFiles(List newFiles) {
- mAdapter.setFiles(newFiles);
- }
-
- /**
- * Interface to implement by any Activity that includes some instance of LocalFileListFragment
- */
- public interface ContainerActivity {
-
- /**
- * Callback method invoked when a directory is clicked by the user on the files list
- *
- * @param directory
- */
- void onDirectoryClick(File directory);
-
- /**
- * Callback method invoked when a file (non directory)
- * is clicked by the user on the files list
- *
- * @param file
- */
- void onFileClick(File file);
-
- /**
- * Callback method invoked when the parent activity
- * is fully created to get the directory to list firstly.
- *
- * @return Directory to list firstly. Can be NULL.
- */
- File getInitialDirectory();
-
- /**
- * config check if the list should behave in folder picker mode only displaying folders but no files.
- *
- * @return true if folder picker mode, else false
- */
- boolean isFolderPickerMode();
-
- boolean isWithinEncryptedFolder();
- }
-
- @SuppressLint("NotifyDataSetChanged")
- public void setupStoragePermissionWarningBanner() {
- mAdapter.notifyDataSetChanged();
- }
-
- @Override
- public void onDestroyView() {
- mAdapter.cleanup();
- super.onDestroyView();
- }
-}
diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/localfilelist/LocalFileListFragment.kt b/app/src/main/java/com/owncloud/android/ui/fragment/localfilelist/LocalFileListFragment.kt
new file mode 100644
index 000000000000..f9f75264a701
--- /dev/null
+++ b/app/src/main/java/com/owncloud/android/ui/fragment/localfilelist/LocalFileListFragment.kt
@@ -0,0 +1,279 @@
+/*
+ * Nextcloud - Android Client
+ *
+ * SPDX-FileCopyrightText: 2026 Alper Ozturk
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+package com.owncloud.android.ui.fragment.localfilelist
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Bundle
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.MenuItem
+import android.view.View
+import android.view.ViewGroup
+import androidx.annotation.VisibleForTesting
+import androidx.core.view.MenuProvider
+import androidx.lifecycle.Lifecycle
+import androidx.recyclerview.widget.GridLayoutManager
+import com.nextcloud.client.di.Injectable
+import com.owncloud.android.R
+import com.owncloud.android.lib.common.utils.Log_OC
+import com.owncloud.android.ui.adapter.localFileList.LocalFileListAdapter
+import com.owncloud.android.ui.fragment.EmptyListState
+import com.owncloud.android.ui.fragment.ExtendedListFragment
+import com.owncloud.android.ui.interfaces.LocalFileListFragmentInterface
+import com.owncloud.android.utils.DisplayUtils
+import com.owncloud.android.utils.FileSortOrder
+import java.io.File
+
+class LocalFileListFragment :
+ ExtendedListFragment(),
+ LocalFileListFragmentInterface,
+ Injectable {
+ var currentDirectory: File? = null
+ private set
+
+ private lateinit var adapter: LocalFileListAdapter
+ private lateinit var listener: LocalFileListListener
+
+ private val menuProvider = object : MenuProvider {
+ override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
+ if (listener.isFolderPickerMode) {
+ menu.removeItem(R.id.action_select_all)
+ menu.removeItem(R.id.action_search)
+ }
+ }
+
+ override fun onMenuItemSelected(menuItem: MenuItem): Boolean = false
+ }
+
+ //region Lifecycle
+ override fun onAttach(context: Context) {
+ super.onAttach(context)
+ listener = context as? LocalFileListListener
+ ?: throw IllegalArgumentException(
+ "$context must implement ${LocalFileListListener::class.java.simpleName}"
+ )
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ Log_OC.i(TAG, "onCreateView() start")
+ val v = super.onCreateView(inflater, container, savedInstanceState)
+
+ if (listener.isFolderPickerMode) {
+ setEmptyListMessage(EmptyListState.LOCAL_FILE_LIST_EMPTY_FOLDER)
+ } else {
+ setEmptyListMessage(EmptyListState.LOCAL_FILE_LIST_EMPTY_FILE)
+ }
+
+ // Disable pull-to-refresh
+ setSwipeEnabled(false)
+
+ Log_OC.i(TAG, "onCreateView() end")
+ return v
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ requireActivity().addMenuProvider(menuProvider, viewLifecycleOwner, Lifecycle.State.RESUMED)
+
+ setupAdapter()
+ listDirectory(listener.initialDirectory)
+ setupSortButton()
+ setupGridViewButton()
+ }
+
+ override fun onDestroyView() {
+ adapter.cleanup()
+ super.onDestroyView()
+ }
+ //endregion
+
+ //region Setup
+ private fun setupAdapter() {
+ adapter = LocalFileListAdapter(
+ listener.isFolderPickerMode,
+ this,
+ preferences,
+ requireActivity(),
+ viewThemeUtils,
+ listener.isWithinEncryptedFolder
+ )
+ setRecyclerViewAdapter(adapter)
+ }
+
+ private fun setupSortButton() {
+ val button = mSortButton ?: return
+
+ button.setOnClickListener {
+ val sortOrder = preferences.getSortOrderByType(FileSortOrder.Type.localFileListView)
+ DisplayUtils.openSortingOrderDialogFragment(parentFragmentManager, sortOrder)
+ }
+
+ val sortOrder = preferences.getSortOrderByType(FileSortOrder.Type.localFileListView) ?: return
+ button.setText(DisplayUtils.getSortOrderStringId(sortOrder))
+ }
+
+ private fun setupGridViewButton() {
+ setLayoutSwitchButton()
+
+ mSwitchGridViewButton?.setOnClickListener {
+ if (isGridEnabled) {
+ switchToListView()
+ } else {
+ switchToGridView()
+ }
+ setLayoutSwitchButton()
+ }
+ }
+ //endregion
+
+ //region Item clicks
+ override fun onItemClicked(file: File?) {
+ val file = file ?: return
+
+ if (file.isDirectory()) {
+ listDirectory(file)
+ listener.onDirectoryClick(file)
+ saveIndexAndTopPosition(adapter.getItemPosition(file))
+ return
+ }
+
+ onItemCheckboxClicked(file)
+ }
+
+ override fun onItemCheckboxClicked(file: File?) {
+ val file = file ?: return
+ adapter.onItemCheckboxClicked(file)
+ listener.onFileClick(file)
+ }
+ //endregion
+
+ //region Directory navigation
+ fun onNavigateUp() {
+ val parentDir = currentDirectory?.getParentFile()
+ listDirectory(parentDir)
+ restoreIndexAndTopPosition()
+ }
+
+ @JvmOverloads
+ fun listDirectory(directory: File? = null) {
+ val target = directory ?: currentDirectory ?: Environment.getExternalStorageDirectory() ?: return
+ val folder = target.asDirectoryOrParent() ?: return
+
+ adapter.removeAllFilesFromCheckedFiles()
+ adapter.swapDirectory(folder)
+ currentDirectory = folder
+
+ recyclerView?.scrollToPosition(0)
+ }
+
+ private fun File.asDirectoryOrParent(): File? {
+ if (isDirectory) {
+ return this
+ }
+
+ Log_OC.w(TAG, "You see, that is not a directory -> $this")
+
+ val parent = parentFile
+ if (parent == null) {
+ Log_OC.w(TAG, "parent directory is null, cannot swap directory")
+ }
+
+ return parent
+ }
+ //endregion
+
+ //region File selection
+ val checkedFilePaths: Array
+ get() = adapter.checkedFilesPath
+
+ val checkedFilesCount: Int
+ get() = adapter.checkedFilesCount()
+
+ val filesCount: Int
+ get() = adapter.filesCount
+
+ fun selectAllFiles(select: Boolean) {
+ if (recyclerView == null) {
+ return
+ }
+
+ val localFileListAdapter = recyclerView?.adapter as? LocalFileListAdapter? ?: return
+
+ if (select) {
+ localFileListAdapter.addAllFilesToCheckedFiles()
+ } else {
+ localFileListAdapter.removeAllFilesFromCheckedFiles()
+ }
+
+ adapter.notifyItemRangeChanged(0, adapter.getItemCount())
+ }
+ //endregion
+
+ //region View options
+ fun sortFiles(sortOrder: FileSortOrder) {
+ mSortButton?.setText(DisplayUtils.getSortOrderStringId(sortOrder))
+ adapter.setSortOrder(sortOrder)
+ }
+
+ override fun switchToGridView() {
+ val recyclerView = recyclerView ?: return
+
+ adapter.gridView = true
+ recyclerView.adapter = adapter
+
+ if (isGridEnabled) {
+ return
+ }
+
+ recyclerView.layoutManager = createGridLayoutManager()
+ }
+
+ private fun createGridLayoutManager(): GridLayoutManager {
+ val layoutManager = GridLayoutManager(context, columnsCount)
+
+ layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
+ override fun getSpanSize(position: Int): Int = when (position) {
+ adapter.itemCount - 1 -> layoutManager.spanCount
+ else -> SINGLE_SPAN
+ }
+ }
+
+ return layoutManager
+ }
+
+ override fun switchToListView() {
+ if (recyclerView == null) {
+ return
+ }
+
+ adapter.gridView = false
+ recyclerView?.setAdapter(adapter)
+ super.switchToListView()
+ }
+ //endregion
+
+ //region Adapter updates
+ @VisibleForTesting
+ fun setFiles(newFiles: List) {
+ adapter.setFiles(newFiles)
+ }
+
+ @SuppressLint("NotifyDataSetChanged")
+ fun setupStoragePermissionWarningBanner() {
+ adapter.notifyDataSetChanged()
+ }
+ //endregion
+
+ companion object {
+ private const val SINGLE_SPAN = 1
+ private val TAG: String = LocalFileListFragment::class.java.getSimpleName()
+ }
+}
diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/localfilelist/LocalFileListListener.kt b/app/src/main/java/com/owncloud/android/ui/fragment/localfilelist/LocalFileListListener.kt
new file mode 100644
index 000000000000..9ce0f0f83b97
--- /dev/null
+++ b/app/src/main/java/com/owncloud/android/ui/fragment/localfilelist/LocalFileListListener.kt
@@ -0,0 +1,18 @@
+/*
+ * Nextcloud - Android Client
+ *
+ * SPDX-FileCopyrightText: 2026 Alper Ozturk
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+package com.owncloud.android.ui.fragment.localfilelist
+
+import java.io.File
+
+interface LocalFileListListener {
+ fun onDirectoryClick(directory: File?)
+ fun onFileClick(file: File?)
+ val initialDirectory: File?
+ val isFolderPickerMode: Boolean
+ val isWithinEncryptedFolder: Boolean
+}
diff --git a/app/src/main/java/com/owncloud/android/ui/interfaces/LocalFileListFragmentInterface.kt b/app/src/main/java/com/owncloud/android/ui/interfaces/LocalFileListFragmentInterface.kt
index fca93caaacc3..32ebfcdf73aa 100644
--- a/app/src/main/java/com/owncloud/android/ui/interfaces/LocalFileListFragmentInterface.kt
+++ b/app/src/main/java/com/owncloud/android/ui/interfaces/LocalFileListFragmentInterface.kt
@@ -12,5 +12,5 @@ interface LocalFileListFragmentInterface {
val columnsCount: Int
fun onItemClicked(file: File?)
fun onItemCheckboxClicked(file: File?)
- fun setLoading(loading: Boolean)
+ fun setLoading(enabled: Boolean)
}
diff --git a/app/src/main/res/layout/upload_files_layout.xml b/app/src/main/res/layout/upload_files_layout.xml
index 4012193eb6a9..38d17a7566a8 100644
--- a/app/src/main/res/layout/upload_files_layout.xml
+++ b/app/src/main/res/layout/upload_files_layout.xml
@@ -20,7 +20,7 @@