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..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 @@ -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; + private static int previousMenuItemId = Menu.NONE; + /** * container layout of the quota view. */ @@ -263,39 +264,17 @@ private void checkAssistantBottomNavigationMenu() { .setVisible(isAssistantAvailable); } - @SuppressFBWarnings("RV") - private void handleBottomNavigationViewClicks() { - bottomNavigationView.setOnItemSelectedListener(menuItem -> { - 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) { - setupToolbar(); - handleSearchEvents(new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH), menuItemId); - } 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()); - } - - // Remove extra icon from the action bar - if (getSupportActionBar() != null) { - getSupportActionBar().setIcon(null); - } - - setNavigationViewItemChecked(); + private void openFavoritesTab() { + resetOnlyPersonalAndOnDevice(); + setupToolbar(); + SearchEvent searchEvent = new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH); + launchActivityForSearch(searchEvent, R.id.nav_favorites); + } - return false; - }); + private void openMediaTab(int menuItemId) { + resetOnlyPersonalAndOnDevice(); + setupToolbar(); + startPhotoSearch(menuItemId); } @Nullable @@ -320,16 +299,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); @@ -338,23 +311,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); } @@ -552,12 +514,9 @@ 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(); - } - + // region navigation item click private void onNavigationItemClicked(final MenuItem menuItem) { + setPreviousMenuItemId(menuItemId); int itemId = menuItem.getItemId(); // Settings screen cannot display drawer menu thus no need to highlight @@ -587,16 +546,11 @@ 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(); } else if (itemId == R.id.nav_gallery) { - resetOnlyPersonalAndOnDevice(); - setupToolbar(); - startPhotoSearch(menuItem.getItemId()); + openMediaTab(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); @@ -645,6 +599,53 @@ private void onNavigationItemClicked(final MenuItem menuItem) { Log_OC.w(TAG, "Unknown drawer menu item clicked: " + menuItem.getTitle()); } } + + 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(); + } 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(); + + if (this instanceof FileDisplayActivity fda) { + fda.configureMenuItem(); + } } private void startComposeActivity(ComposeDestination destination, int titleId) { @@ -684,11 +685,15 @@ public void openAddAccount() { } } - protected void openSharedTab() { + 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); @@ -708,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); @@ -880,14 +872,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() { @@ -963,12 +959,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); } } @@ -1260,6 +1263,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) { @@ -1444,4 +1457,26 @@ 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; + } + + 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; + } + + public static void setPreviousMenuItemId(int menuItemId) { + previousMenuItemId = menuItemId; + } } 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..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 @@ -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 @@ -91,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 @@ -310,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() { @@ -535,7 +537,7 @@ class FileDisplayActivity : } /** reset views */ - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar() } // region Handle Intents @@ -574,6 +576,12 @@ class FileDisplayActivity : leftFragment = GroupfolderListFragment() supportFragmentManager.executePendingTransactions() } + + ON_DEVICE == action -> { + refreshOrInitOCFileListFragment() + listOfFilesFragment?.setCurrentSearchType(SearchType.ON_DEVICE) + updateActionBarTitleAndHomeButton(null) + } } } @@ -634,6 +642,8 @@ class FileDisplayActivity : } } } + + listOfFilesFragment?.setCurrentSearchType(searchEvent) } // endregion @@ -791,8 +801,8 @@ class FileDisplayActivity : return null } - protected fun resetTitleBarAndScrolling() { - updateActionBarTitleAndHomeButton(null) + protected fun resetScrollingAndUpdateActionBar() { + updateActionBarTitleAndHomeButton(file) resetScrolling(true) } @@ -1156,62 +1166,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() - } - } - - // 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) - } - } - } + isDrawerOpen -> { + before() + closeDrawer() + 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 } @@ -1235,8 +1254,8 @@ class FileDisplayActivity : listOfFiles.registerFabListener() } - resetTitleBarAndScrolling() - configureToolbar() + resetScrollingAndUpdateActionBar() + configureMenuItem() startMetadataSyncForCurrentDir() } @@ -1264,20 +1283,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) { @@ -1358,7 +1377,7 @@ class FileDisplayActivity : localBroadcastManager.registerReceiver(it, downloadIntentFilter) } - configureToolbar() + configureMenuItem() // show in-app review dialog to user inAppReviewHelper.showInAppReview(this) @@ -1387,23 +1406,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() { @@ -1535,7 +1540,7 @@ class FileDisplayActivity : private fun handleRemovedFileFromServer(currentFile: OCFile?, currentDir: OCFile?): OCFile? { if (currentFile == null && file?.isFolder == false) { - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar() return currentDir } @@ -1813,12 +1818,12 @@ class FileDisplayActivity : startSyncFolderOperation(root, false) } binding.fabMain.setImageResource(R.drawable.ic_plus) - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar() } override fun onBrowsedDownTo(directory: OCFile?) { file = directory - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar() startSyncFolderOperation(directory, false) startMetadataSyncForCurrentDir() } @@ -2115,7 +2120,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()) { @@ -2321,7 +2326,7 @@ class FileDisplayActivity : leftFragment.updateFileDetails(file, currentUser) } else { if (!file.fileExists()) { - resetTitleBarAndScrolling() + resetScrollingAndUpdateActionBar() } else { leftFragment.updateFileDetails(false, true) } @@ -2572,7 +2577,7 @@ class FileDisplayActivity : fun configureToolbarForPreview(file: OCFile?) { lockScrolling() - super.updateActionBarTitleAndHomeButton(file) + updateActionBarForFile(file) } /** @@ -2726,9 +2731,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) && @@ -2749,6 +2755,10 @@ class FileDisplayActivity : Log_OC.d(this, "Switch to Shared fragment") this.leftFragment = SharedListFragment() } + + listOfFilesFragment?.setCurrentSearchType(event) + updateActionBarTitleAndHomeButton(null) + // listOfFilesFragment?.setActionBarTitle() } @Subscribe(threadMode = ThreadMode.MAIN) @@ -3072,6 +3082,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/activity/ToolbarActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java index f4945899e9ea..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 @@ -35,7 +35,10 @@ 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; import com.owncloud.android.utils.theme.ViewThemeUtils; @@ -43,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; @@ -135,6 +139,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."); @@ -144,6 +151,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."); @@ -153,34 +163,101 @@ public void setupHomeSearchToolbarWithSortAndListButtons() { setupToolbar(true, true); } - /** - * Updates title bar and home buttons (state and icon). - */ - protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) { - boolean isRoot = isRoot(chosenFile); - String title = getActionBarTitle(chosenFile, isRoot); - updateActionBarTitleAndHomeButtonByString(title); - if (mAppBar != null) { - showHomeSearchToolbar(title, isRoot); + private OCFileListFragment getOCFileListFragment() { + if (this instanceof FileDisplayActivity fda) { + return fda.getListOfFilesFragment(); + } + + return null; + } + + private OCFileDepth getCurrentDirDepth() { + OCFileListFragment fragment = getOCFileListFragment(); + if (fragment != null) { + return fragment.getFileDepth(); + } + + return null; + } + + private SearchType getSearchType() { + 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(); + } + + return SearchType.NO_SEARCH; + } + + public String getActionBarRootTitle() { + final SearchType searchType = getSearchType(); + Integer rootTitleId = searchType.titleId(); + String result = themeUtils.getDefaultDisplayNameForRootFolder(this); + + if (rootTitleId != null) { + result = getString(rootTitleId); } + + return result; } - private String getActionBarTitle(OCFile chosenFile, boolean isRoot) { + public String getActionBarTitle(OCFile chosenFile, boolean isRoot) { if (isRoot) { - return themeUtils.getDefaultDisplayNameForRootFolder(this); + return getActionBarRootTitle(); } - if (chosenFile.isFolder()) { - return fileDataStorageManager.getFilenameConsideringOfflineOperation(chosenFile); + return getActionBarTitleFromFile(chosenFile); + } + + 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 file) { + final OCFileDepth currentDirDepth = getCurrentDirDepth(); + final boolean isRoot = isRoot(file) || currentDirDepth == OCFileDepth.Root; + final String title = getActionBarTitle(file, isRoot); + updateActionBarTitleAndHomeButtonByString(title); + + final boolean isToolbarStyleSearch = DrawerActivity.isToolbarStyleSearch(); + final boolean canShowSearchBar = (isHomeSearchToolbarShow && isRoot && isToolbarStyleSearch); + + showHomeSearchToolbar(canShowSearchBar); + + if (mSearchText != null) { + mSearchText.setText(getString(R.string.appbar_search_in, title)); } - long parentId = chosenFile.getParentId(); - OCFile parentFile = fileDataStorageManager.getFileById(parentId); - if (parentFile == null) { - return ""; + final var actionBar = getSupportActionBar(); + if (actionBar != null) { + viewThemeUtils.files.themeActionBar(this, actionBar, title, isRoot); } + } - return fileDataStorageManager.getFilenameConsideringOfflineOperation(parentFile); + protected void updateActionBarForFile(@Nullable OCFile file) { + if (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() { @@ -195,14 +272,14 @@ 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) { + 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/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 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/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 { 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..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 @@ -124,10 +124,8 @@ 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; -import java.util.concurrent.Future; import javax.inject.Inject; @@ -135,8 +133,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; @@ -187,9 +183,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"; @@ -251,23 +245,27 @@ 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); } @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); } @@ -296,8 +294,6 @@ public void onAttach(@NonNull Context context) { Log_OC.i(TAG, "onAttach"); try { mContainerActivity = (FileFragment.ContainerActivity) context; - setTitle(); - } catch (ClassCastException e) { throw new IllegalArgumentException(context.toString() + " must implement " + FileFragment.ContainerActivity.class.getSimpleName(), e); @@ -311,6 +307,26 @@ public void onAttach(@NonNull Context context) { } } + private void setSearchArgs(Bundle state) { + SearchType argSearchType = NO_SEARCH; + 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 (argSearchEvent != null) { + searchEvent = argSearchEvent; + } + + if (searchEvent != null && currentSearchType != NO_SEARCH) { + searchFragment = true; + } + } + /** * {@inheritDoc} */ @@ -319,21 +335,12 @@ 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(); + setSearchArgs(state); - if (savedInstanceState != null && - BundleExtensionsKt.getParcelableArgument(savedInstanceState, KEY_CURRENT_SEARCH_TYPE, SearchType.class) != null && - BundleExtensionsKt.getParcelableArgument(savedInstanceState, SEARCH_EVENT, SearchEvent.class) != null) { - 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); @@ -430,11 +437,8 @@ public void onActivityCreated(Bundle savedInstanceState) { }); } - setTitle(); - - FragmentActivity fragmentActivity; - if ((fragmentActivity = getActivity()) != null && fragmentActivity instanceof FileDisplayActivity fileDisplayActivity) { - fileDisplayActivity.updateActionBarTitleAndHomeButton(fileDisplayActivity.getCurrentDir()); + if (getActivity() instanceof FileDisplayActivity fda) { + fda.updateActionBarTitleAndHomeButton(fda.getCurrentDir()); } listDirectory(MainApp.isOnlyOnDevice(), false); } @@ -463,29 +467,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); } } @@ -976,122 +958,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); - 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() { @@ -1306,7 +1238,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); @@ -1314,13 +1250,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 && @@ -1533,8 +1462,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) { @@ -1764,29 +1699,19 @@ public OCFileListAdapter getAdapter() { return mAdapter; } - protected void setTitle() { - // set title - - 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; - } + public void setCurrentSearchType(SearchEvent event) { + final var searchType = event.toSearchType(); + if (searchType != null) { + currentSearchType = searchType; } + } + + public void setCurrentSearchType(SearchType searchType) { + currentSearchType = searchType; + } + public SearchType getCurrentSearchType() { + return currentSearchType; } protected void prepareActionBarItems(SearchEvent event) { @@ -1839,28 +1764,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(); - } - - setTitle(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); } if (mFile != null) { setFabVisible(mFile.canCreateFileAndFolder()); } + slideHideBottomBehaviourForBottomNavigationView(true); } @@ -1869,7 +1784,7 @@ private void resetMenuItems() { updateSortAndGridMenuItems(); } - private void resetSearchAttributes() { + public void resetSearchAttributes() { searchFragment = false; searchEvent = null; currentSearchType = NO_SEARCH; @@ -2117,34 +2032,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. - * - * @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) { - requireActivity().runOnUiThread(() -> { - if (getActivity() != null) { - final ActionBar actionBar = ((FileDisplayActivity) getActivity()).getSupportActionBar(); - final Context context = getContext(); - - if (actionBar != null && context != null) { - viewThemeUtils.files.themeActionBar(context, actionBar, title, showBackAsMenu); - } - } - }); - } - @Override public void onStart() { super.onStart(); 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..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 @@ -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,17 @@ 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 + } } @Parcelize 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() } } 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..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 @@ -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 = getPreviousMenuItemId() + setNavigationViewItemChecked() super.onPause() active = false trashbinListAdapter?.cancelAllPendingTasks()