diff --git a/app/src/main/java/com/infomaniak/drive/ui/LaunchActivity.kt b/app/src/main/java/com/infomaniak/drive/ui/LaunchActivity.kt index b8fe3b081f..5de6fb4af5 100644 --- a/app/src/main/java/com/infomaniak/drive/ui/LaunchActivity.kt +++ b/app/src/main/java/com/infomaniak/drive/ui/LaunchActivity.kt @@ -43,6 +43,7 @@ import com.infomaniak.drive.ui.publicShare.PublicShareListFragment.Companion.PUB import com.infomaniak.drive.utils.AccountUtils import com.infomaniak.drive.utils.Utils import com.infomaniak.drive.utils.Utils.ROOT_ID +import com.infomaniak.drive.utils.Utils.openDeepLinkInBrowser import com.infomaniak.lib.applock.LockActivity import com.infomaniak.lib.applock.Utils.isKeyguardSecure import com.infomaniak.lib.core.api.ApiController @@ -67,6 +68,7 @@ class LaunchActivity : AppCompatActivity() { private var mainActivityExtras: Bundle? = null private var publicShareActivityExtras: Bundle? = null private var isHelpShortcutPressed = false + private var shouldStartApp = true override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -82,7 +84,8 @@ class LaunchActivity : AppCompatActivity() { handleNotificationDestinationIntent() handleShortcuts() handleDeeplink() - startApp() + + if (shouldStartApp) startApp() // After starting the destination activity, we run finish to make sure we close the LaunchScreen, // so that even when we return, the activity will still be closed. @@ -165,7 +168,7 @@ class LaunchActivity : AppCompatActivity() { } } - private suspend fun handleDeeplink() = withContext(Dispatchers.IO) { + private suspend fun handleDeeplink() = Dispatchers.IO { intent.data?.path?.let { deeplink -> if (deeplink.contains("/app/share/")) processPublicShare(deeplink) else processInternalLink(deeplink) SentryLog.i(UploadWorker.BREADCRUMB_TAG, "DeepLink: $deeplink") @@ -207,8 +210,15 @@ class LaunchActivity : AppCompatActivity() { } private fun processInternalLink(path: String) { - Regex("/app/[a-z]+/(\\d+)/[a-z]*/?[a-z]*/?[a-z]*/?(\\d*)/?[a-z]*/?[a-z]*/?(\\d*)").find(path)?.let { match -> - val (pathDriveId, pathFolderId, pathFileId) = match.destructured + Regex("/app/[a-z]+/(\\d+)/([a-z-]*)/?[a-z]*/?[a-z]*/?(\\d*)/?[a-z]*/?[a-z]*/?(\\d*)").find(path)?.let { match -> + val (pathDriveId, roleFolderId, pathFolderId, pathFileId) = match.destructured + // In case of SharedWithMe deeplinks, we open the link in the web as we cannot support them in-app for now + if (roleFolderId == SHARED_WITH_ME_FOLDER_ROLE) { + openDeepLinkInBrowser(path) + shouldStartApp = false + return + } + val driveId = pathDriveId.toInt() val fileId = if (pathFileId.isEmpty()) pathFolderId.toIntOrNull() ?: ROOT_ID else pathFileId.toInt() @@ -269,5 +279,6 @@ class LaunchActivity : AppCompatActivity() { companion object { private const val SHORTCUTS_TAG = "shortcuts_tag" + private const val SHARED_WITH_ME_FOLDER_ROLE = "shared-with-me" } } diff --git a/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicSharePasswordFragment.kt b/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicSharePasswordFragment.kt index ba518fc92b..364b5057ef 100644 --- a/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicSharePasswordFragment.kt +++ b/app/src/main/java/com/infomaniak/drive/ui/publicShare/PublicSharePasswordFragment.kt @@ -17,10 +17,6 @@ */ package com.infomaniak.drive.ui.publicShare -import android.content.ActivityNotFoundException -import android.content.Context -import android.content.Intent -import android.net.Uri import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -34,11 +30,11 @@ import com.infomaniak.drive.data.models.ShareLink import com.infomaniak.drive.databinding.FragmentPublicSharePasswordBinding import com.infomaniak.drive.ui.publicShare.PublicShareActivity.Companion.PUBLIC_SHARE_TAG import com.infomaniak.drive.ui.publicShare.PublicShareListFragment.Companion.PUBLIC_SHARE_DEFAULT_ID +import com.infomaniak.drive.utils.Utils.openDeepLinkInBrowser import com.infomaniak.lib.core.api.ApiController import com.infomaniak.lib.core.models.ApiError import com.infomaniak.lib.core.utils.* import com.infomaniak.lib.core.utils.SnackbarUtils.showSnackbar -import com.infomaniak.lib.core.R as RCore class PublicSharePasswordFragment : Fragment() { @@ -54,7 +50,7 @@ class PublicSharePasswordFragment : Fragment() { // TODO: Remove this and call setupValidationButton instead // Also change the layout (description, button's title, input visibility) - passwordValidateButton.setOnClickListener { requireContext().openDeepLinkInBrowser(getPublicShareUrl()) } + passwordValidateButton.setOnClickListener { requireActivity().openDeepLinkInBrowser(getPublicShareUrl()) } publicSharePasswordEditText.addTextChangedListener { publicSharePasswordLayout.error = null } observeSubmitPasswordResult() @@ -65,22 +61,6 @@ class PublicSharePasswordFragment : Fragment() { private fun getPublicShareUrl(): String { return "${BuildConfig.SHARE_URL_V1}share/${publicShareViewModel.driveId}/${publicShareViewModel.publicShareUuid}" } - - private fun Context.openDeepLinkInBrowser(url: String) = runCatching { - Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, Intent.CATEGORY_APP_BROWSER).apply { - setData(Uri.parse(url)) - flags = Intent.FLAG_ACTIVITY_NO_HISTORY - }.also(::startActivity) - requireActivity().finishAndRemoveTask() - }.onFailure { exception -> - val errorMessage = if (exception is ActivityNotFoundException) { - RCore.string.browserNotFound - } else { - RCore.string.anErrorHasOccurred - } - - showToast(errorMessage) - } //endregion private fun setupValidationButton() = with(binding.passwordValidateButton) { diff --git a/app/src/main/java/com/infomaniak/drive/utils/Utils.kt b/app/src/main/java/com/infomaniak/drive/utils/Utils.kt index 656f4cb315..640c15be80 100644 --- a/app/src/main/java/com/infomaniak/drive/utils/Utils.kt +++ b/app/src/main/java/com/infomaniak/drive/utils/Utils.kt @@ -17,6 +17,7 @@ */ package com.infomaniak.drive.utils +import android.app.Activity import android.app.Dialog import android.content.ActivityNotFoundException import android.content.ComponentName @@ -67,11 +68,13 @@ import com.infomaniak.drive.ui.publicShare.PublicSharePreviewSliderFragmentArgs import com.infomaniak.drive.utils.SyncUtils.uploadFolder import com.infomaniak.drive.views.FileInfoActionsView.Companion.SINGLE_OPERATION_CUSTOM_TAG import com.infomaniak.lib.core.utils.DownloadManagerUtils +import com.infomaniak.lib.core.utils.SentryLog import com.infomaniak.lib.core.utils.showKeyboard import com.infomaniak.lib.core.utils.showToast import java.util.Date import kotlin.math.min import kotlin.math.pow +import com.infomaniak.lib.core.R as RCore object Utils { @@ -281,6 +284,24 @@ object Utils { }.also(selectFolderResultLauncher::launch) } + fun Activity.openDeepLinkInBrowser(url: String) = runCatching { + Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, Intent.CATEGORY_APP_BROWSER).apply { + setData(Uri.parse(url)) + flags = Intent.FLAG_ACTIVITY_NO_HISTORY + }.also(::startActivity) + + finishAndRemoveTask() + }.onFailure { exception -> + exception.printStackTrace() + SentryLog.d("OpenDeepLinkInBrowser", exception.message.toString(), exception) + val errorMessage = if (exception is ActivityNotFoundException) { + RCore.string.browserNotFound + } else { + RCore.string.anErrorHasOccurred + } + showToast(errorMessage) + } + fun Context.openWith(uri: Uri, type: String?, flags: Int) { startActivityFor(openWithIntentExceptkDrive(uri, type, flags)) }