From 64c8154ebc92f225c453be7caa691d61c4982955 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Fri, 5 Dec 2025 12:58:40 +0100 Subject: [PATCH 01/23] fix shared tab Signed-off-by: alperozturk --- .../ui/fragment/OCFileListFragment.java | 53 ++++++------------- .../android/ui/fragment/SearchType.kt | 16 +++++- 2 files changed, 31 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 25a1d1a0b192..fc27a1244f20 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -135,8 +135,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.OptIn; -import androidx.annotation.StringRes; -import androidx.appcompat.app.ActionBar; import androidx.core.content.ContextCompat; import androidx.drawerlayout.widget.DrawerLayout; import androidx.fragment.app.FragmentActivity; @@ -1765,28 +1763,17 @@ public OCFileListAdapter getAdapter() { } protected void setTitle() { - // set title + if (!(getActivity() instanceof FileDisplayActivity fda) || currentSearchType == null) { + return; + } - if (getActivity() instanceof FileDisplayActivity && currentSearchType != null) { - switch (currentSearchType) { - case FAVORITE_SEARCH: - setTitle(R.string.drawer_item_favorites); - break; - case GALLERY_SEARCH: - setTitle(R.string.drawer_item_gallery); - break; - case RECENTLY_MODIFIED_SEARCH: - setTitle(R.string.drawer_item_recently_modified); - break; - case SHARED_FILTER: - setTitle(R.string.drawer_item_shared); - break; - default: - setTitle(themeUtils.getDefaultDisplayNameForRootFolder(getContext()), false); - break; - } + Integer titleId = currentSearchType.titleId(); + String title = themeUtils.getDefaultDisplayNameForRootFolder(fda); + if (titleId != null) { + title = fda.getString(titleId); } + setTitle(title, currentSearchType.isMenu()); } protected void prepareActionBarItems(SearchEvent event) { @@ -2117,15 +2104,6 @@ public void onMessageEvent(FileLockEvent event) { } } - /** - * Theme default action bar according to provided parameters. Replaces back arrow with hamburger menu icon. - * - * @param title string res id of title to be shown in action bar - */ - protected void setTitle(@StringRes final int title) { - setTitle(requireContext().getString(title), true); - } - /** * Theme default action bar according to provided parameters. * @@ -2133,14 +2111,15 @@ protected void setTitle(@StringRes final int title) { * @param showBackAsMenu iff true replace back arrow with hamburger menu icon */ protected void setTitle(final String title, Boolean showBackAsMenu) { - requireActivity().runOnUiThread(() -> { - if (getActivity() != null) { - final ActionBar actionBar = ((FileDisplayActivity) getActivity()).getSupportActionBar(); - final Context context = getContext(); + if (!(getActivity() instanceof FileDisplayActivity fda)) { + return; + } - if (actionBar != null && context != null) { - viewThemeUtils.files.themeActionBar(context, actionBar, title, showBackAsMenu); - } + fda.runOnUiThread(new Runnable() { + @Override + public void run() { + final var actionBar = fda.getSupportActionBar(); + viewThemeUtils.files.themeActionBar(fda, actionBar, title, showBackAsMenu); } }); } diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt b/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt index 4e27e0222e17..dd6355ca13cf 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt @@ -1,6 +1,7 @@ /* * Nextcloud - Android Client * + * SPDX-FileCopyrightText: 2025 Alper Ozturk * SPDX-FileCopyrightText: 2023 Tobias Kaminsky * SPDX-FileCopyrightText: 2022 Unpublished * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only @@ -8,6 +9,7 @@ package com.owncloud.android.ui.fragment import android.os.Parcelable +import com.owncloud.android.R import kotlinx.parcelize.Parcelize @Parcelize @@ -22,7 +24,19 @@ enum class SearchType : Parcelable { // not a real filter, but nevertheless SHARED_FILTER, - GROUPFOLDER + GROUPFOLDER; + + fun isMenu(): Boolean { + return this in listOf(FAVORITE_SEARCH, GALLERY_SEARCH, RECENTLY_MODIFIED_SEARCH, SHARED_FILTER) + } + + fun titleId(): Int? = when (this) { + FAVORITE_SEARCH -> R.string.drawer_item_favorites + GALLERY_SEARCH -> R.string.drawer_item_gallery + RECENTLY_MODIFIED_SEARCH -> R.string.drawer_item_recently_modified + SHARED_FILTER -> R.string.drawer_item_shared + else -> null + } } @Parcelize From b2b96d4050cb1d18add8100fc2cd717b5754d320 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 10:13:58 +0100 Subject: [PATCH 02/23] fix: shared tab action bar Signed-off-by: alperozturk --- .../ui/fragment/OCFileListFragment.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index fc27a1244f20..beb2c73dae21 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -124,6 +124,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; @@ -185,9 +186,7 @@ public class OCFileListFragment extends ExtendedListFragment implements public static final String FOLDER_LAYOUT_GRID = "GRID"; public static final String SEARCH_EVENT = "SEARCH_EVENT"; - private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE"; - protected static final String KEY_CURRENT_SEARCH_TYPE = "CURRENT_SEARCH_TYPE"; private static final String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER"; @@ -317,21 +316,28 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Log_OC.i(TAG, "onCreateView() start"); View v = super.onCreateView(inflater, container, savedInstanceState); + final Bundle state = savedInstanceState != null ? savedInstanceState : getArguments(); + SearchType argSearchType = null; + SearchEvent argSearchEvent = null; + + if (state != null) { + argSearchType = BundleExtensionsKt.getParcelableArgument(state, KEY_CURRENT_SEARCH_TYPE, SearchType.class); + argSearchEvent = BundleExtensionsKt.getParcelableArgument(state, SEARCH_EVENT, SearchEvent.class); + } + + currentSearchType = Objects.requireNonNullElse(argSearchType, NO_SEARCH); - if (savedInstanceState != null && - BundleExtensionsKt.getParcelableArgument(savedInstanceState, KEY_CURRENT_SEARCH_TYPE, SearchType.class) != null && - BundleExtensionsKt.getParcelableArgument(savedInstanceState, SEARCH_EVENT, SearchEvent.class) != null) { + if (argSearchEvent != null) { + searchEvent = argSearchEvent; + } + + if (searchEvent != null && currentSearchType != NO_SEARCH) { searchFragment = true; - currentSearchType = BundleExtensionsKt.getParcelableArgument(savedInstanceState, KEY_CURRENT_SEARCH_TYPE, SearchType.class); - searchEvent = BundleExtensionsKt.getParcelableArgument(savedInstanceState, SEARCH_EVENT, SearchEvent.class); - } else { - currentSearchType = NO_SEARCH; } - Bundle args = getArguments(); - boolean allowContextualActions = args != null && args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, false); + boolean allowContextualActions = (state != null && state.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, false)); if (allowContextualActions) { - setChoiceModeAsMultipleModal(savedInstanceState); + setChoiceModeAsMultipleModal(state); } mFabMain = requireActivity().findViewById(R.id.fab_main); From 9585982878e31e0ba808241871aa8f86fbbde4b9 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 12:05:25 +0100 Subject: [PATCH 03/23] rely on existing architecture Signed-off-by: alperozturk --- .../java/com/nextcloud/model/ToolbarItem.kt | 38 --------- .../android/ui/activity/DrawerActivity.java | 15 +++- .../ui/activity/FileDisplayActivity.kt | 27 ++----- .../owncloud/android/ui/events/SearchEvent.kt | 11 ++- .../ui/fragment/OCFileListFragment.java | 77 ++++++++----------- 5 files changed, 60 insertions(+), 108 deletions(-) delete mode 100644 app/src/main/java/com/nextcloud/model/ToolbarItem.kt diff --git a/app/src/main/java/com/nextcloud/model/ToolbarItem.kt b/app/src/main/java/com/nextcloud/model/ToolbarItem.kt deleted file mode 100644 index 8995acc1428b..000000000000 --- a/app/src/main/java/com/nextcloud/model/ToolbarItem.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Nextcloud - Android Client - * - * SPDX-FileCopyrightText: 2025 Alper Ozturk - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -package com.nextcloud.model - -import android.view.Menu -import com.owncloud.android.R - -enum class ToolbarItem(val navId: Int, val titleId: Int, val style: ToolbarStyle) { - NONE(Menu.NONE, R.string.drawer_item_all_files, ToolbarStyle.SEARCH), - ALL_FILES(R.id.nav_all_files, R.string.drawer_item_all_files, ToolbarStyle.SEARCH), - PERSONAL_FILES(R.id.nav_personal_files, R.string.drawer_item_personal_files, ToolbarStyle.SEARCH), - ACTIVITIES(R.id.nav_activity, R.string.drawer_item_activities, ToolbarStyle.PLAIN), - FAVORITES(R.id.nav_favorites, R.string.drawer_item_favorites, ToolbarStyle.PLAIN), - GALLERY(R.id.nav_gallery, R.string.drawer_item_gallery, ToolbarStyle.PLAIN), - SHARED(R.id.nav_shared, R.string.drawer_item_shared, ToolbarStyle.PLAIN), - GROUP_FOLDERS(R.id.nav_groupfolders, R.string.drawer_item_groupfolders, ToolbarStyle.PLAIN), - ON_DEVICE(R.id.nav_on_device, R.string.drawer_item_on_device, ToolbarStyle.PLAIN), - RECENTLY_MODIFIED(R.id.nav_recently_modified, R.string.drawer_item_recently_modified, ToolbarStyle.PLAIN), - ASSISTANT(R.id.nav_assistant, R.string.drawer_item_assistant, ToolbarStyle.PLAIN), - UPLOADS(R.id.nav_uploads, R.string.drawer_item_uploads_list, ToolbarStyle.PLAIN), - SETTINGS(R.id.nav_settings, R.string.actionbar_settings, ToolbarStyle.PLAIN), - COMMUNITY(R.id.nav_community, R.string.drawer_community, ToolbarStyle.PLAIN), - TRASHBIN(R.id.nav_trashbin, R.string.drawer_item_trashbin, ToolbarStyle.PLAIN); - - companion object { - fun fromNavId(navId: Int): ToolbarItem? = entries.find { it.navId == navId } - } -} - -enum class ToolbarStyle { - PLAIN, - SEARCH -} diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index e5ca8a79c66e..ddcea4c042b4 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -278,6 +278,7 @@ private void handleBottomNavigationViewClicks() { } EventBus.getDefault().post(new ChangeMenuEvent()); } else if (menuItemId == R.id.nav_favorites) { + resetOnlyPersonalAndOnDevice(); setupToolbar(); handleSearchEvents(new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH), menuItemId); } else if (menuItemId == R.id.nav_assistant && !(this instanceof ComposeActivity)) { @@ -645,6 +646,16 @@ private void onNavigationItemClicked(final MenuItem menuItem) { Log_OC.w(TAG, "Unknown drawer menu item clicked: " + menuItem.getTitle()); } } + + // from navigation user always sees root level + final var ocFileListFragment = getOCFileListFragment(); + if (ocFileListFragment != null) { + ocFileListFragment.resetFileDepth(); + } + + if (this instanceof FileDisplayActivity fda) { + fda.configureMenuItem(); + } } private void startComposeActivity(ComposeDestination destination, int titleId) { @@ -685,10 +696,6 @@ public void openAddAccount() { } protected void openSharedTab() { - final var ocFileListFragment = getOCFileListFragment(); - if (ocFileListFragment != null) { - ocFileListFragment.resetFileDepth(); - } resetOnlyPersonalAndOnDevice(); SearchEvent searchEvent = new SearchEvent("", SearchRemoteOperation.SearchType.SHARED_FILTER); launchActivityForSearch(searchEvent, R.id.nav_shared); diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 30b20ac632da..178fb505784b 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -71,13 +71,11 @@ import com.nextcloud.client.media.PlayerServiceConnection import com.nextcloud.client.network.ClientFactory.CreationException import com.nextcloud.client.preferences.AppPreferences import com.nextcloud.client.utils.IntentUtil -import com.nextcloud.model.ToolbarItem -import com.nextcloud.model.ToolbarStyle import com.nextcloud.model.WorkerState import com.nextcloud.model.WorkerState.FileDownloadCompleted import com.nextcloud.model.WorkerState.FileDownloadStarted -import com.nextcloud.model.WorkerState.OfflineOperationsCompleted import com.nextcloud.model.WorkerState.FileUploadCompleted +import com.nextcloud.model.WorkerState.OfflineOperationsCompleted import com.nextcloud.utils.extensions.getParcelableArgument import com.nextcloud.utils.extensions.isActive import com.nextcloud.utils.extensions.lastFragment @@ -1236,7 +1234,7 @@ class FileDisplayActivity : } resetTitleBarAndScrolling() - configureToolbar() + configureMenuItem() startMetadataSyncForCurrentDir() } @@ -1358,7 +1356,7 @@ class FileDisplayActivity : localBroadcastManager.registerReceiver(it, downloadIntentFilter) } - configureToolbar() + configureMenuItem() // show in-app review dialog to user inAppReviewHelper.showInAppReview(this) @@ -1387,23 +1385,9 @@ class FileDisplayActivity : } } - private fun configureToolbar() { + fun configureMenuItem() { checkAndSetMenuItemId() setNavigationViewItemChecked() - val item = ToolbarItem.fromNavId(menuItemId) - when (item?.style) { - ToolbarStyle.SEARCH -> setupHomeSearchToolbarWithSortAndListButtons() - ToolbarStyle.PLAIN -> { - if (currentDir?.isRootDirectory == true) { - updateActionBarTitleAndHomeButtonByString(getString(item.titleId)) - } else { - setupToolbar() - } - } - else -> { - setupToolbar() - } - } } fun initSyncBroadcastReceiver() { @@ -2749,6 +2733,9 @@ class FileDisplayActivity : Log_OC.d(this, "Switch to Shared fragment") this.leftFragment = SharedListFragment() } + + listOfFilesFragment?.setCurrentSearchType(event) + listOfFilesFragment?.setTitle() } @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/app/src/main/java/com/owncloud/android/ui/events/SearchEvent.kt b/app/src/main/java/com/owncloud/android/ui/events/SearchEvent.kt index e6e95f7b8f11..7fd6aab7cdab 100644 --- a/app/src/main/java/com/owncloud/android/ui/events/SearchEvent.kt +++ b/app/src/main/java/com/owncloud/android/ui/events/SearchEvent.kt @@ -9,6 +9,7 @@ package com.owncloud.android.ui.events import android.os.Parcelable import com.owncloud.android.lib.resources.files.SearchRemoteOperation +import com.owncloud.android.ui.fragment.SearchType import kotlinx.parcelize.Parcelize /** @@ -16,4 +17,12 @@ import kotlinx.parcelize.Parcelize */ @Parcelize -data class SearchEvent(val searchQuery: String, val searchType: SearchRemoteOperation.SearchType) : Parcelable +data class SearchEvent(val searchQuery: String, val searchType: SearchRemoteOperation.SearchType) : Parcelable { + fun toSearchType(): SearchType? = when (searchType) { + SearchRemoteOperation.SearchType.FILE_SEARCH -> SearchType.FILE_SEARCH + SearchRemoteOperation.SearchType.FAVORITE_SEARCH -> SearchType.FAVORITE_SEARCH + SearchRemoteOperation.SearchType.RECENTLY_MODIFIED_SEARCH -> SearchType.RECENTLY_MODIFIED_SEARCH + SearchRemoteOperation.SearchType.SHARED_FILTER -> SearchType.SHARED_FILTER + else -> null + } +} diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index beb2c73dae21..0b20224b69d7 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -248,12 +248,9 @@ public void onCreate(Bundle savedInstanceState) { setHasOptionsMenu(true); mMultiChoiceModeListener = new MultiChoiceModeListener(); - if (savedInstanceState != null) { - currentSearchType = BundleExtensionsKt.getParcelableArgument(savedInstanceState, KEY_CURRENT_SEARCH_TYPE, SearchType.class); - searchEvent = BundleExtensionsKt.getParcelableArgument(savedInstanceState, SEARCH_EVENT, SearchEvent.class); - mFile = BundleExtensionsKt.getParcelableArgument(savedInstanceState, KEY_FILE, OCFile.class); - } - + final Bundle state = savedInstanceState != null ? savedInstanceState : getArguments(); + setSearchArgs(state); + mFile = BundleExtensionsKt.getParcelableArgument(state, KEY_FILE, OCFile.class); searchFragment = currentSearchType != null && isSearchEventSet(searchEvent); } @@ -308,15 +305,7 @@ public void onAttach(@NonNull Context context) { } } - /** - * {@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); - - final Bundle state = savedInstanceState != null ? savedInstanceState : getArguments(); + private void setSearchArgs(Bundle state) { SearchType argSearchType = null; SearchEvent argSearchEvent = null; @@ -334,6 +323,18 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, if (searchEvent != null && currentSearchType != NO_SEARCH) { searchFragment = true; } + } + + /** + * {@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); + + final Bundle state = savedInstanceState != null ? savedInstanceState : getArguments(); + setSearchArgs(state); boolean allowContextualActions = (state != null && state.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, false)); if (allowContextualActions) { @@ -467,29 +468,7 @@ protected void setAdapter(Bundle args) { protected void prepareCurrentSearch(SearchEvent event) { if (isSearchEventSet(event)) { - - switch (event.getSearchType()) { - case FILE_SEARCH: - currentSearchType = FILE_SEARCH; - break; - - case FAVORITE_SEARCH: - currentSearchType = FAVORITE_SEARCH; - break; - - case RECENTLY_MODIFIED_SEARCH: - currentSearchType = RECENTLY_MODIFIED_SEARCH; - break; - - case SHARED_FILTER: - currentSearchType = SHARED_FILTER; - break; - - default: - // do nothing - break; - } - + setCurrentSearchType(event); prepareActionBarItems(event); } } @@ -1768,7 +1747,7 @@ public OCFileListAdapter getAdapter() { return mAdapter; } - protected void setTitle() { + public void setTitle() { if (!(getActivity() instanceof FileDisplayActivity fda) || currentSearchType == null) { return; } @@ -1782,6 +1761,13 @@ protected void setTitle() { setTitle(title, currentSearchType.isMenu()); } + public void setCurrentSearchType(SearchEvent event) { + final var searchType = event.toSearchType(); + if (searchType != null) { + currentSearchType = searchType; + } + } + protected void prepareActionBarItems(SearchEvent event) { if (event != null) { switch (event.getSearchType()) { @@ -2121,12 +2107,13 @@ protected void setTitle(final String title, Boolean showBackAsMenu) { return; } - fda.runOnUiThread(new Runnable() { - @Override - public void run() { - final var actionBar = fda.getSupportActionBar(); - viewThemeUtils.files.themeActionBar(fda, actionBar, title, showBackAsMenu); - } + final var actionBar = fda.getSupportActionBar(); + if (actionBar == null) { + return; + } + + fda.runOnUiThread(() -> { + viewThemeUtils.files.themeActionBar(fda, actionBar, title, showBackAsMenu); }); } From be14cf0775e643bddef31b0bb17b22142cee617b Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 12:08:13 +0100 Subject: [PATCH 04/23] fix crash Signed-off-by: alperozturk --- .../ui/activity/FileDisplayActivity.kt | 2 +- .../ui/fragment/OCFileListFragment.java | 22 ++++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 178fb505784b..81ec42da9254 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -2735,7 +2735,7 @@ class FileDisplayActivity : } listOfFilesFragment?.setCurrentSearchType(event) - listOfFilesFragment?.setTitle() + listOfFilesFragment?.setActionBarTitle() } @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 0b20224b69d7..e4e37533319a 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -290,7 +290,7 @@ public void onAttach(@NonNull Context context) { Log_OC.i(TAG, "onAttach"); try { mContainerActivity = (FileFragment.ContainerActivity) context; - setTitle(); + setActionBarTitle(); } catch (ClassCastException e) { throw new IllegalArgumentException(context.toString() + " must implement " + @@ -435,7 +435,7 @@ public void onActivityCreated(Bundle savedInstanceState) { }); } - setTitle(); + setActionBarTitle(); FragmentActivity fragmentActivity; if ((fragmentActivity = getActivity()) != null && fragmentActivity instanceof FileDisplayActivity fileDisplayActivity) { @@ -1516,8 +1516,14 @@ public void listDirectory(boolean onlyOnDevice, boolean fromSearch) { public void refreshDirectory() { searchFragment = false; - setFabVisible(mFile.canCreateFileAndFolder()); - listDirectory(getCurrentFile(), MainApp.isOnlyOnDevice(), false); + if (mFile != null) { + setFabVisible(mFile.canCreateFileAndFolder()); + } + + final var currentFile = getCurrentFile(); + if (currentFile != null) { + listDirectory(currentFile, MainApp.isOnlyOnDevice(), false); + } } public void listDirectory(OCFile directory, boolean onlyOnDevice, boolean fromSearch) { @@ -1747,7 +1753,7 @@ public OCFileListAdapter getAdapter() { return mAdapter; } - public void setTitle() { + public void setActionBarTitle() { if (!(getActivity() instanceof FileDisplayActivity fda) || currentSearchType == null) { return; } @@ -1758,7 +1764,7 @@ public void setTitle() { title = fda.getString(titleId); } - setTitle(title, currentSearchType.isMenu()); + setActionBarTitle(title, currentSearchType.isMenu()); } public void setCurrentSearchType(SearchEvent event) { @@ -1828,7 +1834,7 @@ public void onMessageEvent(ChangeMenuEvent changeMenuEvent) { ((FileDisplayActivity) activity).initSyncBroadcastReceiver(); } - setTitle(themeUtils.getDefaultDisplayNameForRootFolder(getContext()), false); + setActionBarTitle(themeUtils.getDefaultDisplayNameForRootFolder(getContext()), false); activity.getIntent().removeExtra(OCFileListFragment.SEARCH_EVENT); } @@ -2102,7 +2108,7 @@ public void onMessageEvent(FileLockEvent event) { * @param title title to be shown in action bar * @param showBackAsMenu iff true replace back arrow with hamburger menu icon */ - protected void setTitle(final String title, Boolean showBackAsMenu) { + protected void setActionBarTitle(final String title, Boolean showBackAsMenu) { if (!(getActivity() instanceof FileDisplayActivity fda)) { return; } From bd5d56909534e8adcc1f420f95c5906f1034b1fd Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 12:38:14 +0100 Subject: [PATCH 05/23] override updateActionBarTitleAndHomeButton with search type Signed-off-by: alperozturk --- .../android/ui/activity/DrawerActivity.java | 9 +++- .../android/ui/activity/ToolbarActivity.java | 29 +++++++--- .../ui/fragment/OCFileListFragment.java | 54 ++++++++----------- .../android/ui/fragment/SearchType.kt | 4 -- 4 files changed, 51 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index ddcea4c042b4..7367d907ad78 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -93,6 +93,7 @@ import com.owncloud.android.ui.fragment.GalleryFragment; import com.owncloud.android.ui.fragment.GroupfolderListFragment; import com.owncloud.android.ui.fragment.OCFileListFragment; +import com.owncloud.android.ui.fragment.SearchType; import com.owncloud.android.ui.fragment.SharedListFragment; import com.owncloud.android.ui.preview.PreviewTextStringFragment; import com.owncloud.android.ui.trashbin.TrashbinActivity; @@ -831,7 +832,13 @@ public void setDrawerIndicatorEnabled(boolean enable) { * Updates title bar and home buttons (state and icon). Assumes that navigation drawer is NOT visible. */ protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { - super.updateActionBarTitleAndHomeButton(chosenFile); + final var ocFileListFragment = getOCFileListFragment(); + SearchType searchType = SearchType.NO_SEARCH; + if (ocFileListFragment != null) { + searchType = ocFileListFragment.getCurrentSearchType(); + } + + updateActionBarTitleAndHomeButton(chosenFile, searchType); // set home button properties if (mDrawerToggle != null) { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java index f4945899e9ea..8e68a75d47fc 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java @@ -36,6 +36,7 @@ import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.ui.fragment.SearchType; import com.owncloud.android.utils.theme.ThemeColorUtils; import com.owncloud.android.utils.theme.ThemeUtils; import com.owncloud.android.utils.theme.ViewThemeUtils; @@ -153,21 +154,33 @@ public void setupHomeSearchToolbarWithSortAndListButtons() { setupToolbar(true, true); } - /** - * Updates title bar and home buttons (state and icon). - */ - protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { + public void updateActionBarTitleAndHomeButton(OCFile chosenFile, SearchType searchType) { boolean isRoot = isRoot(chosenFile); - String title = getActionBarTitle(chosenFile, isRoot); + String title = getActionBarTitle(chosenFile, searchType); updateActionBarTitleAndHomeButtonByString(title); if (mAppBar != null) { showHomeSearchToolbar(title, isRoot); } } - private String getActionBarTitle(OCFile chosenFile, boolean isRoot) { - if (isRoot) { - return themeUtils.getDefaultDisplayNameForRootFolder(this); + protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { + updateActionBarTitleAndHomeButton(chosenFile, SearchType.NO_SEARCH); + } + + public String getActionBarRootTitle(@NonNull SearchType searchType) { + Integer rootTitleId = searchType.titleId(); + String result = themeUtils.getDefaultDisplayNameForRootFolder(this); + + if (rootTitleId != null) { + result = getString(rootTitleId); + } + + return result; + } + + public String getActionBarTitle(OCFile chosenFile, @NonNull SearchType searchType) { + if (isRoot(chosenFile)) { + return getActionBarRootTitle(searchType); } if (chosenFile.isFolder()) { diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index e4e37533319a..46ded3e80823 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -291,7 +291,6 @@ public void onAttach(@NonNull Context context) { try { mContainerActivity = (FileFragment.ContainerActivity) context; setActionBarTitle(); - } catch (ClassCastException e) { throw new IllegalArgumentException(context.toString() + " must implement " + FileFragment.ContainerActivity.class.getSimpleName(), e); @@ -437,9 +436,8 @@ public void onActivityCreated(Bundle savedInstanceState) { setActionBarTitle(); - FragmentActivity fragmentActivity; - if ((fragmentActivity = getActivity()) != null && fragmentActivity instanceof FileDisplayActivity fileDisplayActivity) { - fileDisplayActivity.updateActionBarTitleAndHomeButton(fileDisplayActivity.getCurrentDir()); + if (getActivity() instanceof FileDisplayActivity fileDisplayActivity) { + fileDisplayActivity.updateActionBarTitleAndHomeButton(fileDisplayActivity.getCurrentDir(), currentSearchType); } listDirectory(MainApp.isOnlyOnDevice(), false); } @@ -1064,6 +1062,7 @@ public int onBrowseUp() { Pair result = futureResult.get(); mFile = result.second; setFileDepth(mFile); + setActionBarTitle(); updateFileList(); return result.first; } catch (Exception e) { @@ -1289,7 +1288,11 @@ public OCFileDepth getFileDepth() { private void browseToFolder(OCFile file, int position) { setFileDepth(file); - resetSearchIfBrowsingFromFavorites(); + + if (currentSearchType == FAVORITE_SEARCH) { + resetMenuItems(); + } + listDirectory(file, MainApp.isOnlyOnDevice(), false); // then, notify parent activity to let it update its state and view mContainerActivity.onBrowsedDownTo(file); @@ -1297,13 +1300,6 @@ private void browseToFolder(OCFile file, int position) { saveIndexAndTopPosition(position); } - private void resetSearchIfBrowsingFromFavorites() { - if (currentSearchType == FAVORITE_SEARCH) { - resetSearchAttributes(); - resetMenuItems(); - } - } - @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == SETUP_ENCRYPTION_REQUEST_CODE && @@ -1753,20 +1749,6 @@ public OCFileListAdapter getAdapter() { return mAdapter; } - public void setActionBarTitle() { - if (!(getActivity() instanceof FileDisplayActivity fda) || currentSearchType == null) { - return; - } - - Integer titleId = currentSearchType.titleId(); - String title = themeUtils.getDefaultDisplayNameForRootFolder(fda); - if (titleId != null) { - title = fda.getString(titleId); - } - - setActionBarTitle(title, currentSearchType.isMenu()); - } - public void setCurrentSearchType(SearchEvent event) { final var searchType = event.toSearchType(); if (searchType != null) { @@ -1774,6 +1756,10 @@ public void setCurrentSearchType(SearchEvent event) { } } + public SearchType getCurrentSearchType() { + return currentSearchType; + } + protected void prepareActionBarItems(SearchEvent event) { if (event != null) { switch (event.getSearchType()) { @@ -2102,12 +2088,16 @@ public void onMessageEvent(FileLockEvent event) { } } - /** - * Theme default action bar according to provided parameters. - * - * @param title title to be shown in action bar - * @param showBackAsMenu iff true replace back arrow with hamburger menu icon - */ + public void setActionBarTitle() { + if (!(getActivity() instanceof FileDisplayActivity fda) || currentSearchType == null) { + return; + } + + String title = fda.getActionBarTitle(mFile, currentSearchType); + boolean isRoot = (getFileDepth() == OCFileDepth.Root) || fda.isRoot(mFile); + setActionBarTitle(title, isRoot); + } + protected void setActionBarTitle(final String title, Boolean showBackAsMenu) { if (!(getActivity() instanceof FileDisplayActivity fda)) { return; diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt b/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt index dd6355ca13cf..7827e6d053f9 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt @@ -26,10 +26,6 @@ enum class SearchType : Parcelable { SHARED_FILTER, GROUPFOLDER; - fun isMenu(): Boolean { - return this in listOf(FAVORITE_SEARCH, GALLERY_SEARCH, RECENTLY_MODIFIED_SEARCH, SHARED_FILTER) - } - fun titleId(): Int? = when (this) { FAVORITE_SEARCH -> R.string.drawer_item_favorites GALLERY_SEARCH -> R.string.drawer_item_gallery From d1166c14560aa61385d0d4c62d5567765f59f446 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 14:04:13 +0100 Subject: [PATCH 06/23] remove duplicated calls Signed-off-by: alperozturk --- .../ui/activity/FileDisplayActivity.kt | 23 ++++---- .../android/ui/activity/ToolbarActivity.java | 8 +-- .../ui/fragment/OCFileListFragment.java | 53 +++---------------- 3 files changed, 25 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 81ec42da9254..c5bade95e86f 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -533,7 +533,7 @@ class FileDisplayActivity : } /** reset views */ - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar() } // region Handle Intents @@ -632,6 +632,8 @@ class FileDisplayActivity : } } } + + listOfFilesFragment?.setCurrentSearchType(searchEvent) } // endregion @@ -789,8 +791,8 @@ class FileDisplayActivity : return null } - protected fun resetTitleBarAndScrolling() { - updateActionBarTitleAndHomeButton(null) + protected fun resetScrollingAndUpdateActionBar(searchType: SearchType = SearchType.NO_SEARCH) { + updateActionBarTitleAndHomeButton(file, searchType) resetScrolling(true) } @@ -1233,7 +1235,7 @@ class FileDisplayActivity : listOfFiles.registerFabListener() } - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar(listOfFilesFragment?.currentSearchType ?: SearchType.NO_SEARCH) configureMenuItem() startMetadataSyncForCurrentDir() } @@ -1519,7 +1521,7 @@ class FileDisplayActivity : private fun handleRemovedFileFromServer(currentFile: OCFile?, currentDir: OCFile?): OCFile? { if (currentFile == null && file?.isFolder == false) { - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar() return currentDir } @@ -1797,12 +1799,12 @@ class FileDisplayActivity : startSyncFolderOperation(root, false) } binding.fabMain.setImageResource(R.drawable.ic_plus) - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar(listOfFilesFragment?.currentSearchType ?: SearchType.NO_SEARCH) } override fun onBrowsedDownTo(directory: OCFile?) { file = directory - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar() startSyncFolderOperation(directory, false) startMetadataSyncForCurrentDir() } @@ -2099,7 +2101,7 @@ class FileDisplayActivity : val fileAvailable = storageManager.fileExists(removedFile.fileId) if (leftFragment is FileFragment && !fileAvailable && removedFile == leftFragment.file) { file = storageManager.getFileById(removedFile.parentId) - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar() } val parentFile = storageManager.getFileById(removedFile.parentId) if (parentFile != null && parentFile == getCurrentDir()) { @@ -2305,7 +2307,7 @@ class FileDisplayActivity : leftFragment.updateFileDetails(file, currentUser) } else { if (!file.fileExists()) { - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar() } else { leftFragment.updateFileDetails(false, true) } @@ -2735,7 +2737,8 @@ class FileDisplayActivity : } listOfFilesFragment?.setCurrentSearchType(event) - listOfFilesFragment?.setActionBarTitle() + updateActionBarTitleAndHomeButton(null) + //listOfFilesFragment?.setActionBarTitle() } @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java index 8e68a75d47fc..8ef0e75a5711 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java @@ -155,12 +155,14 @@ public void setupHomeSearchToolbarWithSortAndListButtons() { } public void updateActionBarTitleAndHomeButton(OCFile chosenFile, SearchType searchType) { + if (mAppBar == null) { + return; + } + boolean isRoot = isRoot(chosenFile); String title = getActionBarTitle(chosenFile, searchType); updateActionBarTitleAndHomeButtonByString(title); - if (mAppBar != null) { - showHomeSearchToolbar(title, isRoot); - } + showHomeSearchToolbar(title, isRoot); } protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 46ded3e80823..465f4a097ffe 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -290,7 +290,6 @@ public void onAttach(@NonNull Context context) { Log_OC.i(TAG, "onAttach"); try { mContainerActivity = (FileFragment.ContainerActivity) context; - setActionBarTitle(); } catch (ClassCastException e) { throw new IllegalArgumentException(context.toString() + " must implement " + FileFragment.ContainerActivity.class.getSimpleName(), e); @@ -434,10 +433,8 @@ public void onActivityCreated(Bundle savedInstanceState) { }); } - setActionBarTitle(); - - if (getActivity() instanceof FileDisplayActivity fileDisplayActivity) { - fileDisplayActivity.updateActionBarTitleAndHomeButton(fileDisplayActivity.getCurrentDir(), currentSearchType); + if (getActivity() instanceof FileDisplayActivity fda) { + fda.updateActionBarTitleAndHomeButton(fda.getCurrentDir(), currentSearchType); } listDirectory(MainApp.isOnlyOnDevice(), false); } @@ -1062,7 +1059,6 @@ public int onBrowseUp() { Pair result = futureResult.get(); mFile = result.second; setFileDepth(mFile); - setActionBarTitle(); updateFileList(); return result.first; } catch (Exception e) { @@ -1810,28 +1806,18 @@ protected void setEmptyView(SearchEvent event) { @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(ChangeMenuEvent changeMenuEvent) { resetSearchAttributes(); - resetMenuItems(); - Activity activity = getActivity(); - if (activity != null) { - activity.invalidateOptionsMenu(); - - if (activity instanceof FileDisplayActivity) { - ((FileDisplayActivity) activity).initSyncBroadcastReceiver(); - } - - setActionBarTitle(themeUtils.getDefaultDisplayNameForRootFolder(getContext()), false); - activity.getIntent().removeExtra(OCFileListFragment.SEARCH_EVENT); - } - Bundle arguments = getArguments(); - if (arguments != null) { - arguments.putParcelable(OCFileListFragment.SEARCH_EVENT, null); + if (getActivity() instanceof FileDisplayActivity fda) { + fda.invalidateOptionsMenu(); + fda.getIntent().removeExtra(OCFileListFragment.SEARCH_EVENT); + fda.updateActionBarTitleAndHomeButton(null, NO_SEARCH); } if (mFile != null) { setFabVisible(mFile.canCreateFileAndFolder()); } + slideHideBottomBehaviourForBottomNavigationView(true); } @@ -2088,31 +2074,6 @@ public void onMessageEvent(FileLockEvent event) { } } - public void setActionBarTitle() { - if (!(getActivity() instanceof FileDisplayActivity fda) || currentSearchType == null) { - return; - } - - String title = fda.getActionBarTitle(mFile, currentSearchType); - boolean isRoot = (getFileDepth() == OCFileDepth.Root) || fda.isRoot(mFile); - setActionBarTitle(title, isRoot); - } - - protected void setActionBarTitle(final String title, Boolean showBackAsMenu) { - if (!(getActivity() instanceof FileDisplayActivity fda)) { - return; - } - - final var actionBar = fda.getSupportActionBar(); - if (actionBar == null) { - return; - } - - fda.runOnUiThread(() -> { - viewThemeUtils.files.themeActionBar(fda, actionBar, title, showBackAsMenu); - }); - } - @Override public void onStart() { super.onStart(); From e1eecf874b7d8f2e5b08ebd09fe5f06f5009a284 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 14:27:42 +0100 Subject: [PATCH 07/23] while setting toolbar check toolbar style as well Signed-off-by: alperozturk --- .../android/ui/activity/DrawerActivity.java | 15 ++--- .../ui/activity/FileDisplayActivity.kt | 8 +-- .../android/ui/activity/ToolbarActivity.java | 67 ++++++++++++++----- .../ui/fragment/OCFileListFragment.java | 4 +- 4 files changed, 63 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index 7367d907ad78..b35c10ea086f 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -93,7 +93,6 @@ import com.owncloud.android.ui.fragment.GalleryFragment; import com.owncloud.android.ui.fragment.GroupfolderListFragment; import com.owncloud.android.ui.fragment.OCFileListFragment; -import com.owncloud.android.ui.fragment.SearchType; import com.owncloud.android.ui.fragment.SharedListFragment; import com.owncloud.android.ui.preview.PreviewTextStringFragment; import com.owncloud.android.ui.trashbin.TrashbinActivity; @@ -832,13 +831,7 @@ public void setDrawerIndicatorEnabled(boolean enable) { * Updates title bar and home buttons (state and icon). Assumes that navigation drawer is NOT visible. */ protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { - final var ocFileListFragment = getOCFileListFragment(); - SearchType searchType = SearchType.NO_SEARCH; - if (ocFileListFragment != null) { - searchType = ocFileListFragment.getCurrentSearchType(); - } - - updateActionBarTitleAndHomeButton(chosenFile, searchType); + super.updateActionBarTitleAndHomeButton(chosenFile); // set home button properties if (mDrawerToggle != null) { @@ -1458,4 +1451,10 @@ private void checkStoragePermissionWarningBannerVisibility() { uploadFilesActivity.setupStoragePermissionWarningBanner(); } } + + public static boolean isToolbarStyleSearch() { + return menuItemId == Menu.NONE || + menuItemId == R.id.nav_all_files || + menuItemId == R.id.nav_personal_files; + } } diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index c5bade95e86f..db75a12d1164 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -791,8 +791,8 @@ class FileDisplayActivity : return null } - protected fun resetScrollingAndUpdateActionBar(searchType: SearchType = SearchType.NO_SEARCH) { - updateActionBarTitleAndHomeButton(file, searchType) + protected fun resetScrollingAndUpdateActionBar() { + updateActionBarTitleAndHomeButton(file) resetScrolling(true) } @@ -1235,7 +1235,7 @@ class FileDisplayActivity : listOfFiles.registerFabListener() } - resetScrollingAndUpdateActionBar(listOfFilesFragment?.currentSearchType ?: SearchType.NO_SEARCH) + resetScrollingAndUpdateActionBar() configureMenuItem() startMetadataSyncForCurrentDir() } @@ -1799,7 +1799,7 @@ class FileDisplayActivity : startSyncFolderOperation(root, false) } binding.fabMain.setImageResource(R.drawable.ic_plus) - resetScrollingAndUpdateActionBar(listOfFilesFragment?.currentSearchType ?: SearchType.NO_SEARCH) + resetScrollingAndUpdateActionBar() } override fun onBrowsedDownTo(directory: OCFile?) { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java index 8ef0e75a5711..ab2518d22309 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java @@ -35,7 +35,9 @@ import com.owncloud.android.R; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.datamodel.OCFileDepth; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.ui.fragment.OCFileListFragment; import com.owncloud.android.ui.fragment.SearchType; import com.owncloud.android.utils.theme.ThemeColorUtils; import com.owncloud.android.utils.theme.ThemeUtils; @@ -136,6 +138,9 @@ public void setupToolbarShowOnlyMenuButtonAndTitle(String title, View.OnClickLis menuButton.setOnClickListener(toggleDrawer); } + /** + * Shows plain action bar + */ public void setupToolbar() { if (mHomeSearchToolbar != null && mDefaultToolbar != null && mHomeSearchToolbar.getVisibility() == View.GONE && mDefaultToolbar.getVisibility() == View.VISIBLE) { Log_OC.d(TAG, "Search toolbar is already hidden, skipping update."); @@ -145,6 +150,9 @@ public void setupToolbar() { setupToolbar(false, false); } + /** + * Shows action bar with search + */ public void setupHomeSearchToolbarWithSortAndListButtons() { if (mHomeSearchToolbar != null && mDefaultToolbar != null && mHomeSearchToolbar.getVisibility() == View.VISIBLE && mDefaultToolbar.getVisibility() == View.GONE) { Log_OC.d(TAG, "Search toolbar is already visible, skipping update."); @@ -154,22 +162,34 @@ public void setupHomeSearchToolbarWithSortAndListButtons() { setupToolbar(true, true); } - public void updateActionBarTitleAndHomeButton(OCFile chosenFile, SearchType searchType) { - if (mAppBar == null) { - return; + private OCFileListFragment getOCFileListFragment() { + if (this instanceof FileDisplayActivity fda) { + return fda.getListOfFilesFragment(); } - boolean isRoot = isRoot(chosenFile); - String title = getActionBarTitle(chosenFile, searchType); - updateActionBarTitleAndHomeButtonByString(title); - showHomeSearchToolbar(title, isRoot); + return null; } - protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { - updateActionBarTitleAndHomeButton(chosenFile, SearchType.NO_SEARCH); + private OCFileDepth getCurrentDirDepth() { + OCFileListFragment fragment = getOCFileListFragment(); + if (fragment != null) { + return fragment.getFileDepth(); + } + + return null; } - public String getActionBarRootTitle(@NonNull SearchType searchType) { + private SearchType getSearchType() { + OCFileListFragment fragment = getOCFileListFragment(); + if (fragment != null) { + return fragment.getCurrentSearchType(); + } + + return SearchType.NO_SEARCH; + } + + public String getActionBarRootTitle() { + final SearchType searchType = getSearchType(); Integer rootTitleId = searchType.titleId(); String result = themeUtils.getDefaultDisplayNameForRootFolder(this); @@ -180,9 +200,9 @@ public String getActionBarRootTitle(@NonNull SearchType searchType) { return result; } - public String getActionBarTitle(OCFile chosenFile, @NonNull SearchType searchType) { + public String getActionBarTitle(OCFile chosenFile) { if (isRoot(chosenFile)) { - return getActionBarRootTitle(searchType); + return getActionBarRootTitle(); } if (chosenFile.isFolder()) { @@ -198,6 +218,24 @@ public String getActionBarTitle(OCFile chosenFile, @NonNull SearchType searchTyp return fileDataStorageManager.getFilenameConsideringOfflineOperation(parentFile); } + protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { + if (mAppBar == null) { + return; + } + + final OCFileDepth currentDirDepth = getCurrentDirDepth(); + final boolean isRoot = isRoot(chosenFile) || currentDirDepth == OCFileDepth.Root; + final String title = getActionBarTitle(chosenFile); + updateActionBarTitleAndHomeButtonByString(title); + + final boolean isToolbarStyleSearch = DrawerActivity.isToolbarStyleSearch(); + final boolean canShowSearchBar = (isHomeSearchToolbarShow && isRoot && isToolbarStyleSearch); + + showHomeSearchToolbar(canShowSearchBar); + mSearchText.setText(getString(R.string.appbar_search_in, title)); + } + + public void showSearchView() { if (isHomeSearchToolbarShow) { showHomeSearchToolbar(false); @@ -210,11 +248,6 @@ public void hideSearchView(OCFile chosenFile) { } } - private void showHomeSearchToolbar(String title, boolean isRoot) { - showHomeSearchToolbar(isHomeSearchToolbarShow && isRoot); - mSearchText.setText(getString(R.string.appbar_search_in, title)); - } - @SuppressLint("PrivateResource") private void showHomeSearchToolbar(boolean isShow) { viewThemeUtils.material.themeToolbar(mToolbar); diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 465f4a097ffe..6149709b438c 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -434,7 +434,7 @@ public void onActivityCreated(Bundle savedInstanceState) { } if (getActivity() instanceof FileDisplayActivity fda) { - fda.updateActionBarTitleAndHomeButton(fda.getCurrentDir(), currentSearchType); + fda.updateActionBarTitleAndHomeButton(fda.getCurrentDir()); } listDirectory(MainApp.isOnlyOnDevice(), false); } @@ -1811,7 +1811,7 @@ public void onMessageEvent(ChangeMenuEvent changeMenuEvent) { if (getActivity() instanceof FileDisplayActivity fda) { fda.invalidateOptionsMenu(); fda.getIntent().removeExtra(OCFileListFragment.SEARCH_EVENT); - fda.updateActionBarTitleAndHomeButton(null, NO_SEARCH); + fda.updateActionBarTitleAndHomeButton(null); } if (mFile != null) { From 91cdb4b2b3a13a3f4033942b7c774dc44a6008d8 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 14:39:46 +0100 Subject: [PATCH 08/23] fix back button action Signed-off-by: alperozturk --- .../android/ui/activity/DrawerActivity.java | 13 +++++++++---- .../android/ui/activity/ToolbarActivity.java | 11 ++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index b35c10ea086f..0a5e614deb54 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -648,10 +648,7 @@ private void onNavigationItemClicked(final MenuItem menuItem) { } // from navigation user always sees root level - final var ocFileListFragment = getOCFileListFragment(); - if (ocFileListFragment != null) { - ocFileListFragment.resetFileDepth(); - } + resetFileDepth(); if (this instanceof FileDisplayActivity fda) { fda.configureMenuItem(); @@ -695,7 +692,15 @@ public void openAddAccount() { } } + private void resetFileDepth() { + final var ocFileListFragment = getOCFileListFragment(); + if (ocFileListFragment != null) { + ocFileListFragment.resetFileDepth(); + } + } + protected void openSharedTab() { + resetFileDepth(); resetOnlyPersonalAndOnDevice(); SearchEvent searchEvent = new SearchEvent("", SearchRemoteOperation.SearchType.SHARED_FILTER); launchActivityForSearch(searchEvent, R.id.nav_shared); diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java index ab2518d22309..170af4e0408a 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java @@ -200,8 +200,8 @@ public String getActionBarRootTitle() { return result; } - public String getActionBarTitle(OCFile chosenFile) { - if (isRoot(chosenFile)) { + public String getActionBarTitle(OCFile chosenFile, boolean isRoot) { + if (isRoot) { return getActionBarRootTitle(); } @@ -225,7 +225,7 @@ protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { final OCFileDepth currentDirDepth = getCurrentDirDepth(); final boolean isRoot = isRoot(chosenFile) || currentDirDepth == OCFileDepth.Root; - final String title = getActionBarTitle(chosenFile); + final String title = getActionBarTitle(chosenFile, isRoot); updateActionBarTitleAndHomeButtonByString(title); final boolean isToolbarStyleSearch = DrawerActivity.isToolbarStyleSearch(); @@ -233,6 +233,11 @@ protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { showHomeSearchToolbar(canShowSearchBar); mSearchText.setText(getString(R.string.appbar_search_in, title)); + + final var actionBar = getSupportActionBar(); + if (actionBar != null) { + viewThemeUtils.files.themeActionBar(this, actionBar, title, isRoot); + } } From 220b35cd19044fe64f98820c5001833bbb544059 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 14:52:50 +0100 Subject: [PATCH 09/23] fix overriding calculated behaviour via drawer slide Signed-off-by: alperozturk --- .../android/ui/activity/DrawerActivity.java | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index 0a5e614deb54..839fe14b1453 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -321,16 +321,10 @@ private void exitSelectionMode() { } } - /** - * initializes and sets up the drawer toggle. - */ private void setupDrawerToggle() { mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) { - /** Called when a drawer has settled in a completely closed state. */ public void onDrawerClosed(View view) { super.onDrawerClosed(view); - supportInvalidateOptionsMenu(); - mDrawerToggle.setDrawerIndicatorEnabled(isDrawerIndicatorAvailable()); if (pendingRunnable != null) { new Handler().post(pendingRunnable); @@ -339,23 +333,12 @@ public void onDrawerClosed(View view) { closeDrawer(); } - - /** Called when a drawer has settled in a completely open state. */ - public void onDrawerOpened(View drawerView) { - super.onDrawerOpened(drawerView); - mDrawerToggle.setDrawerIndicatorEnabled(true); - supportInvalidateOptionsMenu(); - } }; - // Set the drawer toggle as the DrawerListener mDrawerLayout.addDrawerListener(mDrawerToggle); mDrawerToggle.setDrawerIndicatorEnabled(true); mDrawerToggle.setDrawerSlideAnimationEnabled(true); - Drawable backArrow = ResourcesCompat.getDrawable(getResources(), - R.drawable.ic_arrow_back, - null); - + final Drawable backArrow = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_arrow_back, null); if (backArrow != null) { viewThemeUtils.platform.tintToolbarArrowDrawable(this, mDrawerToggle, backArrow); } From ed8d526b61ccb04ad8d8917ea7db0142bd533147 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 14:56:54 +0100 Subject: [PATCH 10/23] fix codacy Signed-off-by: alperozturk --- .../com/owncloud/android/ui/activity/FileDisplayActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index db75a12d1164..d1cc7ab5a097 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -2738,7 +2738,7 @@ class FileDisplayActivity : listOfFilesFragment?.setCurrentSearchType(event) updateActionBarTitleAndHomeButton(null) - //listOfFilesFragment?.setActionBarTitle() + // listOfFilesFragment?.setActionBarTitle() } @Subscribe(threadMode = ThreadMode.MAIN) From ba836321b20edb65dd1fd91d5a43b79c5b64dc8c Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 15:37:47 +0100 Subject: [PATCH 11/23] fix on device action bar Signed-off-by: alperozturk --- .../android/ui/activity/DrawerActivity.java | 13 +++++++++++-- .../android/ui/activity/FileDisplayActivity.kt | 14 +++++++++++--- .../android/ui/fragment/OCFileListFragment.java | 4 ++++ .../com/owncloud/android/ui/fragment/SearchType.kt | 4 +++- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index 839fe14b1453..54544bf54f67 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -579,8 +579,7 @@ private void onNavigationItemClicked(final MenuItem menuItem) { setupToolbar(); startPhotoSearch(menuItem.getItemId()); } else if (itemId == R.id.nav_on_device) { - EventBus.getDefault().post(new ChangeMenuEvent()); - showFiles(true, false); + showOnDeviceFiles(); } else if (itemId == R.id.nav_uploads) { resetOnlyPersonalAndOnDevice(); startActivity(UploadListActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP); @@ -1255,6 +1254,16 @@ public void showFiles(boolean onDeviceOnly, boolean onlyPersonalFiles) { startActivity(intent); } + private void showOnDeviceFiles() { + MainApp.showOnlyFilesOnDevice(true); + MainApp.showOnlyPersonalFiles(false); + + Intent intent = new Intent(getApplicationContext(), FileDisplayActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + intent.setAction(FileDisplayActivity.ON_DEVICE); + startActivity(intent); + } + @Override public void avatarGenerated(Drawable avatarDrawable, Object callContext) { if (callContext instanceof MenuItem menuItem) { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index d1cc7ab5a097..3970987ef7db 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -572,6 +572,12 @@ class FileDisplayActivity : leftFragment = GroupfolderListFragment() supportFragmentManager.executePendingTransactions() } + + ON_DEVICE == action -> { + refreshOrInitOCFileListFragment() + listOfFilesFragment?.setCurrentSearchType(SearchType.ON_DEVICE) + updateActionBarTitleAndHomeButton(null) + } } } @@ -2712,9 +2718,10 @@ class FileDisplayActivity : override fun showFiles(onDeviceOnly: Boolean, personalFiles: Boolean) { super.showFiles(onDeviceOnly, personalFiles) - if (onDeviceOnly) { - updateActionBarTitleAndHomeButtonByString(getString(R.string.drawer_item_on_device)) - } + refreshOrInitOCFileListFragment() + } + + private fun refreshOrInitOCFileListFragment() { val ocFileListFragment = this.listOfFilesFragment if (ocFileListFragment != null && (ocFileListFragment !is GalleryFragment) && @@ -3062,6 +3069,7 @@ class FileDisplayActivity : const val LIST_GROUPFOLDERS: String = "LIST_GROUPFOLDERS" const val SINGLE_USER_SIZE: Int = 1 const val OPEN_FILE: String = "NC_OPEN_FILE" + const val ON_DEVICE = "ON_DEVICE" const val TAG_PUBLIC_LINK: String = "PUBLIC_LINK" const val FTAG_CHOOSER_DIALOG: String = "CHOOSER_DIALOG" diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 6149709b438c..5eb9e2c3fd6b 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -1752,6 +1752,10 @@ public void setCurrentSearchType(SearchEvent event) { } } + public void setCurrentSearchType(SearchType searchType) { + currentSearchType = searchType; + } + public SearchType getCurrentSearchType() { return currentSearchType; } diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt b/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt index 7827e6d053f9..0e473690a7e4 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/SearchType.kt @@ -24,13 +24,15 @@ enum class SearchType : Parcelable { // not a real filter, but nevertheless SHARED_FILTER, - GROUPFOLDER; + GROUPFOLDER, + ON_DEVICE; fun titleId(): Int? = when (this) { FAVORITE_SEARCH -> R.string.drawer_item_favorites GALLERY_SEARCH -> R.string.drawer_item_gallery RECENTLY_MODIFIED_SEARCH -> R.string.drawer_item_recently_modified SHARED_FILTER -> R.string.drawer_item_shared + ON_DEVICE -> R.string.drawer_item_on_device else -> null } } From 8231a78ae119cbf3d587b4b525003ab1924ca3b2 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 16:21:06 +0100 Subject: [PATCH 12/23] fix multiple item highlight Signed-off-by: alperozturk --- .../android/ui/activity/DrawerActivity.java | 54 ++++++++++++------- .../android/ui/events/DummyDrawerEvent.kt | 13 ----- 2 files changed, 34 insertions(+), 33 deletions(-) delete mode 100644 app/src/main/java/com/owncloud/android/ui/events/DummyDrawerEvent.kt diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index 54544bf54f67..3bd267cdc3e1 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -87,7 +87,6 @@ import com.owncloud.android.ui.activities.ActivitiesActivity; import com.owncloud.android.ui.events.AccountRemovedEvent; import com.owncloud.android.ui.events.ChangeMenuEvent; -import com.owncloud.android.ui.events.DummyDrawerEvent; import com.owncloud.android.ui.events.SearchEvent; import com.owncloud.android.ui.fragment.FileDetailsSharingProcessFragment; import com.owncloud.android.ui.fragment.GalleryFragment; @@ -177,6 +176,8 @@ public abstract class DrawerActivity extends ToolbarActivity */ public static int menuItemId = Menu.NONE; + public static int previousMenuItemId = Menu.NONE; + /** * container layout of the quota view. */ @@ -263,9 +264,22 @@ private void checkAssistantBottomNavigationMenu() { .setVisible(isAssistantAvailable); } + private void openFavoritesTab(int menuItemId) { + resetOnlyPersonalAndOnDevice(); + setupToolbar(); + handleSearchEvents(new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH), menuItemId); + } + + private void openMediaTab(int menuItemId) { + resetOnlyPersonalAndOnDevice(); + setupToolbar(); + startPhotoSearch(menuItemId); + } + @SuppressFBWarnings("RV") private void handleBottomNavigationViewClicks() { bottomNavigationView.setOnItemSelectedListener(menuItem -> { + previousMenuItemId = menuItemId; menuItemId = menuItem.getItemId(); exitSelectionMode(); @@ -278,14 +292,11 @@ private void handleBottomNavigationViewClicks() { } EventBus.getDefault().post(new ChangeMenuEvent()); } else if (menuItemId == R.id.nav_favorites) { - resetOnlyPersonalAndOnDevice(); - setupToolbar(); - handleSearchEvents(new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH), menuItemId); + openFavoritesTab(menuItem.getItemId()); } else if (menuItemId == R.id.nav_assistant && !(this instanceof ComposeActivity)) { startComposeActivity(new ComposeDestination.AssistantScreen(null), R.string.assistant_screen_top_bar_title); } else if (menuItemId == R.id.nav_gallery) { - setupToolbar(); - startPhotoSearch(menuItem.getItemId()); + openMediaTab(menuItem.getItemId()); } // Remove extra icon from the action bar @@ -536,12 +547,8 @@ private void filterDrawerMenu(final Menu menu, @NonNull final User user) { DrawerMenuUtil.removeMenuItem(menu, R.id.nav_logout, !getResources().getBoolean(R.bool.show_drawer_logout)); } - @Subscribe(threadMode = ThreadMode.MAIN) - public void onMessageEvent(DummyDrawerEvent event) { - unsetAllDrawerMenuItems(); - } - private void onNavigationItemClicked(final MenuItem menuItem) { + previousMenuItemId = menuItemId; int itemId = menuItem.getItemId(); // Settings screen cannot display drawer menu thus no need to highlight @@ -571,13 +578,9 @@ private void onNavigationItemClicked(final MenuItem menuItem) { closeDrawer(); } else if (itemId == R.id.nav_favorites) { - resetOnlyPersonalAndOnDevice(); - setupToolbar(); - handleSearchEvents(new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH), menuItem.getItemId()); + openFavoritesTab(menuItem.getItemId()); } else if (itemId == R.id.nav_gallery) { - resetOnlyPersonalAndOnDevice(); - setupToolbar(); - startPhotoSearch(menuItem.getItemId()); + openMediaTab(menuItem.getItemId()); } else if (itemId == R.id.nav_on_device) { showOnDeviceFiles(); } else if (itemId == R.id.nav_uploads) { @@ -874,14 +877,18 @@ private void setQuotaInformation(long usedSpace, long totalSpace, int relative, private void unsetAllDrawerMenuItems() { if (drawerNavigationView != null) { - drawerNavigationView.getMenu(); Menu menu = drawerNavigationView.getMenu(); for (int i = 0; i < menu.size(); i++) { menu.getItem(i).setChecked(false); } } - menuItemId = Menu.NONE; + if (bottomNavigationView != null) { + Menu menu = bottomNavigationView.getMenu(); + for (int i = 0; i < menu.size(); i++) { + menu.getItem(i).setChecked(false); + } + } } private void updateQuotaLink() { @@ -957,12 +964,19 @@ public void onLoadFailed(@Nullable Drawable errorDrawable) { */ @SuppressFBWarnings("RV") public void setNavigationViewItemChecked() { + unsetAllDrawerMenuItems(); + + // Don't check any items + if (menuItemId == Menu.NONE) { + return; + } + if (drawerNavigationView != null) { MenuItem menuItem = drawerNavigationView.getMenu().findItem(menuItemId); if (menuItem != null && !menuItem.isChecked()) { - viewThemeUtils.platform.colorNavigationView(drawerNavigationView); menuItem.setChecked(true); + viewThemeUtils.platform.colorNavigationView(drawerNavigationView); } } diff --git a/app/src/main/java/com/owncloud/android/ui/events/DummyDrawerEvent.kt b/app/src/main/java/com/owncloud/android/ui/events/DummyDrawerEvent.kt deleted file mode 100644 index 795d56460c1c..000000000000 --- a/app/src/main/java/com/owncloud/android/ui/events/DummyDrawerEvent.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Nextcloud - Android Client - * - * SPDX-FileCopyrightText: 2017 Mario Danic - * SPDX-FileCopyrightText: 2017 Nextcloud GmbH - * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only - */ -package com.owncloud.android.ui.events - -/** - * Dummy drawer event - */ -class DummyDrawerEvent From 13d08fdf1c5a5e06367c5ec9524ad8e4e486cc24 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Mon, 8 Dec 2025 16:21:23 +0100 Subject: [PATCH 13/23] fix back button behaviour from trashbin Signed-off-by: alperozturk --- .../java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt b/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt index 75fc42f109fd..aa696499c6de 100644 --- a/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt @@ -90,6 +90,7 @@ class TrashbinActivity : private val onBackPressedCallback = object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { + isEnabled = false trashbinPresenter?.navigateUp() } } @@ -292,6 +293,8 @@ class TrashbinActivity : } override fun onPause() { + menuItemId = previousMenuItemId + setNavigationViewItemChecked() super.onPause() active = false trashbinListAdapter?.cancelAllPendingTasks() From 8d01f211fbffd890090dbe3813f65aafc70233a7 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Tue, 9 Dec 2025 08:36:26 +0100 Subject: [PATCH 14/23] fix file name in action bar Signed-off-by: alperozturk --- .../ui/activity/FileDisplayActivity.kt | 2 +- .../android/ui/activity/ToolbarActivity.java | 36 ++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 3970987ef7db..bcbd74422841 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -2564,7 +2564,7 @@ class FileDisplayActivity : fun configureToolbarForPreview(file: OCFile?) { lockScrolling() - super.updateActionBarTitleAndHomeButton(file) + updateActionBarForFile(file) } /** diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java index 170af4e0408a..dc3d232e71b2 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java @@ -46,6 +46,7 @@ import javax.inject.Inject; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.appcompat.app.ActionBar; import androidx.appcompat.widget.AppCompatSpinner; @@ -205,27 +206,22 @@ public String getActionBarTitle(OCFile chosenFile, boolean isRoot) { return getActionBarRootTitle(); } - if (chosenFile.isFolder()) { - return fileDataStorageManager.getFilenameConsideringOfflineOperation(chosenFile); - } - - long parentId = chosenFile.getParentId(); - OCFile parentFile = fileDataStorageManager.getFileById(parentId); - if (parentFile == null) { - return ""; - } + return getActionBarTitleFromFile(chosenFile); + } - return fileDataStorageManager.getFilenameConsideringOfflineOperation(parentFile); + private String getActionBarTitleFromFile(OCFile file) { + // if offline rename operation already pointing same file, offline operation name will be used + return fileDataStorageManager.getFilenameConsideringOfflineOperation(file); } - protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { + protected void updateActionBarTitleAndHomeButton(OCFile file) { if (mAppBar == null) { return; } final OCFileDepth currentDirDepth = getCurrentDirDepth(); - final boolean isRoot = isRoot(chosenFile) || currentDirDepth == OCFileDepth.Root; - final String title = getActionBarTitle(chosenFile, isRoot); + final boolean isRoot = isRoot(file) || currentDirDepth == OCFileDepth.Root; + final String title = getActionBarTitle(file, isRoot); updateActionBarTitleAndHomeButtonByString(title); final boolean isToolbarStyleSearch = DrawerActivity.isToolbarStyleSearch(); @@ -240,6 +236,20 @@ protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { } } + protected void updateActionBarForFile(@Nullable OCFile file) { + if (mAppBar == null || file == null) { + return; + } + + final String title = getActionBarTitleFromFile(file); + updateActionBarTitleAndHomeButtonByString(title); + + showHomeSearchToolbar(false); + final var actionBar = getSupportActionBar(); + if (actionBar != null) { + viewThemeUtils.files.themeActionBar(this, actionBar, title, false); + } + } public void showSearchView() { if (isHomeSearchToolbarShow) { From 889f41376fb24435618dc4836fa6fdf97b8f7c93 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Tue, 9 Dec 2025 08:41:42 +0100 Subject: [PATCH 15/23] fix lint Signed-off-by: alperozturk --- .../android/ui/activity/DrawerActivity.java | 14 +++++++++++--- .../android/ui/fragment/OCFileListFragment.java | 2 +- .../android/ui/trashbin/TrashbinActivity.kt | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index 3bd267cdc3e1..1b19cb80957b 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -176,7 +176,7 @@ public abstract class DrawerActivity extends ToolbarActivity */ public static int menuItemId = Menu.NONE; - public static int previousMenuItemId = Menu.NONE; + private static int previousMenuItemId = Menu.NONE; /** * container layout of the quota view. @@ -279,7 +279,7 @@ private void openMediaTab(int menuItemId) { @SuppressFBWarnings("RV") private void handleBottomNavigationViewClicks() { bottomNavigationView.setOnItemSelectedListener(menuItem -> { - previousMenuItemId = menuItemId; + setPreviousMenuItemId(menuItemId); menuItemId = menuItem.getItemId(); exitSelectionMode(); @@ -548,7 +548,7 @@ private void filterDrawerMenu(final Menu menu, @NonNull final User user) { } private void onNavigationItemClicked(final MenuItem menuItem) { - previousMenuItemId = menuItemId; + setPreviousMenuItemId(menuItemId); int itemId = menuItem.getItemId(); // Settings screen cannot display drawer menu thus no need to highlight @@ -1468,4 +1468,12 @@ public static boolean isToolbarStyleSearch() { menuItemId == R.id.nav_all_files || menuItemId == R.id.nav_personal_files; } + + public static int getPreviousMenuItemId() { + return previousMenuItemId; + } + + public static void setPreviousMenuItemId(int menuItemId) { + previousMenuItemId = menuItemId; + } } diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 5eb9e2c3fd6b..86fa27d10b98 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -304,7 +304,7 @@ public void onAttach(@NonNull Context context) { } private void setSearchArgs(Bundle state) { - SearchType argSearchType = null; + SearchType argSearchType = NO_SEARCH; SearchEvent argSearchEvent = null; if (state != null) { diff --git a/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt b/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt index aa696499c6de..3f770ebdebff 100644 --- a/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.kt @@ -293,7 +293,7 @@ class TrashbinActivity : } override fun onPause() { - menuItemId = previousMenuItemId + menuItemId = getPreviousMenuItemId() setNavigationViewItemChecked() super.onPause() active = false From ee68b6b0222d0f25e314d5c98a36dc874b4e8ab6 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Tue, 9 Dec 2025 08:45:20 +0100 Subject: [PATCH 16/23] reset file depth for bottom navigation view as well Signed-off-by: alperozturk --- .../android/ui/activity/DrawerActivity.java | 75 ++++++++++--------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index 1b19cb80957b..b8c06c4e32a4 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -276,40 +276,6 @@ private void openMediaTab(int menuItemId) { startPhotoSearch(menuItemId); } - @SuppressFBWarnings("RV") - private void handleBottomNavigationViewClicks() { - bottomNavigationView.setOnItemSelectedListener(menuItem -> { - setPreviousMenuItemId(menuItemId); - menuItemId = menuItem.getItemId(); - - exitSelectionMode(); - resetOnlyPersonalAndOnDevice(); - - if (menuItemId == R.id.nav_all_files) { - showFiles(false,false); - if (this instanceof FileDisplayActivity fda) { - fda.browseToRoot(); - } - EventBus.getDefault().post(new ChangeMenuEvent()); - } else if (menuItemId == R.id.nav_favorites) { - openFavoritesTab(menuItem.getItemId()); - } else if (menuItemId == R.id.nav_assistant && !(this instanceof ComposeActivity)) { - startComposeActivity(new ComposeDestination.AssistantScreen(null), R.string.assistant_screen_top_bar_title); - } else if (menuItemId == R.id.nav_gallery) { - openMediaTab(menuItem.getItemId()); - } - - // Remove extra icon from the action bar - if (getSupportActionBar() != null) { - getSupportActionBar().setIcon(null); - } - - setNavigationViewItemChecked(); - - return false; - }); - } - @Nullable public OCFileListFragment getOCFileListFragment() { Fragment fragment = ActivityExtensionsKt.lastFragment(this); @@ -547,6 +513,7 @@ private void filterDrawerMenu(final Menu menu, @NonNull final User user) { DrawerMenuUtil.removeMenuItem(menu, R.id.nav_logout, !getResources().getBoolean(R.bool.show_drawer_logout)); } + // region navigation item click private void onNavigationItemClicked(final MenuItem menuItem) { setPreviousMenuItemId(menuItemId); int itemId = menuItem.getItemId(); @@ -632,6 +599,46 @@ private void onNavigationItemClicked(final MenuItem menuItem) { } } + resetFileDepthAndConfigureMenuItem(); + } + + @SuppressFBWarnings("RV") + private void handleBottomNavigationViewClicks() { + bottomNavigationView.setOnItemSelectedListener(menuItem -> { + setPreviousMenuItemId(menuItemId); + menuItemId = menuItem.getItemId(); + + exitSelectionMode(); + resetOnlyPersonalAndOnDevice(); + + if (menuItemId == R.id.nav_all_files) { + showFiles(false,false); + if (this instanceof FileDisplayActivity fda) { + fda.browseToRoot(); + } + EventBus.getDefault().post(new ChangeMenuEvent()); + } else if (menuItemId == R.id.nav_favorites) { + openFavoritesTab(menuItem.getItemId()); + } else if (menuItemId == R.id.nav_assistant && !(this instanceof ComposeActivity)) { + startComposeActivity(new ComposeDestination.AssistantScreen(null), R.string.assistant_screen_top_bar_title); + } else if (menuItemId == R.id.nav_gallery) { + openMediaTab(menuItem.getItemId()); + } + + // Remove extra icon from the action bar + if (getSupportActionBar() != null) { + getSupportActionBar().setIcon(null); + } + + setNavigationViewItemChecked(); + resetFileDepthAndConfigureMenuItem(); + + return false; + }); + } + // endregion + + private void resetFileDepthAndConfigureMenuItem() { // from navigation user always sees root level resetFileDepth(); From d02c84664a7e7f6290fe11f6db9b4a7e8c96c50d Mon Sep 17 00:00:00 2001 From: alperozturk Date: Tue, 9 Dec 2025 10:10:39 +0100 Subject: [PATCH 17/23] fix image preview Signed-off-by: alperozturk --- .../android/ui/activity/ToolbarActivity.java | 16 ++++++---- .../ui/preview/PreviewImageActivity.kt | 29 ++++++++----------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java index dc3d232e71b2..2d18da86aaa9 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java @@ -215,10 +215,6 @@ private String getActionBarTitleFromFile(OCFile file) { } protected void updateActionBarTitleAndHomeButton(OCFile file) { - if (mAppBar == null) { - return; - } - final OCFileDepth currentDirDepth = getCurrentDirDepth(); final boolean isRoot = isRoot(file) || currentDirDepth == OCFileDepth.Root; final String title = getActionBarTitle(file, isRoot); @@ -228,7 +224,10 @@ protected void updateActionBarTitleAndHomeButton(OCFile file) { final boolean canShowSearchBar = (isHomeSearchToolbarShow && isRoot && isToolbarStyleSearch); showHomeSearchToolbar(canShowSearchBar); - mSearchText.setText(getString(R.string.appbar_search_in, title)); + + if (mSearchText != null) { + mSearchText.setText(getString(R.string.appbar_search_in, title)); + } final var actionBar = getSupportActionBar(); if (actionBar != null) { @@ -237,7 +236,7 @@ protected void updateActionBarTitleAndHomeButton(OCFile file) { } protected void updateActionBarForFile(@Nullable OCFile file) { - if (mAppBar == null || file == null) { + if (file == null) { return; } @@ -265,7 +264,12 @@ public void hideSearchView(OCFile chosenFile) { @SuppressLint("PrivateResource") private void showHomeSearchToolbar(boolean isShow) { + if (mAppBar == null) { + return; + } + viewThemeUtils.material.themeToolbar(mToolbar); + if (isShow) { viewThemeUtils.platform.resetStatusBar(this); mAppBar.setStateListAnimator(AnimatorInflater.loadStateListAnimator(mAppBar.getContext(), diff --git a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt index 2e06e910a95f..fae01995f9c3 100644 --- a/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/preview/PreviewImageActivity.kt @@ -10,11 +10,11 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.MenuItem import android.view.View import androidx.activity.OnBackPressedCallback -import androidx.appcompat.app.ActionBar import androidx.core.content.ContextCompat import androidx.drawerlayout.widget.DrawerLayout import androidx.localbroadcastmanager.content.LocalBroadcastManager @@ -82,21 +82,17 @@ class PreviewImageActivity : @Inject lateinit var localBroadcastManager: LocalBroadcastManager - private var actionBar: ActionBar? = null - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - actionBar = supportActionBar - if (savedInstanceState != null && !savedInstanceState.getBoolean( KEY_SYSTEM_VISIBLE, true ) && - actionBar != null + supportActionBar != null ) { - actionBar?.hide() + supportActionBar?.hide() } setContentView(R.layout.preview_image_activity) @@ -106,11 +102,14 @@ class PreviewImageActivity : setupDrawer() val chosenFile = intent.getParcelableArgument(EXTRA_FILE, OCFile::class.java) - updateActionBarTitleAndHomeButton(chosenFile) - if (actionBar != null) { - viewThemeUtils.files.setWhiteBackButton(this, actionBar!!) - actionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.let { + updateActionBarTitleAndHomeButton(chosenFile) + viewThemeUtils.files.setWhiteBackButton(this, it) + it.setDisplayHomeAsUpEnabled(true) + it.setBackgroundDrawable( + ColorDrawable(ContextCompat.getColor(this, R.color.black)) + ) } fullScreenAnchorView = window.decorView @@ -147,14 +146,10 @@ class PreviewImageActivity : } fun toggleActionBarVisibility(hide: Boolean) { - if (actionBar == null) { - return - } - if (hide) { - actionBar?.hide() + supportActionBar?.hide() } else { - actionBar?.show() + supportActionBar?.show() } } From 63c18de12c78d3da57fa07fb715b172dad269b61 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Wed, 10 Dec 2025 11:54:20 +0100 Subject: [PATCH 18/23] fix: search fragment value Signed-off-by: alperozturk --- .../com/owncloud/android/ui/activity/DrawerActivity.java | 9 +++++---- .../owncloud/android/ui/fragment/OCFileListFragment.java | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index b8c06c4e32a4..c1ce36bdf5e0 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -264,10 +264,11 @@ private void checkAssistantBottomNavigationMenu() { .setVisible(isAssistantAvailable); } - private void openFavoritesTab(int menuItemId) { + private void openFavoritesTab() { resetOnlyPersonalAndOnDevice(); setupToolbar(); - handleSearchEvents(new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH), menuItemId); + SearchEvent searchEvent = new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH); + launchActivityForSearch(searchEvent, R.id.nav_favorites); } private void openMediaTab(int menuItemId) { @@ -545,7 +546,7 @@ private void onNavigationItemClicked(final MenuItem menuItem) { closeDrawer(); } else if (itemId == R.id.nav_favorites) { - openFavoritesTab(menuItem.getItemId()); + openFavoritesTab(); } else if (itemId == R.id.nav_gallery) { openMediaTab(menuItem.getItemId()); } else if (itemId == R.id.nav_on_device) { @@ -618,7 +619,7 @@ private void handleBottomNavigationViewClicks() { } EventBus.getDefault().post(new ChangeMenuEvent()); } else if (menuItemId == R.id.nav_favorites) { - openFavoritesTab(menuItem.getItemId()); + openFavoritesTab(); } else if (menuItemId == R.id.nav_assistant && !(this instanceof ComposeActivity)) { startComposeActivity(new ComposeDestination.AssistantScreen(null), R.string.assistant_screen_top_bar_title); } else if (menuItemId == R.id.nav_gallery) { diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 86fa27d10b98..129c22f88d83 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -1059,6 +1059,12 @@ public int onBrowseUp() { Pair result = futureResult.get(); mFile = result.second; setFileDepth(mFile); + + // since on browse down sets it to the false, browse up should set back to true if current search type is not NO_SEARCH + if (mFile.isRootDirectory() && currentSearchType != NO_SEARCH) { + searchFragment = true; + } + updateFileList(); return result.first; } catch (Exception e) { From a4836ec3bb0190528940c9cc605d332d70012536 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Fri, 12 Dec 2025 16:15:07 +0100 Subject: [PATCH 19/23] fix FileDetailsFragmentBinding.progressBlock' on a null object reference Signed-off-by: alperozturk --- .../owncloud/android/ui/fragment/FileDetailFragment.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java index e1990f7b652a..555286f2e6ad 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java @@ -231,6 +231,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, } binding = FileDetailsFragmentBinding.inflate(inflater, container, false); + observeWorkerState(); view = binding.getRoot(); if (getFile() == null || user == null) { @@ -610,8 +611,6 @@ public void updateFileDetails(boolean transferring, boolean refresh) { if (view != null) { view.invalidate(); } - - observeWorkerState(); } @Subscribe(threadMode = ThreadMode.MAIN) @@ -627,6 +626,10 @@ public void onDownloadProgress(FileDownloadProgressEvent event) { private void observeWorkerState() { ActivityExtensionsKt.observeWorker(requireActivity(), state -> { + if (binding == null) { + return Unit.INSTANCE; + } + if (state instanceof WorkerState.FileUploadStarted) { binding.progressText.setText(R.string.uploader_upload_in_progress_ticker); } else { From 669413bc619b8bede71eea7b7f58b23c5fce7318 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Fri, 12 Dec 2025 16:57:27 +0100 Subject: [PATCH 20/23] fix getPreviousFile Signed-off-by: alperozturk --- .../ui/activity/FileDisplayActivity.kt | 10 -- .../ui/fragment/OCFileListFragment.java | 153 ++++++------------ 2 files changed, 47 insertions(+), 116 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index bcbd74422841..cdbe74d9b833 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -89,7 +89,6 @@ import com.owncloud.android.R import com.owncloud.android.databinding.FilesBinding import com.owncloud.android.datamodel.FileDataStorageManager import com.owncloud.android.datamodel.OCFile -import com.owncloud.android.datamodel.OCFileDepth import com.owncloud.android.datamodel.SyncedFolderProvider import com.owncloud.android.datamodel.VirtualFolderType import com.owncloud.android.files.services.NameCollisionPolicy @@ -1186,15 +1185,6 @@ class FileDisplayActivity : } } - // shared root - fragment is SharedListFragment && fragment.fileDepth == OCFileDepth.Root -> { - openDrawer() - } - - fragment is SharedListFragment && fragment.fileDepth == OCFileDepth.FirstLevel -> { - openSharedTab() - } - // Normal folder navigation (go up) also works for shared tab else -> { browseUp(fragment) diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 129c22f88d83..bbdad0785f39 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -126,9 +126,6 @@ import java.util.List; import java.util.Objects; import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; import javax.inject.Inject; @@ -954,128 +951,72 @@ private void updateSortAndGridMenuItems() { } } - 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; + /** + * Call this, when the user presses the up button. + *

+ * 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. + *

+ * return Count of folder levels browsed up. + */ + public int onBrowseUp() { + if (mFile == null) { + return 0; + } + + Pair result = getPreviousFile(); + mFile = result.second; + setFileDepth(mFile); + + // since on browse down sets it to the false, browse up should set back to true if current search type is not NO_SEARCH + if (mFile.isRootDirectory() && currentSearchType != NO_SEARCH) { + searchFragment = true; + } + + updateFileList(); + return result.first; } - private Pair getPreviousFileWithoutFilter(FileDataStorageManager storageManager) { + private Pair getPreviousFile() { + if (mFile == null) { + return new Pair<>(0, null); + } + + FileDataStorageManager storageManager = mContainerActivity.getStorageManager(); int moveCount = 0; - OCFile parentDir = null; - String parentPath = null; + String parentPath; + OCFile parentDir; if (mFile.getParentId() != FileDataStorageManager.ROOT_PARENT_ID) { parentPath = new File(mFile.getRemotePath()).getParent(); - - if (parentPath != null) { - parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR; - parentDir = storageManager.getFileByPath(parentPath); - moveCount++; - } + parentPath = ensureTrailingSeparator(parentPath); + parentDir = storageManager.getFileByPath(parentPath); + moveCount++; } else { parentDir = storageManager.getFileByPath(ROOT_PATH); + parentPath = ROOT_PATH; } - while (parentDir == null) { + // Keep going up until we find a valid folder + while (parentDir == null && !ROOT_PATH.equals(parentPath)) { parentPath = new File(parentPath).getParent(); - - if (parentPath != null) { - parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : - parentPath + OCFile.PATH_SEPARATOR; - parentDir = storageManager.getFileByPath(parentPath); - moveCount++; + if (parentPath == null) { + parentPath = ROOT_PATH; // fallback to root } + parentPath = ensureTrailingSeparator(parentPath); + parentDir = storageManager.getFileByPath(parentPath); + moveCount++; } return new Pair<>(moveCount, parentDir); } - private OCFile getPreviousFileWithFilter(FileDataStorageManager storageManager, OCFile currentFile) { - while (true) { - OCFile parent = storageManager.getFileById(currentFile.getParentId()); - if (parent == null) { - return currentFile; - } - - if (parent.isRootDirectory()) { - return parent; - } - - if ((DrawerActivity.menuItemId == R.id.nav_shared && parent.isShared()) || - (DrawerActivity.menuItemId == R.id.nav_favorites && parent.isFavorite())) { - return parent; - } - - currentFile = parent; - } - } - - private Future> getPreviousFile() { - CompletableFuture> completableFuture = new CompletableFuture<>(); - - Executors.newCachedThreadPool().execute(() -> { - var result = new Pair(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 completableFuture; - } - - /** - * Call this, when the user presses the up button. - *

- * 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. - *

- * return Count of folder levels browsed up. - */ - public int onBrowseUp() { - if (mFile == null) { - return 0; - } - - try { - Future> futureResult = getPreviousFile(); - Pair result = futureResult.get(); - mFile = result.second; - setFileDepth(mFile); - - // since on browse down sets it to the false, browse up should set back to true if current search type is not NO_SEARCH - if (mFile.isRootDirectory() && currentSearchType != NO_SEARCH) { - searchFragment = true; - } - - 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; + private String ensureTrailingSeparator(String path) { + if (path == null) { + return ROOT_PATH; } + return path.endsWith(OCFile.PATH_SEPARATOR) ? path : path + OCFile.PATH_SEPARATOR; } private void updateFileList() { From c07d0058ba4e3c60fd24ce5e18dc64ade285d45f Mon Sep 17 00:00:00 2001 From: alperozturk Date: Sat, 13 Dec 2025 11:33:50 +0100 Subject: [PATCH 21/23] fix back press from file details Signed-off-by: alperozturk --- .../ui/activity/FileDisplayActivity.kt | 90 +++++++++++-------- .../ui/fragment/OCFileListFragment.java | 11 ++- 2 files changed, 63 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index cdbe74d9b833..fc85ebd5639f 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -1161,53 +1161,71 @@ class FileDisplayActivity : this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { - when { - isSearchOpen() -> { - isEnabled = false - resetSearchAction() - } + handleBackPressImpl(before = { + isEnabled = false + }, after = { + isEnabled = true + }) + } + } + ) + } - isDrawerOpen -> { - isEnabled = false - onBackPressedDispatcher.onBackPressed() - } + private fun handleBackPressImpl(before: () -> Unit = {}, after: () -> Unit = {}) { + when { + isSearchOpen() -> { + before() + resetSearchAction() + after() + } - leftFragment is OCFileListFragment -> { - val fragment = leftFragment as OCFileListFragment - - when { - // root - isRoot(getCurrentDir()) -> { - if (fragment.shouldNavigateBackToAllFiles()) { - navigateToAllFiles() - } else { - finish() - } - } - - // Normal folder navigation (go up) also works for shared tab - else -> { - browseUp(fragment) - } - } - } + isDrawerOpen -> { + before() + onBackPressedDispatcher.onBackPressed() + after() + } - else -> { - isEnabled = false - popBack() - } - } + leftFragment is OCFileListFragment -> { + before() + handleOCFileListFragmentBackPress() + after() + } + + else -> { + before() + popBack() + after() + } + } + } + + private fun handleOCFileListFragmentBackPress() { + val fragment = leftFragment as OCFileListFragment + + when { + // root + isRoot(getCurrentDir()) -> { + if (fragment.shouldNavigateBackToAllFiles()) { + navigateToAllFiles() + } else { + finish() } } - ) + + // Normal folder navigation (go up) also works for shared tab + else -> { + browseUp(fragment) + } + } } override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { android.R.id.home -> { when { shouldOpenDrawer() -> openDrawer() - isSearchOpen() -> resetSearchAction() - else -> onBackPressedDispatcher.onBackPressed() + else -> { + handleBackPressImpl() + } } true } diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index bbdad0785f39..73b3157a21ce 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -253,12 +253,19 @@ public void onCreate(Bundle savedInstanceState) { @Override public void onResume() { - if (getActivity() == null) { + // Don't handle search events if we're coming back from back stack + // The fragment has already been properly restored in onCreate/onActivityCreated + if (mFile != null) { + super.onResume(); return; } - Intent intent = getActivity().getIntent(); + final var activity = getActivity(); + if (activity == null) { + return; + } + final Intent intent = activity.getIntent(); if (IntentExtensionsKt.getParcelableArgument(intent, SEARCH_EVENT, SearchEvent.class) != null) { searchEvent = IntentExtensionsKt.getParcelableArgument(intent, SEARCH_EVENT, SearchEvent.class); } From f802f06890ea3994afaff207ed3ad5e362410a84 Mon Sep 17 00:00:00 2001 From: alperozturk Date: Sat, 13 Dec 2025 11:48:20 +0100 Subject: [PATCH 22/23] fix back press from file details Signed-off-by: alperozturk --- .../owncloud/android/ui/activity/FileDisplayActivity.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index fc85ebd5639f..2eeda406f9dd 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -1181,7 +1181,7 @@ class FileDisplayActivity : isDrawerOpen -> { before() - onBackPressedDispatcher.onBackPressed() + closeDrawer() after() } @@ -1278,20 +1278,20 @@ class FileDisplayActivity : if (leftFragment is UnifiedSearchFragment) { showSortListGroup(false) - onBackPressedDispatcher.onBackPressed() + supportFragmentManager.popBackStack() } } /** * Use this method when want to pop the fragment on back press. It resets Scrolling (See * [with true][.resetScrolling] and pop the visibility for sortListGroup (See - * [with false][.showSortListGroup]. At last call to onBackPressedDispatcher.onBackPressed() + * [with false][.showSortListGroup]. At last call to supportFragmentManager.popBackStack() */ private fun popBack() { binding.fabMain.setImageResource(R.drawable.ic_plus) resetScrolling(true) showSortListGroup(false) - onBackPressedDispatcher.onBackPressed() + supportFragmentManager.popBackStack() } override fun onSaveInstanceState(outState: Bundle) { From 3297fadb890ac788f2500fb26949e6000a9a2d9b Mon Sep 17 00:00:00 2001 From: alperozturk Date: Sat, 13 Dec 2025 19:12:02 +0100 Subject: [PATCH 23/23] fix action bar press back from unified search fragment and when fda created or recreated Signed-off-by: alperozturk --- .../android/ui/activity/DrawerActivity.java | 21 +++++++------------ .../ui/activity/FileDisplayActivity.kt | 5 +++++ .../android/ui/activity/ToolbarActivity.java | 12 ++++++++++- .../ui/fragment/OCFileListFragment.java | 2 +- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java index c1ce36bdf5e0..f26047d581a3 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java @@ -713,19 +713,6 @@ public void startPhotoSearch(int id) { launchActivityForSearch(searchEvent, id); } - private void handleSearchEvents(SearchEvent searchEvent, int menuItemId) { - if (this instanceof FileDisplayActivity) { - final Fragment leftFragment = ((FileDisplayActivity) this).getLeftFragment(); - if (leftFragment instanceof GalleryFragment || leftFragment instanceof SharedListFragment) { - launchActivityForSearch(searchEvent, menuItemId); - } else { - EventBus.getDefault().post(searchEvent); - } - } else { - launchActivityForSearch(searchEvent, menuItemId); - } - } - private void launchActivityForSearch(SearchEvent searchEvent, int menuItemId) { DrawerActivity.menuItemId = menuItemId; Intent intent = new Intent(getApplicationContext(), FileDisplayActivity.class); @@ -1477,6 +1464,14 @@ public static boolean isToolbarStyleSearch() { menuItemId == R.id.nav_personal_files; } + public static boolean isMenuItemIdBelongsToSearchType() { + return menuItemId == R.id.nav_favorites || + menuItemId == R.id.nav_shared || + menuItemId == R.id.nav_on_device || + menuItemId == R.id.nav_recently_modified || + menuItemId == R.id.nav_gallery; + } + public static int getPreviousMenuItemId() { return previousMenuItemId; } diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index 2eeda406f9dd..ff5e800637b8 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -307,6 +307,11 @@ class FileDisplayActivity : mSwitchAccountButton.setOnClickListener { v: View? -> showManageAccountsDialog() } mNotificationButton.setOnClickListener { v: View? -> startActivity(NotificationsActivity::class.java) } fastScrollUtils.fixAppBarForFastScroll(binding.appbar.appbar, binding.rootLayout) + + // reset ui states when file display activity created/recrated + listOfFilesFragment?.resetSearchAttributes() + menuItemId = R.id.nav_all_files + setNavigationViewItemChecked() } private fun initTaskRetainerFragment() { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java index 2d18da86aaa9..75bbfa7ff180 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java @@ -181,7 +181,17 @@ private OCFileDepth getCurrentDirDepth() { } private SearchType getSearchType() { - OCFileListFragment fragment = getOCFileListFragment(); + final OCFileListFragment fragment = getOCFileListFragment(); + + // if current navigation not matches, reset search event + if (!DrawerActivity.isMenuItemIdBelongsToSearchType()) { + if (fragment != null) { + fragment.resetSearchAttributes(); + } + + return SearchType.NO_SEARCH; + } + if (fragment != null) { return fragment.getCurrentSearchType(); } diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 73b3157a21ce..18038398955f 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -1784,7 +1784,7 @@ private void resetMenuItems() { updateSortAndGridMenuItems(); } - private void resetSearchAttributes() { + public void resetSearchAttributes() { searchFragment = false; searchEvent = null; currentSearchType = NO_SEARCH;