From 285dda50e2e1eabf1d7b73b792a981a0b7a6483f Mon Sep 17 00:00:00 2001 From: daniele-verducci Date: Mon, 9 Nov 2026 17:36:57 +0100 Subject: [PATCH 1/7] External storage repository Signed-off-by: daniele-verducci --- .../java/com/nextcloud/client/di/AppModule.kt | 6 ++++ .../repository/ExternalStorageMountsResult.kt | 16 ++++++++++ .../repository/ExternalStorageRepository.kt | 12 +++++++ .../RemoteExternalStorageRepository.kt | 32 +++++++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 app/src/main/java/com/nextcloud/repository/ExternalStorageMountsResult.kt create mode 100644 app/src/main/java/com/nextcloud/repository/ExternalStorageRepository.kt create mode 100644 app/src/main/java/com/nextcloud/repository/RemoteExternalStorageRepository.kt diff --git a/app/src/main/java/com/nextcloud/client/di/AppModule.kt b/app/src/main/java/com/nextcloud/client/di/AppModule.kt index 8154074c608d..f19c26703c23 100644 --- a/app/src/main/java/com/nextcloud/client/di/AppModule.kt +++ b/app/src/main/java/com/nextcloud/client/di/AppModule.kt @@ -43,7 +43,9 @@ import com.nextcloud.client.notifications.AppNotificationManager import com.nextcloud.client.notifications.AppNotificationManagerImpl import com.nextcloud.client.preferences.AppPreferences import com.nextcloud.repository.ClientRepository +import com.nextcloud.repository.ExternalStorageRepository import com.nextcloud.repository.RemoteClientRepository +import com.nextcloud.repository.RemoteExternalStorageRepository import com.nextcloud.utils.e2ee.E2EEActionResolver import com.nextcloud.utils.e2ee.E2EEKeyInspector import com.nextcloud.utils.thumbnail.FolderThumbnailGenerator @@ -119,6 +121,10 @@ internal class AppModule { @Provides fun clientRepository(repository: RemoteClientRepository): ClientRepository = repository + @Provides + fun externalStorageRepository(repository: RemoteExternalStorageRepository): ExternalStorageRepository = + repository + @Provides fun fileUploadHelper(): FileUploadHelper = FileUploadHelper.instance() diff --git a/app/src/main/java/com/nextcloud/repository/ExternalStorageMountsResult.kt b/app/src/main/java/com/nextcloud/repository/ExternalStorageMountsResult.kt new file mode 100644 index 000000000000..4f0dc928a965 --- /dev/null +++ b/app/src/main/java/com/nextcloud/repository/ExternalStorageMountsResult.kt @@ -0,0 +1,16 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.nextcloud.repository + +import com.nextcloud.android.lib.resources.externalstorage.model.ExternalStorageMount + +sealed interface ExternalStorageMountsResult { + data class Success(val mounts: List) : ExternalStorageMountsResult + + data object Failure : ExternalStorageMountsResult +} diff --git a/app/src/main/java/com/nextcloud/repository/ExternalStorageRepository.kt b/app/src/main/java/com/nextcloud/repository/ExternalStorageRepository.kt new file mode 100644 index 000000000000..9b83e604c240 --- /dev/null +++ b/app/src/main/java/com/nextcloud/repository/ExternalStorageRepository.kt @@ -0,0 +1,12 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.nextcloud.repository + +interface ExternalStorageRepository { + suspend fun fetchMounts(): ExternalStorageMountsResult +} diff --git a/app/src/main/java/com/nextcloud/repository/RemoteExternalStorageRepository.kt b/app/src/main/java/com/nextcloud/repository/RemoteExternalStorageRepository.kt new file mode 100644 index 000000000000..42ff4bef5134 --- /dev/null +++ b/app/src/main/java/com/nextcloud/repository/RemoteExternalStorageRepository.kt @@ -0,0 +1,32 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.nextcloud.repository + +import com.nextcloud.android.lib.resources.externalstorage.ExternalStorageListMountsRemoteOperation +import com.owncloud.android.lib.common.utils.Log_OC +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import javax.inject.Inject + +class RemoteExternalStorageRepository @Inject constructor(private val clientRepository: ClientRepository) : + ExternalStorageRepository { + + override suspend fun fetchMounts(): ExternalStorageMountsResult { + val client = clientRepository.getNextcloudClient() ?: return ExternalStorageMountsResult.Failure + val result = withContext(Dispatchers.IO) { ExternalStorageListMountsRemoteOperation().execute(client) } + if (!result.isSuccess) { + Log_OC.e(TAG, "Could not fetch external storage mounts") + return ExternalStorageMountsResult.Failure + } + return ExternalStorageMountsResult.Success(result.resultData.orEmpty()) + } + + companion object { + private const val TAG = "ExternalStorageRepository" + } +} From 7688862911f087a8f3f624b337c94ee6d621f5cc Mon Sep 17 00:00:00 2001 From: daniele-verducci Date: Mon, 9 Nov 2026 17:53:02 +0100 Subject: [PATCH 2/7] Test log external folders Signed-off-by: daniele-verducci --- .../ui/activity/FileDisplayActivity.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) 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 d3ae4fa89eee..2ed009c619a5 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 @@ -67,6 +67,8 @@ import com.nextcloud.client.player.model.file.toPlaybackCollection import com.nextcloud.client.player.ui.audio.AudioPlayerLauncher import com.nextcloud.client.preferences.AppPreferences import com.nextcloud.client.utils.IntentUtil +import com.nextcloud.repository.ExternalStorageMountsResult +import com.nextcloud.repository.ExternalStorageRepository import com.nextcloud.ui.composeActivity.ComposeProcessTextAlias import com.nextcloud.utils.SnackbarUtil import com.nextcloud.utils.extensions.getParcelableArgument @@ -84,6 +86,7 @@ import com.owncloud.android.datamodel.FileDataStorageManager import com.owncloud.android.datamodel.OCFile import com.owncloud.android.datamodel.SyncedFolderProvider import com.owncloud.android.datamodel.VirtualFolderType +import com.owncloud.android.lib.common.network.WebdavEntry import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC @@ -208,6 +211,9 @@ class FileDisplayActivity : @Inject lateinit var viewModelFactory: ViewModelFactory + @Inject + lateinit var externalStorageRepository: ExternalStorageRepository + private val viewModel by viewModels { viewModelFactory } private lateinit var binding: FilesBinding @@ -1088,6 +1094,20 @@ class FileDisplayActivity : resetScrollingAndUpdateActionBar() startSyncFolderOperation(directory, ignoreETag = false, syncChangedDownloadedFiles = true) startMetadataSyncForCurrentDir() + fetchExternalStorageMountsIfNeeded(directory) + } + + private fun fetchExternalStorageMountsIfNeeded(directory: OCFile?) { + if (WebdavEntry.MountType.EXTERNAL != directory?.mountType) return + + lifecycleScope.launch { + when (val result = externalStorageRepository.fetchMounts()) { + is ExternalStorageMountsResult.Success -> + Log_OC.d(TAG, "Fetched ${result.mounts.size} external storage mounts: ${result.mounts}") + + ExternalStorageMountsResult.Failure -> Log_OC.w(TAG, "Could not fetch external storage mounts") + } + } } private fun browseUp(listOfFiles: OCFileListFragment) { From 8313304912c00ec13e498276aedf7f0e7bc70bab Mon Sep 17 00:00:00 2001 From: daniele-verducci Date: Tue, 10 Nov 2026 09:43:24 +0100 Subject: [PATCH 3/7] Check external storage auth before opening folder Signed-off-by: daniele-verducci --- .../ExternalStorageMountExtension.kt | 16 ++++++++ .../ui/activity/FileDisplayActivity.kt | 39 +++++++++++++------ 2 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/utils/extensions/ExternalStorageMountExtension.kt diff --git a/app/src/main/java/com/nextcloud/utils/extensions/ExternalStorageMountExtension.kt b/app/src/main/java/com/nextcloud/utils/extensions/ExternalStorageMountExtension.kt new file mode 100644 index 000000000000..5e6ae2c60547 --- /dev/null +++ b/app/src/main/java/com/nextcloud/utils/extensions/ExternalStorageMountExtension.kt @@ -0,0 +1,16 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.nextcloud.utils.extensions + +import com.nextcloud.android.lib.resources.externalstorage.model.ExternalStorageMount +import com.owncloud.android.datamodel.OCFile + +fun ExternalStorageMount.remotePath(): String { + val segments = listOf(path.trim(OCFile.PATH_SEPARATOR[0]), name).filter { it.isNotEmpty() } + return segments.joinToString(OCFile.PATH_SEPARATOR, OCFile.PATH_SEPARATOR, OCFile.PATH_SEPARATOR) +} \ No newline at end of file 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 2ed009c619a5..da13423ccf82 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 @@ -52,6 +52,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager import com.google.android.material.appbar.AppBarLayout import com.google.android.material.snackbar.Snackbar import com.nextcloud.android.common.core.utils.ecosystem.AccountReceiverCallback +import com.nextcloud.android.lib.resources.externalstorage.model.AuthMechanism import com.nextcloud.appReview.InAppReviewHelper import com.nextcloud.client.account.User import com.nextcloud.client.core.AsyncRunner @@ -76,6 +77,7 @@ import com.nextcloud.utils.extensions.getSerializableArgument import com.nextcloud.utils.extensions.isActive import com.nextcloud.utils.extensions.lastFragment import com.nextcloud.utils.extensions.navigateToAllFiles +import com.nextcloud.utils.extensions.remotePath import com.nextcloud.utils.extensions.setVisibleIf import com.nextcloud.utils.view.FastScrollUtils import com.owncloud.android.MainApp @@ -1090,23 +1092,38 @@ class FileDisplayActivity : } override fun onBrowsedDownTo(directory: OCFile?) { + if (WebdavEntry.MountType.EXTERNAL != directory?.mountType) { + browseDownTo(directory) + return + } + + lifecycleScope.launch { + val showCredentialsDialog = directory.requiresUserProvidedCredentials() + if (showCredentialsDialog ?: false) { + TODO("Show credentials dialog") + return@launch + } + browseDownTo(directory) + } + } + + private fun browseDownTo(directory: OCFile?) { file = directory resetScrollingAndUpdateActionBar() startSyncFolderOperation(directory, ignoreETag = false, syncChangedDownloadedFiles = true) startMetadataSyncForCurrentDir() - fetchExternalStorageMountsIfNeeded(directory) } - private fun fetchExternalStorageMountsIfNeeded(directory: OCFile?) { - if (WebdavEntry.MountType.EXTERNAL != directory?.mountType) return - - lifecycleScope.launch { - when (val result = externalStorageRepository.fetchMounts()) { - is ExternalStorageMountsResult.Success -> - Log_OC.d(TAG, "Fetched ${result.mounts.size} external storage mounts: ${result.mounts}") - - ExternalStorageMountsResult.Failure -> Log_OC.w(TAG, "Could not fetch external storage mounts") - } + private suspend fun OCFile.requiresUserProvidedCredentials(): Boolean? { + val result = externalStorageRepository.fetchMounts() + if (result !is ExternalStorageMountsResult.Success) { + Log_OC.w(TAG, "Could not fetch external storage mounts to determine if ${this.fileName} requires" + + " user provided credentials.") + return null + } + return result.mounts.any { + it.remotePath() == remotePath && + it.config?.authMechanism == AuthMechanism.PasswordUserProvided } } From ce831562c515127f3a323b8da210fa304dac6e9b Mon Sep 17 00:00:00 2001 From: daniele-verducci Date: Thu, 12 Nov 2026 17:58:55 +0100 Subject: [PATCH 4/7] Moved check to right path (after folder open failure) Signed-off-by: daniele-verducci --- .../ui/activity/FileDisplayActivity.kt | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 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 da13423ccf82..9592411dc6d3 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 @@ -1092,22 +1092,6 @@ class FileDisplayActivity : } override fun onBrowsedDownTo(directory: OCFile?) { - if (WebdavEntry.MountType.EXTERNAL != directory?.mountType) { - browseDownTo(directory) - return - } - - lifecycleScope.launch { - val showCredentialsDialog = directory.requiresUserProvidedCredentials() - if (showCredentialsDialog ?: false) { - TODO("Show credentials dialog") - return@launch - } - browseDownTo(directory) - } - } - - private fun browseDownTo(directory: OCFile?) { file = directory resetScrollingAndUpdateActionBar() startSyncFolderOperation(directory, ignoreETag = false, syncChangedDownloadedFiles = true) @@ -1573,7 +1557,19 @@ class FileDisplayActivity : ).execute( account, this, - { _, _ -> onSyncFinished() }, + { _, result -> + if (!result.isSuccess && WebdavEntry.MountType.EXTERNAL == folder.mountType) { + // May be an external folder: check if user needs authentication + lifecycleScope.launch { + val showCredentialsDialog = folder.requiresUserProvidedCredentials() + if (showCredentialsDialog ?: false) { + TODO("Show credentials dialog") + } + } + } else { + onSyncFinished() + } + }, handler, null ) From 0179a1f1c298623896d3188e91b8a7c57e4343fe Mon Sep 17 00:00:00 2001 From: daniele-verducci Date: Thu, 12 Nov 2026 18:30:46 +0100 Subject: [PATCH 5/7] Implemented external storage credentials dialog Signed-off-by: daniele-verducci --- .../ExternalStorageAuthDialogFragment.kt | 102 ++++++++++++++++++ .../layout/external_storage_auth_dialog.xml | 45 ++++++++ app/src/main/res/values/strings.xml | 2 + 3 files changed, 149 insertions(+) create mode 100644 app/src/main/java/com/owncloud/android/ui/dialog/ExternalStorageAuthDialogFragment.kt create mode 100644 app/src/main/res/layout/external_storage_auth_dialog.xml diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/ExternalStorageAuthDialogFragment.kt b/app/src/main/java/com/owncloud/android/ui/dialog/ExternalStorageAuthDialogFragment.kt new file mode 100644 index 000000000000..0d787f57adad --- /dev/null +++ b/app/src/main/java/com/owncloud/android/ui/dialog/ExternalStorageAuthDialogFragment.kt @@ -0,0 +1,102 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.owncloud.android.ui.dialog + +import android.app.Dialog +import android.os.Bundle +import androidx.appcompat.app.AlertDialog +import androidx.core.os.bundleOf +import androidx.core.widget.doAfterTextChanged +import androidx.fragment.app.DialogFragment +import com.google.android.material.button.MaterialButton +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.nextcloud.client.di.Injectable +import com.nextcloud.utils.extensions.getParcelableArgument +import com.owncloud.android.R +import com.owncloud.android.databinding.ExternalStorageAuthDialogBinding +import com.owncloud.android.datamodel.OCFile +import com.owncloud.android.utils.theme.ViewThemeUtils +import javax.inject.Inject + +class ExternalStorageAuthDialogFragment : + DialogFragment(), + Injectable { + + @Inject + lateinit var viewThemeUtils: ViewThemeUtils + + private lateinit var binding: ExternalStorageAuthDialogBinding + + private var positiveButton: MaterialButton? = null + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val folder = requireArguments().getParcelableArgument(ARG_FOLDER, OCFile::class.java) + + binding = ExternalStorageAuthDialogBinding.inflate(requireActivity().layoutInflater, null, false) + viewThemeUtils.material.colorTextInputLayout(binding.usernameContainer) + viewThemeUtils.material.colorTextInputLayout(binding.passwordContainer) + binding.username.doAfterTextChanged { updatePositiveButtonState() } + binding.password.doAfterTextChanged { updatePositiveButtonState() } + + val builder = MaterialAlertDialogBuilder(requireActivity()) + .setView(binding.root) + .setTitle(R.string.external_storage_auth_dialog_title) + .setMessage(getString(R.string.external_storage_auth_dialog_message, folder?.fileName)) + .setPositiveButton(R.string.login) { _, _ -> sendCredentials(folder) } + .setNegativeButton(R.string.common_cancel, null) + + viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.root.context, builder) + return builder.create() + } + + override fun onStart() { + super.onStart() + themeButtons() + updatePositiveButtonState() + } + + private fun themeButtons() { + val dialog = dialog as? AlertDialog ?: return + + positiveButton = (dialog.getButton(AlertDialog.BUTTON_POSITIVE) as? MaterialButton)?.also { + viewThemeUtils.material.colorMaterialButtonPrimaryTonal(it) + } + (dialog.getButton(AlertDialog.BUTTON_NEGATIVE) as? MaterialButton)?.let { + viewThemeUtils.material.colorMaterialButtonPrimaryBorderless(it) + } + } + + private fun updatePositiveButtonState() { + positiveButton?.isEnabled = !binding.username.text.isNullOrEmpty() && !binding.password.text.isNullOrEmpty() + } + + private fun sendCredentials(folder: OCFile?) { + val result = bundleOf( + RESULT_FOLDER to folder, + RESULT_USERNAME to binding.username.text.toString(), + RESULT_PASSWORD to binding.password.text.toString() + ) + parentFragmentManager.setFragmentResult(REQUEST_KEY, result) + } + + companion object { + const val TAG = "ExternalStorageAuthDialogFragment" + const val REQUEST_KEY = "EXTERNAL_STORAGE_AUTH_REQUEST" + const val RESULT_FOLDER = "FOLDER" + const val RESULT_USERNAME = "USERNAME" + const val RESULT_PASSWORD = "PASSWORD" + + private const val ARG_FOLDER = "FOLDER" + + @JvmStatic + fun newInstance(folder: OCFile): ExternalStorageAuthDialogFragment = + ExternalStorageAuthDialogFragment().apply { + arguments = bundleOf(ARG_FOLDER to folder) + } + } +} diff --git a/app/src/main/res/layout/external_storage_auth_dialog.xml b/app/src/main/res/layout/external_storage_auth_dialog.xml new file mode 100644 index 000000000000..810c8ad3ff85 --- /dev/null +++ b/app/src/main/res/layout/external_storage_auth_dialog.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f3d6f60bf3e1..716282c6fa18 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1185,6 +1185,8 @@ Choose storage location Internal storage External storage + Log in to external storage + Enter your credentials to access %1$s Camera Pictures Movies From 7aae1eccd951c1f79a80b7c852bf60c340d832c0 Mon Sep 17 00:00:00 2001 From: daniele-verducci Date: Thu, 12 Nov 2026 18:40:25 +0100 Subject: [PATCH 6/7] Show fragment Signed-off-by: daniele-verducci --- .../android/ui/activity/FileDisplayActivity.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 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 9592411dc6d3..38b8d97b3011 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 @@ -88,7 +88,6 @@ import com.owncloud.android.datamodel.FileDataStorageManager import com.owncloud.android.datamodel.OCFile import com.owncloud.android.datamodel.SyncedFolderProvider import com.owncloud.android.datamodel.VirtualFolderType -import com.owncloud.android.lib.common.network.WebdavEntry import com.owncloud.android.lib.common.operations.RemoteOperation import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC @@ -120,6 +119,7 @@ import com.owncloud.android.ui.activity.filedisplayactivity.LocalIntentReceiver import com.owncloud.android.ui.asynctasks.FetchRemoteFileTask import com.owncloud.android.ui.asynctasks.GetRemoteFileTask import com.owncloud.android.ui.dialog.DeleteBatchTracker +import com.owncloud.android.ui.dialog.ExternalStorageAuthDialogFragment import com.owncloud.android.ui.dialog.SendShareDialog.SendShareDialogDownloader import com.owncloud.android.ui.dialog.SortingOrderDialogFragment.OnSortingOrderListener import com.owncloud.android.ui.dialog.StoragePermissionDialogFragment @@ -1558,12 +1558,12 @@ class FileDisplayActivity : account, this, { _, result -> - if (!result.isSuccess && WebdavEntry.MountType.EXTERNAL == folder.mountType) { + if (!result.isSuccess /*&& WebdavEntry.MountType.EXTERNAL == folder.mountType*/) { // May be an external folder: check if user needs authentication lifecycleScope.launch { val showCredentialsDialog = folder.requiresUserProvidedCredentials() if (showCredentialsDialog ?: false) { - TODO("Show credentials dialog") + showExternalStorageAuthDialog(folder) } } } else { @@ -1577,6 +1577,14 @@ class FileDisplayActivity : fetchRecommendedFilesIfNeeded(ignoreETag, folder) } + private fun showExternalStorageAuthDialog(folder: OCFile) { + if (supportFragmentManager.isStateSaved) return + if (supportFragmentManager.findFragmentByTag(ExternalStorageAuthDialogFragment.TAG) != null) return + + ExternalStorageAuthDialogFragment.newInstance(folder) + .show(supportFragmentManager, ExternalStorageAuthDialogFragment.TAG) + } + private fun syncCurrentFolder(ignoreETag: Boolean, ignoreFocus: Boolean) { val listOfFiles = listOfFilesFragment ?: return if (listOfFiles.isSearchFragment) return From c9e053820e4a78122235a54834ab12dfd4217eca Mon Sep 17 00:00:00 2001 From: daniele-verducci Date: Fri, 13 Nov 2026 08:26:05 +0100 Subject: [PATCH 7/7] Dialog DI + spotless Signed-off-by: daniele-verducci --- app/src/main/java/com/nextcloud/client/di/AppModule.kt | 3 +-- .../java/com/nextcloud/client/di/ComponentsModule.kt | 4 ++++ .../utils/extensions/ExternalStorageMountExtension.kt | 2 +- .../owncloud/android/ui/activity/FileDisplayActivity.kt | 9 ++++++--- .../ui/dialog/ExternalStorageAuthDialogFragment.kt | 7 +++---- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/di/AppModule.kt b/app/src/main/java/com/nextcloud/client/di/AppModule.kt index f19c26703c23..ec026265437b 100644 --- a/app/src/main/java/com/nextcloud/client/di/AppModule.kt +++ b/app/src/main/java/com/nextcloud/client/di/AppModule.kt @@ -122,8 +122,7 @@ internal class AppModule { fun clientRepository(repository: RemoteClientRepository): ClientRepository = repository @Provides - fun externalStorageRepository(repository: RemoteExternalStorageRepository): ExternalStorageRepository = - repository + fun externalStorageRepository(repository: RemoteExternalStorageRepository): ExternalStorageRepository = repository @Provides fun fileUploadHelper(): FileUploadHelper = FileUploadHelper.instance() diff --git a/app/src/main/java/com/nextcloud/client/di/ComponentsModule.kt b/app/src/main/java/com/nextcloud/client/di/ComponentsModule.kt index 745696d45571..9277f101f501 100644 --- a/app/src/main/java/com/nextcloud/client/di/ComponentsModule.kt +++ b/app/src/main/java/com/nextcloud/client/di/ComponentsModule.kt @@ -84,6 +84,7 @@ import com.owncloud.android.ui.dialog.ConfirmationDialogFragment import com.owncloud.android.ui.dialog.CreateAlbumDialogFragment import com.owncloud.android.ui.dialog.CreateFolderDialogFragment import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment +import com.owncloud.android.ui.dialog.ExternalStorageAuthDialogFragment import com.owncloud.android.ui.dialog.IndeterminateProgressDialog import com.owncloud.android.ui.dialog.LoadingDialog import com.owncloud.android.ui.dialog.LocalStoragePathPickerDialogFragment @@ -529,4 +530,7 @@ internal interface ComponentsModule { @ContributesAndroidInjector fun albumSharingBottomSheet(): AlbumSharingBottomSheet + + @ContributesAndroidInjector + fun externalStorageAuthDialogFragment(): ExternalStorageAuthDialogFragment } diff --git a/app/src/main/java/com/nextcloud/utils/extensions/ExternalStorageMountExtension.kt b/app/src/main/java/com/nextcloud/utils/extensions/ExternalStorageMountExtension.kt index 5e6ae2c60547..6505d65e740f 100644 --- a/app/src/main/java/com/nextcloud/utils/extensions/ExternalStorageMountExtension.kt +++ b/app/src/main/java/com/nextcloud/utils/extensions/ExternalStorageMountExtension.kt @@ -13,4 +13,4 @@ import com.owncloud.android.datamodel.OCFile fun ExternalStorageMount.remotePath(): String { val segments = listOf(path.trim(OCFile.PATH_SEPARATOR[0]), name).filter { it.isNotEmpty() } return segments.joinToString(OCFile.PATH_SEPARATOR, OCFile.PATH_SEPARATOR, OCFile.PATH_SEPARATOR) -} \ No newline at end of file +} 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 38b8d97b3011..eb38a49d386e 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 @@ -1101,8 +1101,11 @@ class FileDisplayActivity : private suspend fun OCFile.requiresUserProvidedCredentials(): Boolean? { val result = externalStorageRepository.fetchMounts() if (result !is ExternalStorageMountsResult.Success) { - Log_OC.w(TAG, "Could not fetch external storage mounts to determine if ${this.fileName} requires" + - " user provided credentials.") + Log_OC.w( + TAG, + "Could not fetch external storage mounts to determine if ${this.fileName} requires" + + " user provided credentials." + ) return null } return result.mounts.any { @@ -1558,7 +1561,7 @@ class FileDisplayActivity : account, this, { _, result -> - if (!result.isSuccess /*&& WebdavEntry.MountType.EXTERNAL == folder.mountType*/) { + if (!result.isSuccess && WebdavEntry.MountType.EXTERNAL == folder.mountType) { // May be an external folder: check if user needs authentication lifecycleScope.launch { val showCredentialsDialog = folder.requiresUserProvidedCredentials() diff --git a/app/src/main/java/com/owncloud/android/ui/dialog/ExternalStorageAuthDialogFragment.kt b/app/src/main/java/com/owncloud/android/ui/dialog/ExternalStorageAuthDialogFragment.kt index 0d787f57adad..bf570629ad8f 100644 --- a/app/src/main/java/com/owncloud/android/ui/dialog/ExternalStorageAuthDialogFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/dialog/ExternalStorageAuthDialogFragment.kt @@ -94,9 +94,8 @@ class ExternalStorageAuthDialogFragment : private const val ARG_FOLDER = "FOLDER" @JvmStatic - fun newInstance(folder: OCFile): ExternalStorageAuthDialogFragment = - ExternalStorageAuthDialogFragment().apply { - arguments = bundleOf(ARG_FOLDER to folder) - } + fun newInstance(folder: OCFile): ExternalStorageAuthDialogFragment = ExternalStorageAuthDialogFragment().apply { + arguments = bundleOf(ARG_FOLDER to folder) + } } }