Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions app/src/main/java/one/mixin/android/extension/ContextExtension.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ import androidx.annotation.ColorInt
import androidx.annotation.RequiresApi
import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.browser.customtabs.CustomTabsIntent
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.ui.platform.LocalDensity
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
Expand Down Expand Up @@ -906,6 +904,52 @@ fun Context.openUrl(
}
}

fun Context.openInBrowser(
url: String,
extraHeaders: Bundle? = null,
): Boolean {
val browserUrl = url.trim()
if (browserUrl.isBlank()) return false
var uri = browserUrl.toUri()
if (uri.scheme.isNullOrBlank()) {
uri = Uri.parse("http://$browserUrl")
}
if (!uri.scheme.equals("http", true) && !uri.scheme.equals("https", true)) {
return false
}
Comment thread
Tougee marked this conversation as resolved.

try {
val customTabsIntent =
CustomTabsIntent.Builder()
.setDefaultColorSchemeParams(
CustomTabColorSchemeParams.Builder()
.setToolbarColor(ContextCompat.getColor(this, android.R.color.white))
.build(),
)
.setShowTitle(true)
.build()
extraHeaders?.let {
customTabsIntent.intent.putExtra(Browser.EXTRA_HEADERS, it)
}
customTabsIntent.launchUrl(this, uri)
return true
} catch (e: Exception) {
Timber.e(e, "OpenInBrowser")
try {
val intent = Intent(Intent.ACTION_VIEW, uri)
.putExtra(Browser.EXTRA_APPLICATION_ID, packageName)
extraHeaders?.let {
intent.putExtra(Browser.EXTRA_HEADERS, it)
}
startActivity(intent)
return true
} catch (e: Exception) {
Timber.e(e, "OpenInBrowser")
}
}
return false
}

fun Context.openExternalUrl(url: String) {
try {
var uri = Uri.parse(url)
Expand Down
42 changes: 41 additions & 1 deletion app/src/main/java/one/mixin/android/ui/web/WebFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ import one.mixin.android.extension.matchResourcePattern
import one.mixin.android.extension.openAsUrl
import one.mixin.android.extension.openAsUrlOrQrScan
import one.mixin.android.extension.openCamera
import one.mixin.android.extension.openInBrowser
import one.mixin.android.extension.openPermissionSetting
import one.mixin.android.extension.openUrl
import one.mixin.android.extension.putString
Expand Down Expand Up @@ -951,7 +952,10 @@ class WebFragment : BaseFragment() {
},
signBotSignature = { appId, reloadPublicKey, metho, path, body, callbackFunction ->
botSign(appId, reloadPublicKey, metho, path, body, callbackFunction)
}
},
openInBrowserAction = { url ->
openInBrowser(url)
},
)
webAppInterface?.let { webView.addJavascriptInterface(it, "MixinContext") }
webView.addJavascriptInterface(
Expand Down Expand Up @@ -1038,6 +1042,36 @@ class WebFragment : BaseFragment() {
}
}

private fun openInBrowser(url: String): Boolean {
if (viewDestroyed()) return false
val browserUrl = url.toOpenInBrowserUrlOrNull() ?: return false
val context = context ?: return false
lifecycleScope.launch {
if (viewDestroyed()) return@launch
context.openInBrowser(
browserUrl,
Bundle().apply {
putString("Mixin", BuildConfig.VERSION_NAME)
},
)
}
return true
}
Comment thread
Tougee marked this conversation as resolved.

private fun String.toOpenInBrowserUrlOrNull(): String? {
val url = trim()
if (url.isBlank() || url.equals("undefined", true) || url.equals("null", true)) {
return null
}
var uri = url.toUri()
if (uri.scheme.isNullOrBlank()) {
uri = Uri.parse("http://$url")
}
return url.takeIf {
uri.scheme.equals("http", true) || uri.scheme.equals("https", true)
}
}

private fun closeSelf() {
if (viewDestroyed()) return
requireActivity().finish()
Expand Down Expand Up @@ -2171,6 +2205,7 @@ class WebFragment : BaseFragment() {
var tipSignAction: ((String, String, String) -> Unit)? = null,
var getAssetAction: ((Array<String>, String) -> Unit)? = null,
var signBotSignature: ((String, Boolean, String, String, String, String) -> Unit)? = null,
var openInBrowserAction: ((String) -> Boolean)? = null,
) {
@JavascriptInterface
fun showToast(toast: String) {
Expand Down Expand Up @@ -2215,6 +2250,11 @@ class WebFragment : BaseFragment() {
closeAction?.invoke()
}

@JavascriptInterface
fun openInBrowser(url: String): Boolean {
return openInBrowserAction?.invoke(url) ?: false
}

@JavascriptInterface
fun getTipAddress(
chainId: String,
Expand Down