From 7355e24baab44de03883894a6068d61b30ed7830 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 17 Oct 2022 19:51:34 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/tap/common/extensions/WebView.kt | 19 ++ .../products/wallet/saltPay/UtorgWebView.kt | 167 ++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 app/src/main/java/com/tangem/tap/common/extensions/WebView.kt create mode 100644 app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/UtorgWebView.kt diff --git a/app/src/main/java/com/tangem/tap/common/extensions/WebView.kt b/app/src/main/java/com/tangem/tap/common/extensions/WebView.kt new file mode 100644 index 0000000000..ebe938a1ec --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/extensions/WebView.kt @@ -0,0 +1,19 @@ +package com.tangem.tap.common.extensions + +import android.webkit.WebView + +/** +[REDACTED_AUTHOR] + */ +fun WebView.configureSettings() { + settings.apply { + javaScriptEnabled = true + domStorageEnabled = true + } +} + +fun WebView.stop() { + stopLoading() + pauseTimers() + destroy() +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/UtorgWebView.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/UtorgWebView.kt new file mode 100644 index 0000000000..865e826100 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/saltPay/UtorgWebView.kt @@ -0,0 +1,167 @@ +package com.tangem.tap.features.onboarding.products.wallet.saltPay + +import android.app.Activity +import android.content.Intent +import android.net.Uri +import android.provider.MediaStore +import android.text.TextUtils +import android.webkit.PermissionRequest +import android.webkit.ValueCallback +import android.webkit.WebChromeClient +import android.webkit.WebResourceRequest +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.activity.ComponentActivity +import androidx.core.app.ActivityCompat +import com.tangem.tap.common.ActivityResultCallbackHolder +import com.tangem.tap.common.OnActivityResultCallback +import com.tangem.tap.common.extensions.dispatchDialogShow +import com.tangem.tap.common.extensions.isPermissionGranted +import com.tangem.tap.common.redux.AppDialog +import com.tangem.tap.store +import com.tangem.wallet.R +import java.io.File + +/** +[REDACTED_AUTHOR] + */ +class UtorgWebViewClient( + private val onSuccess: () -> Unit, + private val successUrl: String, +) : WebViewClient() { + + override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean = + if (successUrl == request.url.toString()) { + onSuccess() + true + } else { + false + } +} + +class UtorgWebChromeClient( + private val activity: ComponentActivity, + private val activityResultCallbackHolder: ActivityResultCallbackHolder = activity as ActivityResultCallbackHolder, +) : WebChromeClient() { + + private val fileChooseRequestCode = 1002 + private val permissionRequestCode = 1003 + private val onActivityResultCallback: OnActivityResultCallback = ::onActivityResult + + private val permissionList = listOf( + "android.permission.CAMERA", + "android.permission.WRITE_EXTERNAL_STORAGE", + ) + + private var filePathCallback: ValueCallback>? = null + private var mediaUri: Uri? = null + + override fun onShowFileChooser( + webView: WebView?, + filePathCallback: ValueCallback>, + fileChooserParams: FileChooserParams?, + ): Boolean { + activityResultCallbackHolder.addOnActivityResultCallback(onActivityResultCallback) + if (!readyToShowFileChooser()) return false + + val type: String + if (fileChooserParams != null && fileChooserParams.acceptTypes != null && fileChooserParams.acceptTypes.isNotEmpty()) { + type = if (!TextUtils.isEmpty(fileChooserParams.acceptTypes[0])) fileChooserParams.acceptTypes[0] else "*/*" + this.filePathCallback = filePathCallback + } else { + return false + } + proceedOnType(type, fileChooserParams.isCaptureEnabled) + + return true + } + + private fun readyToShowFileChooser(): Boolean { + val permissionsToGrant = permissionList.filterNot { activity.isPermissionGranted(it) }.toTypedArray() + return if (permissionsToGrant.isNotEmpty()) { + ActivityCompat.requestPermissions(activity, permissionsToGrant, permissionRequestCode) + false + } else { + true + } + } + + private fun proceedOnType(type: String, isCaptureEnabled: Boolean) { + if (isCaptureEnabled) { + mediaUri = Uri.fromFile(File(getImageCaptureCachePath())) + val imageCaptureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) + imageCaptureIntent.putExtra("output", mediaUri) + activity.startActivityForResult( + Intent.createChooser(imageCaptureIntent, "Image Chooser"), + fileChooseRequestCode, + ) + } else { + mediaUri = Uri.fromFile(File(getImageCaptureCachePath())) + + val getContentIntent = Intent(Intent.ACTION_GET_CONTENT) + getContentIntent.addCategory(Intent.CATEGORY_OPENABLE) + getContentIntent.type = "image/*" + + // val imageCaptureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) + // imageCaptureIntent.putExtra("output", mediaUri) + + val chooserIntent = Intent.createChooser(getContentIntent, "Pick a photo") + // chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(imageCaptureIntent)) + + activity.startActivityForResult( + Intent.createChooser(chooserIntent, "Image Chooser"), + fileChooseRequestCode, + ) + } + } + + private fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + when (requestCode) { + fileChooseRequestCode -> { + if (resultCode != Activity.RESULT_OK) { + filePathCallback?.onReceiveValue(null) + clean() + return + } + if (data == null) { + filePathCallback?.onReceiveValue(arrayOf(mediaUri!!)) + } else { + val uri = FileChooserParams.parseResult(resultCode, data) + filePathCallback?.onReceiveValue(uri) + } + clean() + } + permissionRequestCode -> { + val notGranted = permissionList.filterNot { activity.isPermissionGranted(it) } + if (notGranted.isNotEmpty()) { + val permissionsName = notGranted.joinToString("\n") { it.permissionName() } + store.dispatchDialogShow( + AppDialog.SimpleOkDialog( + header = activity.getString(R.string.common_warning), + message = "Permission access is required to pass authorization." + + "To grant permission \n" + + "$permissionsName \n" + + "you must enable them in the app's settings", + ), + ) + } + } + } + } + + override fun onPermissionRequest(request: PermissionRequest) { + request.grant(request.resources) + } + + private fun getImageCaptureCachePath(): String = "cached_photo_" + System.currentTimeMillis() + ".jpg" + + private fun clean() { + activityResultCallbackHolder.removeOnActivityResultCallback(onActivityResultCallback) + filePathCallback = null + mediaUri = null + } + + private fun String.permissionName(): String { + return this.slice(this.lastIndexOf(".") until this.length) + } +} \ No newline at end of file