mirror of
https://github.com/ProtonMail/protoncore_android.git
synced 2026-05-15 09:50:41 +00:00
refactor: The presentation module does not depend on network* modules.
The following elements have been moved from `presentation` to `network-presentation`: `ProtonWebViewActivity`, `ProtonWebViewClient`, `Throwable.getUserMessage`.
This commit is contained in:
+1
-1
@@ -32,7 +32,7 @@ import me.proton.core.compose.theme.ProtonTheme
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.presentation.ui.ProtonActivity
|
||||
import me.proton.core.presentation.utils.errorToast
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.successToast
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ import me.proton.core.compose.theme.ProtonTheme
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.presentation.ui.ProtonActivity
|
||||
import me.proton.core.presentation.utils.errorToast
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.openBrowserLink
|
||||
import me.proton.core.presentation.utils.successToast
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ dependencies {
|
||||
project(Module.humanVerificationPresentation),
|
||||
project(Module.networkData),
|
||||
project(Module.networkDomain),
|
||||
project(Module.networkPresentation),
|
||||
project(Module.observabilityDomain),
|
||||
project(Module.paymentDomain),
|
||||
project(Module.paymentPresentation),
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ import me.proton.core.auth.presentation.viewmodel.ChooseAddressViewModel
|
||||
import me.proton.core.auth.presentation.viewmodel.ChooseAddressViewModel.State
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.observability.domain.metrics.LoginScreenViewTotal
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.presentation.ui.ProtonFragment
|
||||
import me.proton.core.presentation.utils.SnackbarLength
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.presentation.utils.openBrowserLink
|
||||
import me.proton.core.presentation.utils.viewBinding
|
||||
|
||||
+1
-2
@@ -30,7 +30,6 @@ import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -44,7 +43,7 @@ import me.proton.core.auth.presentation.entity.NextStep
|
||||
import me.proton.core.auth.presentation.viewmodel.LoginViewModel
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.presentation.utils.addOnBackPressedCallback
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.normToast
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
|
||||
+4
-4
@@ -54,11 +54,11 @@ import me.proton.core.network.data.di.BaseProtonApiUrl
|
||||
import me.proton.core.network.domain.NetworkPrefs
|
||||
import me.proton.core.network.domain.client.ExtraHeaderProvider
|
||||
import me.proton.core.network.domain.session.SessionProvider
|
||||
import me.proton.core.network.presentation.ui.ProtonWebViewActivity
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.observability.domain.metrics.LoginScreenViewTotal
|
||||
import me.proton.core.presentation.ui.ProtonWebViewActivity
|
||||
import me.proton.core.presentation.ui.ProtonWebViewActivity.Companion.ResultContract
|
||||
import me.proton.core.presentation.ui.ProtonWebViewActivity.Result
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.ui.ProtonWebViewActivity.Companion.ResultContract
|
||||
import me.proton.core.network.presentation.ui.ProtonWebViewActivity.Result
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
|
||||
+1
-1
@@ -49,10 +49,10 @@ import me.proton.core.auth.presentation.entity.TwoFAMechanisms
|
||||
import me.proton.core.auth.presentation.util.setTextWithAnnotatedLink
|
||||
import me.proton.core.auth.presentation.viewmodel.SecondFactorViewModel
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.observability.domain.metrics.LoginScreenViewTotal
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.errorToast
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ import me.proton.core.auth.presentation.entity.TwoPassModeInput
|
||||
import me.proton.core.auth.presentation.entity.TwoPassModeResult
|
||||
import me.proton.core.auth.presentation.viewmodel.TwoPassModeViewModel
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.presentation.utils.onFailure
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ import me.proton.core.auth.presentation.viewmodel.signup.ChooseExternalEmailView
|
||||
import me.proton.core.auth.presentation.viewmodel.signup.ChooseExternalEmailViewModel.State
|
||||
import me.proton.core.auth.presentation.viewmodel.signup.SignupViewModel
|
||||
import me.proton.core.observability.domain.metrics.SignupScreenViewTotalV1
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ import me.proton.core.auth.presentation.viewmodel.signup.ChooseInternalEmailView
|
||||
import me.proton.core.auth.presentation.viewmodel.signup.ChooseUsernameViewModel
|
||||
import me.proton.core.auth.presentation.viewmodel.signup.SignupViewModel
|
||||
import me.proton.core.observability.domain.metrics.SignupScreenViewTotalV1
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ import me.proton.core.auth.presentation.viewmodel.signup.ChooseUsernameViewModel
|
||||
import me.proton.core.auth.presentation.viewmodel.signup.ChooseUsernameViewModel.State
|
||||
import me.proton.core.auth.presentation.viewmodel.signup.SignupViewModel
|
||||
import me.proton.core.observability.domain.metrics.SignupScreenViewTotalV1
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ import me.proton.core.auth.presentation.viewmodel.signup.TermsConditionsViewMode
|
||||
import me.proton.core.network.domain.NetworkPrefs
|
||||
import me.proton.core.network.domain.client.ExtraHeaderProvider
|
||||
import me.proton.core.presentation.ui.ProtonDialogFragment
|
||||
import me.proton.core.presentation.ui.webview.ProtonWebViewClient
|
||||
import me.proton.core.network.presentation.ui.webview.ProtonWebViewClient
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.viewBinding
|
||||
import javax.inject.Inject
|
||||
|
||||
+1
-2
@@ -32,12 +32,11 @@ import me.proton.core.account.domain.entity.AccountType
|
||||
import me.proton.core.auth.presentation.R
|
||||
import me.proton.core.auth.presentation.databinding.FragmentSignupRecoveryBinding
|
||||
import me.proton.core.auth.presentation.entity.signup.RecoveryMethodType
|
||||
import me.proton.core.auth.presentation.util.setTextWithAnnotatedLink
|
||||
import me.proton.core.auth.presentation.viewmodel.signup.RecoveryMethodViewModel
|
||||
import me.proton.core.auth.presentation.viewmodel.signup.SignupViewModel
|
||||
import me.proton.core.observability.domain.metrics.SignupScreenViewTotalV1
|
||||
import me.proton.core.presentation.ui.alert.FragmentDialogResultLauncher
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ import me.proton.core.plan.presentation.ui.BasePlansFragment.Companion.KEY_PLAN_
|
||||
import me.proton.core.plan.presentation.ui.hasPlanSignupFragment
|
||||
import me.proton.core.plan.presentation.ui.removePlansSignup
|
||||
import me.proton.core.plan.presentation.ui.showPlansSignup
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.telemetry.domain.entity.TelemetryPriority
|
||||
import me.proton.core.telemetry.presentation.ProductMetricsDelegate
|
||||
import me.proton.core.telemetry.presentation.UiComponentProductMetricsDelegateOwner
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ import me.proton.core.auth.presentation.viewmodel.signup.TermsConditionsViewMode
|
||||
import me.proton.core.network.domain.NetworkPrefs
|
||||
import me.proton.core.network.domain.client.ExtraHeaderProvider
|
||||
import me.proton.core.presentation.ui.ProtonDialogFragment
|
||||
import me.proton.core.presentation.ui.webview.ProtonWebViewClient
|
||||
import me.proton.core.network.presentation.ui.webview.ProtonWebViewClient
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.viewBinding
|
||||
import javax.inject.Inject
|
||||
|
||||
+1
-1
@@ -30,12 +30,12 @@ import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import me.proton.core.auth.domain.usecase.AccountAvailability
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.observability.domain.ObservabilityContext
|
||||
import me.proton.core.observability.domain.ObservabilityManager
|
||||
import me.proton.core.observability.domain.metrics.SignupEmailAvailabilityTotal
|
||||
import me.proton.core.observability.domain.metrics.SignupFetchDomainsTotal
|
||||
import me.proton.core.presentation.savedstate.flowState
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.presentation.viewmodel.ProtonViewModel
|
||||
import me.proton.core.util.kotlin.coroutine.launchWithResultContext
|
||||
import javax.inject.Inject
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ import me.proton.core.network.domain.scopes.MissingScopeListener
|
||||
import me.proton.core.network.domain.scopes.Scope
|
||||
import me.proton.core.network.domain.session.SessionId
|
||||
import me.proton.core.observability.domain.ObservabilityManager
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.test.android.ArchTest
|
||||
import me.proton.core.test.kotlin.CoroutinesTest
|
||||
import me.proton.core.test.kotlin.assertIs
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ import me.proton.core.observability.domain.metrics.ObservabilityData
|
||||
import me.proton.core.observability.domain.metrics.SignupLoginTotal
|
||||
import me.proton.core.observability.domain.metrics.SignupUnlockUserTotalV1
|
||||
import me.proton.core.observability.domain.metrics.SignupUserCheckTotalV1
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.telemetry.domain.TelemetryManager
|
||||
import me.proton.core.telemetry.domain.entity.TelemetryEvent
|
||||
import me.proton.core.test.android.ArchTest
|
||||
|
||||
@@ -49,6 +49,7 @@ dependencies {
|
||||
project(Module.humanVerificationDomain),
|
||||
project(Module.observabilityDomain),
|
||||
project(Module.networkDomain),
|
||||
project(Module.networkPresentation),
|
||||
project(Module.presentation),
|
||||
project(Module.userSettingsDomain),
|
||||
project(Module.telemetryPresentation),
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import me.proton.core.humanverification.presentation.LogTag
|
||||
import me.proton.core.humanverification.presentation.LogTag.HV_REQUEST_ERROR
|
||||
import me.proton.core.network.domain.NetworkPrefs
|
||||
import me.proton.core.network.domain.client.ExtraHeaderProvider
|
||||
import me.proton.core.presentation.ui.webview.ProtonWebViewClient
|
||||
import me.proton.core.network.presentation.ui.webview.ProtonWebViewClient
|
||||
import me.proton.core.util.kotlin.CoreLogger
|
||||
import me.proton.core.util.kotlin.annotation.ExcludeFromCoverage
|
||||
import me.proton.core.util.kotlin.takeIfNotBlank
|
||||
|
||||
@@ -22,6 +22,7 @@ import studio.forface.easygradle.dsl.android.*
|
||||
plugins {
|
||||
protonAndroidLibrary
|
||||
protonDagger
|
||||
id("kotlin-parcelize")
|
||||
}
|
||||
|
||||
protonCoverage {
|
||||
@@ -46,6 +47,7 @@ dependencies {
|
||||
implementation(
|
||||
project(Module.accountDomain),
|
||||
project(Module.domain),
|
||||
project(Module.networkData),
|
||||
project(Module.presentation),
|
||||
|
||||
activity,
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<application>
|
||||
<activity
|
||||
android:name="me.proton.core.network.presentation.ui.ProtonWebViewActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.startup.InitializationProvider"
|
||||
|
||||
+37
-18
@@ -1,4 +1,22 @@
|
||||
package me.proton.core.presentation.ui
|
||||
/*
|
||||
* Copyright (c) 2024 Proton Technologies AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ProtonCore is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.network.presentation.ui
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
@@ -18,27 +36,28 @@ import kotlinx.parcelize.Parcelize
|
||||
import me.proton.core.network.data.di.BaseProtonApiUrl
|
||||
import me.proton.core.network.domain.NetworkPrefs
|
||||
import me.proton.core.network.domain.client.ExtraHeaderProvider
|
||||
import me.proton.core.network.presentation.ui.webview.ProtonWebViewClient
|
||||
import me.proton.core.presentation.databinding.ProtonWebviewActivityBinding
|
||||
import me.proton.core.presentation.ui.webview.ProtonWebViewClient
|
||||
import me.proton.core.presentation.ui.ProtonSecureActivity
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import java.io.ByteArrayInputStream
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ProtonWebViewActivity : ProtonSecureActivity<ProtonWebviewActivityBinding>(
|
||||
public class ProtonWebViewActivity : ProtonSecureActivity<ProtonWebviewActivityBinding>(
|
||||
ProtonWebviewActivityBinding::inflate
|
||||
) {
|
||||
|
||||
@Inject
|
||||
@BaseProtonApiUrl
|
||||
lateinit var baseApiUrl: HttpUrl
|
||||
internal lateinit var baseApiUrl: HttpUrl
|
||||
|
||||
@Inject
|
||||
lateinit var networkPrefs: NetworkPrefs
|
||||
internal lateinit var networkPrefs: NetworkPrefs
|
||||
|
||||
@Inject
|
||||
lateinit var extraHeaderProvider: ExtraHeaderProvider
|
||||
internal lateinit var extraHeaderProvider: ExtraHeaderProvider
|
||||
|
||||
private val input: Input by lazy { requireNotNull(intent?.extras?.getParcelable(ARG_INPUT)) }
|
||||
private val successUrlRegex by lazy { input.successUrlRegex?.toRegex() }
|
||||
@@ -114,7 +133,7 @@ class ProtonWebViewActivity : ProtonSecureActivity<ProtonWebviewActivityBinding>
|
||||
finish()
|
||||
}
|
||||
|
||||
inner class CustomWebViewClient(
|
||||
internal inner class CustomWebViewClient(
|
||||
private val shouldInterceptRequest: (request: WebResourceRequest) -> WebResourceResponse?,
|
||||
private val onPageLoadSuccess: () -> Unit,
|
||||
private val onPageLoadError: (Int?) -> Unit,
|
||||
@@ -157,7 +176,7 @@ class ProtonWebViewActivity : ProtonSecureActivity<ProtonWebviewActivityBinding>
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class Input(
|
||||
public data class Input(
|
||||
val url: String,
|
||||
val successUrlRegex: String? = null,
|
||||
val errorUrlRegex: String? = null,
|
||||
@@ -171,32 +190,32 @@ class ProtonWebViewActivity : ProtonSecureActivity<ProtonWebviewActivityBinding>
|
||||
) : Parcelable
|
||||
|
||||
@Parcelize
|
||||
sealed class Result(
|
||||
open val pageLoadErrorCode: Int?
|
||||
public sealed class Result(
|
||||
public open val pageLoadErrorCode: Int?
|
||||
) : Parcelable {
|
||||
data class Cancel(
|
||||
public data class Cancel(
|
||||
override val pageLoadErrorCode: Int?
|
||||
) : Result(pageLoadErrorCode)
|
||||
|
||||
data class Success(
|
||||
public data class Success(
|
||||
val url: String,
|
||||
override val pageLoadErrorCode: Int?
|
||||
) : Result(pageLoadErrorCode = null)
|
||||
|
||||
data class Error(
|
||||
public data class Error(
|
||||
val url: String,
|
||||
override val pageLoadErrorCode: Int?
|
||||
) : Result(pageLoadErrorCode)
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ARG_INPUT = "arg.protonWebViewActivityInput"
|
||||
const val ARG_RESULT = "arg.protonWebViewActivityResult"
|
||||
public companion object {
|
||||
internal const val ARG_INPUT = "arg.protonWebViewActivityInput"
|
||||
internal const val ARG_RESULT = "arg.protonWebViewActivityResult"
|
||||
|
||||
object ResultContract : ActivityResultContract<Input, Result?>() {
|
||||
public object ResultContract : ActivityResultContract<Input, Result?>() {
|
||||
|
||||
override fun createIntent(context: Context, input: Input) =
|
||||
override fun createIntent(context: Context, input: Input): Intent =
|
||||
Intent(context, ProtonWebViewActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
putExtra(ARG_INPUT, input)
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Proton Technologies AG
|
||||
* Copyright (c) 2024 Proton Technologies AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,7 @@
|
||||
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.presentation.ui.webview
|
||||
package me.proton.core.network.presentation.ui.webview
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.net.Uri
|
||||
@@ -36,7 +36,7 @@ import me.proton.core.presentation.utils.openBrowserLink
|
||||
* - Proton Extra Headers.
|
||||
*/
|
||||
// See: https://commonsware.com/blog/2015/06/11/psa-webview-regression.html.
|
||||
open class ProtonWebViewClient(
|
||||
public open class ProtonWebViewClient(
|
||||
private val networkPrefs: NetworkPrefs,
|
||||
private val extraHeaderProvider: ExtraHeaderProvider,
|
||||
) : WebViewClient() {
|
||||
@@ -46,9 +46,9 @@ open class ProtonWebViewClient(
|
||||
|
||||
private var isFinished = false
|
||||
|
||||
var shouldOpenLinkInBrowser = true
|
||||
public var shouldOpenLinkInBrowser: Boolean = true
|
||||
|
||||
fun Uri.isAlternativeHost() = alternativeUrl?.let { host == it.host } ?: false
|
||||
public fun Uri.isAlternativeHost(): Boolean = alternativeUrl?.let { host == it.host } ?: false
|
||||
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
isFinished = true
|
||||
@@ -68,7 +68,7 @@ open class ProtonWebViewClient(
|
||||
return false
|
||||
}
|
||||
|
||||
open fun shouldKeepInWebView(url: String): Boolean {
|
||||
public open fun shouldKeepInWebView(url: String): Boolean {
|
||||
if (!isFinished) return true
|
||||
return false
|
||||
}
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Proton Technologies AG
|
||||
* Copyright (c) 2024 Proton Technologies AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,7 @@
|
||||
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.presentation.ui.webview
|
||||
package me.proton.core.network.presentation.ui.webview
|
||||
|
||||
import android.net.http.SslCertificate
|
||||
import android.os.Build
|
||||
@@ -25,15 +25,15 @@ import me.proton.core.network.data.di.Constants
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.security.cert.X509Certificate
|
||||
|
||||
fun SslCertificate.isTrustedByLeafSPKIPinning() =
|
||||
public fun SslCertificate.isTrustedByLeafSPKIPinning(): Boolean =
|
||||
getCompatX509Cert()?.isTrustedByLeafSPKIPinning() ?: false
|
||||
|
||||
fun X509Certificate.isTrustedByLeafSPKIPinning() =
|
||||
public fun X509Certificate.isTrustedByLeafSPKIPinning(): Boolean =
|
||||
LeafSPKIPinningTrustManager(Constants.ALTERNATIVE_API_SPKI_PINS).runCatching {
|
||||
checkServerTrusted(arrayOf(this@isTrustedByLeafSPKIPinning), "generic")
|
||||
}.isSuccess
|
||||
|
||||
fun SslCertificate.getCompatX509Cert(): X509Certificate? = when (Build.VERSION.SDK_INT) {
|
||||
public fun SslCertificate.getCompatX509Cert(): X509Certificate? = when (Build.VERSION.SDK_INT) {
|
||||
in Build.VERSION_CODES.Q..Int.MAX_VALUE -> x509Certificate
|
||||
else -> {
|
||||
// Hidden API, there is no way to access this value otherwise.
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Proton Technologies AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ProtonCore is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.network.presentation.util
|
||||
|
||||
import android.content.res.Resources
|
||||
import me.proton.core.network.domain.ApiException
|
||||
import me.proton.core.network.domain.ApiResult
|
||||
import me.proton.core.presentation.R
|
||||
|
||||
/**
|
||||
* Return localised and user readable error message.
|
||||
*/
|
||||
@Suppress("UseIfInsteadOfWhen")
|
||||
public fun Throwable.getUserMessage(resources: Resources): String? = when (this) {
|
||||
// All api errors are wrapped with ApiException.
|
||||
is ApiException -> getUserMessage(resources)
|
||||
// Currently all other errors return their original message.
|
||||
else -> message
|
||||
}
|
||||
|
||||
internal fun ApiException.getUserMessage(resources: Resources): String? = when (error) {
|
||||
is ApiResult.Error.Certificate,
|
||||
is ApiResult.Error.Connection -> resources.getString(R.string.presentation_general_connection_error)
|
||||
is ApiResult.Error.Http,
|
||||
is ApiResult.Error.Parse -> message
|
||||
}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Proton Technologies AG
|
||||
* Copyright (c) 2024 Proton Technologies AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,7 @@
|
||||
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.presentation.utils
|
||||
package me.proton.core.network.presentation.util
|
||||
|
||||
import android.content.res.Resources
|
||||
import io.mockk.every
|
||||
@@ -58,6 +58,7 @@ dependencies {
|
||||
implementation(
|
||||
// Core
|
||||
project(Module.kotlinUtil),
|
||||
project(Module.networkPresentation),
|
||||
|
||||
// Features
|
||||
project(Module.countryPresentation),
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ import me.proton.core.payment.presentation.viewmodel.BillingCommonViewModel
|
||||
import me.proton.core.payment.presentation.viewmodel.BillingViewModel
|
||||
import me.proton.core.plan.domain.entity.SubscriptionManagement
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.util.kotlin.CoreLogger
|
||||
import me.proton.core.util.kotlin.exhaustive
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ import me.proton.core.payment.presentation.viewmodel.BillingCommonViewModel
|
||||
import me.proton.core.payment.presentation.viewmodel.PaymentOptionsViewModel
|
||||
import me.proton.core.plan.domain.entity.SubscriptionManagement
|
||||
import me.proton.core.presentation.ui.adapter.selectableProtonAdapter
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.util.kotlin.exhaustive
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ import me.proton.core.payment.presentation.viewmodel.PaymentTokenApprovalViewMod
|
||||
import me.proton.core.payment.domain.entity.PaymentTokenStatus
|
||||
import me.proton.core.payment.domain.entity.ProtonPaymentToken
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.util.kotlin.exhaustive
|
||||
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ import me.proton.core.payment.presentation.R
|
||||
import me.proton.core.plan.domain.entity.SubscriptionManagement
|
||||
import me.proton.core.plan.domain.usecase.PerformSubscribe
|
||||
import me.proton.core.plan.domain.usecase.ValidateSubscriptionPlan
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.test.android.ArchTest
|
||||
import me.proton.core.test.kotlin.CoroutinesTest
|
||||
import me.proton.core.test.kotlin.assertIs
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ import me.proton.core.plan.domain.entity.SubscriptionManagement
|
||||
import me.proton.core.plan.domain.usecase.GetCurrentSubscription
|
||||
import me.proton.core.plan.domain.usecase.PerformSubscribe
|
||||
import me.proton.core.plan.domain.usecase.ValidateSubscriptionPlan
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.test.android.ArchTest
|
||||
import me.proton.core.test.kotlin.CoroutinesTest
|
||||
import me.proton.core.test.kotlin.assertIs
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ import me.proton.core.payment.domain.entity.PaymentTokenStatus
|
||||
import me.proton.core.payment.domain.entity.ProtonPaymentToken
|
||||
import me.proton.core.payment.domain.usecase.GetPaymentTokenStatus
|
||||
import me.proton.core.payment.presentation.entity.SecureEndpoint
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.test.android.ArchTest
|
||||
import me.proton.core.test.kotlin.CoroutinesTest
|
||||
import me.proton.core.test.kotlin.assertIs
|
||||
|
||||
@@ -63,6 +63,7 @@ dependencies {
|
||||
|
||||
implementation(
|
||||
project(Module.kotlinUtil),
|
||||
project(Module.networkPresentation),
|
||||
project(Module.planData),
|
||||
`android-ktx`,
|
||||
`coroutines-core`,
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ import me.proton.core.plan.presentation.viewmodel.DynamicPlanListViewModel.State
|
||||
import me.proton.core.plan.presentation.entity.DynamicUser
|
||||
import me.proton.core.presentation.ui.ProtonFragment
|
||||
import me.proton.core.presentation.utils.formatCentsPriceDefaultLocale
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.presentation.utils.viewBinding
|
||||
import java.util.Objects
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ import me.proton.core.plan.presentation.viewmodel.DynamicSelectPlanViewModel.Act
|
||||
import me.proton.core.plan.presentation.viewmodel.DynamicSelectPlanViewModel.State
|
||||
import me.proton.core.plan.presentation.entity.DynamicUser
|
||||
import me.proton.core.presentation.utils.addOnBackPressedCallback
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.presentation.utils.viewBinding
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ import me.proton.core.plan.presentation.viewmodel.DynamicSubscriptionViewModel.S
|
||||
import me.proton.core.plan.presentation.entity.DynamicUser
|
||||
import me.proton.core.presentation.ui.ProtonFragment
|
||||
import me.proton.core.presentation.utils.formatCentsPriceDefaultLocale
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.presentation.utils.viewBinding
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ import me.proton.core.plan.presentation.viewmodel.DynamicUpgradePlanViewModel.Ac
|
||||
import me.proton.core.plan.presentation.viewmodel.DynamicUpgradePlanViewModel.Action.SetUser
|
||||
import me.proton.core.plan.presentation.viewmodel.DynamicUpgradePlanViewModel.State
|
||||
import me.proton.core.presentation.ui.ProtonFragment
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.presentation.utils.viewBinding
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ import me.proton.core.plan.presentation.viewmodel.BasePlansViewModel
|
||||
import me.proton.core.plan.presentation.viewmodel.SignupPlansViewModel
|
||||
import me.proton.core.presentation.utils.addOnBackPressedCallback
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.viewBinding
|
||||
import me.proton.core.util.kotlin.exhaustive
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ import me.proton.core.plan.presentation.viewmodel.BasePlansViewModel
|
||||
import me.proton.core.plan.presentation.viewmodel.UpgradePlansViewModel
|
||||
import me.proton.core.presentation.utils.addOnBackPressedCallback
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.launchOnScreenView
|
||||
import me.proton.core.presentation.utils.viewBinding
|
||||
import me.proton.core.util.kotlin.exhaustive
|
||||
|
||||
@@ -26,8 +26,8 @@ import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.runtime.structuralEqualityPolicy
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import me.proton.core.presentation.utils.ProtonColorUtils.intenseColorVariant
|
||||
import me.proton.core.presentation.utils.ProtonColorUtils.strongColorVariant
|
||||
import me.proton.core.compose.util.ProtonColorUtils.intenseColorVariant
|
||||
import me.proton.core.compose.util.ProtonColorUtils.strongColorVariant
|
||||
|
||||
private object ProtonPalette {
|
||||
val Haiti = Color(0xFF1B1340)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Proton Technologies AG
|
||||
* Copyright (c) 2024 Proton Technologies AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,7 @@
|
||||
* along with ProtonCore. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package me.proton.core.presentation.utils
|
||||
package me.proton.core.compose.util
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
@@ -43,7 +43,6 @@ android {
|
||||
|
||||
dependencies {
|
||||
api(
|
||||
project(Module.networkDomain),
|
||||
activity,
|
||||
appcompat,
|
||||
`constraint-layout`,
|
||||
@@ -61,7 +60,6 @@ dependencies {
|
||||
|
||||
implementation(
|
||||
project(Module.kotlinUtil),
|
||||
project(Module.networkData),
|
||||
`android-ktx`,
|
||||
`core-splashscreen`,
|
||||
drawerLayout,
|
||||
|
||||
@@ -31,11 +31,6 @@
|
||||
android:name=".ui.alert.ForceUpdateActivity"
|
||||
android:theme="@style/ProtonTheme.Transparent" />
|
||||
|
||||
<activity
|
||||
android:name="me.proton.core.presentation.ui.ProtonWebViewActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Proton Technologies AG
|
||||
* Copyright (c) 2024 Proton Technologies AG
|
||||
* This file is part of Proton AG and ProtonCore.
|
||||
*
|
||||
* ProtonCore is free software: you can redistribute it and/or modify
|
||||
@@ -19,25 +19,10 @@
|
||||
package me.proton.core.presentation.utils
|
||||
|
||||
import android.content.res.Resources
|
||||
import me.proton.core.network.domain.ApiException
|
||||
import me.proton.core.network.domain.ApiResult
|
||||
import me.proton.core.presentation.R
|
||||
|
||||
/**
|
||||
* Return localised and user readable error message.
|
||||
*/
|
||||
@Suppress("UseIfInsteadOfWhen")
|
||||
fun Throwable.getUserMessage(resources: Resources): String? = when (this) {
|
||||
// All api errors are wrapped with ApiException.
|
||||
is ApiException -> getUserMessage(resources)
|
||||
// Currently all other errors return their original message.
|
||||
else -> message
|
||||
}
|
||||
|
||||
internal fun ApiException.getUserMessage(resources: Resources): String? = when (error) {
|
||||
is ApiResult.Error.Certificate,
|
||||
is ApiResult.Error.Connection,
|
||||
is ApiResult.Error.Timeout -> resources.getString(R.string.presentation_general_connection_error)
|
||||
is ApiResult.Error.Http,
|
||||
is ApiResult.Error.Parse -> message
|
||||
}
|
||||
@Deprecated(
|
||||
"Moved to network-presentation",
|
||||
ReplaceWith("getUserMessage(resources)", "me.proton.core.network.presentation.util.getUserMessage"),
|
||||
DeprecationLevel.ERROR
|
||||
)
|
||||
fun Throwable.getUserMessage(resources: Resources): String? = error("Not implemented")
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ import me.proton.core.presentation.utils.InputValidationResult
|
||||
import me.proton.core.presentation.utils.InvalidPasswordProvider
|
||||
import me.proton.core.presentation.utils.addOnBackPressedCallback
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.presentation.utils.onFailure
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import me.proton.core.presentation.ui.ProtonFragment
|
||||
import me.proton.core.presentation.ui.alert.FragmentDialogResultLauncher
|
||||
import me.proton.core.presentation.utils.addOnBackPressedCallback
|
||||
import me.proton.core.presentation.utils.errorSnack
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.presentation.utils.hideKeyboard
|
||||
import me.proton.core.presentation.utils.onClick
|
||||
import me.proton.core.presentation.utils.onFailure
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ import me.proton.core.crypto.common.keystore.KeyStoreCrypto
|
||||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.network.domain.ApiException
|
||||
import me.proton.core.network.domain.ApiResult
|
||||
import me.proton.core.presentation.utils.getUserMessage
|
||||
import me.proton.core.network.presentation.util.getUserMessage
|
||||
import me.proton.core.test.android.ArchTest
|
||||
import me.proton.core.test.kotlin.CoroutinesTest
|
||||
import me.proton.core.test.kotlin.assertIs
|
||||
|
||||
Reference in New Issue
Block a user